new file mode 100644
--- /dev/null
+++ b/.hgignore
@@ -0,0 +1,12 @@
+\.orig$
+\.orig\..*$
+\.chg\..*$
+\.rej$
+\.conflict\~$
+
+^data/templates_c$
+^logs/tickets.log$
+
+syntax: glob
+.hgignore
+.idea/workspace.xml
new file mode 100644
--- /dev/null
+++ b/.htaccess
@@ -0,0 +1,14 @@
+<IfModule mod_rewrite.c>
+ RewriteEngine on
+
+ RewriteBase /
+ RewriteCond %{REQUEST_FILENAME} !-f
+ RewriteCond %{REQUEST_FILENAME} !-d
+ RewriteCond %{REQUEST_URI} !(.*)/$
+ RewriteRule ^(.*) $1/ [R,L]
+
+ RewriteCond %{REQUEST_FILENAME} !-f
+ RewriteCond %{REQUEST_FILENAME} !-d
+ RewriteCond %{REQUEST_URI} (.*)/$ [NC]
+ RewriteRule ^(.*)/$ /?page=$1 [L,QSA]
+</IfModule>
new file mode 100644
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1,1 @@
+TicketSystem
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/.idea/TicketSystem.iml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="WEB_MODULE" version="4">
+ <component name="NewModuleRootManager">
+ <content url="file://$MODULE_DIR$" />
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ </component>
+</module>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/.idea/codeStyleSettings.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="ProjectCodeStyleSettingsManager">
+ <option name="PER_PROJECT_SETTINGS">
+ <value>
+ <XML>
+ <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
+ </XML>
+ </value>
+ </option>
+ <option name="PREFERRED_PROJECT_CODE_STYLE" value="Default (1)" />
+ </component>
+</project>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/.idea/dictionaries/praktikant.xml
@@ -0,0 +1,3 @@
+<component name="ProjectDictionaryState">
+ <dictionary name="praktikant" />
+</component>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="Encoding">
+ <file url="file://$PROJECT_DIR$/config/config.php" charset="UTF-8" />
+ <file url="file://$PROJECT_DIR$/css/main.css" charset="UTF-8" />
+ <file url="file://$PROJECT_DIR$/templates/benutzerverwaltungs/abmelden.tpl" charset="UTF-8" />
+ <file url="file://$PROJECT_DIR$/templates/benutzerverwaltungs/anmelden.tpl" charset="UTF-8" />
+ <file url="file://$PROJECT_DIR$/templates/benutzerverwaltungs/benutzerverwaltung.tpl" charset="UTF-8" />
+ <file url="file://$PROJECT_DIR$/templates/benutzerverwaltungs/meinprofil.tpl" charset="UTF-8" />
+ <file url="file://$PROJECT_DIR$/templates/benutzerverwaltungs/registrieren.tpl" charset="UTF-8" />
+ <file url="file://$PROJECT_DIR$/templates/error/error.tpl" charset="UTF-8" />
+ <file url="file://$PROJECT_DIR$/templates/footer.tpl" charset="UTF-8" />
+ <file url="file://$PROJECT_DIR$/templates/header.tpl" charset="UTF-8" />
+ <file url="file://$PROJECT_DIR$/templates/home/home.tpl" charset="UTF-8" />
+ <file url="file://$PROJECT_DIR$/templates/layout.tpl" charset="UTF-8" />
+ <file url="file://$PROJECT_DIR$/templates/tickets/tickets.tpl" charset="UTF-8" />
+ <file url="PROJECT" charset="UTF-8" />
+ </component>
+</project>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,7 @@
+<component name="InspectionProjectProfileManager">
+ <profile version="1.0">
+ <option name="myName" value="Project Default" />
+ <inspection_tool class="SqlDialectInspection" enabled="false" level="WARNING" enabled_by_default="false" />
+ <inspection_tool class="SqlNoDataSourceInspection" enabled="false" level="WARNING" enabled_by_default="false" />
+ </profile>
+</component>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,7 @@
+<component name="InspectionProjectProfileManager">
+ <settings>
+ <option name="PROJECT_PROFILE" value="Project Default" />
+ <option name="USE_PROJECT_PROFILE" value="true" />
+ <version value="1.0" />
+ </settings>
+</component>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="ProjectLevelVcsManager" settingsEditedManually="false">
+ <OptionsSetting value="true" id="Add" />
+ <OptionsSetting value="true" id="Remove" />
+ <OptionsSetting value="true" id="Checkout" />
+ <OptionsSetting value="true" id="Update" />
+ <OptionsSetting value="true" id="Status" />
+ <OptionsSetting value="true" id="Edit" />
+ <ConfirmationsSetting value="0" id="Add" />
+ <ConfirmationsSetting value="0" id="Remove" />
+ </component>
+</project>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="ProjectModuleManager">
+ <modules>
+ <module fileurl="file://$PROJECT_DIR$/.idea/TicketSystem.iml" filepath="$PROJECT_DIR$/.idea/TicketSystem.iml" />
+ </modules>
+ </component>
+</project>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/.idea/php.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="PhpProjectSharedConfiguration" php_language_level="5.4.0" />
+</project>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="VcsDirectoryMappings">
+ <mapping directory="$PROJECT_DIR$" vcs="hg4idea" />
+ </component>
+</project>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,1279 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="ChangeListManager">
+ <list default="true" id="7bee8c38-4d16-466d-b05e-cfdeec8ff6af" name="Default" comment="Initialies Layout des BfWs" />
+ <list id="8732f4c9-96b1-49c6-9723-a582f5bcb680" name="New changelist" comment="New changelist" />
+ <ignored path="TicketSystem.iws" />
+ <ignored path=".idea/workspace.xml" />
+ <ignored path=".idea/dataSources.local.xml" />
+ <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
+ <option name="TRACKING_ENABLED" value="true" />
+ <option name="SHOW_DIALOG" value="false" />
+ <option name="HIGHLIGHT_CONFLICTS" value="true" />
+ <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
+ <option name="LAST_RESOLUTION" value="IGNORE" />
+ </component>
+ <component name="ChangesViewManager" flattened_view="false" show_ignored="false" />
+ <component name="CreatePatchCommitExecutor">
+ <option name="PATCH_PATH" value="" />
+ </component>
+ <component name="DatabaseView">
+ <option name="FLATTEN" value="false" />
+ <option name="GROUP_BY_TYPE" value="true" />
+ <option name="SORT_CHILDREN" value="false" />
+ <option name="SHOW_TABLE_CONSTRAINTS" value="true" />
+ </component>
+ <component name="ExecutionTargetManager" SELECTED_TARGET="default_target" />
+ <component name="FavoritesManager">
+ <favorites_list name="TicketSystem" />
+ </component>
+ <component name="FileEditorManager">
+ <leaf SIDE_TABS_SIZE_LIMIT_KEY="300" />
+ </component>
+ <component name="Git.Settings">
+ <option name="PREVIOUS_COMMIT_AUTHORS">
+ <list>
+ <option value="Markus Bröker" />
+ </list>
+ </option>
+ <option name="ROOT_SYNC" value="DONT_SYNC" />
+ <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
+ </component>
+ <component name="IdeDocumentHistory">
+ <option name="CHANGED_PATHS">
+ <list>
+ <option value="$PROJECT_DIR$/classes/mvc/model/TTicket.php" />
+ <option value="$PROJECT_DIR$/templates/header.tpl" />
+ <option value="$PROJECT_DIR$/templates/layout.tpl" />
+ <option value="$PROJECT_DIR$/templates/home/home.tpl" />
+ <option value="$PROJECT_DIR$/classes/mvc/model/TGroup.php" />
+ <option value="$PROJECT_DIR$/templates/tickets/ticketanlegen.tpl" />
+ <option value="$PROJECT_DIR$/templates/tickets/tickets.tpl" />
+ <option value="$PROJECT_DIR$/templates/history/historie.tpl" />
+ <option value="$PROJECT_DIR$/classes/mvc/view/View.php" />
+ <option value="$PROJECT_DIR$/classes/Dispatcher.php" />
+ <option value="$PROJECT_DIR$/classes/mvc/controller/BenutzerverwaltungsController.php" />
+ <option value="$PROJECT_DIR$/classes/mvc/controller/Controller.php" />
+ <option value="$PROJECT_DIR$/classes/mvc/controller/ErrorController.php" />
+ <option value="$PROJECT_DIR$/classes/mvc/controller/HistoryController.php" />
+ <option value="$PROJECT_DIR$/classes/mvc/model/Model.php" />
+ <option value="$PROJECT_DIR$/classes/mvc/model/TAction.php" />
+ <option value="$PROJECT_DIR$/classes/mvc/model/TText.php" />
+ <option value="$PROJECT_DIR$/classes/mvc/model/TUser.php" />
+ <option value="$PROJECT_DIR$/classes/mvc/model/TView.php" />
+ <option value="$PROJECT_DIR$/classes/DBInterface.php" />
+ <option value="$PROJECT_DIR$/classes/Request.php" />
+ <option value="$PROJECT_DIR$/classes/mvc/controller/HomeController.php" />
+ <option value="$PROJECT_DIR$/classes/mvc/controller/TicketsController.php" />
+ <option value="$PROJECT_DIR$/library/bfw/Database.php" />
+ <option value="$PROJECT_DIR$/library/bfw/DBInterface.php" />
+ <option value="$PROJECT_DIR$/library/bfw/Dispatcher.php" />
+ <option value="$PROJECT_DIR$/library/bfw/Request.php" />
+ <option value="$PROJECT_DIR$/library/bfw/Response.php" />
+ <option value="$PROJECT_DIR$/classes/bfw/mvc/controller/ErrorController.php" />
+ <option value="$PROJECT_DIR$/classes/bfw/mvc/model/TAction.php" />
+ <option value="$PROJECT_DIR$/classes/bfw/mvc/model/TGroup.php" />
+ <option value="$PROJECT_DIR$/classes/bfw/mvc/model/THistory.php" />
+ <option value="$PROJECT_DIR$/classes/bfw/mvc/model/TStatus.php" />
+ <option value="$PROJECT_DIR$/classes/bfw/mvc/model/TText.php" />
+ <option value="$PROJECT_DIR$/classes/bfw/mvc/model/TUser.php" />
+ <option value="$PROJECT_DIR$/classes/bfw/mvc/model/TView.php" />
+ <option value="$PROJECT_DIR$/index.php" />
+ <option value="$PROJECT_DIR$/classes/bfw/Request.php" />
+ <option value="$PROJECT_DIR$/classes/bfw/mvc/model/Model.php" />
+ <option value="$PROJECT_DIR$/classes/bfw/mvc/controller/HistoryController.php" />
+ <option value="$PROJECT_DIR$/classes/bfw/Database.php" />
+ <option value="$PROJECT_DIR$/classes/bfw/mvc/controller/Controller.php" />
+ <option value="$PROJECT_DIR$/classes/bfw/mvc/view/View.php" />
+ <option value="$PROJECT_DIR$/classes/bfw/Dispatcher.php" />
+ <option value="$PROJECT_DIR$/classes/bfw/mvc/controller/TicketsController.php" />
+ <option value="$PROJECT_DIR$/classes/bfw/mvc/controller/BenutzerverwaltungsController.php" />
+ <option value="$PROJECT_DIR$/config/config.php" />
+ <option value="$PROJECT_DIR$/classes/bfw/mvc/model/TTicket.php" />
+ <option value="$PROJECT_DIR$/classes/bfw/mvc/controller/HomeController.php" />
+ <option value="$PROJECT_DIR$/logs/tickets.log" />
+ <option value="$PROJECT_DIR$/.hgignore" />
+ </list>
+ </option>
+ </component>
+ <component name="JsBuildToolGruntFileManager" detection-done="true" />
+ <component name="JsBuildToolPackageJson" detection-done="true" />
+ <component name="JsGulpfileManager">
+ <detection-done>true</detection-done>
+ </component>
+ <component name="PhpDebugGeneral" hide_empty_superglobals="false" />
+ <component name="PhpServers">
+ <servers>
+ <server host="ticket" id="deecc2df-00c6-496c-a329-f753c4476f9e" name="Ticket-System-App" port="8080" />
+ </servers>
+ </component>
+ <component name="PhpWorkspaceProjectConfiguration" backward_compatibility_performed="true" interpreter_name="PHP 5.4" />
+ <component name="ProjectFrameBounds">
+ <option name="x" value="-8" />
+ <option name="y" value="1" />
+ <option name="width" value="1936" />
+ <option name="height" value="1055" />
+ </component>
+ <component name="ProjectInspectionProfilesVisibleTreeState">
+ <entry key="Project Default">
+ <profile-state>
+ <expanded-state>
+ <State>
+ <id />
+ </State>
+ <State>
+ <id>Blade files</id>
+ </State>
+ <State>
+ <id>CSS</id>
+ </State>
+ <State>
+ <id>Code SmellPHP</id>
+ </State>
+ <State>
+ <id>Code StylePHP</id>
+ </State>
+ <State>
+ <id>CoffeeScript</id>
+ </State>
+ <State>
+ <id>Control flow issuesJavaScript</id>
+ </State>
+ <State>
+ <id>Cucumber</id>
+ </State>
+ <State>
+ <id>DOM issuesJavaScript</id>
+ </State>
+ <State>
+ <id>Error handlingJavaScript</id>
+ </State>
+ <State>
+ <id>General</id>
+ </State>
+ <State>
+ <id>GeneralJavaScript</id>
+ </State>
+ <State>
+ <id>GeneralPHP</id>
+ </State>
+ <State>
+ <id>HTML</id>
+ </State>
+ <State>
+ <id>Ini Files</id>
+ </State>
+ <State>
+ <id>Internationalization issues</id>
+ </State>
+ <State>
+ <id>Invalid elementsCSS</id>
+ </State>
+ <State>
+ <id>JavaScript</id>
+ </State>
+ <State>
+ <id>JavaScript function metricsJavaScript</id>
+ </State>
+ <State>
+ <id>JavaScript validity issuesJavaScript</id>
+ </State>
+ <State>
+ <id>PHP</id>
+ </State>
+ <State>
+ <id>Potentially confusing code constructsJavaScript</id>
+ </State>
+ <State>
+ <id>Probable bugsCoffeeScript</id>
+ </State>
+ <State>
+ <id>Probable bugsJavaScript</id>
+ </State>
+ <State>
+ <id>Probable bugsPHP</id>
+ </State>
+ <State>
+ <id>SQL</id>
+ </State>
+ <State>
+ <id>UndefinedPHP</id>
+ </State>
+ <State>
+ <id>UnusedPHP</id>
+ </State>
+ <State>
+ <id>XPath</id>
+ </State>
+ </expanded-state>
+ </profile-state>
+ </entry>
+ </component>
+ <component name="ProjectLevelVcsManager" settingsEditedManually="true">
+ <OptionsSetting value="true" id="Add" />
+ <OptionsSetting value="true" id="Remove" />
+ <OptionsSetting value="true" id="Checkout" />
+ <OptionsSetting value="true" id="Update" />
+ <OptionsSetting value="true" id="Status" />
+ <OptionsSetting value="true" id="Edit" />
+ <ConfirmationsSetting value="0" id="Add" />
+ <ConfirmationsSetting value="0" id="Remove" />
+ </component>
+ <component name="ProjectView">
+ <navigator currentView="ProjectPane" proportions="" version="1">
+ <flattenPackages />
+ <showMembers />
+ <showModules />
+ <showLibraryContents />
+ <hideEmptyPackages />
+ <abbreviatePackageNames />
+ <autoscrollToSource />
+ <autoscrollFromSource />
+ <sortByType />
+ <manualOrder />
+ <foldersAlwaysOnTop value="true" />
+ </navigator>
+ <panes>
+ <pane id="ProjectPane">
+ <subPane>
+ <PATH>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="TicketSystem" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+ </PATH_ELEMENT>
+ </PATH>
+ </subPane>
+ </pane>
+ <pane id="Scratches" />
+ <pane id="Scope">
+ <subPane subId="Project Files">
+ <PATH>
+ <PATH_ELEMENT USER_OBJECT="Root">
+ <option name="myItemId" value="" />
+ <option name="myItemType" value="" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT USER_OBJECT="TicketSystem">
+ <option name="myItemId" value="" />
+ <option name="myItemType" value="" />
+ </PATH_ELEMENT>
+ </PATH>
+ <PATH>
+ <PATH_ELEMENT USER_OBJECT="Root">
+ <option name="myItemId" value="" />
+ <option name="myItemType" value="" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT USER_OBJECT="TicketSystem">
+ <option name="myItemId" value="" />
+ <option name="myItemType" value="" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT USER_OBJECT="templates">
+ <option name="myItemId" value="" />
+ <option name="myItemType" value="" />
+ </PATH_ELEMENT>
+ </PATH>
+ <PATH>
+ <PATH_ELEMENT USER_OBJECT="Root">
+ <option name="myItemId" value="" />
+ <option name="myItemType" value="" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT USER_OBJECT="TicketSystem">
+ <option name="myItemId" value="" />
+ <option name="myItemType" value="" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT USER_OBJECT="js">
+ <option name="myItemId" value="" />
+ <option name="myItemType" value="" />
+ </PATH_ELEMENT>
+ </PATH>
+ <PATH>
+ <PATH_ELEMENT USER_OBJECT="Root">
+ <option name="myItemId" value="" />
+ <option name="myItemType" value="" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT USER_OBJECT="TicketSystem">
+ <option name="myItemId" value="" />
+ <option name="myItemType" value="" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT USER_OBJECT="css">
+ <option name="myItemId" value="" />
+ <option name="myItemType" value="" />
+ </PATH_ELEMENT>
+ </PATH>
+ <PATH>
+ <PATH_ELEMENT USER_OBJECT="Root">
+ <option name="myItemId" value="" />
+ <option name="myItemType" value="" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT USER_OBJECT="TicketSystem">
+ <option name="myItemId" value="" />
+ <option name="myItemType" value="" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT USER_OBJECT="classes">
+ <option name="myItemId" value="" />
+ <option name="myItemType" value="" />
+ </PATH_ELEMENT>
+ </PATH>
+ </subPane>
+ </pane>
+ </panes>
+ </component>
+ <component name="PropertiesComponent">
+ <property name="last_opened_file_path" value="$PROJECT_DIR$" />
+ <property name="WebServerToolWindowFactoryState" value="false" />
+ <property name="recentsLimit" value="5" />
+ <property name="settings.editor.selected.configurable" value="project.propVCSSupport.Mappings" />
+ <property name="settings.editor.splitter.proportion" value="0.2" />
+ <property name="FileHistory.git4idea.history.GitHistoryProvider_flatWidth0" value="291" />
+ <property name="FileHistory.git4idea.history.GitHistoryProvider_flatOrder0" value="0" />
+ <property name="FileHistory.git4idea.history.GitHistoryProvider_flatWidth1" value="291" />
+ <property name="FileHistory.git4idea.history.GitHistoryProvider_flatOrder1" value="1" />
+ <property name="FileHistory.git4idea.history.GitHistoryProvider_flatWidth2" value="291" />
+ <property name="FileHistory.git4idea.history.GitHistoryProvider_flatOrder2" value="2" />
+ <property name="FileHistory.git4idea.history.GitHistoryProvider_flatWidth3" value="960" />
+ <property name="FileHistory.git4idea.history.GitHistoryProvider_flatOrder3" value="3" />
+ <property name="FileHistory.git4idea.history.GitHistoryProvider_treeWidth0" value="291" />
+ <property name="FileHistory.git4idea.history.GitHistoryProvider_treeOrder0" value="0" />
+ <property name="FileHistory.git4idea.history.GitHistoryProvider_treeWidth1" value="290" />
+ <property name="FileHistory.git4idea.history.GitHistoryProvider_treeOrder1" value="1" />
+ <property name="FileHistory.git4idea.history.GitHistoryProvider_treeWidth2" value="291" />
+ <property name="FileHistory.git4idea.history.GitHistoryProvider_treeOrder2" value="2" />
+ <property name="FileHistory.git4idea.history.GitHistoryProvider_treeWidth3" value="961" />
+ <property name="FileHistory.git4idea.history.GitHistoryProvider_treeOrder3" value="3" />
+ <property name="full.screen.before.presentation.mode" value="false" />
+ <property name="js-jscs-nodeInterpreter" value="C:\Program Files\nodejs\node.exe" />
+ </component>
+ <component name="RecentsManager">
+ <key name="MoveFile.RECENT_KEYS">
+ <recent name="C:\var\www\vhosts\TicketSystem\data\import" />
+ <recent name="C:\var\www\vhosts\TicketSystem\library\bfw\mvc\model" />
+ <recent name="C:\var\www\vhosts\TicketSystem\library\bfw\mvc\controller" />
+ <recent name="C:\var\www\vhosts\TicketSystem\library\bfw" />
+ <recent name="C:\xampp\htdocs\TicketSystem\templates\tickets" />
+ </key>
+ <key name="CopyFile.RECENT_KEYS">
+ <recent name="C:\var\www\vhosts\TicketSystem\library\bfw" />
+ </key>
+ </component>
+ <component name="RunManager" selected="PHP Web Application.Ticket">
+ <configuration default="false" name="index.php" type="JavascriptDebugType" factoryName="JavaScript Debug" temporary="true" nameIsGenerated="true" uri="http://localhost:63342/TicketSystem/index.php">
+ <method />
+ </configuration>
+ <configuration default="false" name="index.php" type="PhpLocalRunConfigurationType" factoryName="PHP Console" temporary="true" path="$PROJECT_DIR$/index.php">
+ <method />
+ </configuration>
+ <configuration default="true" type="AppEnginePhpConfigurationType" factoryName="App Engine for PHP">
+ <method />
+ </configuration>
+ <configuration default="true" type="ChromiumRemoteDebugType" factoryName="Chromium Remote">
+ <method />
+ </configuration>
+ <configuration default="true" type="JavascriptDebugType" factoryName="JavaScript Debug">
+ <method />
+ </configuration>
+ <configuration default="true" type="PHPUnitRunConfigurationType" factoryName="PHPUnit">
+ <TestRunner />
+ <method />
+ </configuration>
+ <configuration default="true" type="PhpBehatConfigurationType" factoryName="Behat">
+ <BehatRunner />
+ <method />
+ </configuration>
+ <configuration default="true" type="PhpLocalRunConfigurationType" factoryName="PHP Console">
+ <method />
+ </configuration>
+ <configuration default="true" type="PhpUnitRemoteRunConfigurationType" factoryName="PHPUnit on Server">
+ <method />
+ </configuration>
+ <configuration default="true" type="PhpWebAppRunConfigurationType" factoryName="PHP Web Application" server_name="Ticket-System-App">
+ <method />
+ </configuration>
+ <configuration default="true" type="js.build_tools.gulp" factoryName="Gulp.js">
+ <node-options />
+ <gulpfile />
+ <tasks />
+ <arguments />
+ <pass-parent-envs>true</pass-parent-envs>
+ <envs />
+ <method />
+ </configuration>
+ <configuration default="true" type="js.build_tools.npm" factoryName="npm">
+ <command value="run-script" />
+ <scripts />
+ <envs />
+ <method />
+ </configuration>
+ <configuration default="false" name="Ticket" type="PhpWebAppRunConfigurationType" factoryName="PHP Web Application" server_name="Ticket-System-App">
+ <method />
+ </configuration>
+ <configuration default="false" name="TicketSystem" type="PHPUnitRunConfigurationType" factoryName="PHPUnit">
+ <TestRunner directory="$PROJECT_DIR$" />
+ <method />
+ </configuration>
+ <list size="4">
+ <item index="0" class="java.lang.String" itemvalue="PHP Web Application.Ticket" />
+ <item index="1" class="java.lang.String" itemvalue="PHPUnit.TicketSystem" />
+ <item index="2" class="java.lang.String" itemvalue="JavaScript Debug.index.php" />
+ <item index="3" class="java.lang.String" itemvalue="PHP Script.index.php" />
+ </list>
+ <recent_temporary>
+ <list size="2">
+ <item index="0" class="java.lang.String" itemvalue="JavaScript Debug.index.php" />
+ <item index="1" class="java.lang.String" itemvalue="PHP Script.index.php" />
+ </list>
+ </recent_temporary>
+ </component>
+ <component name="ShelveChangesManager" show_recycled="false" />
+ <component name="SvnConfiguration">
+ <configuration />
+ </component>
+ <component name="TaskManager">
+ <task active="true" id="Default" summary="Default task">
+ <changelist id="7bee8c38-4d16-466d-b05e-cfdeec8ff6af" name="Default" comment="" />
+ <changelist id="8732f4c9-96b1-49c6-9723-a582f5bcb680" name="New changelist" comment="" />
+ <created>1446106927314</created>
+ <option name="number" value="Default" />
+ <updated>1446106927314</updated>
+ </task>
+ <task id="LOCAL-00004" summary="Entities korrigiert und erweitert ">
+ <created>1446729323360</created>
+ <option name="number" value="00004" />
+ <option name="project" value="LOCAL" />
+ <updated>1446729323360</updated>
+ </task>
+ <task id="LOCAL-00005" summary="Reset und Einspielen der Testdatensätze ">
+ <created>1446729389868</created>
+ <option name="number" value="00005" />
+ <option name="project" value="LOCAL" />
+ <updated>1446729389868</updated>
+ </task>
+ <task id="LOCAL-00006" summary="Korrekturen an den Content-Scripten ">
+ <created>1446729418220</created>
+ <option name="number" value="00006" />
+ <option name="project" value="LOCAL" />
+ <updated>1446729418220</updated>
+ </task>
+ <task id="LOCAL-00007" summary="Usability-Konzept (Entities) * Benutzer bekommen Feedback (Error, Success) ">
+ <created>1446733417486</created>
+ <option name="number" value="00007" />
+ <option name="project" value="LOCAL" />
+ <updated>1446733417486</updated>
+ </task>
+ <task id="LOCAL-00008" summary="Usability-Konzepte (Content) * (Benutzer bekommen Feedback)">
+ <created>1446733466299</created>
+ <option name="number" value="00008" />
+ <option name="project" value="LOCAL" />
+ <updated>1446733466299</updated>
+ </task>
+ <task id="LOCAL-00009" summary="Änderungen an TPersistence: => findMethoden fürs FW => unnötige Fetchmethoden entfernt => State ist wichtig und muss implementiert werden ">
+ <created>1446738450939</created>
+ <option name="number" value="00009" />
+ <option name="project" value="LOCAL" />
+ <updated>1446738450939</updated>
+ </task>
+ <task id="LOCAL-00010" summary="TTicket: Modifizierter State wird berücksichtigt ">
+ <created>1446738581392</created>
+ <option name="number" value="00010" />
+ <option name="project" value="LOCAL" />
+ <updated>1446738581392</updated>
+ </task>
+ <task id="LOCAL-00011" summary="Entities mit Kommentaren ">
+ <created>1446739228859</created>
+ <option name="number" value="00011" />
+ <option name="project" value="LOCAL" />
+ <updated>1446739228859</updated>
+ </task>
+ <task id="LOCAL-00012" summary="Usability-Konzepte (Content: Fehlermeldungen)">
+ <created>1446739263191</created>
+ <option name="number" value="00012" />
+ <option name="project" value="LOCAL" />
+ <updated>1446739263191</updated>
+ </task>
+ <task id="LOCAL-00013" summary="Suche bezieht sich auf /templates/ ">
+ <created>1446739420219</created>
+ <option name="number" value="00013" />
+ <option name="project" value="LOCAL" />
+ <updated>1446739420219</updated>
+ </task>
+ <task id="LOCAL-00014" summary="ticket.php: Textkürzungen ">
+ <created>1446743143014</created>
+ <option name="number" value="00014" />
+ <option name="project" value="LOCAL" />
+ <updated>1446743143014</updated>
+ </task>
+ <task id="LOCAL-00015" summary="Neue Testdaten für CSV Import ">
+ <created>1446743163200</created>
+ <option name="number" value="00015" />
+ <option name="project" value="LOCAL" />
+ <updated>1446743163200</updated>
+ </task>
+ <task id="LOCAL-00016" summary="Einlesen der CSV Daten per Knopfdruck ">
+ <created>1446743196390</created>
+ <option name="number" value="00016" />
+ <option name="project" value="LOCAL" />
+ <updated>1446743196390</updated>
+ </task>
+ <task id="LOCAL-00017" summary="Administratoren sehen auch den Systemdatensatz ">
+ <created>1446743219318</created>
+ <option name="number" value="00017" />
+ <option name="project" value="LOCAL" />
+ <updated>1446743219318</updated>
+ </task>
+ <task id="LOCAL-00018" summary="TPersistence: find liefert Instanz oder NULL TODO: Das muss natürlich konsistent durchgezogen werden ">
+ <created>1446743288336</created>
+ <option name="number" value="00018" />
+ <option name="project" value="LOCAL" />
+ <updated>1446743288336</updated>
+ </task>
+ <task id="LOCAL-00019" summary="Single-Quotes instead of Double-Quotes ">
+ <created>1446744997822</created>
+ <option name="number" value="00019" />
+ <option name="project" value="LOCAL" />
+ <updated>1446744997822</updated>
+ </task>
+ <task id="LOCAL-00020" summary="Kommentare für die Klassen des Projekts! ">
+ <created>1446812011676</created>
+ <option name="number" value="00020" />
+ <option name="project" value="LOCAL" />
+ <updated>1446812011676</updated>
+ </task>
+ <task id="LOCAL-00021" summary="Korrekturen und Kommentare der Entity-Klassen ">
+ <created>1446825176292</created>
+ <option name="number" value="00021" />
+ <option name="project" value="LOCAL" />
+ <updated>1446825176292</updated>
+ </task>
+ <task id="LOCAL-00022" summary="Umstellungen: Auslagerung der Funktionen in externe Datei ">
+ <created>1446825223051</created>
+ <option name="number" value="00022" />
+ <option name="project" value="LOCAL" />
+ <updated>1446825223051</updated>
+ </task>
+ <task id="LOCAL-00023" summary="Triviale Design und CSS Anpassungen ">
+ <created>1446825252554</created>
+ <option name="number" value="00023" />
+ <option name="project" value="LOCAL" />
+ <updated>1446825252554</updated>
+ </task>
+ <task id="LOCAL-00024" summary="functions.php: Fehlerkorrektur TTUser wird TUser ">
+ <created>1446829604486</created>
+ <option name="number" value="00024" />
+ <option name="project" value="LOCAL" />
+ <updated>1446829604486</updated>
+ </task>
+ <task id="LOCAL-00025" summary="Ticket Code kommentiert ">
+ <created>1446829649750</created>
+ <option name="number" value="00025" />
+ <option name="project" value="LOCAL" />
+ <updated>1446829649750</updated>
+ </task>
+ <task id="LOCAL-00026" summary="Systemdatensatz wird nicht mehr angezeigt ">
+ <created>1446829675612</created>
+ <option name="number" value="00026" />
+ <option name="project" value="LOCAL" />
+ <updated>1446829675612</updated>
+ </task>
+ <task id="LOCAL-00027" summary="Ticket-Controller besitzt nun keine Seiteneffekte mehr. ">
+ <created>1446830746242</created>
+ <option name="number" value="00027" />
+ <option name="project" value="LOCAL" />
+ <updated>1446830746242</updated>
+ </task>
+ <task id="LOCAL-00028" summary="Weitere Seiteneffekte korrigiert und behoben ">
+ <created>1446831582445</created>
+ <option name="number" value="00028" />
+ <option name="project" value="LOCAL" />
+ <updated>1446831582445</updated>
+ </task>
+ <task id="LOCAL-00029" summary="Ticketsystem nach Änderungen repariert und begradigt ">
+ <created>1447066664805</created>
+ <option name="number" value="00029" />
+ <option name="project" value="LOCAL" />
+ <updated>1447066664805</updated>
+ </task>
+ <task id="LOCAL-00030" summary="Ticketsystem V-0.9 ">
+ <created>1447084835242</created>
+ <option name="number" value="00030" />
+ <option name="project" value="LOCAL" />
+ <updated>1447084835242</updated>
+ </task>
+ <task id="LOCAL-00031" summary="Ticketsystem V1.0 ">
+ <created>1447089662246</created>
+ <option name="number" value="00031" />
+ <option name="project" value="LOCAL" />
+ <updated>1447089662246</updated>
+ </task>
+ <task id="LOCAL-00032" summary="Kleinere Korrekturen am Benutzer- und TicketController ">
+ <created>1447091968465</created>
+ <option name="number" value="00032" />
+ <option name="project" value="LOCAL" />
+ <updated>1447091968465</updated>
+ </task>
+ <task id="LOCAL-00033" summary="MVC Struktur Beginn">
+ <created>1447150724532</created>
+ <option name="number" value="00033" />
+ <option name="project" value="LOCAL" />
+ <updated>1447150724532</updated>
+ </task>
+ <task id="LOCAL-00034" summary="Umstellung auf MVC Struktur Löschen der alten Content Scripte ">
+ <created>1447163453276</created>
+ <option name="number" value="00034" />
+ <option name="project" value="LOCAL" />
+ <updated>1447163453276</updated>
+ </task>
+ <task id="LOCAL-00035" summary="Umstellung auf MVC Struktur Model, View und Controller rudimentär lauffähig ">
+ <created>1447163499808</created>
+ <option name="number" value="00035" />
+ <option name="project" value="LOCAL" />
+ <updated>1447163499808</updated>
+ </task>
+ <task id="LOCAL-00036" summary="Umstellung auf MVC Struktur Model, View und Controller Struktur verbessert ">
+ <created>1447170912642</created>
+ <option name="number" value="00036" />
+ <option name="project" value="LOCAL" />
+ <updated>1447170912642</updated>
+ </task>
+ <task id="LOCAL-00037" summary="Abschließende Korrekturen fürs MVC und Fehlerbehandlung ">
+ <created>1447177820586</created>
+ <option name="number" value="00037" />
+ <option name="project" value="LOCAL" />
+ <updated>1447177820586</updated>
+ </task>
+ <task id="LOCAL-00038" summary="Annehmen / Laden Nachrichten für Supporter ">
+ <created>1447178469348</created>
+ <option name="number" value="00038" />
+ <option name="project" value="LOCAL" />
+ <updated>1447178469348</updated>
+ </task>
+ <task id="LOCAL-00039" summary="Smarty Templates in Ordnerstruktur verschoben">
+ <created>1447234256012</created>
+ <option name="number" value="00039" />
+ <option name="project" value="LOCAL" />
+ <updated>1447234256012</updated>
+ </task>
+ <task id="LOCAL-00040" summary="View und Dispatcher um Prefix erweitert Jetzt können die verschobenen Smarty-Templates geladen werden">
+ <created>1447234316811</created>
+ <option name="number" value="00040" />
+ <option name="project" value="LOCAL" />
+ <updated>1447234316811</updated>
+ </task>
+ <task id="LOCAL-00041" summary="Wiki-Einträge können nun sicher html-formatiert werden. ">
+ <created>1447234996320</created>
+ <option name="number" value="00041" />
+ <option name="project" value="LOCAL" />
+ <updated>1447234996320</updated>
+ </task>
+ <task id="LOCAL-00042" summary="HomeController nutzt eine klassenspezifische Konstante, die mit self referenziert werden 'kann' und allg. ref. werden muss! ">
+ <created>1447235061106</created>
+ <option name="number" value="00042" />
+ <option name="project" value="LOCAL" />
+ <updated>1447235061106</updated>
+ </task>
+ <task id="LOCAL-00043" summary="Controller implementiert nun ein ActionInterface ">
+ <created>1447235084606</created>
+ <option name="number" value="00043" />
+ <option name="project" value="LOCAL" />
+ <updated>1447235084606</updated>
+ </task>
+ <task id="LOCAL-00044" summary="TicketController mit logischer Korrektur Tickets werden immer geprüft und ausgewertet. ">
+ <created>1447235288555</created>
+ <option name="number" value="00044" />
+ <option name="project" value="LOCAL" />
+ <updated>1447235288555</updated>
+ </task>
+ <task id="LOCAL-00045" summary="Tiny-MCE Integration ">
+ <created>1447237215095</created>
+ <option name="number" value="00045" />
+ <option name="project" value="LOCAL" />
+ <updated>1447237215095</updated>
+ </task>
+ <task id="LOCAL-00046" summary="strip_tags, html_entity_decode und co für Textarea2InputFields ">
+ <created>1447238123381</created>
+ <option name="number" value="00046" />
+ <option name="project" value="LOCAL" />
+ <updated>1447238123381</updated>
+ </task>
+ <task id="LOCAL-00047" summary="Templates aufgehybscht ">
+ <created>1447244018241</created>
+ <option name="number" value="00047" />
+ <option name="project" value="LOCAL" />
+ <updated>1447244018241</updated>
+ </task>
+ <task id="LOCAL-00048" summary="Simpler Router für JS">
+ <created>1447244047276</created>
+ <option name="number" value="00048" />
+ <option name="project" value="LOCAL" />
+ <updated>1447244047276</updated>
+ </task>
+ <task id="LOCAL-00049" summary="CSS und HTML Anpassungen w3c-validor und formulare ">
+ <created>1447246445864</created>
+ <option name="number" value="00049" />
+ <option name="project" value="LOCAL" />
+ <updated>1447246445864</updated>
+ </task>
+ <task id="LOCAL-00050" summary="Änderungen nach Ablehnung Namespace bfw ">
+ <created>1447333974641</created>
+ <option name="number" value="00050" />
+ <option name="project" value="LOCAL" />
+ <updated>1447333974642</updated>
+ </task>
+ <task id="LOCAL-00051" summary="Initialies Layout des BfWs">
+ <created>1447334939609</created>
+ <option name="number" value="00051" />
+ <option name="project" value="LOCAL" />
+ <updated>1447334939611</updated>
+ </task>
+ <task id="LOCAL-00052" summary="Initialies Layout des BfWs">
+ <created>1447335423584</created>
+ <option name="number" value="00052" />
+ <option name="project" value="LOCAL" />
+ <updated>1447335423584</updated>
+ </task>
+ <option name="localTasksCounter" value="53" />
+ <servers />
+ </component>
+ <component name="TodoView">
+ <todo-panel id="selected-file">
+ <is-autoscroll-to-source value="true" />
+ </todo-panel>
+ <todo-panel id="all">
+ <are-packages-shown value="true" />
+ <is-autoscroll-to-source value="true" />
+ </todo-panel>
+ </component>
+ <component name="ToolWindowManager">
+ <frame x="-8" y="1" width="1936" height="1055" extended-state="0" />
+ <editor active="false" />
+ <layout>
+ <window_info id="Project" active="true" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.19189766" sideWeight="0.4962162" order="0" side_tool="false" content_ui="combo" />
+ <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32972974" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
+ <window_info id="Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32932165" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
+ <window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32946146" sideWeight="0.5" order="12" side_tool="true" content_ui="tabs" />
+ <window_info id="Database" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32995737" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
+ <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.23318872" sideWeight="0.5" order="9" side_tool="false" content_ui="tabs" />
+ <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+ <window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32972974" sideWeight="0.5" order="11" side_tool="false" content_ui="tabs" />
+ <window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.16044776" sideWeight="0.50378376" order="2" side_tool="true" content_ui="tabs" />
+ <window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
+ <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+ <window_info id="PHP-CGI Server" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="10" side_tool="false" content_ui="tabs" />
+ <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="SLIDING" type="SLIDING" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+ <window_info id="Application Servers" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="8" side_tool="false" content_ui="tabs" />
+ <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
+ <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32972974" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
+ <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
+ <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.33586133" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+ <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+ <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.3943662" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
+ </layout>
+ <layout-to-restore>
+ <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32972974" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
+ <window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
+ <window_info id="Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32972974" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
+ <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+ <window_info id="PHP-CGI Server" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="10" side_tool="false" content_ui="tabs" />
+ <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="SLIDING" type="SLIDING" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+ <window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32946146" sideWeight="0.5" order="12" side_tool="true" content_ui="tabs" />
+ <window_info id="Application Servers" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="8" side_tool="false" content_ui="tabs" />
+ <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
+ <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.23593074" sideWeight="0.5" order="9" side_tool="false" content_ui="tabs" />
+ <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32972974" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
+ <window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32972974" sideWeight="0.5" order="11" side_tool="false" content_ui="tabs" />
+ <window_info id="Project" active="true" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.1913646" sideWeight="0.4962162" order="0" side_tool="false" content_ui="combo" />
+ <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
+ <window_info id="Database" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32995737" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
+ <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32792208" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+ <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+ <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+ <window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.16044776" sideWeight="0.50378376" order="2" side_tool="true" content_ui="tabs" />
+ <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.3961039" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
+ </layout-to-restore>
+ </component>
+ <component name="UnknownFeatures">
+ <option featureType="com.intellij.fileTypeFactory" implementationName="*.hgignore" />
+ </component>
+ <component name="Vcs.Log.UiProperties">
+ <option name="RECENTLY_FILTERED_USER_GROUPS">
+ <collection />
+ </option>
+ <option name="RECENTLY_FILTERED_BRANCH_GROUPS">
+ <collection />
+ </option>
+ </component>
+ <component name="VcsContentAnnotationSettings">
+ <option name="myLimit" value="2678400000" />
+ </component>
+ <component name="VcsManagerConfiguration">
+ <option name="CHECK_CODE_CLEANUP_BEFORE_PROJECT_COMMIT" value="true" />
+ <MESSAGE value="Ticket-Controller besitzt nun keine Seiteneffekte mehr. " />
+ <MESSAGE value="Weitere Seiteneffekte korrigiert und behoben " />
+ <MESSAGE value="Ticketsystem nach Änderungen repariert und begradigt " />
+ <MESSAGE value="Ticketsystem V-0.9 " />
+ <MESSAGE value="Ticketsystem V1.0 " />
+ <MESSAGE value="Kleinere Korrekturen am Benutzer- und TicketController " />
+ <MESSAGE value="MVC Struktur Beginn" />
+ <MESSAGE value="Umstellung auf MVC Struktur Löschen der alten Content Scripte " />
+ <MESSAGE value="Umstellung auf MVC Struktur Model, View und Controller rudimentär lauffähig " />
+ <MESSAGE value="Umstellung auf MVC Struktur Model, View und Controller Struktur verbessert " />
+ <MESSAGE value="Abschließende Korrekturen fürs MVC und Fehlerbehandlung " />
+ <MESSAGE value="Annehmen / Laden Nachrichten für Supporter " />
+ <MESSAGE value="Smarty Templates in Ordnerstruktur verschoben" />
+ <MESSAGE value="View und Dispatcher um Prefix erweitert Jetzt können die verschobenen Smarty-Templates geladen werden" />
+ <MESSAGE value="Wiki-Einträge können nun sicher html-formatiert werden. " />
+ <MESSAGE value="HomeController nutzt eine klassenspezifische Konstante, die mit self referenziert werden 'kann' und allg. ref. werden muss! " />
+ <MESSAGE value="Controller implementiert nun ein ActionInterface " />
+ <MESSAGE value="TicketController mit logischer Korrektur Tickets werden immer geprüft und ausgewertet. " />
+ <MESSAGE value="Tiny-MCE Integration " />
+ <MESSAGE value="strip_tags, html_entity_decode und co für Textarea2InputFields " />
+ <MESSAGE value="Templates aufgehybscht " />
+ <MESSAGE value="Simpler Router für JS" />
+ <MESSAGE value="CSS und HTML Anpassungen w3c-validor und formulare " />
+ <MESSAGE value="Änderungen nach Ablehnung Namespace bfw " />
+ <MESSAGE value="Initialies Layout des BfWs" />
+ <option name="LAST_COMMIT_MESSAGE" value="Initialies Layout des BfWs" />
+ <option name="OPTIMIZE_IMPORTS_BEFORE_PROJECT_COMMIT" value="true" />
+ <option name="REFORMAT_BEFORE_PROJECT_COMMIT" value="true" />
+ </component>
+ <component name="XDebuggerManager">
+ <breakpoint-manager>
+ <option name="time" value="94" />
+ </breakpoint-manager>
+ <watches-manager />
+ </component>
+ <component name="editorHistoryManager">
+ <entry file="file://$PROJECT_DIR$/library/smarty/libs/sysplugins/smarty_internal_template.php">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="-15.153846">
+ <caret line="920" column="0" selection-start-line="920" selection-start-column="0" selection-end-line="920" selection-end-column="0" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/templates/error/error.tpl">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="-3.2692308">
+ <caret line="5" column="0" selection-start-line="5" selection-start-column="0" selection-end-line="5" selection-end-column="0" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/templates/footer.tpl">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="-7.8461537">
+ <caret line="12" column="6" selection-start-line="12" selection-start-column="6" selection-end-line="12" selection-end-column="6" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/js/main.js">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.07522124">
+ <caret line="3" column="0" selection-start-line="3" selection-start-column="0" selection-end-line="3" selection-end-column="0" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/templates/benutzerverwaltungs/resetpasswort.tpl">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0">
+ <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/templates/benutzerverwaltungs/anmelden.tpl">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="-0.0">
+ <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/templates/benutzerverwaltungs/abmelden.tpl">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0">
+ <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/templates/benutzerverwaltungs/registrieren.tpl">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0">
+ <caret line="0" column="3" selection-start-line="0" selection-start-column="3" selection-end-line="0" selection-end-column="3" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/config/log4php.xml">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.07825086">
+ <caret line="4" column="8" selection-start-line="4" selection-start-column="8" selection-end-line="4" selection-end-column="8" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/templates/benutzerverwaltungs/meinprofil.tpl">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="-0.0">
+ <caret line="0" column="40" selection-start-line="0" selection-start-column="40" selection-end-line="0" selection-end-column="40" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/templates/benutzerverwaltungs/benutzerverwaltung.tpl">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="-0.0">
+ <caret line="0" column="47" selection-start-line="0" selection-start-column="47" selection-end-line="0" selection-end-column="47" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="jar://$APPLICATION_HOME_DIR$/plugins/php/lib/php.jar!/com/jetbrains/php/lang/psi/stubs/data/standard_2.php">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.5330948">
+ <caret line="323" column="9" selection-start-line="323" selection-start-column="9" selection-end-line="323" selection-end-column="9" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/templates/home/home.tpl">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="-9.807693">
+ <caret line="15" column="10" selection-start-line="15" selection-start-column="10" selection-end-line="15" selection-end-column="10" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/templates/header.tpl">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="-0.5769231">
+ <caret line="13" column="121" selection-start-line="13" selection-start-column="121" selection-end-line="13" selection-end-column="121" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/templates/layout.tpl">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="-13.076923">
+ <caret line="20" column="40" selection-start-line="20" selection-start-column="40" selection-end-line="20" selection-end-column="40" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/templates/tickets/ticketanlegen.tpl">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="-19.615385">
+ <caret line="30" column="110" selection-start-line="30" selection-start-column="110" selection-end-line="30" selection-end-column="110" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/templates/tickets/tickets.tpl">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="-20.192308">
+ <caret line="77" column="5" selection-start-line="77" selection-start-column="5" selection-end-line="77" selection-end-column="5" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/templates/history/historie.tpl">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="-20.192308">
+ <caret line="35" column="0" selection-start-line="35" selection-start-column="0" selection-end-line="35" selection-end-column="0" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/.htaccess">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0">
+ <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/css/main.css">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="1.6422182">
+ <caret line="54" column="0" selection-start-line="54" selection-start-column="0" selection-end-line="54" selection-end-column="0" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/library/log4php/Logger.php">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="-258.92307">
+ <caret line="461" column="27" selection-start-line="461" selection-start-column="27" selection-end-line="461" selection-end-column="27" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/library/log4php/LoggerAppender.php">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="2.0679786">
+ <caret line="85" column="0" selection-start-line="85" selection-start-column="0" selection-end-line="85" selection-end-column="0" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/sql/init.sql">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0">
+ <caret line="397" column="0" selection-start-line="397" selection-start-column="0" selection-end-line="397" selection-end-column="0" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/classes/bfw/mvc/model/TStatus.php">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="-1.3076923">
+ <caret line="2" column="14" selection-start-line="2" selection-start-column="14" selection-end-line="2" selection-end-column="14" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/index.php">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="-4.576923">
+ <caret line="7" column="14" selection-start-line="7" selection-start-column="14" selection-end-line="7" selection-end-column="14" />
+ <folding>
+ <element signature="e#7#34#0#PHP" expanded="false" />
+ </folding>
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/classes/bfw/mvc/model/TView.php">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="-1.3076923">
+ <caret line="2" column="14" selection-start-line="2" selection-start-column="14" selection-end-line="2" selection-end-column="14" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/classes/bfw/mvc/model/TAction.php">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="-1.3076923">
+ <caret line="2" column="14" selection-start-line="2" selection-start-column="14" selection-end-line="2" selection-end-column="14" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/classes/bfw/mvc/model/TGroup.php">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="-0.65384614">
+ <caret line="2" column="5" selection-start-line="2" selection-start-column="5" selection-end-line="2" selection-end-column="5" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/classes/bfw/mvc/model/THistory.php">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="-0.65384614">
+ <caret line="3" column="0" selection-start-line="3" selection-start-column="0" selection-end-line="3" selection-end-column="0" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/classes/bfw/mvc/model/TText.php">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="-1.3076923">
+ <caret line="2" column="14" selection-start-line="2" selection-start-column="14" selection-end-line="2" selection-end-column="14" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/classes/bfw/mvc/model/TUser.php">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="-0.65384614">
+ <caret line="2" column="14" selection-start-line="2" selection-start-column="14" selection-end-line="2" selection-end-column="14" />
+ <folding>
+ <marker date="1447331073637" expanded="true" signature="1963:2077" placeholder="SELECT * FRO..%s..." />
+ <marker date="1447331073637" expanded="true" signature="2631:2907" placeholder="SELECT u.id,..t_user..." />
+ <marker date="1447331073637" expanded="true" signature="3446:3574" placeholder="SELECT count..t_ticket..." />
+ </folding>
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/classes/bfw/mvc/view/View.php">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="41.76923">
+ <caret line="6" column="27" selection-start-line="6" selection-start-column="27" selection-end-line="6" selection-end-column="27" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/classes/bfw/mvc/model/Model.php">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.12164579">
+ <caret line="4" column="11" selection-start-line="4" selection-start-column="11" selection-end-line="4" selection-end-column="11" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/classes/bfw/mvc/controller/TicketsController.php">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.33273703">
+ <caret line="15" column="23" selection-start-line="15" selection-start-column="23" selection-end-line="15" selection-end-column="23" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/classes/bfw/DBInterface.php">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0">
+ <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/classes/bfw/Dispatcher.php">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0">
+ <caret line="50" column="66" selection-start-line="50" selection-start-column="66" selection-end-line="50" selection-end-column="66" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/classes/bfw/Response.php">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.33452594">
+ <caret line="11" column="39" selection-start-line="11" selection-start-column="39" selection-end-line="11" selection-end-column="39" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/classes/bfw/Request.php">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0">
+ <caret line="14" column="29" selection-start-line="14" selection-start-column="29" selection-end-line="14" selection-end-column="29" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/classes/bfw/mvc/controller/Controller.php">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.34263566">
+ <caret line="13" column="26" selection-start-line="13" selection-start-column="26" selection-end-line="13" selection-end-column="26" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/classes/bfw/mvc/controller/ErrorController.php">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.052713178">
+ <caret line="2" column="14" selection-start-line="2" selection-start-column="14" selection-end-line="2" selection-end-column="14" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/classes/bfw/mvc/controller/HistoryController.php">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.28992248">
+ <caret line="11" column="27" selection-start-line="11" selection-start-column="27" selection-end-line="11" selection-end-column="27" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/config/config.php">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="-21.576923">
+ <caret line="35" column="16" selection-start-line="35" selection-start-column="16" selection-end-line="35" selection-end-column="16" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/data/import/test_users.csv">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0">
+ <caret line="11" column="80" selection-start-line="11" selection-start-column="80" selection-end-line="11" selection-end-column="80" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/data/import/test_tickets.csv">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0">
+ <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/classes/bfw/mvc/controller/BenutzerverwaltungsController.php">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.026356589">
+ <caret line="13" column="23" selection-start-line="13" selection-start-column="23" selection-end-line="13" selection-end-column="23" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/classes/bfw/mvc/model/TTicket.php">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="100.96154">
+ <caret line="4" column="4" selection-start-line="4" selection-start-column="4" selection-end-line="4" selection-end-column="4" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/library/smarty/demo/templates/footer.tpl">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.026356589">
+ <caret line="1" column="0" selection-start-line="1" selection-start-column="0" selection-end-line="1" selection-end-column="0" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/classes/bfw/mvc/controller/HomeController.php">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.2372093">
+ <caret line="9" column="28" selection-start-line="9" selection-start-column="28" selection-end-line="9" selection-end-column="28" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/classes/bfw/Database.php">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.026356589">
+ <caret line="372" column="0" selection-start-line="372" selection-start-column="0" selection-end-line="372" selection-end-column="0" />
+ <folding>
+ <marker date="1447331919883" expanded="true" signature="3192:3287" placeholder="SELECT * FRO..${$table}..." />
+ <marker date="1447331919883" expanded="true" signature="3967:4060" placeholder="SELECT * FRO..%s..." />
+ <marker date="1447331919883" expanded="true" signature="4608:4708" placeholder="SELECT * FRO..%s..." />
+ <marker date="1447331919883" expanded="true" signature="5331:5431" placeholder="SELECT * FRO..%s..." />
+ <marker date="1447331919883" expanded="true" signature="5932:6034" placeholder="SELECT * FRO..%s..." />
+ <marker date="1447331919883" expanded="true" signature="6678:6780" placeholder="SELECT * FRO..%s..." />
+ <marker date="1447331919883" expanded="true" signature="7791:7848" placeholder="INSERT INTO `%s`..." />
+ <marker date="1447331919883" expanded="true" signature="8643:8701" placeholder="UPDATE `%s` ..." />
+ <marker date="1447331919883" expanded="true" signature="9179:9223" placeholder="DELETE FROM ..." />
+ <marker date="1447331919883" expanded="true" signature="10274:10311" placeholder="DELETE FROM ..." />
+ <marker date="1447331919883" expanded="true" signature="10355:10393" placeholder="DELETE FROM ..." />
+ <marker date="1447331919883" expanded="true" signature="10437:10472" placeholder="DELETE FROM ..." />
+ <marker date="1447331919883" expanded="true" signature="10517:10559" placeholder="ALTER TABLE `t_history`..." />
+ <marker date="1447331919883" expanded="true" signature="10603:10644" placeholder="ALTER TABLE `t_ticket`..." />
+ <marker date="1447331919883" expanded="true" signature="10688:10727" placeholder="ALTER TABLE `t_user`..." />
+ <marker date="1447331919883" expanded="true" signature="12473:12512" placeholder="INSERT INTO ..." />
+ </folding>
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/logs/tickets.log">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0">
+ <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/.hgignore">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.20029455">
+ <caret line="8" column="0" selection-start-line="8" selection-start-column="0" selection-end-line="8" selection-end-column="0" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </component>
+ <component name="hg4idea.settings">
+ <option name="RECENT_HG_ROOT_PATH" value="$PROJECT_DIR$" />
+ </component>
+ <component name="masterDetails">
+ <states>
+ <state key="ScopeChooserConfigurable.UI">
+ <settings>
+ <splitter-proportions>
+ <option name="proportions">
+ <list>
+ <option value="0.2" />
+ </list>
+ </option>
+ </splitter-proportions>
+ </settings>
+ </state>
+ </states>
+ </component>
+</project>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/classes/bfw/DBInterface.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace bfw {
+ interface DBInterface {
+
+ /* fetch methods */
+ public function fetch($table, $cond);
+
+ public function fetchAll($table, $cond);
+
+ /* find methoden */
+ public function find($table, $id);
+
+ public function findAll($table, $sys);
+
+ public function findByField($table, $field, $value);
+
+ function findAllByField($table, $field, $value);
+
+ /* Abfrage Methoden */
+ public function query($sql);
+
+ /* Persistence Methods */
+ public function persist($table, $array);
+
+ public function store($table, $id, $array);
+
+ public function delete($table, $id);
+
+ /* PK Management */
+ public function getLastInsertedId();
+ }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/classes/bfw/Database.php
@@ -0,0 +1,438 @@
+<?php
+
+namespace bfw {
+
+ /**
+ * Copyright(C) 2015 Markus Bröker<broeker.markus@googlemail.com>
+ *
+ */
+ class Database implements DBInterface {
+ private static $logger = null;
+
+ private $link;
+ private static $handle = null;
+
+ private function __construct() {
+ self::$logger = \Logger::getLogger('__CLASS__');
+
+ $this->link = mysqli_connect($host = 'localhost', $user = 'ticketsystem', $password = 'ticketsystem', $database = 'ticketsystem');
+ mysqli_set_charset($this->link, 'utf8');
+ }
+
+ /**
+ * <b>Liefert das Singleton-Pattern der Datenbank-Schicht</b>
+ *
+ * Es existiert in einem Lauf, einem Scope, immer nur ein DB-Handle zur gleichen Zeit.
+ *
+ * Damit das ganze vernünftig flutscht, muss man natürlich berücksichtigen, dass ein SP state-lastig ist!
+ *
+ * Definition des States: Ein Abfrageergebnis stellt solange den State des SP da, bis eine neue Abfrage
+ * einen neuen State erzeugt.
+ *
+ * @return Database|null
+ */
+ public static function getInstance() {
+ if (self::$handle == null) {
+ self::$handle = new Database();
+ }
+
+ return self::$handle;
+ }
+
+ /**
+ * <b>Std-Abfrage Methode der DB-Klasse</b>
+ *
+ * Das übergebene SQL-Statement wird als assoziatives, ein-oder mehrdimensionales Array zurück geliefert.
+ *
+ * array = (
+ * 'id' => 1,
+ * 'name' => 'Ticket',
+ * );
+ *
+ * @param $sql
+ * @return array|null
+ */
+ public function query($sql) {
+ self::$logger->info(sprintf('%s(%s) ', __METHOD__, $sql));
+
+ $result = mysqli_query($this->link, $sql);
+
+ if ($result == false) {
+ return null;
+ }
+
+ if ($result->num_rows == 0) {
+ return null;
+ }
+
+ $rows = array();
+ while (($row = $result->fetch_assoc())) {
+ $rows[] = $row;
+ }
+
+
+ return $rows;
+ }
+
+ /**
+ * <b>Abfragen, die kein ResultSet zurück liefern</b>
+ *
+ * SQL-Statements, die nur TRUE oder FALSE zurück liefern,
+ * müssen per EXECUTE ausgeführt werden.
+ *
+ * @param $sql
+ * @return bool|mysqli_result
+ */
+ public function execute($sql) {
+ self::$logger->info(sprintf('%s(%s) ', __METHOD__, $sql));
+
+ $result = mysqli_query($this->link, $sql);
+
+ return $result;
+ }
+
+ /**
+ * <b>Die einfache Fetch-Methode für das Table-Row-Pattern</b>
+ *
+ * Es wird ein SQL Statement bezogen auf die aktuelle Tabelle zusammen
+ * gebaut. Dieses kann optional eine WHERE clause beinhalten.
+ *
+ * @param $table
+ * @param string $cond
+ * @return array|null
+ */
+ public function fetch($table, $cond = 'id > 1') {
+ self::$logger->info(sprintf('%s(%s, %s) ', __METHOD__, $table, $cond));
+
+ $sql = "
+ SELECT
+ *
+ FROM
+ $table
+ WHERE
+ $cond
+ ";
+
+ $result = mysqli_query($this->link, $sql);
+
+ if ($result == false) {
+ return null;
+ }
+
+ return $result->fetch_assoc();
+ }
+
+ /**
+ * <b>Die multiple Fetch-Methode für das Table-Row-Pattern</b>
+ *
+ * Der Rückgabewert ist ein Array mit allen Zeilen als assoziatives Array
+ *
+ * @param $table
+ * @param string $cond
+ * @return array|null
+ */
+ public function fetchAll($table, $cond = 'id > 0') {
+ self::$logger->info(sprintf('%s(%s, %s) ', __METHOD__, $table, $cond));
+
+ $sql = sprintf("
+ SELECT
+ *
+ FROM
+ `%s`
+ WHERE
+ %s
+ ", $table, $cond);
+
+ return $this->query($sql);
+ }
+
+ /**
+ * <b>Die einfache Find-Methode für das Table-Row-Pattern</b>
+ *
+ * Der Rückgabewert ist entweder die Tabellenzeile 'id' oder null
+ * im assoziativen Array.
+ *
+ * @param $table
+ * @param $id
+ * @return array|null
+ */
+ public function find($table, $id) {
+ self::$logger->info(sprintf('%s(%s, %s) ', __METHOD__, $table, $id));
+
+ $sql = sprintf("
+ SELECT
+ *
+ FROM
+ `%s`
+ WHERE
+ `id` = %d
+ ", $table, $id);
+
+ $result = mysqli_query($this->link, $sql);
+
+ if ($result == false) {
+ return null;
+ }
+
+ return $result->fetch_assoc();
+ }
+
+ /**
+ * <b>Die multiple Find-Methode für das Table-Row-Pattern</b>
+ *
+ * Es liefert alle Reihen als assoziatives Array zurück.
+ *
+ * @param $table
+ * @return array|null
+ */
+ public function findAll($table, $sys_id = 1) {
+ self::$logger->info(sprintf('%s(%s) ', __METHOD__, $table));
+
+ $sql = sprintf("
+ SELECT
+ *
+ FROM
+ `%s`
+ WHERE
+ `id` > %d
+ ", $table, $sys_id);
+
+ return $this->query($sql);
+ }
+
+ /**
+ * <b>Liefert ein Resultset bezogen auf ein bestimmtes Feld zurück</b>
+ *
+ * @param $table
+ * @param $field
+ * @param $value
+ * @return array|null
+ */
+ public function findByField($table, $field, $value) {
+ self::$logger->info(sprintf('%s(%s, %s, %s) ', __METHOD__, $table, $field, $value));
+
+ $sql = sprintf("
+ SELECT
+ *
+ FROM
+ `%s`
+ WHERE
+ `%s` = '%s'
+ ", $table, $field, $value);
+
+ $result = mysqli_query($this->link, $sql);
+
+ if ($result == false) {
+ return null;
+ }
+
+ return $result->fetch_assoc();
+ }
+
+ /**
+ * <b>Liefert mehrere Resultsets bezogen auf ein bestimmtes Feld zurück</b>
+ *
+ * @param $table
+ * @param $field
+ * @param $value
+ * @return array|null
+ */
+ public function findAllByField($table, $field, $value) {
+ self::$logger->info(sprintf('%s(%s, %s) ', __METHOD__, $table, $field));
+
+ $sql = sprintf("
+ SELECT
+ *
+ FROM
+ `%s`
+ WHERE
+ `%s` = '%s'
+ ", $table, $field, $value);
+
+ return $this->query($sql);
+ }
+
+ /**
+ * <b>Die Standard Persist Methode erstellt einen neuen DB-Eintrag in der angegebenen Tabelle</b>
+ *
+ * @param $table
+ * @param $array
+ * @return bool|mysqli_result
+ */
+ public function persist($table, $array) {
+ self::$logger->info(sprintf('%s(%s, %s) ', __METHOD__, $table, print_r($array, true)));
+
+ $keys = array();
+ foreach (array_keys($array) as $key) {
+ if ($key != 'id') {
+ $keys[] = sprintf("`%s`", $key);
+ }
+ }
+
+ $fieldList = implode(", ", $keys);
+
+ $values = array();
+ foreach ($array as $key => $value) {
+ if ($key != 'id') {
+ $values[] = sprintf("'%s'", $value);
+ }
+ }
+
+ $fields = implode(",", $values);
+
+ $sql = sprintf("
+ INSERT INTO `%s`
+ (`id`, %s) VALUES (NULL, %s)
+ ", $table, $fieldList, $fields);
+
+ return $this->execute($sql);
+ }
+
+ /**
+ * <b>Die Standard store Methode aktualisiert einen DB-Eintrag in der angegebenen Tabelle</b>
+ *
+ * @param $table
+ * @param $id
+ * @param $array
+ * @return bool
+ */
+ public function store($table, $id, $array) {
+ self::$logger->info(sprintf('%s(%s, %d, %s) ', __METHOD__, $table, $id, print_r($array, true)));
+
+ $list = array();
+ foreach ($array as $key => $value) {
+ if ($key != 'id') {
+ $list[] = sprintf("`%s` = '%s'", $key, $value);
+ }
+ }
+
+ $listItems = implode(", ", $list);
+
+ $sql = sprintf("
+ UPDATE `%s`
+ SET %s
+ WHERE `id` = %d
+ ", $table, $listItems, $id);
+
+
+ return $this->execute($sql);
+ }
+
+ /**
+ * <b>Die Standard Delete Methode löscht einen bestehenden DB-Eintrag aus der angegebenen Tabelle</b>
+ *
+ * @param $table
+ * @param $id
+ * @return bool
+ */
+ public function delete($table, $id) {
+ self::$logger->info(sprintf('%s(%s, %s) ', __METHOD__, $table, $id));
+
+ $sql = sprintf("
+ DELETE FROM `%s`
+ WHERE `id` = %d;
+ ", $table, $id);
+
+ return $this->execute($sql);
+ }
+
+ /**
+ * <b>Liefert die letzte, verwendete ID, die eingefügt wurde.</b>
+ *
+ * Es gilt zu beachten, dass es sich hierbei um eine state-behaftete Methode handelt.
+ *
+ * <b>Nach 3 Inserts liefert diese Methode definitiv nur den PK des letzten INSERTS.</b>
+ *
+ * @return int|string
+ */
+ public function getLastInsertedId() {
+ $lastInsertedId = mysqli_insert_id($this->link);
+
+ self::$logger->info(sprintf('%s(): %d', __METHOD__, $lastInsertedId));
+
+ return $lastInsertedId;
+ }
+
+ /**
+ * <b>Diese Methode löscht alle Tickets, History und Benutzer weg</b>
+ *
+ * Diese Methode sollte dann aufgerufen werden, wenn die Anwendung deployed wird
+ *
+ * Auf Deutsch: "Vor der Präsi alles weglöschen."
+ *
+ * @return bool
+ */
+ public function cleanup() {
+ $status = $this->execute("DELETE FROM `t_ticket` WHERE `id` > 1;");
+ $status &= $this->execute("DELETE FROM `t_history` WHERE `id` > 1;");
+ $status &= $this->execute("DELETE FROM `t_user` WHERE `id` > 2;");
+
+ $status &= $this->execute("ALTER TABLE `t_history` AUTO_INCREMENT = 1;");
+ $status &= $this->execute("ALTER TABLE `t_ticket` AUTO_INCREMENT = 1;");
+ $status &= $this->execute("ALTER TABLE `t_user` AUTO_INCREMENT = 2;");
+
+ return $status;
+ }
+
+ /**
+ * <b>Import von Datensätzen im CSV-Format(besser gesagt SSV-Format)</b>
+ *
+ * Die Tabelle 'table' wird automatisiert mit den Werten aus der SSV-Datei befüllt.
+ *
+ * @param $table
+ * @param $filename
+ * @return bool
+ */
+ public function csvImport($table, $filename) {
+ $db = Database::getInstance();
+
+ $handle = fopen($filename, 'r');
+
+ $lines = array();
+ while (!feof($handle)) {
+ $lines[] = trim(fgets($handle), "[\r\n\t]");
+ }
+
+ fclose($handle);
+
+ if (count($lines) < 2) {
+ return false;
+ }
+
+ $spaltenKoepfeArray = explode(';', $lines[0]);
+ for ($i = 0; $i < count($spaltenKoepfeArray); $i++) {
+ $spaltenKoepfeArray[$i] = sprintf("`%s`", $spaltenKoepfeArray[$i]);
+ }
+
+ $spaltenInhaltArray = array();
+ for ($i = 1; $i < count($lines); $i++) {
+ $spaltenInhaltArray[] = explode(';', $lines[$i]);
+ }
+
+ $spaltenKoepfe = implode(', ', $spaltenKoepfeArray);
+
+ foreach ($spaltenInhaltArray as $sia) {
+ for ($i = 0; $i < count($sia); $i++) {
+
+ if ($spaltenKoepfeArray[$i] == '`last_access`') {
+ $sia[$i] = sprintf("'%s'", date("Y-m-d H:i:s"));
+ } else {
+ $sia[$i] = sprintf("'%s'", $sia[$i]);
+ }
+ }
+
+ $spaltenInhalt = implode(', ', $sia);
+ if (count($spaltenKoepfeArray) == count($sia)) {
+ $sql = sprintf("INSERT INTO %s(id, %s) VALUES(NULL, %s);", $table, $spaltenKoepfe, $spaltenInhalt);
+ if (!$db->execute($sql)) {
+
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/classes/bfw/Dispatcher.php
@@ -0,0 +1,81 @@
+<?php
+
+namespace bfw {
+
+ /**
+ * Copyright(C) 2015 Markus Bröker<broeker.markus@googlemail.com>
+ *
+ */
+
+ use bfw\mvc\controller\Controller as Controller;
+ use bfw\mvc\view\View as View;
+
+ class Dispatcher {
+ private $request;
+
+ public function __construct() {
+ $this->request = new Request();
+ }
+
+ /**
+ * <b>Standard Request Handler für das Projekt</b>
+ *
+ * Diese Instanz kümmert sich selbständig um die GET- und POST Werte und
+ * speichert diese in der Session.
+ *
+ * Einfach zu nutzende Methoden(Schnittstelle zur Session) komplettieren diesen Handler
+ *
+ * @return Request
+ */
+ public function getRequest() {
+ return $this->request;
+ }
+
+ /**
+ * <b>Führt den jeweiligen Controller aus und liefert ein View zurück</b>
+ *
+ */
+ public function getView() {
+ $page = $this->request->get('page');
+ $this->request->keepRequestData();
+
+ if ($page == '') {
+ $page = 'home';
+ }
+
+ try {
+ $class = Controller::mapControllerName($page);
+ $args = Controller::getArgsForController($class);
+
+ $reflection = new \ReflectionClass($class);
+ $controller = $reflection->newInstanceArgs($args);
+
+ $prefix = str_replace('bfw\mvc\controller\\', '', strtolower($class));
+ $controller->setPrefix(str_replace('controller', '', $prefix));
+
+ // Mapping vom GET-Parameter 'page' auf Controller::$page()
+ if ($reflection->hasMethod($page)) {
+ $controller->$page();
+ } else {
+ $controller->index();
+ }
+ } catch (Exception $e) {
+ $controller = new ErrorController(new TView('NON_EXISTENT'), $this->request);
+ }
+
+ $view = new View($controller, $controller->getModel());
+ $view->assign('page', sprintf('%s/%s', $controller->getPrefix(), $page));
+
+ return $view;
+ }
+
+ /**
+ * @param $url
+ */
+ public static function route($url) {
+ header(sprintf("Location: %s", $url));
+ exit(0);
+ }
+
+ }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/classes/bfw/Request.php
@@ -0,0 +1,249 @@
+<?php
+
+namespace bfw {
+
+ use bfw\mvc\model\TGroup as TGroup;
+ use bfw\mvc\model\TUser as TUser;
+
+ /**
+ * Class Request
+ */
+ class Request {
+ private static $logger = null;
+
+ public function __construct() {
+ self::$logger = \Logger::getLogger('__CLASS__');
+
+ $this->initSession();
+ }
+
+ /**
+ * Liefert die Basis-URL des jeweiligen Projekts
+ *
+ * @return string
+ */
+ public static function getBaseUrl() {
+ return sprintf("%s://%s",
+ isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off' ? 'https' : 'http',
+ $_SERVER['SERVER_NAME']
+ );
+ }
+
+ /**
+ * Liefert die komplette URL des jeweiligen Requests
+ *
+ * @return string
+ */
+ public static function getUrl() {
+ return sprintf("%s%s", self::getBaseUrl(), $_SERVER['REQUEST_URI']);
+ }
+
+ /**
+ * Keine Warnung, keine Gnade
+ */
+ public function destroySession() {
+ unset($_SESSION['prefix']);
+ @session_destroy();
+
+ $this->initSession();
+ }
+
+ /**
+ * <b>Initialisiert die Session für das jeweilige Projekt</b>
+ *
+ *
+ */
+ public function initSession() {
+ if (!isset($_SESSION['prefix'])) {
+ $_SESSION['prefix'] = array(
+ 'get' => array(),
+ 'session' => array(),
+ 'isLoggedIn' => false,
+ 'user_id' => TUser::SYSTEM,
+ 'group_id' => TGroup::GUEST,
+ 'fehler' => 'Tickets for Free!',
+ 'msg' => 'Tickets for Free!',
+ 'lastpage' => 'home',
+ );
+ }
+ }
+
+ /**
+ * <b>Bei jedem Seitenaufruf werden die GET/Post Anfragen in der Session separiert gespeichert</b>
+ *
+ * Struktur:
+ * GET Sachen ins 'get' array
+ * POST Sachen ins 'session' array
+ */
+ public function keepRequestData() {
+ foreach ($_GET as $key => $value) {
+ $filteredKey = $this->filter($key);
+ $filteredValue = $this->filter($value);
+
+ $_SESSION['prefix']['get'][$filteredKey] = $filteredValue;
+ }
+
+ foreach ($_POST as $key => $value) {
+ $filteredKey = $this->filter($key);
+ $filteredValue = $this->filter($value);
+
+ $_SESSION['prefix']['session'][$filteredKey] = $filteredValue;
+ }
+ }
+
+ /**
+ * <b>Statische Filtermethode für beliebige Strings/Array of Strings</b>
+ *
+ * filter_input kann nur mit GET/POST umgehen, diese Methode mit Allem.
+ *
+ * @param string $param
+ * @return string|array
+ */
+ public static function filter($param) {
+ if (is_array($param)) {
+ $filtered = array();
+ foreach ($param as $key => $value) {
+ $filtered[self::filter($key)] = self::filter($value);
+ }
+
+ return $filtered;
+ }
+
+ return htmlspecialchars($param, ENT_QUOTES, 'utf-8');
+ }
+
+ /**
+ * <b>Liefert einen gefilterten GET-Wert</b>
+ *
+ * @param $param
+ * @return string
+ */
+ public function get($param) {
+ return filter_input(INPUT_GET, $param);
+ }
+
+ /**
+ * <b>Liefert einen gefilterten POST-Wert</b>
+ *
+ * @param $param
+ * @return mixed|string
+ */
+ public function post($param) {
+ return filter_input(INPUT_POST, $param);
+ }
+
+ /**
+ * <b>Liefert einen gefilterten 'session' Wert
+ *
+ * Hierbei handelt es sich um einen zuvor gespeicherten POST-Wert,
+ * der in ['prefix']['session'] geladet ist...
+ *
+ * @param $param
+ * @param string $default
+ * @return string
+ */
+ public static function session($param, $default = '') {
+ if (isset($_SESSION['prefix']['session'][$param])) {
+ return $_SESSION['prefix']['session'][$param];
+ }
+
+ return $default;
+ }
+
+ /**
+ * <b>Liefert einen gefilterten 'get' Wert
+ *
+ * Hierbei handelt es sich um einen zuvor gespeicherten POST-Wert,
+ * der in ['prefix']['session'] geladet ist...
+ *
+ * @param $param
+ * @param string $default
+ * @return string
+ */
+ public static function getParameter($param, $default = '') {
+ if (isset($_SESSION['prefix']['get'][$param])) {
+ return $_SESSION['prefix']['get'][$param];
+ }
+
+ return $default;
+ }
+
+ /**
+ * <b>Setzt einen neuen Session Wert ins jeweilige Prefix</b>
+ *
+ * @param $key
+ * @param $value
+ */
+ public function setKey($key, $value, $storage = null) {
+ if ($storage != null) {
+ $_SESSION['prefix'][$storage][self::filter($key)] = self::filter($value);
+ } else {
+ $_SESSION['prefix'][self::filter($key)] = self::filter($value);
+ }
+ }
+
+ /**
+ * <b>Holt einen Session Wert aus dem jeweiligen Prefix</b>
+ *
+ * @param $key
+ * @param string $default
+ * @param null $storage
+ * @return string
+ */
+ public static function getKey($key, $default = '', $storage = null) {
+ if ($storage != null) {
+ return $_SESSION['prefix'][$storage][$key];
+ }
+
+ if (isset($_SESSION['prefix'][$key])) {
+ return $_SESSION['prefix'][$key];
+ }
+
+ return $default;
+ }
+
+ /**
+ * <b>Löscht einen Get-Wert aus dem jeweiligen Prefix</b>
+ *
+ * @param $key
+ */
+ public static function deleteParameterKey($key) {
+ unset($_SESSION['prefix']['get'][$key]);
+ }
+
+ /**
+ * <b>Löscht einen Session Wert aus dem jeweiligen Prefix</b>
+ *
+ * @param $key
+ */
+ public static function deleteKey($key) {
+ unset($_SESSION['prefix'][$key]);
+ }
+
+ /**
+ * <b>Prüft, ob der aktuelle Request einen POST enthält</b>
+ *
+ * @return bool
+ */
+ public static function hasPost() {
+ return (isset($_POST));
+ }
+
+ /**
+ * <b>Interne Debug-Funktion zum Anzeigen der Session Struktur</b>
+ *
+ * Beliebige URL mit ?debug=1 aufrufen und der Debug Mechanismus ist aktiviert.
+ *
+ * @return string
+ */
+ public function printSession() {
+ self::$logger->info(sprintf('SESSION: %s', print_r($_SESSION['prefix'], true)));
+
+ if ($this->get('debug') == '') {
+ return '';
+ }
+
+ return "<br /><pre>" . print_r($_SESSION['prefix'], true) . "</pre>";
+ }
+ }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/classes/bfw/Response.php
@@ -0,0 +1,43 @@
+<?php
+
+namespace bfw {
+ /**
+ * Response Headers sind kompliziert
+ *
+ */
+ class Response {
+ private $headers;
+ private $statusCode;
+
+ public function __construct() {
+ $this->headers = headers_list();
+ $this->statusCode = http_response_code();
+ }
+
+ public function getHeaders() {
+ return $this->headers;
+ }
+
+ public function setStatusCode($statusCode) {
+ $this->statusCode = $statusCode;
+
+ return $this;
+ }
+
+ public function getStatusCode() {
+ return $this->statusCode;
+ }
+
+ /**
+ * @return string
+ */
+ public function get($key) {
+ if (array_key_exists($key, $this->headers)) {
+ return $this->headers[$key];
+ }
+
+ return '';
+ }
+
+ }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/classes/bfw/mvc/controller/BenutzerverwaltungsController.php
@@ -0,0 +1,314 @@
+<?php
+
+namespace bfw\mvc\controller {
+
+ /**
+ * Copyright(C) 2015 Markus Bröker<broeker.markus@googlemail.com>
+ *
+ */
+
+ use bfw\Dispatcher;
+ use bfw\mvc\model\Model;
+ use bfw\mvc\model\TGroup;
+ use bfw\mvc\model\TUser;
+
+ class BenutzerverwaltungsController extends Controller {
+ private static $logger = null;
+
+ /**
+ * BenutzerverwaltungsController constructor.
+ *
+ * @param Model $model
+ * @param Request $request
+ */
+ public function __construct($model, $request) {
+
+ parent::__construct($model, $request);
+ }
+
+ /**
+ *
+ */
+ public function loeschenFunc() {
+ $tUser = $this->getModel();
+ $request = $this->getRequest();
+
+ $uid = $request->session('uid');
+
+ if (!$tUser->delete($uid)) {
+ $request->setKey('fehler', 'Der Benutzer konnte nicht gelöscht werden.');
+ Dispatcher::route('/home/');
+ } else {
+ $request->setKey('msg', 'Der Benutzer wurde gelöscht.');
+ }
+ }
+
+ /**
+ *
+ */
+ public function aendernFunc() {
+ $request = $this->getRequest();
+
+ $uid = $request->session('uid');
+ $username = $request->session('username');
+ $password = $request->session('password');
+ $group_id = $request->session('groupbox');
+
+ $tUser = $this->getModel();
+ $user = $tUser->find($uid);
+
+ $user->setUsername($username);
+ if ($password != '') {
+ $user->setPassword(md5($password));
+ }
+
+ if ($group_id != '') {
+ $user->setGroup_id($group_id);
+ }
+
+ if ($tUser->store($user->getId(), $user)) {
+ $request->setKey('msg', 'Der Benutzer wurde erfolgreich aktualisiert.');
+ } else {
+ $request->setKey('fehler', 'Der Benutzer konnte nicht aktualisiert werden.');
+ }
+ }
+
+ /**
+ *
+ * @param $currentUser
+ * @return mixed
+ */
+ public function registrierenFunc($currentUser) {
+ $request = $this->getRequest();
+
+ $password1 = $request->session('password1');
+ $password2 = $request->session('password2');
+
+ if (strlen($password1) == 0) {
+ return $currentUser;
+ }
+
+ // Validierung
+ if ($password1 != $password2) {
+ $request->setKey('fehler', 'Die Passwörter sind verschieden.');
+ return $currentUser;
+ }
+
+ $username = $request->session('username');
+ $firstname = $request->session('firstname');
+ $lastname = $request->session('lastname');
+
+ $currentUser->setUsername($username);
+ $currentUser->setPassword(md5($password1));
+ $currentUser->setFirstname($firstname);
+ $currentUser->setLastname($lastname);
+ $currentUser->setGroup_Id(TGroup::SUPPORTER);
+
+ if ($username == '' || $firstname == '' || $lastname == '') {
+ $request->setKey('fehler', 'Sie müssen die Pflichtfelder ausfüllen.');
+ return $currentUser;
+ }
+
+ if ($currentUser->persist($currentUser)) {
+ $request->setKey('msg', 'Der Nutzer wurde angelegt.');
+
+ if ($currentUser->findByUsername($currentUser->getUsername())) {
+ $request->setKey('isLoggedIn', true);
+ $request->setKey('user_id', $currentUser->getId());
+ $request->setKey('group_id', $currentUser->getGroup_id());
+
+ Dispatcher::route('/meinprofil/');
+ }
+ } else {
+ $request->setKey('fehler', 'Der Nutzer konnte nicht angelegt werden.');
+ }
+
+ return $currentUser;
+ }
+
+ /**
+ *
+ * @return bool
+ */
+ public function resetPasswordFunc() {
+ $request = $this->getRequest();
+ $engine = $this->getView();
+
+ $username = $request->session('username');
+
+ if (!$request->hasPost()) {
+ return false;
+ }
+
+ $tUser = $this->getModel();
+
+ if ($tUser->findByUsername($username)) {
+ $tUser->setPassword(md5($tUser->getUsername()));
+
+ return $tUser->store($tUser->getId(), $tUser);
+ }
+
+ $engine->assign('request', $request);
+ return false;
+ }
+
+ /**
+ *
+ */
+ public function meinProfil() {
+ $request = $this->getRequest();
+ $engine = $this->getView();
+
+ $username = $request->session('username');
+
+ $tUser = $this->getModel();
+ $user = $tUser->find($request->getKey('user_id'));
+
+ if ($request->post('aendern') != '') {
+ $firstname = $request->session('firstname');
+ $lastname = $request->session('lastname');
+
+ $tUser = new TUser();
+ $tUser->setUsername($username);
+ $tUser->setFirstname($firstname);
+ $tUser->setLastname($lastname);
+
+ $password = $request->session('password');
+ if ($password != '') {
+ $tUser->setPassword(md5($password));
+ }
+
+ if ($tUser->store($user->getId(), $tUser)) {
+ $request->setKey('msg', 'Der Nutzer wurde aktualisiert.');
+ $tUser->findByField('username', $tUser->getUsername());
+ } else {
+ $request->setKey('fehler', 'Der Nutzer konnte nicht aktualisiert werden.');
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ public function abmelden() {
+ $request = $this->getRequest();
+ $engine = $this->getView();
+
+ $request->deleteKey('username');
+ $request->deleteKey('group_id');
+ $request->destroySession();
+
+ Dispatcher::route('/');
+ }
+
+ /**
+ *
+ */
+ public function anmelden() {
+ $request = $this->getRequest();
+ $engine = $this->getView();
+
+ $username = $request->session('username');
+ $password = md5($request->session('password'));
+
+ $tUser = $this->getModel();
+ $user = $tUser->findByUsername($username);
+
+ if ($user == null) {
+ return;
+ }
+
+ if (($username == $user->getUsername()) && ($password == $user->getPassword())) {
+ $request->setKey('isLoggedIn', true);
+ $request->setKey('user_id', $user->getId());
+ $request->setKey('group_id', $user->getGroup_id());
+
+ $tGroup = new TGroup();
+ if (($group = $tGroup->find($user->getGroup_Id())) == null) {
+ $request->setKey('fehler', "DB-Inkonsistenz: Prüfen Sie die exisitierenden Gruppen.");
+ }
+
+ $msg = sprintf('Sie gehören der Gruppe %s an.', $group->getName());
+ $request->setKey('msg', $msg);
+
+ $lastpage = $request->getKey('lastpage');
+ if ($lastpage == 'anmelden') {
+ $lastpage = 'tickets';
+ }
+
+ $request->setKey('lastpage', $lastpage);
+
+ // Routing ist final
+ Dispatcher::route(sprintf('/%s/', $lastpage));
+ }
+
+ }
+
+ /**
+ *
+ */
+ public function registrieren() {
+ $request = $this->getRequest();
+ $engine = $this->getView();
+
+ $currentUser = new TUser();
+ if ($request->post('registrieren') != '') {
+ $currentUser = $this->registrierenFunc($currentUser);
+ }
+
+ $engine->assign('currentUser', $currentUser);
+ }
+
+ /**
+ *
+ */
+ public function index() {
+ $request = $this->getRequest();
+ $engine = $this->getView();
+
+ $tUser = $this->getModel();
+ $tGroup = new TGroup();
+
+ if ($request->post('loeschen') != '') {
+ $this->loeschenFunc();
+ }
+
+ if ($request->post('aendern') != '') {
+ $this->aendernFunc();
+ }
+
+ $group_id = $request->getKey('group_id', TGroup::GUEST);
+
+ switch ($group_id) {
+ case TGroup::ADMIN:
+ $users = $tUser->findAll();
+ $groups = $tGroup->findAll();
+ break;
+ case TGroup::MANAGER:
+ $users = $tUser->findAllManagersAndBelow();
+ $groups = $tGroup->findAllManagersAndBelow();
+ break;
+ default:
+ Dispatcher::route('/home/');
+ }
+
+ $engine->assign('users', $users);
+ $engine->assign('groups', $groups);
+ }
+
+ /**
+ *
+ */
+ public function resetpasswort() {
+ $request = $this->getRequest();
+ $engine = $this->getView();
+
+ if ($request->post('pw-reset')) {
+ if ($this->resetPasswordFunc()) {
+ Dispatcher::route('/anmelden/');
+ }
+ }
+ }
+
+ }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/classes/bfw/mvc/controller/Controller.php
@@ -0,0 +1,186 @@
+<?php
+
+namespace bfw\mvc\controller {
+
+ /**
+ * Copyright(C) 2015 Markus Bröker<broeker.markus@googlemail.com>
+ *
+ */
+
+ use bfw\mvc\model\Model;
+ use bfw\mvc\model\THistory;
+ use bfw\mvc\model\TTicket;
+ use bfw\mvc\model\TUser;
+ use bfw\mvc\view\View;
+ use bfw\Request;
+ use bfw\Response;
+
+ interface ActionInterface {
+ public function index();
+ }
+
+ /**
+ *
+ */
+ abstract class Controller implements ActionInterface {
+ /**
+ * @var Model
+ */
+ private $model;
+
+ /**
+ * @var Request
+ */
+ private $request;
+
+ /**
+ * @var Response
+ */
+ private $response;
+
+ /**
+ * @var View
+ */
+ private $view;
+
+ /**
+ * @var
+ */
+ private $prefix;
+
+ /**
+ * Controller constructor.
+ *
+ * @param Model $model
+ * @param Request $request
+ */
+ public function __construct(Model $model, Request $request) {
+ $this->request = $request;
+ $this->response = new Response();
+
+ $this->model = $model;
+ $this->view = new View($this, $model);
+
+ $this->prefix = '';
+ }
+
+ public function getPrefix() {
+ return $this->prefix;
+ }
+
+ public function setPrefix($prefix) {
+ $this->prefix = $prefix;
+
+ return $this;
+ }
+
+ public function getView() {
+ return $this->view;
+ }
+
+ public function setView($view) {
+ $this->view = $view;
+
+ return $this;
+ }
+
+ public function getResponse() {
+ return $this->response;
+ }
+
+ public function setResponse($response) {
+ $this->response = $response;
+
+ return $this;
+ }
+
+ /**
+ * @return Model
+ */
+ public function getModel() {
+ return $this->model;
+ }
+
+ /**
+ * @param $model
+ * @return $this
+ */
+ public function setModel($model) {
+ $this->model = $model;
+
+ return $this;
+ }
+
+ /**
+ * @return Request
+ */
+ public function getRequest() {
+ return $this->request;
+ }
+
+ /**
+ * @return string
+ */
+ public function getPage() {
+ if ($this->getPrefix() != '') {
+ return sprintf('%s/%s', $this->prefix, $this->request->get('page'));
+ }
+
+ return $this->request->get('page');
+ }
+
+ /**
+ * @param $page
+ * @return string
+ */
+ public static function mapControllerName($page) {
+ switch ($page) {
+ case 'benutzerverwaltung':
+ case 'meinprofil':
+ case 'resetpasswort':
+ case 'registrieren':
+ case 'anmelden':
+ case 'abmelden':
+ return 'bfw\mvc\controller\BenutzerverwaltungsController';
+ case 'home':
+ return 'bfw\mvc\controller\HomeController';
+ case 'tickets':
+ case 'ticketanlegen':
+ return 'bfw\mvc\controller\TicketsController';
+ case 'historie':
+ return 'bfw\mvc\controller\HistoryController';
+
+ default:
+ return 'bfw\mvc\controller\ErrorController';
+ }
+ }
+
+ public static function getArgsForController($controllerName) {
+ switch ($controllerName) {
+ case 'bfw\mvc\controller\BenutzerverwaltungsController':
+ $model = new TUser();
+
+ return array($model, new Request());
+ case 'bfw\mvc\controller\HistoryController':
+ $model = new THistory();
+
+ return array($model, new Request());
+ case 'bfw\mvc\controller\HomeController':
+ $model = new TUser();
+
+ return array($model, new Request());
+ case 'bfw\mvc\controller\TicketsController':
+ $model = new TTicket();
+
+ return array($model, new Request());
+ default:
+ $model = new TUser();
+
+ return array($model, new Request());
+ }
+
+ throw new InvalidArgumentException(sprintf('Unbekannter Controller für %s', $controllerName));
+ }
+
+ }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/classes/bfw/mvc/controller/ErrorController.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace bfw\mvc\controller {
+
+ /**
+ * Copyright(C) 2015 Markus Bröker<broeker.markus@googlemail.com>
+ *
+ */
+ class ErrorController extends Controller {
+
+ public function __construct($model, $request) {
+ parent::__construct($model, $request);
+ }
+
+ public function index() {
+ $request = $this->getRequest();
+ $engine = $this->getView();
+ }
+
+ }
+}
new file mode 100644
--- /dev/null
+++ b/classes/bfw/mvc/controller/HistoryController.php
@@ -0,0 +1,54 @@
+<?php
+
+namespace bfw\mvc\controller {
+
+ /**
+ * Copyright(C) 2015 Markus Bröker<broeker.markus@googlemail.com>
+ *
+ */
+
+ use bfw\mvc\model\TGroup;
+ use bfw\mvc\model\TTicket;
+ use bfw\mvc\model\TUser;
+
+ class HistoryController extends Controller {
+
+ private $user_id;
+ private $group_id;
+ private $currentTicket;
+
+ public function __construct($model, $request) {
+ parent::__construct($model, $request);
+
+ $this->currentTicket = null;
+
+ $this->user_id = $request->getKey('user_id', TUser::SYSTEM);
+ $this->group_id = $request->getKey('group_id', TGroup::GUEST);
+ }
+
+ public function index() {
+ $request = $this->getRequest();
+ $engine = $this->getView();
+
+ $tid = $request->session('tid');
+ $ticket = new TTicket();
+
+ $user_id = $request->session('user_id');
+
+ if ($ticket->find($tid, $user_id) == null) {
+ $request->setKey('fehler', 'Datensatz nicht gefunden.');
+ $ticket = new TTicket();
+ }
+
+ $history = $this->getModel();
+ $histories = $history->findAllByField('ticket_id', $tid);
+ if ($histories == null) {
+ $request->setKey('fehler', 'Die Daten sind nicht aktuell.');
+ }
+
+ $engine->assign('ticket', $ticket);
+ $engine->assign('histories', $histories);
+ }
+
+ }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/classes/bfw/mvc/controller/HomeController.php
@@ -0,0 +1,124 @@
+<?php
+
+namespace bfw\mvc\controller {
+
+ /**
+ * Copyright(C) 2015 Markus Bröker<broeker.markus@googlemail.com>
+ *
+ */
+
+ use bfw\Database;
+ use bfw\Dispatcher;
+ use bfw\mvc\model\Model;
+ use bfw\mvc\model\TGroup;
+ use bfw\mvc\model\TText;
+
+ class HomeController extends Controller {
+ const TEXT_ID = 2;
+
+ /**
+ * HomeController constructor.
+ *
+ * @param Model $model
+ * @param Request $request
+ */
+ public function __construct($model, $request) {
+ parent::__construct($model, $request);
+ }
+
+ /**
+ *
+ */
+ public function eintragen() {
+ $request = $this->getRequest();
+
+ $tText = new TText();
+ $text = $tText->find(self::TEXT_ID);
+
+ $text->setHeadline($request->session('headline'));
+ $text->setText($request->session('text'));
+
+ if ($tText->store(self::TEXT_ID, $text)) {
+ $request->setKey('msg', 'Der CMS-Text wurde aktualisiert.');
+ } else {
+ $request->setKey('fehler', 'Der CMS-Text kontne nicht aktualisiert werden.');
+ }
+ }
+
+ /**
+ *
+ */
+ public function reset() {
+ $request = $this->getRequest();
+ $db = Database::getInstance();
+
+ if (!$db->cleanup()) {
+ $request->deleteParameterKey('reset');
+ $request->setKey('fehler', 'Fehler beim Aufräumen');
+ Dispatcher::route('/');
+ }
+
+ $request->deleteParameterKey('reset');
+ $request->destroySession();
+
+ Dispatcher::route('/');
+ }
+
+ /**
+ *
+ */
+ public function unit() {
+ $request = $this->getRequest();
+
+ $db = Database::getInstance();
+ $db->csvImport('t_user', 'data/import/test_users.csv');
+ $db->csvImport('t_ticket', 'data/import/test_tickets.csv');
+
+ $request->deleteParameterKey('unit');
+
+ Dispatcher::route('/');
+ }
+
+ /**
+ * Default Index Action
+ *
+ * Zu berücksichtigen ist hier:
+ *
+ * Sowohl GET-Actions als auch POST Actions werden berücksichtigt
+ */
+ public function index() {
+ $request = $this->getRequest();
+ $engine = $this->getView();
+
+ /**
+ * Reset mit Redirect
+ */
+ if ($request->getParameter('reset') == '1') {
+ $this->reset($engine, $request);
+
+ return;
+ }
+
+ /**
+ * Eintragen mit Redirect
+ */
+ if ($request->get('unit') == '1') {
+ $this->unit();
+
+ return;
+ }
+
+ if ($request->post('eintragen') != '') {
+ $this->eintragen();
+ }
+
+ $tText = new TText();
+ $group_id = $request->getKey('group_id', TGroup::GUEST);
+
+ $text = $tText->find(self::TEXT_ID);
+ $engine->assign('text', $text);
+ $engine->assign('group_id', $group_id);
+ }
+
+ }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/classes/bfw/mvc/controller/TicketsController.php
@@ -0,0 +1,351 @@
+<?php
+
+namespace bfw\mvc\controller {
+
+ /**
+ * Copyright(C) 2015 Markus Bröker<broeker.markus@googlemail.com>
+ *
+ */
+
+ use bfw\Dispatcher;
+ use bfw\mvc\model\Model;
+ use bfw\mvc\model\TGroup;
+ use bfw\mvc\model\TStatus;
+ use bfw\mvc\model\TTicket;
+ use bfw\mvc\model\TUser;
+
+ class TicketsController extends Controller {
+ private $user_id;
+ private $group_id;
+ private $currentTicket;
+
+ /**
+ * TicketsController constructor.
+ *
+ * @param Model $model
+ * @param Request $request
+ */
+ public function __construct($model, $request) {
+ parent::__construct($model, $request);
+
+ $this->currentTicket = null;
+
+ $this->user_id = $request->getKey('user_id', TUser::SYSTEM);
+ $this->group_id = $request->getKey('group_id', TGroup::GUEST);
+ }
+
+ /**
+ * <b>Diese Funktion kümmert sich um die Anfragen dieses Ticket-Controllers</b>
+ *
+ * @param $currentTicket
+ * @param $user_id
+ * @param $group_id
+ */
+ public function handleRequest($currentTicket, $user_id, $group_id) {
+ $request = $this->getRequest();
+ $engine = $this->getView();
+
+ /**
+ * @var Model
+ */
+ $tTicket = $this->getModel();
+
+ $tUser = new TUser();
+ $user = $tUser->find($user_id);
+
+ /**
+ * 'Cron-Job' ohne 'Cron': Alle Tickets werden bei jedem Zugriff geprüft
+ *
+ * Gibt es Tickets, die derzeit gesperrt sind? Befreie Sie! Free Tickets!!!
+ * Falls Tickets frei sind, weise diese korrekt und fair wieder zu.
+ */
+ $tTicket->unlockTickets($tTicket);
+ $tTicket->reassignFreeTickets();
+
+ switch ($group_id) {
+ case TGroup::SUPPORTER:
+ $tickets = $tTicket->findAllTicketsByUserid($user_id);
+ if ($tickets == null) {
+ $request->setKey('fehler', 'Es existieren derzeit keine Tickets für Sie!');
+ }
+
+ $users = array($tUser->findByUsername($user->getUsername()));
+ break;
+ case TGroup::ADMIN:
+ case TGroup::MANAGER:
+ $tickets = $tTicket->findAll();
+ $users = $tUser->findAll(false);
+ break;
+ default:
+ $tickets = $tTicket->findAll();
+ $users = $tUser->findAll();
+ }
+
+ $tStatus = new TStatus();
+ $statusItems = $tStatus->findAll();
+
+ // erstelle eine neue Ticket-Instanz, falls es keine instanzierte gibt.
+ if ($currentTicket == null) {
+ $currentTicket = new TTicket();
+ }
+
+ $engine->assign('users', $users);
+ $engine->assign('tStatus', $tStatus);
+ $engine->assign('tickets', $tickets);
+ $engine->assign('statusItems', $statusItems);
+ $engine->assign('currentTicket', $currentTicket);
+ $engine->assign('group_id', $group_id);
+ }
+
+ /**
+ * @param $user_id
+ * @return null|TTicket
+ */
+ public function processTickedId($user_id) {
+ $request = $this->getRequest();
+ $engine = $this->getView();
+
+ $tUser = new TUser();
+ $user = $tUser->find($user_id);
+
+ if ($user == null) {
+ $request->setKey('fehler', sprintf('Benutzer(%d) konnte nicht mehr gefunden werden.', $user_id));
+ Dispatcher::route('/');
+ }
+
+ $tid = $request->get('tid');
+
+ $tTicket = $this->getModel();
+ $currentTicket = $tTicket->find($tid);
+
+ if ($currentTicket == null) {
+ $request->setKey('fehler', sprintf('Ticket Nr. %d konnte nicht gefunden werden.', $tid));
+
+ return null;
+ }
+
+ if (!$currentTicket->hasPrivilege($currentTicket, $user, false)) {
+ $request->setKey('fehler', sprintf('Ihnen fehlen die Berechtigungen für das Ticket Nr. %d.', $tid));
+
+ return null;
+ }
+
+ return $currentTicket;
+ }
+
+ /**
+ * <b>Ticket nach TID laden</b>
+ *
+ * @param $user_id
+ *
+ * @return null|TTicket
+ */
+ public function processLaden($user_id) {
+ $request = $this->getRequest();
+ $engine = $this->getView();
+
+ $tid = $request->session('tid');
+
+ $tTicket = $this->getModel();
+ $currentTicket = $tTicket->find($tid);
+
+ if ($currentTicket == null) {
+ $request->setKey('fehler', sprintf('Ticket Nr. %d konnte nicht gefunden werden.', $tid));
+
+ return null;
+ }
+
+ $tUser = new TUser();
+ $user = $tUser->find($user_id);
+
+ if ($user == null) {
+ $request->setKey('fehler', sprintf('Benutzer(%d) konnte nicht mehr gefunden werden.', $user_id));
+
+ return null;
+ }
+
+ $tTicket->lockTicket($currentTicket, $user);
+
+ if (!$currentTicket->hasPrivilege($currentTicket, $user, true)) {
+ $request->setKey('fehler', sprintf('Ihnen fehlen die Berechtigungen für das Ticket Nr. %d.', $tid));
+
+ return null;
+ }
+
+ return $currentTicket;
+ }
+
+ /**
+ * <b>Löschen von Tickets</b>
+ *
+ * @return bool
+ */
+ public function processLoeschen($user_id) {
+ $request = $this->getRequest();
+ $engine = $this->getView();
+
+ $tid = $request->session('tid');
+
+ $tTicket = $this->getModel();
+ $currentTicket = $tTicket->find($tid);
+
+ if ($currentTicket == null) {
+ $request->setKey('fehler', sprintf('Nicht existierende Tickets(%d) können nicht gelöscht werden.', $tid));
+
+ return false;
+ }
+
+ $tUser = new TUser();
+ $user = $tUser->find($user_id);
+
+ if ($user == null) {
+ $request->setKey('fehler', sprintf('Benutzer(%d) konnte nicht mehr gefunden werden.', $user_id));
+
+ return false;
+ }
+
+ if (!$currentTicket->hasPrivilege($currentTicket, $user, true)) {
+ $request->setKey('fehler', sprintf('Ihnen fehlen die Berechtigungen für das Ticket Nr. %d.', $tid));
+
+ return false;
+ }
+
+ if ($currentTicket->delete($tid)) {
+ $request->setKey('msg', sprintf('Das Ticket mit der Nummer %d wurde gelöscht.', $tid));
+
+ return true;
+ }
+
+ $request->setKey('fehler', sprintf('Das Ticket mit der Nummer %d konnte nicht gelöscht werden.', $tid));
+
+ return false;
+ }
+
+ /**
+ * @param $user_id
+ * @param $group_id
+ * @return Model|null
+ */
+ public function processEintragen($user_id, $group_id) {
+ $request = $this->getRequest();
+ $engine = $this->getView();
+
+ $logger = Logger::getLogger('main');
+
+ $tid = $request->session('tid');
+ $status_id = $request->session('status', TStatus::OFFEN);
+
+ $tTicket = $this->getModel();
+
+ if ($tid != '') {
+ $tTicket->find($tid, $user_id);
+ }
+
+ $tUser = new TUser();
+ $user = $tUser->find($user_id);
+ if ($user == null) {
+ return null;
+ }
+
+ $theHolyUserId = $tTicket->getUser_Id();
+ if ($group_id == TGroup::ADMIN || $group_id == TGroup::MANAGER) {
+ $theHolyUserId = $request->session('user_id');
+ }
+
+ $subject = $request->session('subject');
+ $message = $request->session('message');
+
+ if (($subject == '') && ($message == '')) {
+ $request->setKey('fehler', sprintf('Füllen Sie die Pflichtfelder aus.'));
+
+ return null;
+ }
+
+ $tTicket->setUser_Id($theHolyUserId);
+ $tTicket->setStatus_Id($status_id);
+ $tTicket->setSubject($subject);
+ $tTicket->setMessage($message);
+ $tTicket->setLast_Access(date("Y-m-d H:i:s"));
+
+ if ($tid == '') {
+ if ($tTicket->persist($tTicket)) {
+ $request->setKey('msg', sprintf('Ein neues Ticket wurde erfolgreich eingetragen.'));
+ $logger->info(sprintf('Ticket wurde eingetragen: (%s)', print_r($tTicket->getData(), true)));
+
+ return null;
+ }
+ } else {
+ if (!$tTicket->hasPrivilege($tTicket, $user, true)) {
+ $request->setKey('fehler', sprintf('Ihnen fehlen die Berechtigungen für das Ticket Nr. %d.', $tid));
+
+ return null;
+ }
+
+ if ($tTicket->getId() != 1) {
+ if ($tTicket->store($tid, $tTicket)) {
+ $request->setKey('msg', 'Das Ticket wurde erfolgreich aktualisiert.');
+ $logger->info(sprintf('Ticket wurde aktualisiert: (%s)', print_r($tTicket->getData(), true)));
+ }
+
+ return $tTicket;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Default Index Action
+ */
+ public function index() {
+ $request = $this->getRequest();
+ $engine = $this->getView();
+
+ $user_id = $this->user_id;
+ $group_id = $this->group_id;
+
+ $engine = $this->getView();
+ $currentTicket = $this->currentTicket;
+
+ // Umleiten zur Historie
+ if ($request->post('historie') != '') {
+ Dispatcher::route("/historie/");
+ }
+
+ // finde das aktuelle Ticket, welches per GET live angegeben wurde.
+ if ($request->get('tid') != '') {
+ $currentTicket = $this->processTickedId($user_id);
+ $this->handleRequest($currentTicket, $user_id, $group_id);
+
+ return;
+ }
+
+ // lade das ausgewählte Ticket, Supporter nehmen es automatisch an.
+ if ($request->post('laden') != '') {
+ $currentTicket = $this->processLaden($user_id);
+ $this->handleRequest($currentTicket, $user_id, $group_id);
+
+ return;
+ }
+
+ // erstelle oder aktualisiere das aktuelle Ticket.
+ if ($request->post('eintragen') != '') {
+ $currentTicket = $this->processEintragen($user_id, $group_id);
+ $this->handleRequest($currentTicket, $user_id, $group_id);
+
+ return;
+ }
+
+ // lösche das aktuelle Ticket.
+ if ($request->post('loeschen') != '') {
+ $this->processLoeschen($user_id);
+ $this->handleRequest($currentTicket, $user_id, $group_id);
+
+ return;
+ }
+
+ $this->handleRequest($this->currentTicket, $this->user_id, $this->group_id);
+ }
+
+ }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/classes/bfw/mvc/model/Model.php
@@ -0,0 +1,217 @@
+<?php
+
+namespace bfw\mvc\model {
+
+ use bfw\Database;
+
+ /**
+ * Class Model
+ *
+ * Model besitzt einen State in $data
+ *
+ *
+ * @method string getId()
+ * @method setId($param)
+ */
+ class Model {
+ private static $logger = null;
+
+ protected $table;
+ protected $db;
+
+ protected $data;
+
+ public function getData() {
+ return $this->data;
+ }
+
+ /**
+ * <b>Herzstück des Persistence-Frameworks</b>
+ *
+ * Dynamische Erzeugung von Getttern- und Settern
+ *
+ * Anstatt diese explizit zu pflegen und zu warten,
+ * werden Diese dynamisch, on, the fly, erzeugt.
+ *
+ * <b>Der Vorteil: Nicht Konfigurieren, nicht Erzeugen. Einfach Nutzen...</b>
+ *
+ * @param $methodName
+ * @param null $params
+ * @return $this
+ */
+ public function __call($methodName, $params = null) {
+ $prefix = substr($methodName, 0, 3);
+ $key = strtolower(substr($methodName, 3));
+
+ if ($prefix == 'set') {
+ $value = $params[0];
+
+ $this->data[$key] = $value;
+
+ // fluent please!
+ return $this;
+
+ } else if ($prefix == 'get') {
+ if (array_key_exists($key, $this->data)) {
+ return $this->data[$key];
+ }
+ }
+
+ exit(sprintf('Unbekannte Methode %s::%s(%s, %s) wurde aufgerufen.', get_class($this), $methodName, $key, $prefix));
+ }
+
+ /**
+ * @param $table
+ */
+ public function __construct($table) {
+ self::$logger = \Logger::getLogger('__CLASS__');
+
+ $this->db = Database::getInstance();
+ $this->table = $table;
+ $this->data = array();
+ }
+
+ /**
+ * <b>Vereinfachte Find Methode bezogen auf die jeweilige Instanz</b>
+ *
+ * @param $id
+ * @return Model
+ */
+ public function find($id) {
+ self::$logger->info(sprintf('%s(%d) ', __METHOD__, $id));
+
+ if (($this->data = $this->db->find($this->table, $id)) == null) {
+ return null;
+ }
+
+ return $this;
+ }
+
+ /**
+ * <b>Die Findall Methode erzeugt typsicher den Supertyp</b>
+ *
+ * @param bool|false $sys
+ * @return Model[]
+ */
+ public function findAll($sys = false) {
+ self::$logger->info(sprintf('%s() ', __METHOD__));
+
+ $initial_id = ($sys) ? 0 : 1;
+ $rows = $this->db->findAll($this->table, $initial_id);
+
+ if (count($rows) == 0) {
+ return array();
+ }
+
+ $list = array();
+ foreach ($rows as $row) {
+ $item = new static();
+ $item->data = $row;
+
+ $list[] = $item;
+ }
+
+ self::$logger->info(sprintf('%s(): %d', __METHOD__, count($list)));
+
+ return $list;
+ }
+
+ /**
+ * <b>Vereinfachte FindByField Methode</b>
+ *
+ * @param $field
+ * @param $value
+ * @return Model
+ */
+ public function findByField($field, $value) {
+ self::$logger->info(sprintf('%s(%s, %s) ', __METHOD__, $field, $value));
+
+ $this->data = $this->db->findByField($this->table, $field, $value);
+
+ // Keine Daten, keine Instanz
+ if ($this->data == null) {
+ return null;
+ }
+
+ return $this;
+ }
+
+ /**
+ * <b>Vereinfachte FindAllByField Methode</b>
+ *
+ * Erzeugt on the fly ein array mit dem Supertyp der Klasseninstanz
+ * @param $field
+ * @param $value
+ * @return Model[]
+ */
+ public function findAllByField($field, $value) {
+ self::$logger->info(sprintf('%s(%s, %s) ', __METHOD__, $field, $value));
+
+ $rows = $this->db->findAllByField($this->table, $field, $value);
+
+ if ($rows == null) {
+ return null;
+ }
+
+ $list = array();
+ foreach ($rows as $row) {
+ $item = new static();
+ $item->data = $row;
+
+ $list[] = $item;
+ }
+
+ return $list;
+ }
+
+ /**
+ * <b>Vereinfachte persist Methode</b>
+ *
+ * Der Logger loggt nur die Nutzdaten, deswegen sieht das im Log identisch aus.
+ *
+ * Es handelt sich allerdings einmal um ein Objekt und einmal nur um ein Array.
+ *
+ * @param $object
+ * @return bool
+ */
+ public function persist($object) {
+ self::$logger->info(sprintf('%s(%s)', __METHOD__, print_r($object->getData(), true)));
+
+ return $this->db->persist($this->table, $object->getData());
+ }
+
+ /**
+ * <b>Vereinfachte store Methode</b>
+ *
+ * @param $id
+ * @param $object
+ * @return bool
+ */
+ public function store($id, $object) {
+ self::$logger->info(sprintf('%s(%d, %s)', __METHOD__, $id, print_r($object->getData(), true)));
+
+ if ($id > 1) {
+ return $this->db->store($this->table, $id, $object->getData());
+ }
+
+ return false;
+ }
+
+ /**
+ * <b>Vereinfachte delete Methode</b>
+ *
+ * @param $id
+ * @return bool
+ */
+ public function delete($id) {
+ self::$logger->info(sprintf('%s(%d) ', __METHOD__, $id));
+
+ if ($id > 1) {
+ return $this->db->delete($this->table, $id);
+ }
+
+ return false;
+ }
+
+ }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/classes/bfw/mvc/model/TAction.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace bfw\mvc\model {
+
+ /**
+ * Class TAction
+ *
+ * @method string getName()
+ * @mthod setName($param)
+ */
+ class TAction extends Model {
+ const ANGELEGT = 2;
+ const GEANDERT = 3;
+ const GELOESCHT = 4;
+
+ public function __construct() {
+ parent::__construct('t_action');
+
+ $this->data = array(
+ 'id' => NULL,
+ 'name' => '',
+ );
+ }
+
+ }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/classes/bfw/mvc/model/TGroup.php
@@ -0,0 +1,60 @@
+<?php
+
+namespace bfw\mvc\model {
+
+ /**
+ * Class TGroup
+ *
+ * @method string getName()
+ * @mthod setName($param)
+ */
+ class TGroup extends Model {
+ const GUEST = 5;
+ const SUPPORTER = 4;
+ const MANAGER = 3;
+ const ADMIN = 2;
+ const SYSTEM = 1;
+
+ public function __construct() {
+ parent::__construct('t_group');
+
+ $this->data = array(
+ 'id' => NULL,
+ 'name' => '',
+ );
+ }
+
+ /**
+ * @param $name
+ * @return array|null
+ */
+ public function findByName($name) {
+ return $this->db->findByField('t_group', 'name', $name);
+ }
+
+ /**
+ * <b>Besorgt ein Array mit der Liste der Manager und Darunter</b>
+ *
+ * @return array|null
+ */
+ public function findAllManagersAndBelow() {
+ /**
+ * SYSTEM = 1
+ * ADMIN = 2
+ * [MANAGER = 3, SUPPORTER = 4]
+ * GUEST = 5
+ */
+ $groups = $this->db->fetchAll($this->table, 'id > 2 and id < 5');
+
+ $list = array();
+ foreach ($groups as $group) {
+ $item = new static();
+ $item->data = $group;
+
+ $list[] = $item;
+ }
+
+ return $list;
+ }
+ }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/classes/bfw/mvc/model/THistory.php
@@ -0,0 +1,84 @@
+<?php
+
+namespace bfw\mvc\model {
+
+ /**
+ * Class THistory
+ *
+ * @method getTicket_Id()
+ * @method getAction_Id()
+ * @method getUser_Id()
+ * @method getStatus_Id()
+ *
+ * @method getSubject()
+ * @method getMessage()
+ *
+ * @method getLocked()
+ * @method getLast_Access()
+ *
+ * @method setTicket_Id($param)
+ * @method setAction_Id($param)
+ * @method setUser_Id($param)
+ * @method setStatus_Id($param)
+ *
+ * @method setSubject($param)
+ * @method setMessage($param)
+ *
+ * @method setLocked($locked)
+ * @method setLast_Access($lastAccess)
+ *
+ */
+ class THistory extends Model {
+
+ public function __construct() {
+ parent::__construct('t_history');
+
+ $this->data = array(
+ 'id' => NULL,
+ 'ticked_id' => 1,
+ 'action_id' => 1,
+ 'user_id' => 1,
+ 'status_id' => 1,
+ 'subject' => '',
+ 'message' => '',
+ 'locked' => false,
+ 'last_access' => 'now()',
+ );
+ }
+
+ /**
+ * <b>Liefert das Name-Attribut der jeweiligen Action</b>
+ *
+ * @return string
+ */
+ public function getActionName() {
+ $action = new TAction();
+ $action->find($this->getAction_Id());
+
+ return $action->getName();
+ }
+
+ /**
+ * <b>Liefert das Name-Attribut des jeweiligen Status</b>
+ *
+ * @return string|null
+ */
+ public function getStatusName() {
+ $status = new TStatus();
+ $status->find($this->getStatus_Id());
+
+ return $status->getName();
+ }
+
+ /**
+ * <b>Liefert das jeweilige Username Attribut des angebenen Benutzers</b>
+ *
+ * @return string
+ */
+ public function getUsername() {
+ $user = new TUser();
+
+ return $user->getFormattedUsername($this->getUser_Id());
+ }
+ }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/classes/bfw/mvc/model/TStatus.php
@@ -0,0 +1,36 @@
+<?php
+
+namespace bfw\mvc\model {
+
+ /**
+ * Class TStatus
+ *
+ * @method getName()
+ */
+ class TStatus extends Model {
+ const OFFEN = 2;
+ const GESCHLOSSEN = 3;
+
+ public function __construct() {
+ parent::__construct('t_status');
+
+ $this->data = array(
+ 'id' => NULL,
+ 'name' => '',
+ );
+
+ }
+
+ /**
+ * <b>Liefert den Bezeichner des angegebenen PKs der Status-Instanz<</b>
+ *
+ * @param $id
+ * @return mixed
+ */
+ public function getFormattedStatus($id) {
+ $status = $this->find($id);
+
+ return $status->getName();
+ }
+ }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/classes/bfw/mvc/model/TText.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace bfw\mvc\model {
+
+ /**
+ * Class TText
+ *
+ * @method int getUser_Id()
+ * @method string getHeadline()
+ * @method string getText()
+ * @method setUser_Id($param)
+ * @method setHeadline($param)
+ * @method setText($param)
+ */
+ class TText extends Model {
+ public function __construct() {
+ parent::__construct('t_text');
+
+ $this->data = array(
+ 'id' => NULL,
+ 'user_id' => 1,
+ 'headline' => '',
+ 'text' => '',
+ );
+
+ }
+ }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/classes/bfw/mvc/model/TTicket.php
@@ -0,0 +1,196 @@
+<?php
+
+namespace bfw\mvc\model {
+
+ /**
+ * Class TTicket
+ *
+ * @method int getUser_Id()
+ * @method int getStatus_Id()
+ * @method string getSubject()
+ * @method string getMessage()
+ * @method bool getLocked()
+ * @method timestamp getLast_Access()
+ *
+ * @method setStatus_Id($param)
+ * @method setSubject($param)
+ * @method setMessage($param)
+ * @method setLocked($param)
+ * @method setLast_Access($param)
+ *
+ */
+ class TTicket extends Model {
+ private static $logger = null;
+
+ public function __construct() {
+ parent::__construct('t_ticket');
+
+ self::$logger = \Logger::getLogger('__CLASS__');
+
+ $this->data = array(
+ 'id' => NULL,
+ 'user_id' => 1,
+ 'status_id' => 1,
+ 'subject' => '',
+ 'message' => '',
+ 'locked' => 0,
+ 'last_access' => 'now()',
+ );
+ }
+
+ /**
+ * <b>Findet alle Tickets des angegebenen Nutzers</b>
+ *
+ *
+ * @param SERIAL $uid
+ * @return array|null
+ */
+ public function findAllTicketsByUserid($uid) {
+ return $this->findAllByField('user_id', $uid);
+ }
+
+ /**
+ * <b>Weisst frei gewordenen Tickets automatisiert zu.</b>
+ */
+ public function reassignFreeTickets() {
+ $tickets = $this->findAllByField('user_id', 1);
+
+ $tUser = new TUser();
+ foreach ($tickets as $ticket) {
+ $freeSupporterId = $tUser->getFreeSupporterId();
+
+ /**
+ * Niemals vergessen: Nur aktualisieren, wenn auch
+ * aktualisiert werden muss.
+ *
+ */
+ if ($freeSupporterId > 1) {
+ $ticket->setUser_Id($freeSupporterId);
+ if ($ticket->store($ticket->getId(), $ticket)) {
+ self::$logger->info(sprintf("TICKET %d wurde neu zugewiesen.", $ticket->getId()));
+ }
+ }
+ }
+ }
+
+ public function lockTicket($ticket, $user) {
+ if ($user->getGroup_id() == TGroup::SUPPORTER) {
+ if ($ticket->getLocked() == false) {
+ $ticket->setLocked(1);
+ $ticket->setLast_Access(date('Y-m-d H:i:s'));
+
+ if ($this->store($ticket->getId(), $ticket)) {
+ self::$logger->info(sprintf("TICKET %d wurde gesperrt", $ticket->getId()));
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * <b>Das Ticket wird automatisch entsperrt nach 2 Stunden</b>
+ *
+ * @param $tTicket
+ * @return bool
+ */
+ public function unlockTickets($tTicket) {
+ $tickets = $tTicket->findAll(false);
+ $user = new TUser();
+
+ foreach ($tickets as $ticket) {
+ if ($ticket->getStatus_Id() == TStatus::GESCHLOSSEN) {
+ continue;
+ }
+
+ // Ticketalter
+ $ticketAge = time() - strtotime($ticket->getLast_Access());
+
+ // Die Bearbeitungszeit beträgt 2 Stunden pro Supporter
+ $deadLine = 3600 * 2;
+
+ self::$logger->info('Ticket-Alter: ' . $ticketAge);
+ self::$logger->info('Deadline: ' . $deadLine);
+
+ if ($ticketAge > $deadLine) {
+ self::$logger->info('Time is up: Daten werden geändert.');
+ $freeSupporterId = $user->getFreeSupporterId();
+
+ if ($freeSupporterId > 1) {
+ $ticket->setUser_Id($freeSupporterId);
+ $ticket->setLocked(0);
+
+ if ($this->store($ticket->getId(), $ticket)) {
+ continue;
+ }
+ } else {
+ // Es existieren keine Supporter
+ self::$logger->info(sprintf("%s(): Es existieren keine Supporter!", __METHOD__));
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * <b>Überladene find Methode</b>
+ *
+ * In früheren Versionen wurde hier das Ticket 'on the fly' modifiziert.
+ * Da das aber nicht Sinn und Zweck einer 'find' Methode ist, wurde das
+ * wieder entfernt und die Modifizierung erfolgt außerhalb...
+ *
+ * <b>Sinn und Zweck dieser Methode ist: 'Ticket-ID: nnn' ins Log zu schreiben...</b>
+ *
+ * @param $id
+ *
+ * @return array|null
+ */
+ public function find($id) {
+ self::$logger->info(sprintf("Ticket-ID: %d", $id));
+
+ return parent::find($id);
+ }
+
+ /**
+ * <b>Prüft, ob der übergebene Nutzer überhaupt die Berechtigung für das übergebene Ticket besitzt.</b>
+ *
+ * @param $ticket
+ * @param $user
+ * @return bool
+ */
+ public function hasPrivilege($ticket, $user, $write = true) {
+
+ // NULL Tickets: Kein Zugriff
+ if (!is_object($ticket)) {
+ self::$logger->warn(sprintf("%s(): Ticket wurde nicht initialisiert!", __METHOD__));
+ return false;
+ }
+
+ // NULL User: Kein Zugriff
+ if (!is_object($user)) {
+ self::$logger->warn(sprintf("%s(): Benutzer wurde nicht initialisiert!", __METHOD__));
+ return false;
+ }
+
+ // ADMIN UND MANAGER: Zugriff per Default
+ switch ($user->getGroup_Id()) {
+ case TGroup::ADMIN:
+ case TGroup::MANAGER:
+ return true;
+ }
+
+ if ($write == false) {
+ // System-Datensatz herausfiltern
+ if ($ticket->getId() > 1) {
+ return true;
+ }
+ }
+
+ // Ticketbasierter Zugriff: Ticket-Owner == Angemeldeter Benutzer?
+ return ($ticket->getUser_Id() == $user->getId());
+ }
+
+ }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/classes/bfw/mvc/model/TUser.php
@@ -0,0 +1,149 @@
+<?php
+
+namespace bfw\mvc\model {
+
+ /**
+ * Class TUser
+ *
+ * @method string getUsername()
+ * @method int getGroup_Id()
+ * @method string getPassword()
+ * @method string getFirstname()
+ * @method string getLastname()
+ * @method setUsername()
+ * @method setGroup_Id()
+ * @method setPassword()
+ * @method setFirstname()
+ * @method setLastname()
+ */
+ class TUser extends Model {
+ private static $logger = null;
+
+ const SYSTEM = 1;
+
+ public function __construct() {
+ parent::__construct('t_user');
+
+ self::$logger = \Logger::getLogger('__CLASS__');
+
+ $this->data = array(
+ 'id' => NULL,
+ 'group_id' => TUser::SYSTEM,
+ 'username' => '',
+ 'firstname' => '',
+ 'lastname' => '',
+ 'password' => '',
+ );
+ }
+
+ /**
+ * <b>Liefert eine User-Instanz für den per Parameter übergebenen Nutzernamen.</b>
+ *
+ * @param $username
+ * @return array|null
+ */
+ public function findByUsername($username) {
+ $this->data = $this->db->findByField($this->table, 'username', $username);
+
+ if ($this->data == null) {
+ return null;
+ }
+
+ return $this;
+ }
+
+ /**
+ * <b>Liefert den formatierten Nutzernamen zur übergebenen Nutzer-Id</b>
+ *
+ * @param $user_id
+ * @return string
+ */
+ public function getFormattedUsername($user_id) {
+ $user = $this->find($user_id);
+ return sprintf("%s, %s", $user->getLastname(), $user->getFirstname());
+ }
+
+ /**
+ * <b>FindMethode für alle Manager und Darunter</b>
+ *
+ * @return array|null
+ */
+ public function findAllManagersAndBelow() {
+ $managers = $this->db->query(sprintf("
+ SELECT
+ *
+ FROM
+ `%s`
+ WHERE
+ `group_id` in (3,4,5)",
+ $this->table));
+
+ $list = array();
+ foreach ($managers as $manager) {
+ $item = new static();
+ $item->data = $manager;
+
+ $list[] = $item;
+ }
+
+ return $list;
+ }
+
+ /**
+ * liefert den PK des nächst freien Supporters oder
+ * im Falle von nicht vorhandenen Supportern den System-Datensatz
+ *
+ * @return int
+ */
+ public function getFreeSupporterId() {
+
+ $sql = sprintf("
+ SELECT
+ u.id,
+ COUNT(t.user_id) AS `count`
+ FROM
+ t_user u
+ LEFT JOIN
+ t_ticket t ON u.id = t.user_id
+ WHERE
+ u.group_id = 4
+ GROUP BY
+ u.id
+ ORDER BY
+ `count` ASC
+ ");
+
+ $data = $this->db->query($sql);
+
+ if ($data == null) {
+ // Ich will hier definitiv immer eine gültige ID haben, also einen PK
+ return 1;
+ }
+
+ self::$logger->info(sprintf("Data: %s", print_r($data, true)));
+
+ return $data[0]['id'];
+ }
+
+ /**
+ * <b>Anzahl der Tickets eines Benutzers</b>
+ *
+ * @return mixed
+ */
+ public function getTicketCount() {
+ $sql = sprintf("
+ SELECT
+ count(*) as anzahl
+ FROM
+ t_ticket
+ WHERE
+ user_id = %d
+ ", $this->getId());
+
+ $data = $this->db->query($sql);
+
+ return $data[0]['anzahl'];
+ }
+
+ }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/classes/bfw/mvc/model/TView.php
@@ -0,0 +1,58 @@
+<?php
+
+namespace bfw\mvc\model {
+
+ /**
+ * Class TView
+ *
+ * @method string getId()
+ */
+ class TView extends Model {
+
+ /**
+ * Nur Get-Methoden im View
+ *
+ * @param $methodName
+ * @param null $params
+ * @return mixed
+ */
+ public function __call($methodName, $params = null) {
+ $prefix = substr($methodName, 0, 3);
+ $key = strtolower(substr($methodName, 3));
+
+ if ($prefix == 'get') {
+ if (array_key_exists($key, $this->data)) {
+ return $this->data[$key];
+ }
+ }
+
+ exit(sprintf('Unbekannte Methode %s(%s, %s) wurde aufgerufen.', $methodName, $key, $prefix));
+ }
+
+ /**
+ * @param $id
+ * @param $object
+ * @return bool
+ */
+ public function store($id, $object) {
+ return false;
+ }
+
+ /**
+ * @param $id
+ * @return bool
+ */
+ public function delete($id) {
+ return false;
+ }
+
+ /**
+ * @param $id
+ * @param $object
+ * @return bool
+ */
+ public function persist($id, $object) {
+ return false;
+ }
+ }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/classes/bfw/mvc/view/View.php
@@ -0,0 +1,115 @@
+<?php
+
+namespace bfw\mvc\view {
+
+ use bfw\mvc\controller\Controller;
+ use bfw\mvc\model\Model;
+ use bfw\mvc\model\TGroup;
+ use bfw\mvc\model\TStatus;
+ use bfw\mvc\model\TUser;
+
+ require_once 'library/smarty/libs/Smarty.class.php';
+
+ class View extends \Smarty {
+ /**
+ * @var Model
+ */
+ private $model;
+
+ /**
+ * @var Controller
+ */
+ private $controller;
+
+ /**
+ * Statische Referenz auf die reale Template Engine, hier Smarty
+ *
+ * @var Smarty
+ */
+ private static $tpl = null;
+
+ /**
+ * View constructor.
+ *
+ * @param Controller $controller
+ * @param Model $model
+ */
+ public function __construct(Controller $controller, Model $model) {
+ $this->controller = $controller;
+ $this->model = $model;
+
+ self::$tpl = self::getTemplateEngine();
+ }
+
+ /**
+ * <b>Liefert ein statisches Handle auf die aktuelle Template Engine zurück</b>
+ *
+ * Das Singleton Pattern garantiert genau eine Instanz der Template Engine im Speicher.
+ *
+ * <b>Verschiedene Skripte können so nacheinander Variablen zuweisen und diese bei Bedarf auslesen</b>
+ *
+ * @return Smarty
+ */
+ private static function getTemplateEngine() {
+ if (self::$tpl == null) {
+ self::$tpl = new \Smarty();
+
+ $tpl = self::$tpl;
+
+ $tpl->setCompileDir('./data/templates_c/');
+ $tpl->setTemplateDir('./templates/');
+ }
+
+ return self::$tpl;
+ }
+
+ public function assign($key, $value) {
+ self::$tpl->assign($key, $value);
+ }
+
+ /**
+ * weisst automatisch eine user-instanz zu: Seiten-Effekte beachten
+ *
+ * TODO: Namensschema festlegen, damit dieser Effekt nicht auftritt
+ */
+ public function display() {
+ $tUser = new TUser();
+ $tGroup = new TGroup();
+ $tStatus = new TStatus();
+
+ $request = $this->controller->getRequest();
+
+ if ($request->getKey('isLoggedIn')) {
+ $tUser->find($request->getKey('user_id'));
+ }
+
+ $controller = $this->controller;
+
+ $response = $controller->getResponse();
+ $this->assign('response', $response);
+
+ $this->assign('tUser', $tUser);
+ $this->assign('tGroup', $tGroup);
+ $this->assign('tStatus', $tStatus);
+ $this->assign('request', $request);
+
+ try {
+ self::$tpl->display('layout.tpl');
+ } catch (SmartyException $se) {
+ $response->setStatusCode(404);
+
+ $page = 'error/error';
+ self::$tpl->assign('page', $page);
+
+ self::$tpl->display('layout.tpl');
+ }
+
+ // Msg wieder auf Null setzen...
+ $request->setKey('msg', '');
+
+ // Fehler wieder auf Null setzen...
+ $request->setKey('fehler', '');
+ }
+
+ }
+}
new file mode 100644
--- /dev/null
+++ b/config/config.php
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ *
+ */
+
+define('TICKET_PATH', dirname(dirname(__FILE__)));
+
+/**
+ * Standard-Autoloader für die Basis-Klassen des Projekts
+ *
+ * @param $class
+ * @return bool
+ */
+function bfw_autoLoader($class) {
+ $nsClass = str_replace('\\', '/', $class);
+ $filename = sprintf('%s/classes/%s.php', TICKET_PATH, $nsClass);
+ $classPath = sprintf('classes/%s.php', str_replace('\\', '/', $nsClass));
+
+ if (file_exists($filename)) {
+ require_once "$classPath";
+
+ return true;
+ }
+
+ return false;
+}
+
+require_once 'library/log4php/Logger.php';
+Logger::configure(TICKET_PATH . '/config/log4php.xml');
+
+spl_autoload_register('bfw_autoLoader');
+
+// Durchs Überschreiben habe ich eine eigene Session und teile mir diese nicht mit den 'PHPSESSID' Leuten...
+session_name('ticked-id');
+session_start();
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/config/log4php.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://logging.apache.org/log4php/">
+ <appender name="default" class="LoggerAppenderFile">
+ <layout class="LoggerLayoutSimple"/>
+ <param name="file" value="/var/www/vhosts/TicketSystem/logs/tickets.log"/>
+ <param name="append" value="true"/>
+ </appender>
+ <root>
+ <appender_ref ref="default"/>
+ </root>
+</configuration>
new file mode 100644
--- /dev/null
+++ b/css/main.css
@@ -0,0 +1,110 @@
+html, body, p, textarea, input, select {
+ margin: 0;
+ padding: 0;
+}
+
+p {
+ padding: 5px;
+}
+
+label, input, select, textarea {
+ width: 100%;
+ line-height: 100%;
+}
+
+form textarea {
+ min-height: 250px;
+}
+
+.content {
+ margin-bottom: 50px;
+}
+
+.text-info {
+ color: #080808;
+}
+
+.footer-area {
+ height: 30px;
+}
+
+.footer {
+ margin: 0;
+ padding: 0;
+
+ width: 100%;
+ text-align: center;
+
+ position: fixed;
+ bottom: 0;
+
+ color: #080808;
+ background-color: #e7e7e7;
+
+ overflow: hidden;
+}
+
+/* Tabellen Fusch für den Validator */
+table {
+ width: 100%;
+}
+
+table, tr, td, th {
+ border: 1px solid #000;
+}
+
+.achtel td, .achtel th {
+ width: 12.5% !important;
+}
+
+table td, table th {
+ text-align: center;
+}
+
+table tr td input {
+ text-align: center;
+}
+
+.auto-width {
+ width: auto;
+}
+
+.knopf {
+ margin-top: 25px;
+
+ font-size: 2em;
+ border: 2px solid #444;
+ background-color: #996666;
+
+}
+
+.knopf a {
+ text-decoration: none;
+ padding: 20px;
+}
+
+.ellipsis {
+ text-overflow: ellipsis;
+}
+
+.bold {
+ font-size: 1.5em;
+ font-weight: bold;
+}
+
+table input {
+ color: #fff;
+ background-color: #660000;
+
+ padding: 5px;
+}
+
+.red-row, .red-row td input {
+ color: #080808;
+ background-color: rgb(255, 0, 0);
+}
+
+.yellow-row, .yellow-row td input {
+ color: #080808;
+ background-color: rgb(255, 255, 0);
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/data/import/test_tickets.csv
@@ -0,0 +1,11 @@
+user_id;status_id;subject;message;locked;last_access
+1;2;Ticket-1;Beschreibung-1;f;NULL
+1;2;Ticket-2;Beschreibung-2;f;NULL
+1;2;Ticket-3;Beschreibung-3;f;NULL
+1;2;Ticket-4;Beschreibung-4;f;NULL
+1;2;Ticket-5;Beschreibung-5;f;NULL
+1;2;Ticket-6;Beschreibung-6;f;NULL
+1;2;Ticket-7;Beschreibung-7;f;NULL
+1;2;Ticket-8;Beschreibung-8;f;NULL
+1;2;Ticket-9;Beschreibung-9;f;NULL
+1;2;Ticket-10;Beschreibung-10;f;NULL
new file mode 100644
--- /dev/null
+++ b/data/import/test_users.csv
@@ -0,0 +1,12 @@
+group_id;username;password;firstname;lastname
+3;manager1@onscreen.net;098f6bcd4621d373cade4e832627b4f6;Manager1;Onscreen
+4;supporter1@onscreen.net;098f6bcd4621d373cade4e832627b4f6;supporter1;Onscreen
+4;supporter2@onscreen.net;098f6bcd4621d373cade4e832627b4f6;supporter2;Onscreen
+4;supporter3@onscreen.net;098f6bcd4621d373cade4e832627b4f6;supporter3;Onscreen
+4;supporter4@onscreen.net;098f6bcd4621d373cade4e832627b4f6;supporter4;Onscreen
+4;supporter5@onscreen.net;098f6bcd4621d373cade4e832627b4f6;supporter5;Onscreen
+4;supporter6@onscreen.net;098f6bcd4621d373cade4e832627b4f6;supporter6;Onscreen
+4;supporter7@onscreen.net;098f6bcd4621d373cade4e832627b4f6;supporter7;Onscreen
+4;supporter8@onscreen.net;098f6bcd4621d373cade4e832627b4f6;supporter8;Onscreen
+4;supporter9@onscreen.net;098f6bcd4621d373cade4e832627b4f6;supporter9;Onscreen
+4;supporter10@onscreen.net;098f6bcd4621d373cade4e832627b4f6;supporter10;Onscreen
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..d35d9b6749d7133e0b48558d791926d8a6b174f9
GIT binary patch
literal 755
zc%17D@N?(olHy`uVBq!ia0y~yU@Qc(FK{pc$+}C&cz_gRage(c!@6@aFM%AEbVpxD
z28NCO+<y{Tfqc#akH}&M2EM}}%y>M1MG6B0Q-`OEV@O5Z+bf2Q3=BMn7yLB8JM#pm
o(hkOwIZRVV(I}z|D%r-aw_H)sMfXz`FrhMdy85}Sb4q9e0Cp=J4*&oF
new file mode 100644
--- /dev/null
+++ b/index.php
@@ -0,0 +1,14 @@
+<?php
+
+/**
+ * Ticket-System
+ *
+ */
+
+namespace bfw;
+
+require_once 'config/config.php';
+
+$dispatcher = new Dispatcher();
+$view = $dispatcher->getView();
+$view->display();
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/js/bootstrap/bootstrap.js
@@ -0,0 +1,2378 @@
+/*!
+ * Bootstrap v3.3.5 (http://getbootstrap.com)
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under the MIT license
+ */
+
+if (typeof jQuery === 'undefined') {
+ throw new Error('Bootstrap\'s JavaScript requires jQuery')
+}
+
++function ($) {
+ 'use strict';
+ var version = $.fn.jquery.split(' ')[0].split('.');
+ if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) {
+ throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher')
+ }
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: transition.js v3.3.5
+ * http://getbootstrap.com/javascript/#transitions
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
+ // ============================================================
+
+ function transitionEnd() {
+ var el = document.createElement('bootstrap');
+
+ var transEndEventNames = {
+ WebkitTransition: 'webkitTransitionEnd',
+ MozTransition: 'transitionend',
+ OTransition: 'oTransitionEnd otransitionend',
+ transition: 'transitionend'
+ };
+
+ for (var name in transEndEventNames) {
+ if (el.style[name] !== undefined) {
+ return {end: transEndEventNames[name]}
+ }
+ }
+
+ return false; // explicit for ie8 ( ._.)
+ }
+
+ // http://blog.alexmaccaw.com/css-transitions
+ $.fn.emulateTransitionEnd = function (duration) {
+ var called = false;
+ var $el = this;
+ $(this).one('bsTransitionEnd', function () {
+ called = true
+ });
+ var callback = function () {
+ if (!called) $($el).trigger($.support.transition.end)
+ };
+ setTimeout(callback, duration);
+ return this
+ };
+
+ $(function () {
+ $.support.transition = transitionEnd();
+
+ if (!$.support.transition) return;
+
+ $.event.special.bsTransitionEnd = {
+ bindType: $.support.transition.end,
+ delegateType: $.support.transition.end,
+ handle: function (e) {
+ if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
+ }
+ }
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: alert.js v3.3.5
+ * http://getbootstrap.com/javascript/#alerts
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // ALERT CLASS DEFINITION
+ // ======================
+
+ var dismiss = '[data-dismiss="alert"]';
+ var Alert = function (el) {
+ $(el).on('click', dismiss, this.close)
+ };
+
+ Alert.VERSION = '3.3.5';
+
+ Alert.TRANSITION_DURATION = 150;
+
+ Alert.prototype.close = function (e) {
+ var $this = $(this);
+ var selector = $this.attr('data-target');
+
+ if (!selector) {
+ selector = $this.attr('href');
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, ''); // strip for ie7
+ }
+
+ var $parent = $(selector);
+
+ if (e) e.preventDefault();
+
+ if (!$parent.length) {
+ $parent = $this.closest('.alert')
+ }
+
+ $parent.trigger(e = $.Event('close.bs.alert'));
+
+ if (e.isDefaultPrevented()) return;
+
+ $parent.removeClass('in');
+
+ function removeElement() {
+ // detach from parent, fire event then clean up data
+ $parent.detach().trigger('closed.bs.alert').remove()
+ }
+
+ $.support.transition && $parent.hasClass('fade') ?
+ $parent
+ .one('bsTransitionEnd', removeElement)
+ .emulateTransitionEnd(Alert.TRANSITION_DURATION) :
+ removeElement()
+ };
+
+
+ // ALERT PLUGIN DEFINITION
+ // =======================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this);
+ var data = $this.data('bs.alert');
+
+ if (!data) $this.data('bs.alert', (data = new Alert(this)));
+ if (typeof option == 'string') data[option].call($this)
+ })
+ }
+
+ var old = $.fn.alert;
+
+ $.fn.alert = Plugin;
+ $.fn.alert.Constructor = Alert;
+
+
+ // ALERT NO CONFLICT
+ // =================
+
+ $.fn.alert.noConflict = function () {
+ $.fn.alert = old;
+ return this
+ };
+
+
+ // ALERT DATA-API
+ // ==============
+
+ $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: button.js v3.3.5
+ * http://getbootstrap.com/javascript/#buttons
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // BUTTON PUBLIC CLASS DEFINITION
+ // ==============================
+
+ var Button = function (element, options) {
+ this.$element = $(element);
+ this.options = $.extend({}, Button.DEFAULTS, options);
+ this.isLoading = false
+ };
+
+ Button.VERSION = '3.3.5';
+
+ Button.DEFAULTS = {
+ loadingText: 'loading...'
+ };
+
+ Button.prototype.setState = function (state) {
+ var d = 'disabled';
+ var $el = this.$element;
+ var val = $el.is('input') ? 'val' : 'html';
+ var data = $el.data();
+
+ state += 'Text';
+
+ if (data.resetText == null) $el.data('resetText', $el[val]());
+
+ // push to event loop to allow forms to submit
+ setTimeout($.proxy(function () {
+ $el[val](data[state] == null ? this.options[state] : data[state]);
+
+ if (state == 'loadingText') {
+ this.isLoading = true;
+ $el.addClass(d).attr(d, d)
+ } else if (this.isLoading) {
+ this.isLoading = false;
+ $el.removeClass(d).removeAttr(d)
+ }
+ }, this), 0)
+ };
+
+ Button.prototype.toggle = function () {
+ var changed = true;
+ var $parent = this.$element.closest('[data-toggle="buttons"]');
+
+ if ($parent.length) {
+ var $input = this.$element.find('input');
+ if ($input.prop('type') == 'radio') {
+ if ($input.prop('checked')) changed = false;
+ $parent.find('.active').removeClass('active');
+ this.$element.addClass('active')
+ } else if ($input.prop('type') == 'checkbox') {
+ if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false;
+ this.$element.toggleClass('active')
+ }
+ $input.prop('checked', this.$element.hasClass('active'));
+ if (changed) $input.trigger('change')
+ } else {
+ this.$element.attr('aria-pressed', !this.$element.hasClass('active'));
+ this.$element.toggleClass('active')
+ }
+ };
+
+
+ // BUTTON PLUGIN DEFINITION
+ // ========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this);
+ var data = $this.data('bs.button');
+ var options = typeof option == 'object' && option;
+
+ if (!data) $this.data('bs.button', (data = new Button(this, options)));
+
+ if (option == 'toggle') data.toggle();
+ else if (option) data.setState(option)
+ })
+ }
+
+ var old = $.fn.button;
+
+ $.fn.button = Plugin;
+ $.fn.button.Constructor = Button;
+
+
+ // BUTTON NO CONFLICT
+ // ==================
+
+ $.fn.button.noConflict = function () {
+ $.fn.button = old;
+ return this
+ };
+
+
+ // BUTTON DATA-API
+ // ===============
+
+ $(document)
+ .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
+ var $btn = $(e.target);
+ if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn');
+ Plugin.call($btn, 'toggle');
+ if (!($(e.target).is('input[type="radio"]') || $(e.target).is('input[type="checkbox"]'))) e.preventDefault()
+ })
+ .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
+ $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: carousel.js v3.3.5
+ * http://getbootstrap.com/javascript/#carousel
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // CAROUSEL CLASS DEFINITION
+ // =========================
+
+ var Carousel = function (element, options) {
+ this.$element = $(element);
+ this.$indicators = this.$element.find('.carousel-indicators');
+ this.options = options;
+ this.paused = null;
+ this.sliding = null;
+ this.interval = null;
+ this.$active = null;
+ this.$items = null;
+
+ this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this));
+
+ this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
+ .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
+ .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
+ };
+
+ Carousel.VERSION = '3.3.5';
+
+ Carousel.TRANSITION_DURATION = 600;
+
+ Carousel.DEFAULTS = {
+ interval: 5000,
+ pause: 'hover',
+ wrap: true,
+ keyboard: true
+ };
+
+ Carousel.prototype.keydown = function (e) {
+ if (/input|textarea/i.test(e.target.tagName)) return;
+ switch (e.which) {
+ case 37:
+ this.prev();
+ break;
+ case 39:
+ this.next();
+ break;
+ default:
+ return
+ }
+
+ e.preventDefault()
+ };
+
+ Carousel.prototype.cycle = function (e) {
+ e || (this.paused = false);
+
+ this.interval && clearInterval(this.interval);
+
+ this.options.interval
+ && !this.paused
+ && (this.interval = setInterval($.proxy(this.next, this), this.options.interval));
+
+ return this
+ };
+
+ Carousel.prototype.getItemIndex = function (item) {
+ this.$items = item.parent().children('.item');
+ return this.$items.index(item || this.$active)
+ };
+
+ Carousel.prototype.getItemForDirection = function (direction, active) {
+ var activeIndex = this.getItemIndex(active);
+ var willWrap = (direction == 'prev' && activeIndex === 0)
+ || (direction == 'next' && activeIndex == (this.$items.length - 1));
+ if (willWrap && !this.options.wrap) return active;
+ var delta = direction == 'prev' ? -1 : 1;
+ var itemIndex = (activeIndex + delta) % this.$items.length;
+ return this.$items.eq(itemIndex)
+ };
+
+ Carousel.prototype.to = function (pos) {
+ var that = this;
+ var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'));
+
+ if (pos > (this.$items.length - 1) || pos < 0) return;
+
+ if (this.sliding) return this.$element.one('slid.bs.carousel', function () {
+ that.to(pos)
+ }); // yes, "slid"
+ if (activeIndex == pos) return this.pause().cycle();
+
+ return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
+ };
+
+ Carousel.prototype.pause = function (e) {
+ e || (this.paused = true);
+
+ if (this.$element.find('.next, .prev').length && $.support.transition) {
+ this.$element.trigger($.support.transition.end);
+ this.cycle(true)
+ }
+
+ this.interval = clearInterval(this.interval);
+
+ return this
+ };
+
+ Carousel.prototype.next = function () {
+ if (this.sliding) return;
+ return this.slide('next')
+ };
+
+ Carousel.prototype.prev = function () {
+ if (this.sliding) return;
+ return this.slide('prev')
+ };
+
+ Carousel.prototype.slide = function (type, next) {
+ var $active = this.$element.find('.item.active');
+ var $next = next || this.getItemForDirection(type, $active);
+ var isCycling = this.interval;
+ var direction = type == 'next' ? 'left' : 'right';
+ var that = this;
+
+ if ($next.hasClass('active')) return (this.sliding = false);
+
+ var relatedTarget = $next[0];
+ var slideEvent = $.Event('slide.bs.carousel', {
+ relatedTarget: relatedTarget,
+ direction: direction
+ });
+ this.$element.trigger(slideEvent);
+ if (slideEvent.isDefaultPrevented()) return;
+
+ this.sliding = true;
+
+ isCycling && this.pause();
+
+ if (this.$indicators.length) {
+ this.$indicators.find('.active').removeClass('active');
+ var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)]);
+ $nextIndicator && $nextIndicator.addClass('active')
+ }
+
+ var slidEvent = $.Event('slid.bs.carousel', {relatedTarget: relatedTarget, direction: direction}); // yes, "slid"
+ if ($.support.transition && this.$element.hasClass('slide')) {
+ $next.addClass(type);
+ $next[0].offsetWidth; // force reflow
+ $active.addClass(direction);
+ $next.addClass(direction);
+ $active
+ .one('bsTransitionEnd', function () {
+ $next.removeClass([type, direction].join(' ')).addClass('active');
+ $active.removeClass(['active', direction].join(' '));
+ that.sliding = false;
+ setTimeout(function () {
+ that.$element.trigger(slidEvent)
+ }, 0)
+ })
+ .emulateTransitionEnd(Carousel.TRANSITION_DURATION)
+ } else {
+ $active.removeClass('active');
+ $next.addClass('active');
+ this.sliding = false;
+ this.$element.trigger(slidEvent)
+ }
+
+ isCycling && this.cycle();
+
+ return this
+ };
+
+
+ // CAROUSEL PLUGIN DEFINITION
+ // ==========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this);
+ var data = $this.data('bs.carousel');
+ var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option);
+ var action = typeof option == 'string' ? option : options.slide;
+
+ if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)));
+ if (typeof option == 'number') data.to(option);
+ else if (action) data[action]();
+ else if (options.interval) data.pause().cycle()
+ })
+ }
+
+ var old = $.fn.carousel;
+
+ $.fn.carousel = Plugin;
+ $.fn.carousel.Constructor = Carousel;
+
+
+ // CAROUSEL NO CONFLICT
+ // ====================
+
+ $.fn.carousel.noConflict = function () {
+ $.fn.carousel = old;
+ return this
+ };
+
+
+ // CAROUSEL DATA-API
+ // =================
+
+ var clickHandler = function (e) {
+ var href;
+ var $this = $(this);
+ var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')); // strip for ie7
+ if (!$target.hasClass('carousel')) return;
+ var options = $.extend({}, $target.data(), $this.data());
+ var slideIndex = $this.attr('data-slide-to');
+ if (slideIndex) options.interval = false;
+
+ Plugin.call($target, options);
+
+ if (slideIndex) {
+ $target.data('bs.carousel').to(slideIndex)
+ }
+
+ e.preventDefault()
+ };
+
+ $(document)
+ .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
+ .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler);
+
+ $(window).on('load', function () {
+ $('[data-ride="carousel"]').each(function () {
+ var $carousel = $(this);
+ Plugin.call($carousel, $carousel.data())
+ })
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: collapse.js v3.3.5
+ * http://getbootstrap.com/javascript/#collapse
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // COLLAPSE PUBLIC CLASS DEFINITION
+ // ================================
+
+ var Collapse = function (element, options) {
+ this.$element = $(element);
+ this.options = $.extend({}, Collapse.DEFAULTS, options);
+ this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
+ '[data-toggle="collapse"][data-target="#' + element.id + '"]');
+ this.transitioning = null;
+
+ if (this.options.parent) {
+ this.$parent = this.getParent()
+ } else {
+ this.addAriaAndCollapsedClass(this.$element, this.$trigger)
+ }
+
+ if (this.options.toggle) this.toggle()
+ };
+
+ Collapse.VERSION = '3.3.5';
+
+ Collapse.TRANSITION_DURATION = 350;
+
+ Collapse.DEFAULTS = {
+ toggle: true
+ };
+
+ Collapse.prototype.dimension = function () {
+ var hasWidth = this.$element.hasClass('width');
+ return hasWidth ? 'width' : 'height'
+ };
+
+ Collapse.prototype.show = function () {
+ if (this.transitioning || this.$element.hasClass('in')) return;
+
+ var activesData;
+ var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing');
+
+ if (actives && actives.length) {
+ activesData = actives.data('bs.collapse');
+ if (activesData && activesData.transitioning) return
+ }
+
+ var startEvent = $.Event('show.bs.collapse');
+ this.$element.trigger(startEvent);
+ if (startEvent.isDefaultPrevented()) return;
+
+ if (actives && actives.length) {
+ Plugin.call(actives, 'hide');
+ activesData || actives.data('bs.collapse', null)
+ }
+
+ var dimension = this.dimension();
+
+ this.$element
+ .removeClass('collapse')
+ .addClass('collapsing')[dimension](0)
+ .attr('aria-expanded', true);
+
+ this.$trigger
+ .removeClass('collapsed')
+ .attr('aria-expanded', true);
+
+ this.transitioning = 1;
+
+ var complete = function () {
+ this.$element
+ .removeClass('collapsing')
+ .addClass('collapse in')[dimension]('');
+ this.transitioning = 0;
+ this.$element
+ .trigger('shown.bs.collapse')
+ };
+
+ if (!$.support.transition) return complete.call(this);
+
+ var scrollSize = $.camelCase(['scroll', dimension].join('-'));
+
+ this.$element
+ .one('bsTransitionEnd', $.proxy(complete, this))
+ .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
+ };
+
+ Collapse.prototype.hide = function () {
+ if (this.transitioning || !this.$element.hasClass('in')) return;
+
+ var startEvent = $.Event('hide.bs.collapse');
+ this.$element.trigger(startEvent);
+ if (startEvent.isDefaultPrevented()) return;
+
+ var dimension = this.dimension();
+
+ this.$element[dimension](this.$element[dimension]())[0].offsetHeight;
+
+ this.$element
+ .addClass('collapsing')
+ .removeClass('collapse in')
+ .attr('aria-expanded', false);
+
+ this.$trigger
+ .addClass('collapsed')
+ .attr('aria-expanded', false);
+
+ this.transitioning = 1;
+
+ var complete = function () {
+ this.transitioning = 0;
+ this.$element
+ .removeClass('collapsing')
+ .addClass('collapse')
+ .trigger('hidden.bs.collapse')
+ };
+
+ if (!$.support.transition) return complete.call(this);
+
+ this.$element
+ [dimension](0)
+ .one('bsTransitionEnd', $.proxy(complete, this))
+ .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
+ };
+
+ Collapse.prototype.toggle = function () {
+ this[this.$element.hasClass('in') ? 'hide' : 'show']()
+ };
+
+ Collapse.prototype.getParent = function () {
+ return $(this.options.parent)
+ .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
+ .each($.proxy(function (i, element) {
+ var $element = $(element);
+ this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
+ }, this))
+ .end()
+ };
+
+ Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
+ var isOpen = $element.hasClass('in');
+
+ $element.attr('aria-expanded', isOpen);
+ $trigger
+ .toggleClass('collapsed', !isOpen)
+ .attr('aria-expanded', isOpen)
+ };
+
+ function getTargetFromTrigger($trigger) {
+ var href;
+ var target = $trigger.attr('data-target')
+ || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, ''); // strip for ie7
+
+ return $(target)
+ }
+
+
+ // COLLAPSE PLUGIN DEFINITION
+ // ==========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this);
+ var data = $this.data('bs.collapse');
+ var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option);
+
+ if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false;
+ if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)));
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.collapse;
+
+ $.fn.collapse = Plugin;
+ $.fn.collapse.Constructor = Collapse;
+
+
+ // COLLAPSE NO CONFLICT
+ // ====================
+
+ $.fn.collapse.noConflict = function () {
+ $.fn.collapse = old;
+ return this
+ };
+
+
+ // COLLAPSE DATA-API
+ // =================
+
+ $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
+ var $this = $(this);
+
+ if (!$this.attr('data-target')) e.preventDefault();
+
+ var $target = getTargetFromTrigger($this);
+ var data = $target.data('bs.collapse');
+ var option = data ? 'toggle' : $this.data();
+
+ Plugin.call($target, option)
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: dropdown.js v3.3.5
+ * http://getbootstrap.com/javascript/#dropdowns
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // DROPDOWN CLASS DEFINITION
+ // =========================
+
+ var backdrop = '.dropdown-backdrop';
+ var toggle = '[data-toggle="dropdown"]';
+ var Dropdown = function (element) {
+ $(element).on('click.bs.dropdown', this.toggle)
+ };
+
+ Dropdown.VERSION = '3.3.5';
+
+ function getParent($this) {
+ var selector = $this.attr('data-target');
+
+ if (!selector) {
+ selector = $this.attr('href');
+ selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, ''); // strip for ie7
+ }
+
+ var $parent = selector && $(selector);
+
+ return $parent && $parent.length ? $parent : $this.parent()
+ }
+
+ function clearMenus(e) {
+ if (e && e.which === 3) return;
+ $(backdrop).remove();
+ $(toggle).each(function () {
+ var $this = $(this);
+ var $parent = getParent($this);
+ var relatedTarget = {relatedTarget: this};
+
+ if (!$parent.hasClass('open')) return;
+
+ if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return;
+
+ $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget));
+
+ if (e.isDefaultPrevented()) return;
+
+ $this.attr('aria-expanded', 'false');
+ $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
+ })
+ }
+
+ Dropdown.prototype.toggle = function (e) {
+ var $this = $(this);
+
+ if ($this.is('.disabled, :disabled')) return;
+
+ var $parent = getParent($this);
+ var isActive = $parent.hasClass('open');
+
+ clearMenus();
+
+ if (!isActive) {
+ if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
+ // if mobile we use a backdrop because click events don't delegate
+ $(document.createElement('div'))
+ .addClass('dropdown-backdrop')
+ .insertAfter($(this))
+ .on('click', clearMenus)
+ }
+
+ var relatedTarget = {relatedTarget: this};
+ $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget));
+
+ if (e.isDefaultPrevented()) return;
+
+ $this
+ .trigger('focus')
+ .attr('aria-expanded', 'true');
+
+ $parent
+ .toggleClass('open')
+ .trigger('shown.bs.dropdown', relatedTarget)
+ }
+
+ return false
+ };
+
+ Dropdown.prototype.keydown = function (e) {
+ if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return;
+
+ var $this = $(this);
+
+ e.preventDefault();
+ e.stopPropagation();
+
+ if ($this.is('.disabled, :disabled')) return;
+
+ var $parent = getParent($this);
+ var isActive = $parent.hasClass('open');
+
+ if (!isActive && e.which != 27 || isActive && e.which == 27) {
+ if (e.which == 27) $parent.find(toggle).trigger('focus');
+ return $this.trigger('click')
+ }
+
+ var desc = ' li:not(.disabled):visible a';
+ var $items = $parent.find('.dropdown-menu' + desc);
+
+ if (!$items.length) return;
+
+ var index = $items.index(e.target);
+
+ if (e.which == 38 && index > 0) index--; // up
+ if (e.which == 40 && index < $items.length - 1) index++; // down
+ if (!~index) index = 0;
+
+ $items.eq(index).trigger('focus')
+ };
+
+
+ // DROPDOWN PLUGIN DEFINITION
+ // ==========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this);
+ var data = $this.data('bs.dropdown');
+
+ if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)));
+ if (typeof option == 'string') data[option].call($this)
+ })
+ }
+
+ var old = $.fn.dropdown;
+
+ $.fn.dropdown = Plugin;
+ $.fn.dropdown.Constructor = Dropdown;
+
+
+ // DROPDOWN NO CONFLICT
+ // ====================
+
+ $.fn.dropdown.noConflict = function () {
+ $.fn.dropdown = old;
+ return this
+ };
+
+
+ // APPLY TO STANDARD DROPDOWN ELEMENTS
+ // ===================================
+
+ $(document)
+ .on('click.bs.dropdown.data-api', clearMenus)
+ .on('click.bs.dropdown.data-api', '.dropdown form', function (e) {
+ e.stopPropagation()
+ })
+ .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
+ .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
+ .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: modal.js v3.3.5
+ * http://getbootstrap.com/javascript/#modals
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // MODAL CLASS DEFINITION
+ // ======================
+
+ var Modal = function (element, options) {
+ this.options = options;
+ this.$body = $(document.body);
+ this.$element = $(element);
+ this.$dialog = this.$element.find('.modal-dialog');
+ this.$backdrop = null;
+ this.isShown = null;
+ this.originalBodyPad = null;
+ this.scrollbarWidth = 0;
+ this.ignoreBackdropClick = false;
+
+ if (this.options.remote) {
+ this.$element
+ .find('.modal-content')
+ .load(this.options.remote, $.proxy(function () {
+ this.$element.trigger('loaded.bs.modal')
+ }, this))
+ }
+ };
+
+ Modal.VERSION = '3.3.5';
+
+ Modal.TRANSITION_DURATION = 300;
+ Modal.BACKDROP_TRANSITION_DURATION = 150;
+
+ Modal.DEFAULTS = {
+ backdrop: true,
+ keyboard: true,
+ show: true
+ };
+
+ Modal.prototype.toggle = function (_relatedTarget) {
+ return this.isShown ? this.hide() : this.show(_relatedTarget)
+ };
+
+ Modal.prototype.show = function (_relatedTarget) {
+ var that = this;
+ var e = $.Event('show.bs.modal', {relatedTarget: _relatedTarget});
+
+ this.$element.trigger(e);
+
+ if (this.isShown || e.isDefaultPrevented()) return;
+
+ this.isShown = true;
+
+ this.checkScrollbar();
+ this.setScrollbar();
+ this.$body.addClass('modal-open');
+
+ this.escape();
+ this.resize();
+
+ this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this));
+
+ this.$dialog.on('mousedown.dismiss.bs.modal', function () {
+ that.$element.one('mouseup.dismiss.bs.modal', function (e) {
+ if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
+ })
+ });
+
+ this.backdrop(function () {
+ var transition = $.support.transition && that.$element.hasClass('fade');
+
+ if (!that.$element.parent().length) {
+ that.$element.appendTo(that.$body); // don't move modals dom position
+ }
+
+ that.$element
+ .show()
+ .scrollTop(0);
+
+ that.adjustDialog();
+
+ if (transition) {
+ that.$element[0].offsetWidth; // force reflow
+ }
+
+ that.$element.addClass('in');
+
+ that.enforceFocus();
+
+ var e = $.Event('shown.bs.modal', {relatedTarget: _relatedTarget});
+
+ transition ?
+ that.$dialog // wait for modal to slide in
+ .one('bsTransitionEnd', function () {
+ that.$element.trigger('focus').trigger(e)
+ })
+ .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
+ that.$element.trigger('focus').trigger(e)
+ })
+ };
+
+ Modal.prototype.hide = function (e) {
+ if (e) e.preventDefault();
+
+ e = $.Event('hide.bs.modal');
+
+ this.$element.trigger(e);
+
+ if (!this.isShown || e.isDefaultPrevented()) return;
+
+ this.isShown = false;
+
+ this.escape();
+ this.resize();
+
+ $(document).off('focusin.bs.modal');
+
+ this.$element
+ .removeClass('in')
+ .off('click.dismiss.bs.modal')
+ .off('mouseup.dismiss.bs.modal');
+
+ this.$dialog.off('mousedown.dismiss.bs.modal');
+
+ $.support.transition && this.$element.hasClass('fade') ?
+ this.$element
+ .one('bsTransitionEnd', $.proxy(this.hideModal, this))
+ .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
+ this.hideModal()
+ };
+
+ Modal.prototype.enforceFocus = function () {
+ $(document)
+ .off('focusin.bs.modal') // guard against infinite focus loop
+ .on('focusin.bs.modal', $.proxy(function (e) {
+ if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
+ this.$element.trigger('focus')
+ }
+ }, this))
+ };
+
+ Modal.prototype.escape = function () {
+ if (this.isShown && this.options.keyboard) {
+ this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
+ e.which == 27 && this.hide()
+ }, this))
+ } else if (!this.isShown) {
+ this.$element.off('keydown.dismiss.bs.modal')
+ }
+ };
+
+ Modal.prototype.resize = function () {
+ if (this.isShown) {
+ $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
+ } else {
+ $(window).off('resize.bs.modal')
+ }
+ };
+
+ Modal.prototype.hideModal = function () {
+ var that = this;
+ this.$element.hide();
+ this.backdrop(function () {
+ that.$body.removeClass('modal-open');
+ that.resetAdjustments();
+ that.resetScrollbar();
+ that.$element.trigger('hidden.bs.modal')
+ })
+ };
+
+ Modal.prototype.removeBackdrop = function () {
+ this.$backdrop && this.$backdrop.remove();
+ this.$backdrop = null
+ };
+
+ Modal.prototype.backdrop = function (callback) {
+ var that = this;
+ var animate = this.$element.hasClass('fade') ? 'fade' : '';
+
+ if (this.isShown && this.options.backdrop) {
+ var doAnimate = $.support.transition && animate;
+
+ this.$backdrop = $(document.createElement('div'))
+ .addClass('modal-backdrop ' + animate)
+ .appendTo(this.$body);
+
+ this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
+ if (this.ignoreBackdropClick) {
+ this.ignoreBackdropClick = false;
+ return
+ }
+ if (e.target !== e.currentTarget) return;
+ this.options.backdrop == 'static'
+ ? this.$element[0].focus()
+ : this.hide()
+ }, this));
+
+ if (doAnimate) this.$backdrop[0].offsetWidth; // force reflow
+
+ this.$backdrop.addClass('in');
+
+ if (!callback) return;
+
+ doAnimate ?
+ this.$backdrop
+ .one('bsTransitionEnd', callback)
+ .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
+ callback()
+
+ } else if (!this.isShown && this.$backdrop) {
+ this.$backdrop.removeClass('in');
+
+ var callbackRemove = function () {
+ that.removeBackdrop();
+ callback && callback()
+ };
+ $.support.transition && this.$element.hasClass('fade') ?
+ this.$backdrop
+ .one('bsTransitionEnd', callbackRemove)
+ .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
+ callbackRemove()
+
+ } else if (callback) {
+ callback()
+ }
+ };
+
+ // these following methods are used to handle overflowing modals
+
+ Modal.prototype.handleUpdate = function () {
+ this.adjustDialog()
+ };
+
+ Modal.prototype.adjustDialog = function () {
+ var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight;
+
+ this.$element.css({
+ paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
+ paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
+ })
+ };
+
+ Modal.prototype.resetAdjustments = function () {
+ this.$element.css({
+ paddingLeft: '',
+ paddingRight: ''
+ })
+ };
+
+ Modal.prototype.checkScrollbar = function () {
+ var fullWindowWidth = window.innerWidth;
+ if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
+ var documentElementRect = document.documentElement.getBoundingClientRect();
+ fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
+ }
+ this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth;
+ this.scrollbarWidth = this.measureScrollbar()
+ };
+
+ Modal.prototype.setScrollbar = function () {
+ var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10);
+ this.originalBodyPad = document.body.style.paddingRight || '';
+ if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
+ };
+
+ Modal.prototype.resetScrollbar = function () {
+ this.$body.css('padding-right', this.originalBodyPad)
+ };
+
+ Modal.prototype.measureScrollbar = function () { // thx walsh
+ var scrollDiv = document.createElement('div');
+ scrollDiv.className = 'modal-scrollbar-measure';
+ this.$body.append(scrollDiv);
+ var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
+ this.$body[0].removeChild(scrollDiv);
+ return scrollbarWidth
+ };
+
+
+ // MODAL PLUGIN DEFINITION
+ // =======================
+
+ function Plugin(option, _relatedTarget) {
+ return this.each(function () {
+ var $this = $(this);
+ var data = $this.data('bs.modal');
+ var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option);
+
+ if (!data) $this.data('bs.modal', (data = new Modal(this, options)));
+ if (typeof option == 'string') data[option](_relatedTarget);
+ else if (options.show) data.show(_relatedTarget)
+ })
+ }
+
+ var old = $.fn.modal;
+
+ $.fn.modal = Plugin;
+ $.fn.modal.Constructor = Modal;
+
+
+ // MODAL NO CONFLICT
+ // =================
+
+ $.fn.modal.noConflict = function () {
+ $.fn.modal = old;
+ return this
+ };
+
+
+ // MODAL DATA-API
+ // ==============
+
+ $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
+ var $this = $(this);
+ var href = $this.attr('href');
+ var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))); // strip for ie7
+ var option = $target.data('bs.modal') ? 'toggle' : $.extend({remote: !/#/.test(href) && href}, $target.data(), $this.data());
+
+ if ($this.is('a')) e.preventDefault();
+
+ $target.one('show.bs.modal', function (showEvent) {
+ if (showEvent.isDefaultPrevented()) return; // only register focus restorer if modal will actually get shown
+ $target.one('hidden.bs.modal', function () {
+ $this.is(':visible') && $this.trigger('focus')
+ })
+ });
+ Plugin.call($target, option, this)
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: tooltip.js v3.3.5
+ * http://getbootstrap.com/javascript/#tooltip
+ * Inspired by the original jQuery.tipsy by Jason Frame
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // TOOLTIP PUBLIC CLASS DEFINITION
+ // ===============================
+
+ var Tooltip = function (element, options) {
+ this.type = null;
+ this.options = null;
+ this.enabled = null;
+ this.timeout = null;
+ this.hoverState = null;
+ this.$element = null;
+ this.inState = null;
+
+ this.init('tooltip', element, options)
+ };
+
+ Tooltip.VERSION = '3.3.5';
+
+ Tooltip.TRANSITION_DURATION = 150;
+
+ Tooltip.DEFAULTS = {
+ animation: true,
+ placement: 'top',
+ selector: false,
+ template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
+ trigger: 'hover focus',
+ title: '',
+ delay: 0,
+ html: false,
+ container: false,
+ viewport: {
+ selector: 'body',
+ padding: 0
+ }
+ };
+
+ Tooltip.prototype.init = function (type, element, options) {
+ this.enabled = true;
+ this.type = type;
+ this.$element = $(element);
+ this.options = this.getOptions(options);
+ this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport));
+ this.inState = {click: false, hover: false, focus: false};
+
+ if (this.$element[0] instanceof document.constructor && !this.options.selector) {
+ throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
+ }
+
+ var triggers = this.options.trigger.split(' ');
+
+ for (var i = triggers.length; i--;) {
+ var trigger = triggers[i];
+
+ if (trigger == 'click') {
+ this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
+ } else if (trigger != 'manual') {
+ var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin';
+ var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout';
+
+ this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this));
+ this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
+ }
+ }
+
+ this.options.selector ?
+ (this._options = $.extend({}, this.options, {trigger: 'manual', selector: ''})) :
+ this.fixTitle()
+ };
+
+ Tooltip.prototype.getDefaults = function () {
+ return Tooltip.DEFAULTS
+ };
+
+ Tooltip.prototype.getOptions = function (options) {
+ options = $.extend({}, this.getDefaults(), this.$element.data(), options);
+
+ if (options.delay && typeof options.delay == 'number') {
+ options.delay = {
+ show: options.delay,
+ hide: options.delay
+ }
+ }
+
+ return options
+ };
+
+ Tooltip.prototype.getDelegateOptions = function () {
+ var options = {};
+ var defaults = this.getDefaults();
+
+ this._options && $.each(this._options, function (key, value) {
+ if (defaults[key] != value) options[key] = value
+ });
+
+ return options
+ };
+
+ Tooltip.prototype.enter = function (obj) {
+ var self = obj instanceof this.constructor ?
+ obj : $(obj.currentTarget).data('bs.' + this.type);
+
+ if (!self) {
+ self = new this.constructor(obj.currentTarget, this.getDelegateOptions());
+ $(obj.currentTarget).data('bs.' + this.type, self)
+ }
+
+ if (obj instanceof $.Event) {
+ self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true
+ }
+
+ if (self.tip().hasClass('in') || self.hoverState == 'in') {
+ self.hoverState = 'in';
+ return
+ }
+
+ clearTimeout(self.timeout);
+
+ self.hoverState = 'in';
+
+ if (!self.options.delay || !self.options.delay.show) return self.show();
+
+ self.timeout = setTimeout(function () {
+ if (self.hoverState == 'in') self.show()
+ }, self.options.delay.show)
+ };
+
+ Tooltip.prototype.isInStateTrue = function () {
+ for (var key in this.inState) {
+ if (this.inState[key]) return true
+ }
+
+ return false
+ };
+
+ Tooltip.prototype.leave = function (obj) {
+ var self = obj instanceof this.constructor ?
+ obj : $(obj.currentTarget).data('bs.' + this.type);
+
+ if (!self) {
+ self = new this.constructor(obj.currentTarget, this.getDelegateOptions());
+ $(obj.currentTarget).data('bs.' + this.type, self)
+ }
+
+ if (obj instanceof $.Event) {
+ self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false
+ }
+
+ if (self.isInStateTrue()) return;
+
+ clearTimeout(self.timeout);
+
+ self.hoverState = 'out';
+
+ if (!self.options.delay || !self.options.delay.hide) return self.hide();
+
+ self.timeout = setTimeout(function () {
+ if (self.hoverState == 'out') self.hide()
+ }, self.options.delay.hide)
+ };
+
+ Tooltip.prototype.show = function () {
+ var e = $.Event('show.bs.' + this.type);
+
+ if (this.hasContent() && this.enabled) {
+ this.$element.trigger(e);
+
+ var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]);
+ if (e.isDefaultPrevented() || !inDom) return;
+ var that = this;
+
+ var $tip = this.tip();
+
+ var tipId = this.getUID(this.type);
+
+ this.setContent();
+ $tip.attr('id', tipId);
+ this.$element.attr('aria-describedby', tipId);
+
+ if (this.options.animation) $tip.addClass('fade');
+
+ var placement = typeof this.options.placement == 'function' ?
+ this.options.placement.call(this, $tip[0], this.$element[0]) :
+ this.options.placement;
+
+ var autoToken = /\s?auto?\s?/i;
+ var autoPlace = autoToken.test(placement);
+ if (autoPlace) placement = placement.replace(autoToken, '') || 'top';
+
+ $tip
+ .detach()
+ .css({top: 0, left: 0, display: 'block'})
+ .addClass(placement)
+ .data('bs.' + this.type, this);
+
+ this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element);
+ this.$element.trigger('inserted.bs.' + this.type);
+
+ var pos = this.getPosition();
+ var actualWidth = $tip[0].offsetWidth;
+ var actualHeight = $tip[0].offsetHeight;
+
+ if (autoPlace) {
+ var orgPlacement = placement;
+ var viewportDim = this.getPosition(this.$viewport);
+
+ placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' :
+ placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' :
+ placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' :
+ placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' :
+ placement;
+
+ $tip
+ .removeClass(orgPlacement)
+ .addClass(placement)
+ }
+
+ var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight);
+
+ this.applyPlacement(calculatedOffset, placement);
+
+ var complete = function () {
+ var prevHoverState = that.hoverState;
+ that.$element.trigger('shown.bs.' + that.type);
+ that.hoverState = null;
+
+ if (prevHoverState == 'out') that.leave(that)
+ };
+
+ $.support.transition && this.$tip.hasClass('fade') ?
+ $tip
+ .one('bsTransitionEnd', complete)
+ .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
+ complete()
+ }
+ };
+
+ Tooltip.prototype.applyPlacement = function (offset, placement) {
+ var $tip = this.tip();
+ var width = $tip[0].offsetWidth;
+ var height = $tip[0].offsetHeight;
+
+ // manually read margins because getBoundingClientRect includes difference
+ var marginTop = parseInt($tip.css('margin-top'), 10);
+ var marginLeft = parseInt($tip.css('margin-left'), 10);
+
+ // we must check for NaN for ie 8/9
+ if (isNaN(marginTop)) marginTop = 0;
+ if (isNaN(marginLeft)) marginLeft = 0;
+
+ offset.top += marginTop;
+ offset.left += marginLeft;
+
+ // $.fn.offset doesn't round pixel values
+ // so we use setOffset directly with our own function B-0
+ $.offset.setOffset($tip[0], $.extend({
+ using: function (props) {
+ $tip.css({
+ top: Math.round(props.top),
+ left: Math.round(props.left)
+ })
+ }
+ }, offset), 0);
+
+ $tip.addClass('in');
+
+ // check to see if placing tip in new offset caused the tip to resize itself
+ var actualWidth = $tip[0].offsetWidth;
+ var actualHeight = $tip[0].offsetHeight;
+
+ if (placement == 'top' && actualHeight != height) {
+ offset.top = offset.top + height - actualHeight
+ }
+
+ var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight);
+
+ if (delta.left) offset.left += delta.left;
+ else offset.top += delta.top;
+
+ var isVertical = /top|bottom/.test(placement);
+ var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight;
+ var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight';
+
+ $tip.offset(offset);
+ this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
+ };
+
+ Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
+ this.arrow()
+ .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
+ .css(isVertical ? 'top' : 'left', '')
+ };
+
+ Tooltip.prototype.setContent = function () {
+ var $tip = this.tip();
+ var title = this.getTitle();
+
+ $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title);
+ $tip.removeClass('fade in top bottom left right')
+ };
+
+ Tooltip.prototype.hide = function (callback) {
+ var that = this;
+ var $tip = $(this.$tip);
+ var e = $.Event('hide.bs.' + this.type);
+
+ function complete() {
+ if (that.hoverState != 'in') $tip.detach();
+ that.$element
+ .removeAttr('aria-describedby')
+ .trigger('hidden.bs.' + that.type);
+ callback && callback()
+ }
+
+ this.$element.trigger(e);
+
+ if (e.isDefaultPrevented()) return;
+
+ $tip.removeClass('in');
+
+ $.support.transition && $tip.hasClass('fade') ?
+ $tip
+ .one('bsTransitionEnd', complete)
+ .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
+ complete();
+
+ this.hoverState = null;
+
+ return this
+ };
+
+ Tooltip.prototype.fixTitle = function () {
+ var $e = this.$element;
+ if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {
+ $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
+ }
+ };
+
+ Tooltip.prototype.hasContent = function () {
+ return this.getTitle()
+ };
+
+ Tooltip.prototype.getPosition = function ($element) {
+ $element = $element || this.$element;
+
+ var el = $element[0];
+ var isBody = el.tagName == 'BODY';
+
+ var elRect = el.getBoundingClientRect();
+ if (elRect.width == null) {
+ // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
+ elRect = $.extend({}, elRect, {width: elRect.right - elRect.left, height: elRect.bottom - elRect.top})
+ }
+ var elOffset = isBody ? {top: 0, left: 0} : $element.offset();
+ var scroll = {scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop()};
+ var outerDims = isBody ? {width: $(window).width(), height: $(window).height()} : null;
+
+ return $.extend({}, elRect, scroll, outerDims, elOffset)
+ };
+
+ Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
+ return placement == 'bottom' ? {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2} :
+ placement == 'top' ? {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2} :
+ placement == 'left' ? {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth} :
+ /* placement == 'right' */ {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
+
+ };
+
+ Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
+ var delta = {top: 0, left: 0};
+ if (!this.$viewport) return delta;
+
+ var viewportPadding = this.options.viewport && this.options.viewport.padding || 0;
+ var viewportDimensions = this.getPosition(this.$viewport);
+
+ if (/right|left/.test(placement)) {
+ var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll;
+ var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight;
+ if (topEdgeOffset < viewportDimensions.top) { // top overflow
+ delta.top = viewportDimensions.top - topEdgeOffset
+ } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
+ delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
+ }
+ } else {
+ var leftEdgeOffset = pos.left - viewportPadding;
+ var rightEdgeOffset = pos.left + viewportPadding + actualWidth;
+ if (leftEdgeOffset < viewportDimensions.left) { // left overflow
+ delta.left = viewportDimensions.left - leftEdgeOffset
+ } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow
+ delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
+ }
+ }
+
+ return delta
+ };
+
+ Tooltip.prototype.getTitle = function () {
+ var title;
+ var $e = this.$element;
+ var o = this.options;
+
+ title = $e.attr('data-original-title')
+ || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title);
+
+ return title
+ };
+
+ Tooltip.prototype.getUID = function (prefix) {
+ do prefix += ~~(Math.random() * 1000000);
+ while (document.getElementById(prefix));
+ return prefix
+ };
+
+ Tooltip.prototype.tip = function () {
+ if (!this.$tip) {
+ this.$tip = $(this.options.template);
+ if (this.$tip.length != 1) {
+ throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')
+ }
+ }
+ return this.$tip
+ };
+
+ Tooltip.prototype.arrow = function () {
+ return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
+ };
+
+ Tooltip.prototype.enable = function () {
+ this.enabled = true
+ };
+
+ Tooltip.prototype.disable = function () {
+ this.enabled = false
+ };
+
+ Tooltip.prototype.toggleEnabled = function () {
+ this.enabled = !this.enabled
+ };
+
+ Tooltip.prototype.toggle = function (e) {
+ var self = this;
+ if (e) {
+ self = $(e.currentTarget).data('bs.' + this.type);
+ if (!self) {
+ self = new this.constructor(e.currentTarget, this.getDelegateOptions());
+ $(e.currentTarget).data('bs.' + this.type, self)
+ }
+ }
+
+ if (e) {
+ self.inState.click = !self.inState.click;
+ if (self.isInStateTrue()) self.enter(self);
+ else self.leave(self)
+ } else {
+ self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
+ }
+ };
+
+ Tooltip.prototype.destroy = function () {
+ var that = this;
+ clearTimeout(this.timeout);
+ this.hide(function () {
+ that.$element.off('.' + that.type).removeData('bs.' + that.type);
+ if (that.$tip) {
+ that.$tip.detach()
+ }
+ that.$tip = null;
+ that.$arrow = null;
+ that.$viewport = null
+ })
+ };
+
+
+ // TOOLTIP PLUGIN DEFINITION
+ // =========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this);
+ var data = $this.data('bs.tooltip');
+ var options = typeof option == 'object' && option;
+
+ if (!data && /destroy|hide/.test(option)) return;
+ if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)));
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.tooltip;
+
+ $.fn.tooltip = Plugin;
+ $.fn.tooltip.Constructor = Tooltip;
+
+
+ // TOOLTIP NO CONFLICT
+ // ===================
+
+ $.fn.tooltip.noConflict = function () {
+ $.fn.tooltip = old;
+ return this
+ }
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: popover.js v3.3.5
+ * http://getbootstrap.com/javascript/#popovers
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // POPOVER PUBLIC CLASS DEFINITION
+ // ===============================
+
+ var Popover = function (element, options) {
+ this.init('popover', element, options)
+ };
+
+ if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js');
+
+ Popover.VERSION = '3.3.5';
+
+ Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
+ placement: 'right',
+ trigger: 'click',
+ content: '',
+ template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
+ });
+
+
+ // NOTE: POPOVER EXTENDS tooltip.js
+ // ================================
+
+ Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype);
+
+ Popover.prototype.constructor = Popover;
+
+ Popover.prototype.getDefaults = function () {
+ return Popover.DEFAULTS
+ };
+
+ Popover.prototype.setContent = function () {
+ var $tip = this.tip();
+ var title = this.getTitle();
+ var content = this.getContent();
+
+ $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title);
+ $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
+ this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
+ ](content);
+
+ $tip.removeClass('fade top bottom left right in');
+
+ // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
+ // this manually by checking the contents.
+ if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
+ };
+
+ Popover.prototype.hasContent = function () {
+ return this.getTitle() || this.getContent()
+ };
+
+ Popover.prototype.getContent = function () {
+ var $e = this.$element;
+ var o = this.options;
+
+ return $e.attr('data-content')
+ || (typeof o.content == 'function' ?
+ o.content.call($e[0]) :
+ o.content)
+ };
+
+ Popover.prototype.arrow = function () {
+ return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
+ };
+
+
+ // POPOVER PLUGIN DEFINITION
+ // =========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this);
+ var data = $this.data('bs.popover');
+ var options = typeof option == 'object' && option;
+
+ if (!data && /destroy|hide/.test(option)) return;
+ if (!data) $this.data('bs.popover', (data = new Popover(this, options)));
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.popover;
+
+ $.fn.popover = Plugin;
+ $.fn.popover.Constructor = Popover;
+
+
+ // POPOVER NO CONFLICT
+ // ===================
+
+ $.fn.popover.noConflict = function () {
+ $.fn.popover = old;
+ return this
+ }
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: scrollspy.js v3.3.5
+ * http://getbootstrap.com/javascript/#scrollspy
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // SCROLLSPY CLASS DEFINITION
+ // ==========================
+
+ function ScrollSpy(element, options) {
+ this.$body = $(document.body);
+ this.$scrollElement = $(element).is(document.body) ? $(window) : $(element);
+ this.options = $.extend({}, ScrollSpy.DEFAULTS, options);
+ this.selector = (this.options.target || '') + ' .nav li > a';
+ this.offsets = [];
+ this.targets = [];
+ this.activeTarget = null;
+ this.scrollHeight = 0;
+
+ this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this));
+ this.refresh();
+ this.process()
+ }
+
+ ScrollSpy.VERSION = '3.3.5';
+
+ ScrollSpy.DEFAULTS = {
+ offset: 10
+ };
+
+ ScrollSpy.prototype.getScrollHeight = function () {
+ return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
+ };
+
+ ScrollSpy.prototype.refresh = function () {
+ var that = this;
+ var offsetMethod = 'offset';
+ var offsetBase = 0;
+
+ this.offsets = [];
+ this.targets = [];
+ this.scrollHeight = this.getScrollHeight();
+
+ if (!$.isWindow(this.$scrollElement[0])) {
+ offsetMethod = 'position';
+ offsetBase = this.$scrollElement.scrollTop()
+ }
+
+ this.$body
+ .find(this.selector)
+ .map(function () {
+ var $el = $(this);
+ var href = $el.data('target') || $el.attr('href');
+ var $href = /^#./.test(href) && $(href);
+
+ return ($href
+ && $href.length
+ && $href.is(':visible')
+ && [[$href[offsetMethod]().top + offsetBase, href]]) || null
+ })
+ .sort(function (a, b) {
+ return a[0] - b[0]
+ })
+ .each(function () {
+ that.offsets.push(this[0]);
+ that.targets.push(this[1])
+ })
+ };
+
+ ScrollSpy.prototype.process = function () {
+ var scrollTop = this.$scrollElement.scrollTop() + this.options.offset;
+ var scrollHeight = this.getScrollHeight();
+ var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height();
+ var offsets = this.offsets;
+ var targets = this.targets;
+ var activeTarget = this.activeTarget;
+ var i;
+
+ if (this.scrollHeight != scrollHeight) {
+ this.refresh()
+ }
+
+ if (scrollTop >= maxScroll) {
+ return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
+ }
+
+ if (activeTarget && scrollTop < offsets[0]) {
+ this.activeTarget = null;
+ return this.clear()
+ }
+
+ for (i = offsets.length; i--;) {
+ activeTarget != targets[i]
+ && scrollTop >= offsets[i]
+ && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])
+ && this.activate(targets[i])
+ }
+ };
+
+ ScrollSpy.prototype.activate = function (target) {
+ this.activeTarget = target;
+
+ this.clear();
+
+ var selector = this.selector +
+ '[data-target="' + target + '"],' +
+ this.selector + '[href="' + target + '"]';
+
+ var active = $(selector)
+ .parents('li')
+ .addClass('active');
+
+ if (active.parent('.dropdown-menu').length) {
+ active = active
+ .closest('li.dropdown')
+ .addClass('active')
+ }
+
+ active.trigger('activate.bs.scrollspy')
+ };
+
+ ScrollSpy.prototype.clear = function () {
+ $(this.selector)
+ .parentsUntil(this.options.target, '.active')
+ .removeClass('active')
+ };
+
+
+ // SCROLLSPY PLUGIN DEFINITION
+ // ===========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this);
+ var data = $this.data('bs.scrollspy');
+ var options = typeof option == 'object' && option;
+
+ if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)));
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.scrollspy;
+
+ $.fn.scrollspy = Plugin;
+ $.fn.scrollspy.Constructor = ScrollSpy;
+
+
+ // SCROLLSPY NO CONFLICT
+ // =====================
+
+ $.fn.scrollspy.noConflict = function () {
+ $.fn.scrollspy = old;
+ return this
+ };
+
+
+ // SCROLLSPY DATA-API
+ // ==================
+
+ $(window).on('load.bs.scrollspy.data-api', function () {
+ $('[data-spy="scroll"]').each(function () {
+ var $spy = $(this);
+ Plugin.call($spy, $spy.data())
+ })
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: tab.js v3.3.5
+ * http://getbootstrap.com/javascript/#tabs
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // TAB CLASS DEFINITION
+ // ====================
+
+ var Tab = function (element) {
+ // jscs:disable requireDollarBeforejQueryAssignment
+ this.element = $(element);
+ // jscs:enable requireDollarBeforejQueryAssignment
+ };
+
+ Tab.VERSION = '3.3.5';
+
+ Tab.TRANSITION_DURATION = 150;
+
+ Tab.prototype.show = function () {
+ var $this = this.element;
+ var $ul = $this.closest('ul:not(.dropdown-menu)');
+ var selector = $this.data('target');
+
+ if (!selector) {
+ selector = $this.attr('href');
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, ''); // strip for ie7
+ }
+
+ if ($this.parent('li').hasClass('active')) return;
+
+ var $previous = $ul.find('.active:last a');
+ var hideEvent = $.Event('hide.bs.tab', {
+ relatedTarget: $this[0]
+ });
+ var showEvent = $.Event('show.bs.tab', {
+ relatedTarget: $previous[0]
+ });
+
+ $previous.trigger(hideEvent);
+ $this.trigger(showEvent);
+
+ if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return;
+
+ var $target = $(selector);
+
+ this.activate($this.closest('li'), $ul);
+ this.activate($target, $target.parent(), function () {
+ $previous.trigger({
+ type: 'hidden.bs.tab',
+ relatedTarget: $this[0]
+ });
+ $this.trigger({
+ type: 'shown.bs.tab',
+ relatedTarget: $previous[0]
+ })
+ })
+ };
+
+ Tab.prototype.activate = function (element, container, callback) {
+ var $active = container.find('> .active');
+ var transition = callback
+ && $.support.transition
+ && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length);
+
+ function next() {
+ $active
+ .removeClass('active')
+ .find('> .dropdown-menu > .active')
+ .removeClass('active')
+ .end()
+ .find('[data-toggle="tab"]')
+ .attr('aria-expanded', false);
+
+ element
+ .addClass('active')
+ .find('[data-toggle="tab"]')
+ .attr('aria-expanded', true);
+
+ if (transition) {
+ element[0].offsetWidth; // reflow for transition
+ element.addClass('in')
+ } else {
+ element.removeClass('fade')
+ }
+
+ if (element.parent('.dropdown-menu').length) {
+ element
+ .closest('li.dropdown')
+ .addClass('active')
+ .end()
+ .find('[data-toggle="tab"]')
+ .attr('aria-expanded', true)
+ }
+
+ callback && callback()
+ }
+
+ $active.length && transition ?
+ $active
+ .one('bsTransitionEnd', next)
+ .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
+ next();
+
+ $active.removeClass('in')
+ };
+
+
+ // TAB PLUGIN DEFINITION
+ // =====================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this);
+ var data = $this.data('bs.tab');
+
+ if (!data) $this.data('bs.tab', (data = new Tab(this)));
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.tab;
+
+ $.fn.tab = Plugin;
+ $.fn.tab.Constructor = Tab;
+
+
+ // TAB NO CONFLICT
+ // ===============
+
+ $.fn.tab.noConflict = function () {
+ $.fn.tab = old;
+ return this
+ };
+
+
+ // TAB DATA-API
+ // ============
+
+ var clickHandler = function (e) {
+ e.preventDefault();
+ Plugin.call($(this), 'show')
+ };
+
+ $(document)
+ .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
+ .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: affix.js v3.3.5
+ * http://getbootstrap.com/javascript/#affix
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // AFFIX CLASS DEFINITION
+ // ======================
+
+ var Affix = function (element, options) {
+ this.options = $.extend({}, Affix.DEFAULTS, options);
+
+ this.$target = $(this.options.target)
+ .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
+ .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this));
+
+ this.$element = $(element);
+ this.affixed = null;
+ this.unpin = null;
+ this.pinnedOffset = null;
+
+ this.checkPosition()
+ };
+
+ Affix.VERSION = '3.3.5';
+
+ Affix.RESET = 'affix affix-top affix-bottom';
+
+ Affix.DEFAULTS = {
+ offset: 0,
+ target: window
+ };
+
+ Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
+ var scrollTop = this.$target.scrollTop();
+ var position = this.$element.offset();
+ var targetHeight = this.$target.height();
+
+ if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false;
+
+ if (this.affixed == 'bottom') {
+ if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom';
+ return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
+ }
+
+ var initializing = this.affixed == null;
+ var colliderTop = initializing ? scrollTop : position.top;
+ var colliderHeight = initializing ? targetHeight : height;
+
+ if (offsetTop != null && scrollTop <= offsetTop) return 'top';
+ if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom';
+
+ return false
+ };
+
+ Affix.prototype.getPinnedOffset = function () {
+ if (this.pinnedOffset) return this.pinnedOffset;
+ this.$element.removeClass(Affix.RESET).addClass('affix');
+ var scrollTop = this.$target.scrollTop();
+ var position = this.$element.offset();
+ return (this.pinnedOffset = position.top - scrollTop)
+ };
+
+ Affix.prototype.checkPositionWithEventLoop = function () {
+ setTimeout($.proxy(this.checkPosition, this), 1)
+ };
+
+ Affix.prototype.checkPosition = function () {
+ if (!this.$element.is(':visible')) return;
+
+ var height = this.$element.height();
+ var offset = this.options.offset;
+ var offsetTop = offset.top;
+ var offsetBottom = offset.bottom;
+ var scrollHeight = Math.max($(document).height(), $(document.body).height());
+
+ if (typeof offset != 'object') offsetBottom = offsetTop = offset;
+ if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element);
+ if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element);
+
+ var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom);
+
+ if (this.affixed != affix) {
+ if (this.unpin != null) this.$element.css('top', '');
+
+ var affixType = 'affix' + (affix ? '-' + affix : '');
+ var e = $.Event(affixType + '.bs.affix');
+
+ this.$element.trigger(e);
+
+ if (e.isDefaultPrevented()) return;
+
+ this.affixed = affix;
+ this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null;
+
+ this.$element
+ .removeClass(Affix.RESET)
+ .addClass(affixType)
+ .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
+ }
+
+ if (affix == 'bottom') {
+ this.$element.offset({
+ top: scrollHeight - height - offsetBottom
+ })
+ }
+ };
+
+
+ // AFFIX PLUGIN DEFINITION
+ // =======================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this);
+ var data = $this.data('bs.affix');
+ var options = typeof option == 'object' && option;
+
+ if (!data) $this.data('bs.affix', (data = new Affix(this, options)));
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.affix;
+
+ $.fn.affix = Plugin;
+ $.fn.affix.Constructor = Affix;
+
+
+ // AFFIX NO CONFLICT
+ // =================
+
+ $.fn.affix.noConflict = function () {
+ $.fn.affix = old;
+ return this
+ };
+
+
+ // AFFIX DATA-API
+ // ==============
+
+ $(window).on('load', function () {
+ $('[data-spy="affix"]').each(function () {
+ var $spy = $(this);
+ var data = $spy.data();
+
+ data.offset = data.offset || {};
+
+ if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom;
+ if (data.offsetTop != null) data.offset.top = data.offsetTop;
+
+ Plugin.call($spy, data)
+ })
+ })
+
+}(jQuery);
new file mode 100644
--- /dev/null
+++ b/js/bootstrap/bootstrap.min.js
@@ -0,0 +1,754 @@
+/*!
+ * Bootstrap v3.3.5 (http://getbootstrap.com)
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under the MIT license
+ */
+if ("undefined" == typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");
++function (a) {
+ "use strict";
+ var b = a.fn.jquery.split(" ")[0].split(".");
+ if (b[0] < 2 && b[1] < 9 || 1 == b[0] && 9 == b[1] && b[2] < 1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")
+}(jQuery), +function (a) {
+ "use strict";
+ function b() {
+ var a = document.createElement("bootstrap"), b = {
+ WebkitTransition: "webkitTransitionEnd",
+ MozTransition: "transitionend",
+ OTransition: "oTransitionEnd otransitionend",
+ transition: "transitionend"
+ };
+ for (var c in b)if (void 0 !== a.style[c])return {end: b[c]};
+ return !1
+ }
+
+ a.fn.emulateTransitionEnd = function (b) {
+ var c = !1, d = this;
+ a(this).one("bsTransitionEnd", function () {
+ c = !0
+ });
+ var e = function () {
+ c || a(d).trigger(a.support.transition.end)
+ };
+ return setTimeout(e, b), this
+ }, a(function () {
+ a.support.transition = b(), a.support.transition && (a.event.special.bsTransitionEnd = {
+ bindType: a.support.transition.end,
+ delegateType: a.support.transition.end,
+ handle: function (b) {
+ return a(b.target).is(this) ? b.handleObj.handler.apply(this, arguments) : void 0
+ }
+ })
+ })
+}(jQuery), +function (a) {
+ "use strict";
+ function b(b) {
+ return this.each(function () {
+ var c = a(this), e = c.data("bs.alert");
+ e || c.data("bs.alert", e = new d(this)), "string" == typeof b && e[b].call(c)
+ })
+ }
+
+ var c = '[data-dismiss="alert"]', d = function (b) {
+ a(b).on("click", c, this.close)
+ };
+ d.VERSION = "3.3.5", d.TRANSITION_DURATION = 150, d.prototype.close = function (b) {
+ function c() {
+ g.detach().trigger("closed.bs.alert").remove()
+ }
+
+ var e = a(this), f = e.attr("data-target");
+ f || (f = e.attr("href"), f = f && f.replace(/.*(?=#[^\s]*$)/, ""));
+ var g = a(f);
+ b && b.preventDefault(), g.length || (g = e.closest(".alert")), g.trigger(b = a.Event("close.bs.alert")), b.isDefaultPrevented() || (g.removeClass("in"), a.support.transition && g.hasClass("fade") ? g.one("bsTransitionEnd", c).emulateTransitionEnd(d.TRANSITION_DURATION) : c())
+ };
+ var e = a.fn.alert;
+ a.fn.alert = b, a.fn.alert.Constructor = d, a.fn.alert.noConflict = function () {
+ return a.fn.alert = e, this
+ }, a(document).on("click.bs.alert.data-api", c, d.prototype.close)
+}(jQuery), +function (a) {
+ "use strict";
+ function b(b) {
+ return this.each(function () {
+ var d = a(this), e = d.data("bs.button"), f = "object" == typeof b && b;
+ e || d.data("bs.button", e = new c(this, f)), "toggle" == b ? e.toggle() : b && e.setState(b)
+ })
+ }
+
+ var c = function (b, d) {
+ this.$element = a(b), this.options = a.extend({}, c.DEFAULTS, d), this.isLoading = !1
+ };
+ c.VERSION = "3.3.5", c.DEFAULTS = {loadingText: "loading..."}, c.prototype.setState = function (b) {
+ var c = "disabled", d = this.$element, e = d.is("input") ? "val" : "html", f = d.data();
+ b += "Text", null == f.resetText && d.data("resetText", d[e]()), setTimeout(a.proxy(function () {
+ d[e](null == f[b] ? this.options[b] : f[b]), "loadingText" == b ? (this.isLoading = !0, d.addClass(c).attr(c, c)) : this.isLoading && (this.isLoading = !1, d.removeClass(c).removeAttr(c))
+ }, this), 0)
+ }, c.prototype.toggle = function () {
+ var a = !0, b = this.$element.closest('[data-toggle="buttons"]');
+ if (b.length) {
+ var c = this.$element.find("input");
+ "radio" == c.prop("type") ? (c.prop("checked") && (a = !1), b.find(".active").removeClass("active"), this.$element.addClass("active")) : "checkbox" == c.prop("type") && (c.prop("checked") !== this.$element.hasClass("active") && (a = !1), this.$element.toggleClass("active")), c.prop("checked", this.$element.hasClass("active")), a && c.trigger("change")
+ } else this.$element.attr("aria-pressed", !this.$element.hasClass("active")), this.$element.toggleClass("active")
+ };
+ var d = a.fn.button;
+ a.fn.button = b, a.fn.button.Constructor = c, a.fn.button.noConflict = function () {
+ return a.fn.button = d, this
+ }, a(document).on("click.bs.button.data-api", '[data-toggle^="button"]', function (c) {
+ var d = a(c.target);
+ d.hasClass("btn") || (d = d.closest(".btn")), b.call(d, "toggle"), a(c.target).is('input[type="radio"]') || a(c.target).is('input[type="checkbox"]') || c.preventDefault()
+ }).on("focus.bs.button.data-api blur.bs.button.data-api", '[data-toggle^="button"]', function (b) {
+ a(b.target).closest(".btn").toggleClass("focus", /^focus(in)?$/.test(b.type))
+ })
+}(jQuery), +function (a) {
+ "use strict";
+ function b(b) {
+ return this.each(function () {
+ var d = a(this), e = d.data("bs.carousel"), f = a.extend({}, c.DEFAULTS, d.data(), "object" == typeof b && b), g = "string" == typeof b ? b : f.slide;
+ e || d.data("bs.carousel", e = new c(this, f)), "number" == typeof b ? e.to(b) : g ? e[g]() : f.interval && e.pause().cycle()
+ })
+ }
+
+ var c = function (b, c) {
+ this.$element = a(b), this.$indicators = this.$element.find(".carousel-indicators"), this.options = c, this.paused = null, this.sliding = null, this.interval = null, this.$active = null, this.$items = null, this.options.keyboard && this.$element.on("keydown.bs.carousel", a.proxy(this.keydown, this)), "hover" == this.options.pause && !("ontouchstart" in document.documentElement) && this.$element.on("mouseenter.bs.carousel", a.proxy(this.pause, this)).on("mouseleave.bs.carousel", a.proxy(this.cycle, this))
+ };
+ c.VERSION = "3.3.5", c.TRANSITION_DURATION = 600, c.DEFAULTS = {interval: 5e3, pause: "hover", wrap: !0, keyboard: !0}, c.prototype.keydown = function (a) {
+ if (!/input|textarea/i.test(a.target.tagName)) {
+ switch (a.which) {
+ case 37:
+ this.prev();
+ break;
+ case 39:
+ this.next();
+ break;
+ default:
+ return
+ }
+ a.preventDefault()
+ }
+ }, c.prototype.cycle = function (b) {
+ return b || (this.paused = !1), this.interval && clearInterval(this.interval), this.options.interval && !this.paused && (this.interval = setInterval(a.proxy(this.next, this), this.options.interval)), this
+ }, c.prototype.getItemIndex = function (a) {
+ return this.$items = a.parent().children(".item"), this.$items.index(a || this.$active)
+ }, c.prototype.getItemForDirection = function (a, b) {
+ var c = this.getItemIndex(b), d = "prev" == a && 0 === c || "next" == a && c == this.$items.length - 1;
+ if (d && !this.options.wrap)return b;
+ var e = "prev" == a ? -1 : 1, f = (c + e) % this.$items.length;
+ return this.$items.eq(f)
+ }, c.prototype.to = function (a) {
+ var b = this, c = this.getItemIndex(this.$active = this.$element.find(".item.active"));
+ return a > this.$items.length - 1 || 0 > a ? void 0 : this.sliding ? this.$element.one("slid.bs.carousel", function () {
+ b.to(a)
+ }) : c == a ? this.pause().cycle() : this.slide(a > c ? "next" : "prev", this.$items.eq(a))
+ }, c.prototype.pause = function (b) {
+ return b || (this.paused = !0), this.$element.find(".next, .prev").length && a.support.transition && (this.$element.trigger(a.support.transition.end), this.cycle(!0)), this.interval = clearInterval(this.interval), this
+ }, c.prototype.next = function () {
+ return this.sliding ? void 0 : this.slide("next")
+ }, c.prototype.prev = function () {
+ return this.sliding ? void 0 : this.slide("prev")
+ }, c.prototype.slide = function (b, d) {
+ var e = this.$element.find(".item.active"), f = d || this.getItemForDirection(b, e), g = this.interval, h = "next" == b ? "left" : "right", i = this;
+ if (f.hasClass("active"))return this.sliding = !1;
+ var j = f[0], k = a.Event("slide.bs.carousel", {relatedTarget: j, direction: h});
+ if (this.$element.trigger(k), !k.isDefaultPrevented()) {
+ if (this.sliding = !0, g && this.pause(), this.$indicators.length) {
+ this.$indicators.find(".active").removeClass("active");
+ var l = a(this.$indicators.children()[this.getItemIndex(f)]);
+ l && l.addClass("active")
+ }
+ var m = a.Event("slid.bs.carousel", {relatedTarget: j, direction: h});
+ return a.support.transition && this.$element.hasClass("slide") ? (f.addClass(b), f[0].offsetWidth, e.addClass(h), f.addClass(h), e.one("bsTransitionEnd", function () {
+ f.removeClass([b, h].join(" ")).addClass("active"), e.removeClass(["active", h].join(" ")), i.sliding = !1, setTimeout(function () {
+ i.$element.trigger(m)
+ }, 0)
+ }).emulateTransitionEnd(c.TRANSITION_DURATION)) : (e.removeClass("active"), f.addClass("active"), this.sliding = !1, this.$element.trigger(m)), g && this.cycle(), this
+ }
+ };
+ var d = a.fn.carousel;
+ a.fn.carousel = b, a.fn.carousel.Constructor = c, a.fn.carousel.noConflict = function () {
+ return a.fn.carousel = d, this
+ };
+ var e = function (c) {
+ var d, e = a(this), f = a(e.attr("data-target") || (d = e.attr("href")) && d.replace(/.*(?=#[^\s]+$)/, ""));
+ if (f.hasClass("carousel")) {
+ var g = a.extend({}, f.data(), e.data()), h = e.attr("data-slide-to");
+ h && (g.interval = !1), b.call(f, g), h && f.data("bs.carousel").to(h), c.preventDefault()
+ }
+ };
+ a(document).on("click.bs.carousel.data-api", "[data-slide]", e).on("click.bs.carousel.data-api", "[data-slide-to]", e), a(window).on("load", function () {
+ a('[data-ride="carousel"]').each(function () {
+ var c = a(this);
+ b.call(c, c.data())
+ })
+ })
+}(jQuery), +function (a) {
+ "use strict";
+ function b(b) {
+ var c, d = b.attr("data-target") || (c = b.attr("href")) && c.replace(/.*(?=#[^\s]+$)/, "");
+ return a(d)
+ }
+
+ function c(b) {
+ return this.each(function () {
+ var c = a(this), e = c.data("bs.collapse"), f = a.extend({}, d.DEFAULTS, c.data(), "object" == typeof b && b);
+ !e && f.toggle && /show|hide/.test(b) && (f.toggle = !1), e || c.data("bs.collapse", e = new d(this, f)), "string" == typeof b && e[b]()
+ })
+ }
+
+ var d = function (b, c) {
+ this.$element = a(b), this.options = a.extend({}, d.DEFAULTS, c), this.$trigger = a('[data-toggle="collapse"][href="#' + b.id + '"],[data-toggle="collapse"][data-target="#' + b.id + '"]'), this.transitioning = null, this.options.parent ? this.$parent = this.getParent() : this.addAriaAndCollapsedClass(this.$element, this.$trigger), this.options.toggle && this.toggle()
+ };
+ d.VERSION = "3.3.5", d.TRANSITION_DURATION = 350, d.DEFAULTS = {toggle: !0}, d.prototype.dimension = function () {
+ var a = this.$element.hasClass("width");
+ return a ? "width" : "height"
+ }, d.prototype.show = function () {
+ if (!this.transitioning && !this.$element.hasClass("in")) {
+ var b, e = this.$parent && this.$parent.children(".panel").children(".in, .collapsing");
+ if (!(e && e.length && (b = e.data("bs.collapse"), b && b.transitioning))) {
+ var f = a.Event("show.bs.collapse");
+ if (this.$element.trigger(f), !f.isDefaultPrevented()) {
+ e && e.length && (c.call(e, "hide"), b || e.data("bs.collapse", null));
+ var g = this.dimension();
+ this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded", !0), this.$trigger.removeClass("collapsed").attr("aria-expanded", !0), this.transitioning = 1;
+ var h = function () {
+ this.$element.removeClass("collapsing").addClass("collapse in")[g](""), this.transitioning = 0, this.$element.trigger("shown.bs.collapse")
+ };
+ if (!a.support.transition)return h.call(this);
+ var i = a.camelCase(["scroll", g].join("-"));
+ this.$element.one("bsTransitionEnd", a.proxy(h, this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])
+ }
+ }
+ }
+ }, d.prototype.hide = function () {
+ if (!this.transitioning && this.$element.hasClass("in")) {
+ var b = a.Event("hide.bs.collapse");
+ if (this.$element.trigger(b), !b.isDefaultPrevented()) {
+ var c = this.dimension();
+ this.$element[c](this.$element[c]())[0].offsetHeight, this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded", !1), this.$trigger.addClass("collapsed").attr("aria-expanded", !1), this.transitioning = 1;
+ var e = function () {
+ this.transitioning = 0, this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")
+ };
+ return a.support.transition ? void this.$element[c](0).one("bsTransitionEnd", a.proxy(e, this)).emulateTransitionEnd(d.TRANSITION_DURATION) : e.call(this)
+ }
+ }
+ }, d.prototype.toggle = function () {
+ this[this.$element.hasClass("in") ? "hide" : "show"]()
+ }, d.prototype.getParent = function () {
+ return a(this.options.parent).find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]').each(a.proxy(function (c, d) {
+ var e = a(d);
+ this.addAriaAndCollapsedClass(b(e), e)
+ }, this)).end()
+ }, d.prototype.addAriaAndCollapsedClass = function (a, b) {
+ var c = a.hasClass("in");
+ a.attr("aria-expanded", c), b.toggleClass("collapsed", !c).attr("aria-expanded", c)
+ };
+ var e = a.fn.collapse;
+ a.fn.collapse = c, a.fn.collapse.Constructor = d, a.fn.collapse.noConflict = function () {
+ return a.fn.collapse = e, this
+ }, a(document).on("click.bs.collapse.data-api", '[data-toggle="collapse"]', function (d) {
+ var e = a(this);
+ e.attr("data-target") || d.preventDefault();
+ var f = b(e), g = f.data("bs.collapse"), h = g ? "toggle" : e.data();
+ c.call(f, h)
+ })
+}(jQuery), +function (a) {
+ "use strict";
+ function b(b) {
+ var c = b.attr("data-target");
+ c || (c = b.attr("href"), c = c && /#[A-Za-z]/.test(c) && c.replace(/.*(?=#[^\s]*$)/, ""));
+ var d = c && a(c);
+ return d && d.length ? d : b.parent()
+ }
+
+ function c(c) {
+ c && 3 === c.which || (a(e).remove(), a(f).each(function () {
+ var d = a(this), e = b(d), f = {relatedTarget: this};
+ e.hasClass("open") && (c && "click" == c.type && /input|textarea/i.test(c.target.tagName) && a.contains(e[0], c.target) || (e.trigger(c = a.Event("hide.bs.dropdown", f)), c.isDefaultPrevented() || (d.attr("aria-expanded", "false"), e.removeClass("open").trigger("hidden.bs.dropdown", f))))
+ }))
+ }
+
+ function d(b) {
+ return this.each(function () {
+ var c = a(this), d = c.data("bs.dropdown");
+ d || c.data("bs.dropdown", d = new g(this)), "string" == typeof b && d[b].call(c)
+ })
+ }
+
+ var e = ".dropdown-backdrop", f = '[data-toggle="dropdown"]', g = function (b) {
+ a(b).on("click.bs.dropdown", this.toggle)
+ };
+ g.VERSION = "3.3.5", g.prototype.toggle = function (d) {
+ var e = a(this);
+ if (!e.is(".disabled, :disabled")) {
+ var f = b(e), g = f.hasClass("open");
+ if (c(), !g) {
+ "ontouchstart" in document.documentElement && !f.closest(".navbar-nav").length && a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click", c);
+ var h = {relatedTarget: this};
+ if (f.trigger(d = a.Event("show.bs.dropdown", h)), d.isDefaultPrevented())return;
+ e.trigger("focus").attr("aria-expanded", "true"), f.toggleClass("open").trigger("shown.bs.dropdown", h)
+ }
+ return !1
+ }
+ }, g.prototype.keydown = function (c) {
+ if (/(38|40|27|32)/.test(c.which) && !/input|textarea/i.test(c.target.tagName)) {
+ var d = a(this);
+ if (c.preventDefault(), c.stopPropagation(), !d.is(".disabled, :disabled")) {
+ var e = b(d), g = e.hasClass("open");
+ if (!g && 27 != c.which || g && 27 == c.which)return 27 == c.which && e.find(f).trigger("focus"), d.trigger("click");
+ var h = " li:not(.disabled):visible a", i = e.find(".dropdown-menu" + h);
+ if (i.length) {
+ var j = i.index(c.target);
+ 38 == c.which && j > 0 && j--, 40 == c.which && j < i.length - 1 && j++, ~j || (j = 0), i.eq(j).trigger("focus")
+ }
+ }
+ }
+ };
+ var h = a.fn.dropdown;
+ a.fn.dropdown = d, a.fn.dropdown.Constructor = g, a.fn.dropdown.noConflict = function () {
+ return a.fn.dropdown = h, this
+ }, a(document).on("click.bs.dropdown.data-api", c).on("click.bs.dropdown.data-api", ".dropdown form", function (a) {
+ a.stopPropagation()
+ }).on("click.bs.dropdown.data-api", f, g.prototype.toggle).on("keydown.bs.dropdown.data-api", f, g.prototype.keydown).on("keydown.bs.dropdown.data-api", ".dropdown-menu", g.prototype.keydown)
+}(jQuery), +function (a) {
+ "use strict";
+ function b(b, d) {
+ return this.each(function () {
+ var e = a(this), f = e.data("bs.modal"), g = a.extend({}, c.DEFAULTS, e.data(), "object" == typeof b && b);
+ f || e.data("bs.modal", f = new c(this, g)), "string" == typeof b ? f[b](d) : g.show && f.show(d)
+ })
+ }
+
+ var c = function (b, c) {
+ this.options = c, this.$body = a(document.body), this.$element = a(b), this.$dialog = this.$element.find(".modal-dialog"), this.$backdrop = null, this.isShown = null, this.originalBodyPad = null, this.scrollbarWidth = 0, this.ignoreBackdropClick = !1, this.options.remote && this.$element.find(".modal-content").load(this.options.remote, a.proxy(function () {
+ this.$element.trigger("loaded.bs.modal")
+ }, this))
+ };
+ c.VERSION = "3.3.5", c.TRANSITION_DURATION = 300, c.BACKDROP_TRANSITION_DURATION = 150, c.DEFAULTS = {backdrop: !0, keyboard: !0, show: !0}, c.prototype.toggle = function (a) {
+ return this.isShown ? this.hide() : this.show(a)
+ }, c.prototype.show = function (b) {
+ var d = this, e = a.Event("show.bs.modal", {relatedTarget: b});
+ this.$element.trigger(e), this.isShown || e.isDefaultPrevented() || (this.isShown = !0, this.checkScrollbar(), this.setScrollbar(), this.$body.addClass("modal-open"), this.escape(), this.resize(), this.$element.on("click.dismiss.bs.modal", '[data-dismiss="modal"]', a.proxy(this.hide, this)), this.$dialog.on("mousedown.dismiss.bs.modal", function () {
+ d.$element.one("mouseup.dismiss.bs.modal", function (b) {
+ a(b.target).is(d.$element) && (d.ignoreBackdropClick = !0)
+ })
+ }), this.backdrop(function () {
+ var e = a.support.transition && d.$element.hasClass("fade");
+ d.$element.parent().length || d.$element.appendTo(d.$body), d.$element.show().scrollTop(0), d.adjustDialog(), e && d.$element[0].offsetWidth, d.$element.addClass("in"), d.enforceFocus();
+ var f = a.Event("shown.bs.modal", {relatedTarget: b});
+ e ? d.$dialog.one("bsTransitionEnd", function () {
+ d.$element.trigger("focus").trigger(f)
+ }).emulateTransitionEnd(c.TRANSITION_DURATION) : d.$element.trigger("focus").trigger(f)
+ }))
+ }, c.prototype.hide = function (b) {
+ b && b.preventDefault(), b = a.Event("hide.bs.modal"), this.$element.trigger(b), this.isShown && !b.isDefaultPrevented() && (this.isShown = !1, this.escape(), this.resize(), a(document).off("focusin.bs.modal"), this.$element.removeClass("in").off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal"), this.$dialog.off("mousedown.dismiss.bs.modal"), a.support.transition && this.$element.hasClass("fade") ? this.$element.one("bsTransitionEnd", a.proxy(this.hideModal, this)).emulateTransitionEnd(c.TRANSITION_DURATION) : this.hideModal())
+ }, c.prototype.enforceFocus = function () {
+ a(document).off("focusin.bs.modal").on("focusin.bs.modal", a.proxy(function (a) {
+ this.$element[0] === a.target || this.$element.has(a.target).length || this.$element.trigger("focus")
+ }, this))
+ }, c.prototype.escape = function () {
+ this.isShown && this.options.keyboard ? this.$element.on("keydown.dismiss.bs.modal", a.proxy(function (a) {
+ 27 == a.which && this.hide()
+ }, this)) : this.isShown || this.$element.off("keydown.dismiss.bs.modal")
+ }, c.prototype.resize = function () {
+ this.isShown ? a(window).on("resize.bs.modal", a.proxy(this.handleUpdate, this)) : a(window).off("resize.bs.modal")
+ }, c.prototype.hideModal = function () {
+ var a = this;
+ this.$element.hide(), this.backdrop(function () {
+ a.$body.removeClass("modal-open"), a.resetAdjustments(), a.resetScrollbar(), a.$element.trigger("hidden.bs.modal")
+ })
+ }, c.prototype.removeBackdrop = function () {
+ this.$backdrop && this.$backdrop.remove(), this.$backdrop = null
+ }, c.prototype.backdrop = function (b) {
+ var d = this, e = this.$element.hasClass("fade") ? "fade" : "";
+ if (this.isShown && this.options.backdrop) {
+ var f = a.support.transition && e;
+ if (this.$backdrop = a(document.createElement("div")).addClass("modal-backdrop " + e).appendTo(this.$body), this.$element.on("click.dismiss.bs.modal", a.proxy(function (a) {
+ return this.ignoreBackdropClick ? void(this.ignoreBackdropClick = !1) : void(a.target === a.currentTarget && ("static" == this.options.backdrop ? this.$element[0].focus() : this.hide()))
+ }, this)), f && this.$backdrop[0].offsetWidth, this.$backdrop.addClass("in"), !b)return;
+ f ? this.$backdrop.one("bsTransitionEnd", b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION) : b()
+ } else if (!this.isShown && this.$backdrop) {
+ this.$backdrop.removeClass("in");
+ var g = function () {
+ d.removeBackdrop(), b && b()
+ };
+ a.support.transition && this.$element.hasClass("fade") ? this.$backdrop.one("bsTransitionEnd", g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION) : g()
+ } else b && b()
+ }, c.prototype.handleUpdate = function () {
+ this.adjustDialog()
+ }, c.prototype.adjustDialog = function () {
+ var a = this.$element[0].scrollHeight > document.documentElement.clientHeight;
+ this.$element.css({paddingLeft: !this.bodyIsOverflowing && a ? this.scrollbarWidth : "", paddingRight: this.bodyIsOverflowing && !a ? this.scrollbarWidth : ""})
+ }, c.prototype.resetAdjustments = function () {
+ this.$element.css({paddingLeft: "", paddingRight: ""})
+ }, c.prototype.checkScrollbar = function () {
+ var a = window.innerWidth;
+ if (!a) {
+ var b = document.documentElement.getBoundingClientRect();
+ a = b.right - Math.abs(b.left)
+ }
+ this.bodyIsOverflowing = document.body.clientWidth < a, this.scrollbarWidth = this.measureScrollbar()
+ }, c.prototype.setScrollbar = function () {
+ var a = parseInt(this.$body.css("padding-right") || 0, 10);
+ this.originalBodyPad = document.body.style.paddingRight || "", this.bodyIsOverflowing && this.$body.css("padding-right", a + this.scrollbarWidth)
+ }, c.prototype.resetScrollbar = function () {
+ this.$body.css("padding-right", this.originalBodyPad)
+ }, c.prototype.measureScrollbar = function () {
+ var a = document.createElement("div");
+ a.className = "modal-scrollbar-measure", this.$body.append(a);
+ var b = a.offsetWidth - a.clientWidth;
+ return this.$body[0].removeChild(a), b
+ };
+ var d = a.fn.modal;
+ a.fn.modal = b, a.fn.modal.Constructor = c, a.fn.modal.noConflict = function () {
+ return a.fn.modal = d, this
+ }, a(document).on("click.bs.modal.data-api", '[data-toggle="modal"]', function (c) {
+ var d = a(this), e = d.attr("href"), f = a(d.attr("data-target") || e && e.replace(/.*(?=#[^\s]+$)/, "")), g = f.data("bs.modal") ? "toggle" : a.extend({remote: !/#/.test(e) && e}, f.data(), d.data());
+ d.is("a") && c.preventDefault(), f.one("show.bs.modal", function (a) {
+ a.isDefaultPrevented() || f.one("hidden.bs.modal", function () {
+ d.is(":visible") && d.trigger("focus")
+ })
+ }), b.call(f, g, this)
+ })
+}(jQuery), +function (a) {
+ "use strict";
+ function b(b) {
+ return this.each(function () {
+ var d = a(this), e = d.data("bs.tooltip"), f = "object" == typeof b && b;
+ (e || !/destroy|hide/.test(b)) && (e || d.data("bs.tooltip", e = new c(this, f)), "string" == typeof b && e[b]())
+ })
+ }
+
+ var c = function (a, b) {
+ this.type = null, this.options = null, this.enabled = null, this.timeout = null, this.hoverState = null, this.$element = null, this.inState = null, this.init("tooltip", a, b)
+ };
+ c.VERSION = "3.3.5", c.TRANSITION_DURATION = 150, c.DEFAULTS = {
+ animation: !0,
+ placement: "top",
+ selector: !1,
+ template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
+ trigger: "hover focus",
+ title: "",
+ delay: 0,
+ html: !1,
+ container: !1,
+ viewport: {selector: "body", padding: 0}
+ }, c.prototype.init = function (b, c, d) {
+ if (this.enabled = !0, this.type = b, this.$element = a(c), this.options = this.getOptions(d), this.$viewport = this.options.viewport && a(a.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : this.options.viewport.selector || this.options.viewport), this.inState = {
+ click: !1,
+ hover: !1,
+ focus: !1
+ }, this.$element[0] instanceof document.constructor && !this.options.selector)throw new Error("`selector` option must be specified when initializing " + this.type + " on the window.document object!");
+ for (var e = this.options.trigger.split(" "), f = e.length; f--;) {
+ var g = e[f];
+ if ("click" == g)this.$element.on("click." + this.type, this.options.selector, a.proxy(this.toggle, this)); else if ("manual" != g) {
+ var h = "hover" == g ? "mouseenter" : "focusin", i = "hover" == g ? "mouseleave" : "focusout";
+ this.$element.on(h + "." + this.type, this.options.selector, a.proxy(this.enter, this)), this.$element.on(i + "." + this.type, this.options.selector, a.proxy(this.leave, this))
+ }
+ }
+ this.options.selector ? this._options = a.extend({}, this.options, {trigger: "manual", selector: ""}) : this.fixTitle()
+ }, c.prototype.getDefaults = function () {
+ return c.DEFAULTS
+ }, c.prototype.getOptions = function (b) {
+ return b = a.extend({}, this.getDefaults(), this.$element.data(), b), b.delay && "number" == typeof b.delay && (b.delay = {show: b.delay, hide: b.delay}), b
+ }, c.prototype.getDelegateOptions = function () {
+ var b = {}, c = this.getDefaults();
+ return this._options && a.each(this._options, function (a, d) {
+ c[a] != d && (b[a] = d)
+ }), b
+ }, c.prototype.enter = function (b) {
+ var c = b instanceof this.constructor ? b : a(b.currentTarget).data("bs." + this.type);
+ return c || (c = new this.constructor(b.currentTarget, this.getDelegateOptions()), a(b.currentTarget).data("bs." + this.type, c)), b instanceof a.Event && (c.inState["focusin" == b.type ? "focus" : "hover"] = !0), c.tip().hasClass("in") || "in" == c.hoverState ? void(c.hoverState = "in") : (clearTimeout(c.timeout), c.hoverState = "in", c.options.delay && c.options.delay.show ? void(c.timeout = setTimeout(function () {
+ "in" == c.hoverState && c.show()
+ }, c.options.delay.show)) : c.show())
+ }, c.prototype.isInStateTrue = function () {
+ for (var a in this.inState)if (this.inState[a])return !0;
+ return !1
+ }, c.prototype.leave = function (b) {
+ var c = b instanceof this.constructor ? b : a(b.currentTarget).data("bs." + this.type);
+ return c || (c = new this.constructor(b.currentTarget, this.getDelegateOptions()), a(b.currentTarget).data("bs." + this.type, c)), b instanceof a.Event && (c.inState["focusout" == b.type ? "focus" : "hover"] = !1), c.isInStateTrue() ? void 0 : (clearTimeout(c.timeout), c.hoverState = "out", c.options.delay && c.options.delay.hide ? void(c.timeout = setTimeout(function () {
+ "out" == c.hoverState && c.hide()
+ }, c.options.delay.hide)) : c.hide())
+ }, c.prototype.show = function () {
+ var b = a.Event("show.bs." + this.type);
+ if (this.hasContent() && this.enabled) {
+ this.$element.trigger(b);
+ var d = a.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]);
+ if (b.isDefaultPrevented() || !d)return;
+ var e = this, f = this.tip(), g = this.getUID(this.type);
+ this.setContent(), f.attr("id", g), this.$element.attr("aria-describedby", g), this.options.animation && f.addClass("fade");
+ var h = "function" == typeof this.options.placement ? this.options.placement.call(this, f[0], this.$element[0]) : this.options.placement, i = /\s?auto?\s?/i, j = i.test(h);
+ j && (h = h.replace(i, "") || "top"), f.detach().css({
+ top: 0,
+ left: 0,
+ display: "block"
+ }).addClass(h).data("bs." + this.type, this), this.options.container ? f.appendTo(this.options.container) : f.insertAfter(this.$element), this.$element.trigger("inserted.bs." + this.type);
+ var k = this.getPosition(), l = f[0].offsetWidth, m = f[0].offsetHeight;
+ if (j) {
+ var n = h, o = this.getPosition(this.$viewport);
+ h = "bottom" == h && k.bottom + m > o.bottom ? "top" : "top" == h && k.top - m < o.top ? "bottom" : "right" == h && k.right + l > o.width ? "left" : "left" == h && k.left - l < o.left ? "right" : h, f.removeClass(n).addClass(h)
+ }
+ var p = this.getCalculatedOffset(h, k, l, m);
+ this.applyPlacement(p, h);
+ var q = function () {
+ var a = e.hoverState;
+ e.$element.trigger("shown.bs." + e.type), e.hoverState = null, "out" == a && e.leave(e)
+ };
+ a.support.transition && this.$tip.hasClass("fade") ? f.one("bsTransitionEnd", q).emulateTransitionEnd(c.TRANSITION_DURATION) : q()
+ }
+ }, c.prototype.applyPlacement = function (b, c) {
+ var d = this.tip(), e = d[0].offsetWidth, f = d[0].offsetHeight, g = parseInt(d.css("margin-top"), 10), h = parseInt(d.css("margin-left"), 10);
+ isNaN(g) && (g = 0), isNaN(h) && (h = 0), b.top += g, b.left += h, a.offset.setOffset(d[0], a.extend({
+ using: function (a) {
+ d.css({top: Math.round(a.top), left: Math.round(a.left)})
+ }
+ }, b), 0), d.addClass("in");
+ var i = d[0].offsetWidth, j = d[0].offsetHeight;
+ "top" == c && j != f && (b.top = b.top + f - j);
+ var k = this.getViewportAdjustedDelta(c, b, i, j);
+ k.left ? b.left += k.left : b.top += k.top;
+ var l = /top|bottom/.test(c), m = l ? 2 * k.left - e + i : 2 * k.top - f + j, n = l ? "offsetWidth" : "offsetHeight";
+ d.offset(b), this.replaceArrow(m, d[0][n], l)
+ }, c.prototype.replaceArrow = function (a, b, c) {
+ this.arrow().css(c ? "left" : "top", 50 * (1 - a / b) + "%").css(c ? "top" : "left", "")
+ }, c.prototype.setContent = function () {
+ var a = this.tip(), b = this.getTitle();
+ a.find(".tooltip-inner")[this.options.html ? "html" : "text"](b), a.removeClass("fade in top bottom left right")
+ }, c.prototype.hide = function (b) {
+ function d() {
+ "in" != e.hoverState && f.detach(), e.$element.removeAttr("aria-describedby").trigger("hidden.bs." + e.type), b && b()
+ }
+
+ var e = this, f = a(this.$tip), g = a.Event("hide.bs." + this.type);
+ return this.$element.trigger(g), g.isDefaultPrevented() ? void 0 : (f.removeClass("in"), a.support.transition && f.hasClass("fade") ? f.one("bsTransitionEnd", d).emulateTransitionEnd(c.TRANSITION_DURATION) : d(), this.hoverState = null, this)
+ }, c.prototype.fixTitle = function () {
+ var a = this.$element;
+ (a.attr("title") || "string" != typeof a.attr("data-original-title")) && a.attr("data-original-title", a.attr("title") || "").attr("title", "")
+ }, c.prototype.hasContent = function () {
+ return this.getTitle()
+ }, c.prototype.getPosition = function (b) {
+ b = b || this.$element;
+ var c = b[0], d = "BODY" == c.tagName, e = c.getBoundingClientRect();
+ null == e.width && (e = a.extend({}, e, {width: e.right - e.left, height: e.bottom - e.top}));
+ var f = d ? {
+ top: 0,
+ left: 0
+ } : b.offset(), g = {scroll: d ? document.documentElement.scrollTop || document.body.scrollTop : b.scrollTop()}, h = d ? {
+ width: a(window).width(),
+ height: a(window).height()
+ } : null;
+ return a.extend({}, e, g, h, f)
+ }, c.prototype.getCalculatedOffset = function (a, b, c, d) {
+ return "bottom" == a ? {top: b.top + b.height, left: b.left + b.width / 2 - c / 2} : "top" == a ? {
+ top: b.top - d,
+ left: b.left + b.width / 2 - c / 2
+ } : "left" == a ? {top: b.top + b.height / 2 - d / 2, left: b.left - c} : {top: b.top + b.height / 2 - d / 2, left: b.left + b.width}
+ }, c.prototype.getViewportAdjustedDelta = function (a, b, c, d) {
+ var e = {top: 0, left: 0};
+ if (!this.$viewport)return e;
+ var f = this.options.viewport && this.options.viewport.padding || 0, g = this.getPosition(this.$viewport);
+ if (/right|left/.test(a)) {
+ var h = b.top - f - g.scroll, i = b.top + f - g.scroll + d;
+ h < g.top ? e.top = g.top - h : i > g.top + g.height && (e.top = g.top + g.height - i)
+ } else {
+ var j = b.left - f, k = b.left + f + c;
+ j < g.left ? e.left = g.left - j : k > g.right && (e.left = g.left + g.width - k)
+ }
+ return e
+ }, c.prototype.getTitle = function () {
+ var a, b = this.$element, c = this.options;
+ return a = b.attr("data-original-title") || ("function" == typeof c.title ? c.title.call(b[0]) : c.title)
+ }, c.prototype.getUID = function (a) {
+ do a += ~~(1e6 * Math.random()); while (document.getElementById(a));
+ return a
+ }, c.prototype.tip = function () {
+ if (!this.$tip && (this.$tip = a(this.options.template), 1 != this.$tip.length))throw new Error(this.type + " `template` option must consist of exactly 1 top-level element!");
+ return this.$tip
+ }, c.prototype.arrow = function () {
+ return this.$arrow = this.$arrow || this.tip().find(".tooltip-arrow")
+ }, c.prototype.enable = function () {
+ this.enabled = !0
+ }, c.prototype.disable = function () {
+ this.enabled = !1
+ }, c.prototype.toggleEnabled = function () {
+ this.enabled = !this.enabled
+ }, c.prototype.toggle = function (b) {
+ var c = this;
+ b && (c = a(b.currentTarget).data("bs." + this.type), c || (c = new this.constructor(b.currentTarget, this.getDelegateOptions()), a(b.currentTarget).data("bs." + this.type, c))), b ? (c.inState.click = !c.inState.click, c.isInStateTrue() ? c.enter(c) : c.leave(c)) : c.tip().hasClass("in") ? c.leave(c) : c.enter(c)
+ }, c.prototype.destroy = function () {
+ var a = this;
+ clearTimeout(this.timeout), this.hide(function () {
+ a.$element.off("." + a.type).removeData("bs." + a.type), a.$tip && a.$tip.detach(), a.$tip = null, a.$arrow = null, a.$viewport = null
+ })
+ };
+ var d = a.fn.tooltip;
+ a.fn.tooltip = b, a.fn.tooltip.Constructor = c, a.fn.tooltip.noConflict = function () {
+ return a.fn.tooltip = d, this
+ }
+}(jQuery), +function (a) {
+ "use strict";
+ function b(b) {
+ return this.each(function () {
+ var d = a(this), e = d.data("bs.popover"), f = "object" == typeof b && b;
+ (e || !/destroy|hide/.test(b)) && (e || d.data("bs.popover", e = new c(this, f)), "string" == typeof b && e[b]())
+ })
+ }
+
+ var c = function (a, b) {
+ this.init("popover", a, b)
+ };
+ if (!a.fn.tooltip)throw new Error("Popover requires tooltip.js");
+ c.VERSION = "3.3.5", c.DEFAULTS = a.extend({}, a.fn.tooltip.Constructor.DEFAULTS, {
+ placement: "right",
+ trigger: "click",
+ content: "",
+ template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
+ }), c.prototype = a.extend({}, a.fn.tooltip.Constructor.prototype), c.prototype.constructor = c, c.prototype.getDefaults = function () {
+ return c.DEFAULTS
+ }, c.prototype.setContent = function () {
+ var a = this.tip(), b = this.getTitle(), c = this.getContent();
+ a.find(".popover-title")[this.options.html ? "html" : "text"](b), a.find(".popover-content").children().detach().end()[this.options.html ? "string" == typeof c ? "html" : "append" : "text"](c), a.removeClass("fade top bottom left right in"), a.find(".popover-title").html() || a.find(".popover-title").hide()
+ }, c.prototype.hasContent = function () {
+ return this.getTitle() || this.getContent()
+ }, c.prototype.getContent = function () {
+ var a = this.$element, b = this.options;
+ return a.attr("data-content") || ("function" == typeof b.content ? b.content.call(a[0]) : b.content)
+ }, c.prototype.arrow = function () {
+ return this.$arrow = this.$arrow || this.tip().find(".arrow")
+ };
+ var d = a.fn.popover;
+ a.fn.popover = b, a.fn.popover.Constructor = c, a.fn.popover.noConflict = function () {
+ return a.fn.popover = d, this
+ }
+}(jQuery), +function (a) {
+ "use strict";
+ function b(c, d) {
+ this.$body = a(document.body), this.$scrollElement = a(a(c).is(document.body) ? window : c), this.options = a.extend({}, b.DEFAULTS, d), this.selector = (this.options.target || "") + " .nav li > a", this.offsets = [], this.targets = [], this.activeTarget = null, this.scrollHeight = 0, this.$scrollElement.on("scroll.bs.scrollspy", a.proxy(this.process, this)), this.refresh(), this.process()
+ }
+
+ function c(c) {
+ return this.each(function () {
+ var d = a(this), e = d.data("bs.scrollspy"), f = "object" == typeof c && c;
+ e || d.data("bs.scrollspy", e = new b(this, f)), "string" == typeof c && e[c]()
+ })
+ }
+
+ b.VERSION = "3.3.5", b.DEFAULTS = {offset: 10}, b.prototype.getScrollHeight = function () {
+ return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
+ }, b.prototype.refresh = function () {
+ var b = this, c = "offset", d = 0;
+ this.offsets = [], this.targets = [], this.scrollHeight = this.getScrollHeight(), a.isWindow(this.$scrollElement[0]) || (c = "position", d = this.$scrollElement.scrollTop()), this.$body.find(this.selector).map(function () {
+ var b = a(this), e = b.data("target") || b.attr("href"), f = /^#./.test(e) && a(e);
+ return f && f.length && f.is(":visible") && [[f[c]().top + d, e]] || null
+ }).sort(function (a, b) {
+ return a[0] - b[0]
+ }).each(function () {
+ b.offsets.push(this[0]), b.targets.push(this[1])
+ })
+ }, b.prototype.process = function () {
+ var a, b = this.$scrollElement.scrollTop() + this.options.offset, c = this.getScrollHeight(), d = this.options.offset + c - this.$scrollElement.height(), e = this.offsets, f = this.targets, g = this.activeTarget;
+ if (this.scrollHeight != c && this.refresh(), b >= d)return g != (a = f[f.length - 1]) && this.activate(a);
+ if (g && b < e[0])return this.activeTarget = null, this.clear();
+ for (a = e.length; a--;)g != f[a] && b >= e[a] && (void 0 === e[a + 1] || b < e[a + 1]) && this.activate(f[a])
+ }, b.prototype.activate = function (b) {
+ this.activeTarget = b, this.clear();
+ var c = this.selector + '[data-target="' + b + '"],' + this.selector + '[href="' + b + '"]', d = a(c).parents("li").addClass("active");
+ d.parent(".dropdown-menu").length && (d = d.closest("li.dropdown").addClass("active")),
+ d.trigger("activate.bs.scrollspy")
+ }, b.prototype.clear = function () {
+ a(this.selector).parentsUntil(this.options.target, ".active").removeClass("active")
+ };
+ var d = a.fn.scrollspy;
+ a.fn.scrollspy = c, a.fn.scrollspy.Constructor = b, a.fn.scrollspy.noConflict = function () {
+ return a.fn.scrollspy = d, this
+ }, a(window).on("load.bs.scrollspy.data-api", function () {
+ a('[data-spy="scroll"]').each(function () {
+ var b = a(this);
+ c.call(b, b.data())
+ })
+ })
+}(jQuery), +function (a) {
+ "use strict";
+ function b(b) {
+ return this.each(function () {
+ var d = a(this), e = d.data("bs.tab");
+ e || d.data("bs.tab", e = new c(this)), "string" == typeof b && e[b]()
+ })
+ }
+
+ var c = function (b) {
+ this.element = a(b)
+ };
+ c.VERSION = "3.3.5", c.TRANSITION_DURATION = 150, c.prototype.show = function () {
+ var b = this.element, c = b.closest("ul:not(.dropdown-menu)"), d = b.data("target");
+ if (d || (d = b.attr("href"), d = d && d.replace(/.*(?=#[^\s]*$)/, "")), !b.parent("li").hasClass("active")) {
+ var e = c.find(".active:last a"), f = a.Event("hide.bs.tab", {relatedTarget: b[0]}), g = a.Event("show.bs.tab", {relatedTarget: e[0]});
+ if (e.trigger(f), b.trigger(g), !g.isDefaultPrevented() && !f.isDefaultPrevented()) {
+ var h = a(d);
+ this.activate(b.closest("li"), c), this.activate(h, h.parent(), function () {
+ e.trigger({type: "hidden.bs.tab", relatedTarget: b[0]}), b.trigger({type: "shown.bs.tab", relatedTarget: e[0]})
+ })
+ }
+ }
+ }, c.prototype.activate = function (b, d, e) {
+ function f() {
+ g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded", !1), b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded", !0), h ? (b[0].offsetWidth, b.addClass("in")) : b.removeClass("fade"), b.parent(".dropdown-menu").length && b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded", !0), e && e()
+ }
+
+ var g = d.find("> .active"), h = e && a.support.transition && (g.length && g.hasClass("fade") || !!d.find("> .fade").length);
+ g.length && h ? g.one("bsTransitionEnd", f).emulateTransitionEnd(c.TRANSITION_DURATION) : f(), g.removeClass("in")
+ };
+ var d = a.fn.tab;
+ a.fn.tab = b, a.fn.tab.Constructor = c, a.fn.tab.noConflict = function () {
+ return a.fn.tab = d, this
+ };
+ var e = function (c) {
+ c.preventDefault(), b.call(a(this), "show")
+ };
+ a(document).on("click.bs.tab.data-api", '[data-toggle="tab"]', e).on("click.bs.tab.data-api", '[data-toggle="pill"]', e)
+}(jQuery), +function (a) {
+ "use strict";
+ function b(b) {
+ return this.each(function () {
+ var d = a(this), e = d.data("bs.affix"), f = "object" == typeof b && b;
+ e || d.data("bs.affix", e = new c(this, f)), "string" == typeof b && e[b]()
+ })
+ }
+
+ var c = function (b, d) {
+ this.options = a.extend({}, c.DEFAULTS, d), this.$target = a(this.options.target).on("scroll.bs.affix.data-api", a.proxy(this.checkPosition, this)).on("click.bs.affix.data-api", a.proxy(this.checkPositionWithEventLoop, this)), this.$element = a(b), this.affixed = null, this.unpin = null, this.pinnedOffset = null, this.checkPosition()
+ };
+ c.VERSION = "3.3.5", c.RESET = "affix affix-top affix-bottom", c.DEFAULTS = {offset: 0, target: window}, c.prototype.getState = function (a, b, c, d) {
+ var e = this.$target.scrollTop(), f = this.$element.offset(), g = this.$target.height();
+ if (null != c && "top" == this.affixed)return c > e ? "top" : !1;
+ if ("bottom" == this.affixed)return null != c ? e + this.unpin <= f.top ? !1 : "bottom" : a - d >= e + g ? !1 : "bottom";
+ var h = null == this.affixed, i = h ? e : f.top, j = h ? g : b;
+ return null != c && c >= e ? "top" : null != d && i + j >= a - d ? "bottom" : !1
+ }, c.prototype.getPinnedOffset = function () {
+ if (this.pinnedOffset)return this.pinnedOffset;
+ this.$element.removeClass(c.RESET).addClass("affix");
+ var a = this.$target.scrollTop(), b = this.$element.offset();
+ return this.pinnedOffset = b.top - a
+ }, c.prototype.checkPositionWithEventLoop = function () {
+ setTimeout(a.proxy(this.checkPosition, this), 1)
+ }, c.prototype.checkPosition = function () {
+ if (this.$element.is(":visible")) {
+ var b = this.$element.height(), d = this.options.offset, e = d.top, f = d.bottom, g = Math.max(a(document).height(), a(document.body).height());
+ "object" != typeof d && (f = e = d), "function" == typeof e && (e = d.top(this.$element)), "function" == typeof f && (f = d.bottom(this.$element));
+ var h = this.getState(g, b, e, f);
+ if (this.affixed != h) {
+ null != this.unpin && this.$element.css("top", "");
+ var i = "affix" + (h ? "-" + h : ""), j = a.Event(i + ".bs.affix");
+ if (this.$element.trigger(j), j.isDefaultPrevented())return;
+ this.affixed = h, this.unpin = "bottom" == h ? this.getPinnedOffset() : null, this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix", "affixed") + ".bs.affix")
+ }
+ "bottom" == h && this.$element.offset({top: g - b - f})
+ }
+ };
+ var d = a.fn.affix;
+ a.fn.affix = b, a.fn.affix.Constructor = c, a.fn.affix.noConflict = function () {
+ return a.fn.affix = d, this
+ }, a(window).on("load", function () {
+ a('[data-spy="affix"]').each(function () {
+ var c = a(this), d = c.data();
+ d.offset = d.offset || {}, null != d.offsetBottom && (d.offset.bottom = d.offsetBottom), null != d.offsetTop && (d.offset.top = d.offsetTop), b.call(c, d)
+ })
+ })
+}(jQuery);
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/js/bootstrap/css/bootstrap-theme.css
@@ -0,0 +1,650 @@
+/*!
+ * Bootstrap v3.3.5 (http://getbootstrap.com)
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+.btn-default,
+.btn-primary,
+.btn-success,
+.btn-info,
+.btn-warning,
+.btn-danger {
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, .2);
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
+}
+
+.btn-default:active,
+.btn-primary:active,
+.btn-success:active,
+.btn-info:active,
+.btn-warning:active,
+.btn-danger:active,
+.btn-default.active,
+.btn-primary.active,
+.btn-success.active,
+.btn-info.active,
+.btn-warning.active,
+.btn-danger.active {
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+}
+
+.btn-default.disabled,
+.btn-primary.disabled,
+.btn-success.disabled,
+.btn-info.disabled,
+.btn-warning.disabled,
+.btn-danger.disabled,
+.btn-default[disabled],
+.btn-primary[disabled],
+.btn-success[disabled],
+.btn-info[disabled],
+.btn-warning[disabled],
+.btn-danger[disabled],
+fieldset[disabled] .btn-default,
+fieldset[disabled] .btn-primary,
+fieldset[disabled] .btn-success,
+fieldset[disabled] .btn-info,
+fieldset[disabled] .btn-warning,
+fieldset[disabled] .btn-danger {
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+
+.btn-default .badge,
+.btn-primary .badge,
+.btn-success .badge,
+.btn-info .badge,
+.btn-warning .badge,
+.btn-danger .badge {
+ text-shadow: none;
+}
+
+.btn:active,
+.btn.active {
+ background-image: none;
+}
+
+.btn-default {
+ text-shadow: 0 1px 0 #fff;
+ background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);
+ background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0));
+ background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+ background-repeat: repeat-x;
+ border-color: #dbdbdb;
+ border-color: #ccc;
+}
+
+.btn-default:hover,
+.btn-default:focus {
+ background-color: #e0e0e0;
+ background-position: 0 -15px;
+}
+
+.btn-default:active,
+.btn-default.active {
+ background-color: #e0e0e0;
+ border-color: #dbdbdb;
+}
+
+.btn-default.disabled,
+.btn-default[disabled],
+fieldset[disabled] .btn-default,
+.btn-default.disabled:hover,
+.btn-default[disabled]:hover,
+fieldset[disabled] .btn-default:hover,
+.btn-default.disabled:focus,
+.btn-default[disabled]:focus,
+fieldset[disabled] .btn-default:focus,
+.btn-default.disabled.focus,
+.btn-default[disabled].focus,
+fieldset[disabled] .btn-default.focus,
+.btn-default.disabled:active,
+.btn-default[disabled]:active,
+fieldset[disabled] .btn-default:active,
+.btn-default.disabled.active,
+.btn-default[disabled].active,
+fieldset[disabled] .btn-default.active {
+ background-color: #e0e0e0;
+ background-image: none;
+}
+
+.btn-primary {
+ background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);
+ background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88));
+ background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+ background-repeat: repeat-x;
+ border-color: #245580;
+}
+
+.btn-primary:hover,
+.btn-primary:focus {
+ background-color: #265a88;
+ background-position: 0 -15px;
+}
+
+.btn-primary:active,
+.btn-primary.active {
+ background-color: #265a88;
+ border-color: #245580;
+}
+
+.btn-primary.disabled,
+.btn-primary[disabled],
+fieldset[disabled] .btn-primary,
+.btn-primary.disabled:hover,
+.btn-primary[disabled]:hover,
+fieldset[disabled] .btn-primary:hover,
+.btn-primary.disabled:focus,
+.btn-primary[disabled]:focus,
+fieldset[disabled] .btn-primary:focus,
+.btn-primary.disabled.focus,
+.btn-primary[disabled].focus,
+fieldset[disabled] .btn-primary.focus,
+.btn-primary.disabled:active,
+.btn-primary[disabled]:active,
+fieldset[disabled] .btn-primary:active,
+.btn-primary.disabled.active,
+.btn-primary[disabled].active,
+fieldset[disabled] .btn-primary.active {
+ background-color: #265a88;
+ background-image: none;
+}
+
+.btn-success {
+ background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);
+ background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641));
+ background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+ background-repeat: repeat-x;
+ border-color: #3e8f3e;
+}
+
+.btn-success:hover,
+.btn-success:focus {
+ background-color: #419641;
+ background-position: 0 -15px;
+}
+
+.btn-success:active,
+.btn-success.active {
+ background-color: #419641;
+ border-color: #3e8f3e;
+}
+
+.btn-success.disabled,
+.btn-success[disabled],
+fieldset[disabled] .btn-success,
+.btn-success.disabled:hover,
+.btn-success[disabled]:hover,
+fieldset[disabled] .btn-success:hover,
+.btn-success.disabled:focus,
+.btn-success[disabled]:focus,
+fieldset[disabled] .btn-success:focus,
+.btn-success.disabled.focus,
+.btn-success[disabled].focus,
+fieldset[disabled] .btn-success.focus,
+.btn-success.disabled:active,
+.btn-success[disabled]:active,
+fieldset[disabled] .btn-success:active,
+.btn-success.disabled.active,
+.btn-success[disabled].active,
+fieldset[disabled] .btn-success.active {
+ background-color: #419641;
+ background-image: none;
+}
+
+.btn-info {
+ background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
+ background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2));
+ background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+ background-repeat: repeat-x;
+ border-color: #28a4c9;
+}
+
+.btn-info:hover,
+.btn-info:focus {
+ background-color: #2aabd2;
+ background-position: 0 -15px;
+}
+
+.btn-info:active,
+.btn-info.active {
+ background-color: #2aabd2;
+ border-color: #28a4c9;
+}
+
+.btn-info.disabled,
+.btn-info[disabled],
+fieldset[disabled] .btn-info,
+.btn-info.disabled:hover,
+.btn-info[disabled]:hover,
+fieldset[disabled] .btn-info:hover,
+.btn-info.disabled:focus,
+.btn-info[disabled]:focus,
+fieldset[disabled] .btn-info:focus,
+.btn-info.disabled.focus,
+.btn-info[disabled].focus,
+fieldset[disabled] .btn-info.focus,
+.btn-info.disabled:active,
+.btn-info[disabled]:active,
+fieldset[disabled] .btn-info:active,
+.btn-info.disabled.active,
+.btn-info[disabled].active,
+fieldset[disabled] .btn-info.active {
+ background-color: #2aabd2;
+ background-image: none;
+}
+
+.btn-warning {
+ background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
+ background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316));
+ background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+ background-repeat: repeat-x;
+ border-color: #e38d13;
+}
+
+.btn-warning:hover,
+.btn-warning:focus {
+ background-color: #eb9316;
+ background-position: 0 -15px;
+}
+
+.btn-warning:active,
+.btn-warning.active {
+ background-color: #eb9316;
+ border-color: #e38d13;
+}
+
+.btn-warning.disabled,
+.btn-warning[disabled],
+fieldset[disabled] .btn-warning,
+.btn-warning.disabled:hover,
+.btn-warning[disabled]:hover,
+fieldset[disabled] .btn-warning:hover,
+.btn-warning.disabled:focus,
+.btn-warning[disabled]:focus,
+fieldset[disabled] .btn-warning:focus,
+.btn-warning.disabled.focus,
+.btn-warning[disabled].focus,
+fieldset[disabled] .btn-warning.focus,
+.btn-warning.disabled:active,
+.btn-warning[disabled]:active,
+fieldset[disabled] .btn-warning:active,
+.btn-warning.disabled.active,
+.btn-warning[disabled].active,
+fieldset[disabled] .btn-warning.active {
+ background-color: #eb9316;
+ background-image: none;
+}
+
+.btn-danger {
+ background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
+ background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a));
+ background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+ background-repeat: repeat-x;
+ border-color: #b92c28;
+}
+
+.btn-danger:hover,
+.btn-danger:focus {
+ background-color: #c12e2a;
+ background-position: 0 -15px;
+}
+
+.btn-danger:active,
+.btn-danger.active {
+ background-color: #c12e2a;
+ border-color: #b92c28;
+}
+
+.btn-danger.disabled,
+.btn-danger[disabled],
+fieldset[disabled] .btn-danger,
+.btn-danger.disabled:hover,
+.btn-danger[disabled]:hover,
+fieldset[disabled] .btn-danger:hover,
+.btn-danger.disabled:focus,
+.btn-danger[disabled]:focus,
+fieldset[disabled] .btn-danger:focus,
+.btn-danger.disabled.focus,
+.btn-danger[disabled].focus,
+fieldset[disabled] .btn-danger.focus,
+.btn-danger.disabled:active,
+.btn-danger[disabled]:active,
+fieldset[disabled] .btn-danger:active,
+.btn-danger.disabled.active,
+.btn-danger[disabled].active,
+fieldset[disabled] .btn-danger.active {
+ background-color: #c12e2a;
+ background-image: none;
+}
+
+.thumbnail,
+.img-thumbnail {
+ -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
+ box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
+}
+
+.dropdown-menu > li > a:hover,
+.dropdown-menu > li > a:focus {
+ background-color: #e8e8e8;
+ background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
+ background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
+ background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
+ background-repeat: repeat-x;
+}
+
+.dropdown-menu > .active > a,
+.dropdown-menu > .active > a:hover,
+.dropdown-menu > .active > a:focus {
+ background-color: #2e6da4;
+ background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
+ background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
+ background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
+ background-repeat: repeat-x;
+}
+
+.navbar-default {
+ background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%);
+ background-image: -o-linear-gradient(top, #fff 0%, #f8f8f8 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8));
+ background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+ background-repeat: repeat-x;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
+}
+
+.navbar-default .navbar-nav > .open > a,
+.navbar-default .navbar-nav > .active > a {
+ background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
+ background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2));
+ background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);
+ background-repeat: repeat-x;
+ -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
+}
+
+.navbar-brand,
+.navbar-nav > li > a {
+ text-shadow: 0 1px 0 rgba(255, 255, 255, .25);
+}
+
+.navbar-inverse {
+ background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);
+ background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222));
+ background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+ background-repeat: repeat-x;
+ border-radius: 4px;
+}
+
+.navbar-inverse .navbar-nav > .open > a,
+.navbar-inverse .navbar-nav > .active > a {
+ background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);
+ background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f));
+ background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);
+ background-repeat: repeat-x;
+ -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
+ box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
+}
+
+.navbar-inverse .navbar-brand,
+.navbar-inverse .navbar-nav > li > a {
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, .25);
+}
+
+.navbar-static-top,
+.navbar-fixed-top,
+.navbar-fixed-bottom {
+ border-radius: 0;
+}
+
+@media (max-width: 767px) {
+ .navbar .navbar-nav .open .dropdown-menu > .active > a,
+ .navbar .navbar-nav .open .dropdown-menu > .active > a:hover,
+ .navbar .navbar-nav .open .dropdown-menu > .active > a:focus {
+ color: #fff;
+ background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
+ background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
+ background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
+ background-repeat: repeat-x;
+ }
+}
+
+.alert {
+ text-shadow: 0 1px 0 rgba(255, 255, 255, .2);
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
+}
+
+.alert-success {
+ background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
+ background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc));
+ background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);
+ background-repeat: repeat-x;
+ border-color: #b2dba1;
+}
+
+.alert-info {
+ background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
+ background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0));
+ background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);
+ background-repeat: repeat-x;
+ border-color: #9acfea;
+}
+
+.alert-warning {
+ background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
+ background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0));
+ background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);
+ background-repeat: repeat-x;
+ border-color: #f5e79e;
+}
+
+.alert-danger {
+ background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
+ background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3));
+ background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);
+ background-repeat: repeat-x;
+ border-color: #dca7a7;
+}
+
+.progress {
+ background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
+ background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5));
+ background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);
+ background-repeat: repeat-x;
+}
+
+.progress-bar {
+ background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);
+ background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090));
+ background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);
+ background-repeat: repeat-x;
+}
+
+.progress-bar-success {
+ background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);
+ background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44));
+ background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);
+ background-repeat: repeat-x;
+}
+
+.progress-bar-info {
+ background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
+ background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5));
+ background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);
+ background-repeat: repeat-x;
+}
+
+.progress-bar-warning {
+ background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
+ background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f));
+ background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);
+ background-repeat: repeat-x;
+}
+
+.progress-bar-danger {
+ background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);
+ background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c));
+ background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);
+ background-repeat: repeat-x;
+}
+
+.progress-bar-striped {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+}
+
+.list-group {
+ border-radius: 4px;
+ -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
+ box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
+}
+
+.list-group-item.active,
+.list-group-item.active:hover,
+.list-group-item.active:focus {
+ text-shadow: 0 -1px 0 #286090;
+ background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);
+ background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a));
+ background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);
+ background-repeat: repeat-x;
+ border-color: #2b669a;
+}
+
+.list-group-item.active .badge,
+.list-group-item.active:hover .badge,
+.list-group-item.active:focus .badge {
+ text-shadow: none;
+}
+
+.panel {
+ -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
+ box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
+}
+
+.panel-default > .panel-heading {
+ background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
+ background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
+ background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
+ background-repeat: repeat-x;
+}
+
+.panel-primary > .panel-heading {
+ background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
+ background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
+ background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
+ background-repeat: repeat-x;
+}
+
+.panel-success > .panel-heading {
+ background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
+ background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6));
+ background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);
+ background-repeat: repeat-x;
+}
+
+.panel-info > .panel-heading {
+ background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
+ background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3));
+ background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);
+ background-repeat: repeat-x;
+}
+
+.panel-warning > .panel-heading {
+ background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
+ background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc));
+ background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);
+ background-repeat: repeat-x;
+}
+
+.panel-danger > .panel-heading {
+ background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
+ background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc));
+ background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);
+ background-repeat: repeat-x;
+}
+
+.well {
+ background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
+ background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5));
+ background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);
+ background-repeat: repeat-x;
+ border-color: #dcdcdc;
+ -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
+ box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
+}
+
+/*# sourceMappingURL=bootstrap-theme.css.map */
new file mode 100644
--- /dev/null
+++ b/js/bootstrap/css/bootstrap-theme.css.map
@@ -0,0 +1,20 @@
+{
+ "version": 3,
+ "sources": [
+ "bootstrap-theme.css",
+ "less/theme.less",
+ "less/mixins/vendor-prefixes.less",
+ "less/mixins/gradients.less",
+ "less/mixins/reset-filter.less"
+ ],
+ "names": [],
+ "mappings": "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",
+ "file": "bootstrap-theme.css",
+ "sourcesContent": [
+ "/*!\n * Bootstrap v3.3.5 (http://getbootstrap.com)\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.btn-default:active,\n.btn-primary:active,\n.btn-success:active,\n.btn-info:active,\n.btn-warning:active,\n.btn-danger:active,\n.btn-default.active,\n.btn-primary.active,\n.btn-success.active,\n.btn-info.active,\n.btn-warning.active,\n.btn-danger.active {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-default.disabled,\n.btn-primary.disabled,\n.btn-success.disabled,\n.btn-info.disabled,\n.btn-warning.disabled,\n.btn-danger.disabled,\n.btn-default[disabled],\n.btn-primary[disabled],\n.btn-success[disabled],\n.btn-info[disabled],\n.btn-warning[disabled],\n.btn-danger[disabled],\nfieldset[disabled] .btn-default,\nfieldset[disabled] .btn-primary,\nfieldset[disabled] .btn-success,\nfieldset[disabled] .btn-info,\nfieldset[disabled] .btn-warning,\nfieldset[disabled] .btn-danger {\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-default .badge,\n.btn-primary .badge,\n.btn-success .badge,\n.btn-info .badge,\n.btn-warning .badge,\n.btn-danger .badge {\n text-shadow: none;\n}\n.btn:active,\n.btn.active {\n background-image: none;\n}\n.btn-default {\n background-image: -webkit-linear-gradient(top, #ffffff 0%, #e0e0e0 100%);\n background-image: -o-linear-gradient(top, #ffffff 0%, #e0e0e0 100%);\n background-image: linear-gradient(to bottom, #ffffff 0%, #e0e0e0 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #dbdbdb;\n text-shadow: 0 1px 0 #fff;\n border-color: #ccc;\n}\n.btn-default:hover,\n.btn-default:focus {\n background-color: #e0e0e0;\n background-position: 0 -15px;\n}\n.btn-default:active,\n.btn-default.active {\n background-color: #e0e0e0;\n border-color: #dbdbdb;\n}\n.btn-default.disabled,\n.btn-default[disabled],\nfieldset[disabled] .btn-default,\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus,\n.btn-default.disabled:active,\n.btn-default[disabled]:active,\nfieldset[disabled] .btn-default:active,\n.btn-default.disabled.active,\n.btn-default[disabled].active,\nfieldset[disabled] .btn-default.active {\n background-color: #e0e0e0;\n background-image: none;\n}\n.btn-primary {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #245580;\n}\n.btn-primary:hover,\n.btn-primary:focus {\n background-color: #265a88;\n background-position: 0 -15px;\n}\n.btn-primary:active,\n.btn-primary.active {\n background-color: #265a88;\n border-color: #245580;\n}\n.btn-primary.disabled,\n.btn-primary[disabled],\nfieldset[disabled] .btn-primary,\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus,\n.btn-primary.disabled:active,\n.btn-primary[disabled]:active,\nfieldset[disabled] .btn-primary:active,\n.btn-primary.disabled.active,\n.btn-primary[disabled].active,\nfieldset[disabled] .btn-primary.active {\n background-color: #265a88;\n background-image: none;\n}\n.btn-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #3e8f3e;\n}\n.btn-success:hover,\n.btn-success:focus {\n background-color: #419641;\n background-position: 0 -15px;\n}\n.btn-success:active,\n.btn-success.active {\n background-color: #419641;\n border-color: #3e8f3e;\n}\n.btn-success.disabled,\n.btn-success[disabled],\nfieldset[disabled] .btn-success,\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus,\n.btn-success.disabled:active,\n.btn-success[disabled]:active,\nfieldset[disabled] .btn-success:active,\n.btn-success.disabled.active,\n.btn-success[disabled].active,\nfieldset[disabled] .btn-success.active {\n background-color: #419641;\n background-image: none;\n}\n.btn-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #28a4c9;\n}\n.btn-info:hover,\n.btn-info:focus {\n background-color: #2aabd2;\n background-position: 0 -15px;\n}\n.btn-info:active,\n.btn-info.active {\n background-color: #2aabd2;\n border-color: #28a4c9;\n}\n.btn-info.disabled,\n.btn-info[disabled],\nfieldset[disabled] .btn-info,\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus,\n.btn-info.disabled:active,\n.btn-info[disabled]:active,\nfieldset[disabled] .btn-info:active,\n.btn-info.disabled.active,\n.btn-info[disabled].active,\nfieldset[disabled] .btn-info.active {\n background-color: #2aabd2;\n background-image: none;\n}\n.btn-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #e38d13;\n}\n.btn-warning:hover,\n.btn-warning:focus {\n background-color: #eb9316;\n background-position: 0 -15px;\n}\n.btn-warning:active,\n.btn-warning.active {\n background-color: #eb9316;\n border-color: #e38d13;\n}\n.btn-warning.disabled,\n.btn-warning[disabled],\nfieldset[disabled] .btn-warning,\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus,\n.btn-warning.disabled:active,\n.btn-warning[disabled]:active,\nfieldset[disabled] .btn-warning:active,\n.btn-warning.disabled.active,\n.btn-warning[disabled].active,\nfieldset[disabled] .btn-warning.active {\n background-color: #eb9316;\n background-image: none;\n}\n.btn-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #b92c28;\n}\n.btn-danger:hover,\n.btn-danger:focus {\n background-color: #c12e2a;\n background-position: 0 -15px;\n}\n.btn-danger:active,\n.btn-danger.active {\n background-color: #c12e2a;\n border-color: #b92c28;\n}\n.btn-danger.disabled,\n.btn-danger[disabled],\nfieldset[disabled] .btn-danger,\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus,\n.btn-danger.disabled:active,\n.btn-danger[disabled]:active,\nfieldset[disabled] .btn-danger:active,\n.btn-danger.disabled.active,\n.btn-danger[disabled].active,\nfieldset[disabled] .btn-danger.active {\n background-color: #c12e2a;\n background-image: none;\n}\n.thumbnail,\n.img-thumbnail {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n background-color: #e8e8e8;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n background-color: #2e6da4;\n}\n.navbar-default {\n background-image: -webkit-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: -o-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: linear-gradient(to bottom, #ffffff 0%, #f8f8f8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);\n}\n.navbar-inverse {\n background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222222 100%);\n background-image: -o-linear-gradient(top, #3c3c3c 0%, #222222 100%);\n background-image: linear-gradient(to bottom, #3c3c3c 0%, #222222 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n border-radius: 4px;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n}\n.navbar-inverse .navbar-brand,\n.navbar-inverse .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n@media (max-width: 767px) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n }\n}\n.alert {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.alert-success {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);\n border-color: #b2dba1;\n}\n.alert-info {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);\n border-color: #9acfea;\n}\n.alert-warning {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);\n border-color: #f5e79e;\n}\n.alert-danger {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);\n border-color: #dca7a7;\n}\n.progress {\n background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);\n}\n.progress-bar {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);\n}\n.progress-bar-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);\n}\n.progress-bar-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);\n}\n.progress-bar-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);\n}\n.progress-bar-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);\n}\n.progress-bar-striped {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.list-group {\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 #286090;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);\n border-color: #2b669a;\n}\n.list-group-item.active .badge,\n.list-group-item.active:hover .badge,\n.list-group-item.active:focus .badge {\n text-shadow: none;\n}\n.panel {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.panel-default > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n}\n.panel-primary > .panel-heading {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n}\n.panel-success > .panel-heading {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);\n}\n.panel-info > .panel-heading {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);\n}\n.panel-warning > .panel-heading {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);\n}\n.panel-danger > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);\n}\n.well {\n background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);\n border-color: #dcdcdc;\n -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n}\n/*# sourceMappingURL=bootstrap-theme.css.map */",
+ "/*!\n * Bootstrap v3.3.5 (http://getbootstrap.com)\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n@import \"variables.less\";\n@import \"mixins.less\";\n\n\n//\n// Buttons\n// --------------------------------------------------\n\n// Common styles\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0,0,0,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n // Reset the shadow\n &:active,\n &.active {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n .box-shadow(none);\n }\n\n .badge {\n text-shadow: none;\n }\n}\n\n// Mixin for generating new styles\n.btn-styles(@btn-color: #555) {\n #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));\n .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners; see https://github.com/twbs/bootstrap/issues/10620\n background-repeat: repeat-x;\n border-color: darken(@btn-color, 14%);\n\n &:hover,\n &:focus {\n background-color: darken(@btn-color, 12%);\n background-position: 0 -15px;\n }\n\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n border-color: darken(@btn-color, 14%);\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &,\n &:hover,\n &:focus,\n &.focus,\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n background-image: none;\n }\n }\n}\n\n// Common styles\n.btn {\n // Remove the gradient for the pressed/active state\n &:active,\n &.active {\n background-image: none;\n }\n}\n\n// Apply the mixin to the buttons\n.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }\n.btn-primary { .btn-styles(@btn-primary-bg); }\n.btn-success { .btn-styles(@btn-success-bg); }\n.btn-info { .btn-styles(@btn-info-bg); }\n.btn-warning { .btn-styles(@btn-warning-bg); }\n.btn-danger { .btn-styles(@btn-danger-bg); }\n\n\n//\n// Images\n// --------------------------------------------------\n\n.thumbnail,\n.img-thumbnail {\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n\n\n//\n// Dropdowns\n// --------------------------------------------------\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));\n background-color: darken(@dropdown-link-hover-bg, 5%);\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n background-color: darken(@dropdown-link-active-bg, 5%);\n}\n\n\n//\n// Navbar\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n border-radius: @navbar-border-radius;\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: darken(@navbar-default-link-active-bg, 5%); @end-color: darken(@navbar-default-link-active-bg, 2%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));\n }\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255,255,255,.25);\n}\n\n// Inverted navbar\n.navbar-inverse {\n #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered; see https://github.com/twbs/bootstrap/issues/10257\n border-radius: @navbar-border-radius;\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: @navbar-inverse-link-active-bg; @end-color: lighten(@navbar-inverse-link-active-bg, 2.5%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));\n }\n\n .navbar-brand,\n .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0,0,0,.25);\n }\n}\n\n// Undo rounded corners in static and fixed navbars\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n\n// Fix active state of dropdown items in collapsed mode\n@media (max-width: @grid-float-breakpoint-max) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: #fff;\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n }\n }\n}\n\n\n//\n// Alerts\n// --------------------------------------------------\n\n// Common styles\n.alert {\n text-shadow: 0 1px 0 rgba(255,255,255,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);\n .box-shadow(@shadow);\n}\n\n// Mixin for generating new styles\n.alert-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));\n border-color: darken(@color, 15%);\n}\n\n// Apply the mixin to the alerts\n.alert-success { .alert-styles(@alert-success-bg); }\n.alert-info { .alert-styles(@alert-info-bg); }\n.alert-warning { .alert-styles(@alert-warning-bg); }\n.alert-danger { .alert-styles(@alert-danger-bg); }\n\n\n//\n// Progress bars\n// --------------------------------------------------\n\n// Give the progress background some depth\n.progress {\n #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)\n}\n\n// Mixin for generating new styles\n.progress-bar-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));\n}\n\n// Apply the mixin to the progress bars\n.progress-bar { .progress-bar-styles(@progress-bar-bg); }\n.progress-bar-success { .progress-bar-styles(@progress-bar-success-bg); }\n.progress-bar-info { .progress-bar-styles(@progress-bar-info-bg); }\n.progress-bar-warning { .progress-bar-styles(@progress-bar-warning-bg); }\n.progress-bar-danger { .progress-bar-styles(@progress-bar-danger-bg); }\n\n// Reset the striped class because our mixins don't do multiple gradients and\n// the above custom styles override the new `.progress-bar-striped` in v3.2.0.\n.progress-bar-striped {\n #gradient > .striped();\n}\n\n\n//\n// List groups\n// --------------------------------------------------\n\n.list-group {\n border-radius: @border-radius-base;\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);\n #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));\n border-color: darken(@list-group-active-border, 7.5%);\n\n .badge {\n text-shadow: none;\n }\n}\n\n\n//\n// Panels\n// --------------------------------------------------\n\n// Common styles\n.panel {\n .box-shadow(0 1px 2px rgba(0,0,0,.05));\n}\n\n// Mixin for generating new styles\n.panel-heading-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));\n}\n\n// Apply the mixin to the panel headings only\n.panel-default > .panel-heading { .panel-heading-styles(@panel-default-heading-bg); }\n.panel-primary > .panel-heading { .panel-heading-styles(@panel-primary-heading-bg); }\n.panel-success > .panel-heading { .panel-heading-styles(@panel-success-heading-bg); }\n.panel-info > .panel-heading { .panel-heading-styles(@panel-info-heading-bg); }\n.panel-warning > .panel-heading { .panel-heading-styles(@panel-warning-heading-bg); }\n.panel-danger > .panel-heading { .panel-heading-styles(@panel-danger-heading-bg); }\n\n\n//\n// Wells\n// --------------------------------------------------\n\n.well {\n #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);\n border-color: darken(@well-bg, 10%);\n @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n}\n",
+ "// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They will be removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility){\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n",
+ "// Gradients\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n",
+ "// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n"
+ ]
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/js/bootstrap/css/bootstrap-theme.min.css
@@ -0,0 +1,479 @@
+/*!
+ * Bootstrap v3.3.5 (http://getbootstrap.com)
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+.btn-danger, .btn-default, .btn-info, .btn-primary, .btn-success, .btn-warning {
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, .2);
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075)
+}
+
+.btn-danger.active, .btn-danger:active, .btn-default.active, .btn-default:active, .btn-info.active, .btn-info:active, .btn-primary.active, .btn-primary:active, .btn-success.active, .btn-success:active, .btn-warning.active, .btn-warning:active {
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125)
+}
+
+.btn-danger.disabled, .btn-danger[disabled], .btn-default.disabled, .btn-default[disabled], .btn-info.disabled, .btn-info[disabled], .btn-primary.disabled, .btn-primary[disabled], .btn-success.disabled, .btn-success[disabled], .btn-warning.disabled, .btn-warning[disabled], fieldset[disabled] .btn-danger, fieldset[disabled] .btn-default, fieldset[disabled] .btn-info, fieldset[disabled] .btn-primary, fieldset[disabled] .btn-success, fieldset[disabled] .btn-warning {
+ -webkit-box-shadow: none;
+ box-shadow: none
+}
+
+.btn-danger .badge, .btn-default .badge, .btn-info .badge, .btn-primary .badge, .btn-success .badge, .btn-warning .badge {
+ text-shadow: none
+}
+
+.btn.active, .btn:active {
+ background-image: none
+}
+
+.btn-default {
+ text-shadow: 0 1px 0 #fff;
+ background-image: -webkit-linear-gradient(top, #fff 0, #e0e0e0 100%);
+ background-image: -o-linear-gradient(top, #fff 0, #e0e0e0 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0));
+ background-image: linear-gradient(to bottom, #fff 0, #e0e0e0 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+ background-repeat: repeat-x;
+ border-color: #dbdbdb;
+ border-color: #ccc
+}
+
+.btn-default:focus, .btn-default:hover {
+ background-color: #e0e0e0;
+ background-position: 0 -15px
+}
+
+.btn-default.active, .btn-default:active {
+ background-color: #e0e0e0;
+ border-color: #dbdbdb
+}
+
+.btn-default.disabled, .btn-default.disabled.active, .btn-default.disabled.focus, .btn-default.disabled:active, .btn-default.disabled:focus, .btn-default.disabled:hover, .btn-default[disabled], .btn-default[disabled].active, .btn-default[disabled].focus, .btn-default[disabled]:active, .btn-default[disabled]:focus, .btn-default[disabled]:hover, fieldset[disabled] .btn-default, fieldset[disabled] .btn-default.active, fieldset[disabled] .btn-default.focus, fieldset[disabled] .btn-default:active, fieldset[disabled] .btn-default:focus, fieldset[disabled] .btn-default:hover {
+ background-color: #e0e0e0;
+ background-image: none
+}
+
+.btn-primary {
+ background-image: -webkit-linear-gradient(top, #337ab7 0, #265a88 100%);
+ background-image: -o-linear-gradient(top, #337ab7 0, #265a88 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88));
+ background-image: linear-gradient(to bottom, #337ab7 0, #265a88 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+ background-repeat: repeat-x;
+ border-color: #245580
+}
+
+.btn-primary:focus, .btn-primary:hover {
+ background-color: #265a88;
+ background-position: 0 -15px
+}
+
+.btn-primary.active, .btn-primary:active {
+ background-color: #265a88;
+ border-color: #245580
+}
+
+.btn-primary.disabled, .btn-primary.disabled.active, .btn-primary.disabled.focus, .btn-primary.disabled:active, .btn-primary.disabled:focus, .btn-primary.disabled:hover, .btn-primary[disabled], .btn-primary[disabled].active, .btn-primary[disabled].focus, .btn-primary[disabled]:active, .btn-primary[disabled]:focus, .btn-primary[disabled]:hover, fieldset[disabled] .btn-primary, fieldset[disabled] .btn-primary.active, fieldset[disabled] .btn-primary.focus, fieldset[disabled] .btn-primary:active, fieldset[disabled] .btn-primary:focus, fieldset[disabled] .btn-primary:hover {
+ background-color: #265a88;
+ background-image: none
+}
+
+.btn-success {
+ background-image: -webkit-linear-gradient(top, #5cb85c 0, #419641 100%);
+ background-image: -o-linear-gradient(top, #5cb85c 0, #419641 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641));
+ background-image: linear-gradient(to bottom, #5cb85c 0, #419641 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+ background-repeat: repeat-x;
+ border-color: #3e8f3e
+}
+
+.btn-success:focus, .btn-success:hover {
+ background-color: #419641;
+ background-position: 0 -15px
+}
+
+.btn-success.active, .btn-success:active {
+ background-color: #419641;
+ border-color: #3e8f3e
+}
+
+.btn-success.disabled, .btn-success.disabled.active, .btn-success.disabled.focus, .btn-success.disabled:active, .btn-success.disabled:focus, .btn-success.disabled:hover, .btn-success[disabled], .btn-success[disabled].active, .btn-success[disabled].focus, .btn-success[disabled]:active, .btn-success[disabled]:focus, .btn-success[disabled]:hover, fieldset[disabled] .btn-success, fieldset[disabled] .btn-success.active, fieldset[disabled] .btn-success.focus, fieldset[disabled] .btn-success:active, fieldset[disabled] .btn-success:focus, fieldset[disabled] .btn-success:hover {
+ background-color: #419641;
+ background-image: none
+}
+
+.btn-info {
+ background-image: -webkit-linear-gradient(top, #5bc0de 0, #2aabd2 100%);
+ background-image: -o-linear-gradient(top, #5bc0de 0, #2aabd2 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2));
+ background-image: linear-gradient(to bottom, #5bc0de 0, #2aabd2 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+ background-repeat: repeat-x;
+ border-color: #28a4c9
+}
+
+.btn-info:focus, .btn-info:hover {
+ background-color: #2aabd2;
+ background-position: 0 -15px
+}
+
+.btn-info.active, .btn-info:active {
+ background-color: #2aabd2;
+ border-color: #28a4c9
+}
+
+.btn-info.disabled, .btn-info.disabled.active, .btn-info.disabled.focus, .btn-info.disabled:active, .btn-info.disabled:focus, .btn-info.disabled:hover, .btn-info[disabled], .btn-info[disabled].active, .btn-info[disabled].focus, .btn-info[disabled]:active, .btn-info[disabled]:focus, .btn-info[disabled]:hover, fieldset[disabled] .btn-info, fieldset[disabled] .btn-info.active, fieldset[disabled] .btn-info.focus, fieldset[disabled] .btn-info:active, fieldset[disabled] .btn-info:focus, fieldset[disabled] .btn-info:hover {
+ background-color: #2aabd2;
+ background-image: none
+}
+
+.btn-warning {
+ background-image: -webkit-linear-gradient(top, #f0ad4e 0, #eb9316 100%);
+ background-image: -o-linear-gradient(top, #f0ad4e 0, #eb9316 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316));
+ background-image: linear-gradient(to bottom, #f0ad4e 0, #eb9316 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+ background-repeat: repeat-x;
+ border-color: #e38d13
+}
+
+.btn-warning:focus, .btn-warning:hover {
+ background-color: #eb9316;
+ background-position: 0 -15px
+}
+
+.btn-warning.active, .btn-warning:active {
+ background-color: #eb9316;
+ border-color: #e38d13
+}
+
+.btn-warning.disabled, .btn-warning.disabled.active, .btn-warning.disabled.focus, .btn-warning.disabled:active, .btn-warning.disabled:focus, .btn-warning.disabled:hover, .btn-warning[disabled], .btn-warning[disabled].active, .btn-warning[disabled].focus, .btn-warning[disabled]:active, .btn-warning[disabled]:focus, .btn-warning[disabled]:hover, fieldset[disabled] .btn-warning, fieldset[disabled] .btn-warning.active, fieldset[disabled] .btn-warning.focus, fieldset[disabled] .btn-warning:active, fieldset[disabled] .btn-warning:focus, fieldset[disabled] .btn-warning:hover {
+ background-color: #eb9316;
+ background-image: none
+}
+
+.btn-danger {
+ background-image: -webkit-linear-gradient(top, #d9534f 0, #c12e2a 100%);
+ background-image: -o-linear-gradient(top, #d9534f 0, #c12e2a 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a));
+ background-image: linear-gradient(to bottom, #d9534f 0, #c12e2a 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+ background-repeat: repeat-x;
+ border-color: #b92c28
+}
+
+.btn-danger:focus, .btn-danger:hover {
+ background-color: #c12e2a;
+ background-position: 0 -15px
+}
+
+.btn-danger.active, .btn-danger:active {
+ background-color: #c12e2a;
+ border-color: #b92c28
+}
+
+.btn-danger.disabled, .btn-danger.disabled.active, .btn-danger.disabled.focus, .btn-danger.disabled:active, .btn-danger.disabled:focus, .btn-danger.disabled:hover, .btn-danger[disabled], .btn-danger[disabled].active, .btn-danger[disabled].focus, .btn-danger[disabled]:active, .btn-danger[disabled]:focus, .btn-danger[disabled]:hover, fieldset[disabled] .btn-danger, fieldset[disabled] .btn-danger.active, fieldset[disabled] .btn-danger.focus, fieldset[disabled] .btn-danger:active, fieldset[disabled] .btn-danger:focus, fieldset[disabled] .btn-danger:hover {
+ background-color: #c12e2a;
+ background-image: none
+}
+
+.img-thumbnail, .thumbnail {
+ -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
+ box-shadow: 0 1px 2px rgba(0, 0, 0, .075)
+}
+
+.dropdown-menu > li > a:focus, .dropdown-menu > li > a:hover {
+ background-color: #e8e8e8;
+ background-image: -webkit-linear-gradient(top, #f5f5f5 0, #e8e8e8 100%);
+ background-image: -o-linear-gradient(top, #f5f5f5 0, #e8e8e8 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
+ background-image: linear-gradient(to bottom, #f5f5f5 0, #e8e8e8 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
+ background-repeat: repeat-x
+}
+
+.dropdown-menu > .active > a, .dropdown-menu > .active > a:focus, .dropdown-menu > .active > a:hover {
+ background-color: #2e6da4;
+ background-image: -webkit-linear-gradient(top, #337ab7 0, #2e6da4 100%);
+ background-image: -o-linear-gradient(top, #337ab7 0, #2e6da4 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
+ background-image: linear-gradient(to bottom, #337ab7 0, #2e6da4 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
+ background-repeat: repeat-x
+}
+
+.navbar-default {
+ background-image: -webkit-linear-gradient(top, #fff 0, #f8f8f8 100%);
+ background-image: -o-linear-gradient(top, #fff 0, #f8f8f8 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8));
+ background-image: linear-gradient(to bottom, #fff 0, #f8f8f8 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+ background-repeat: repeat-x;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075)
+}
+
+.navbar-default .navbar-nav > .active > a, .navbar-default .navbar-nav > .open > a {
+ background-image: -webkit-linear-gradient(top, #dbdbdb 0, #e2e2e2 100%);
+ background-image: -o-linear-gradient(top, #dbdbdb 0, #e2e2e2 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2));
+ background-image: linear-gradient(to bottom, #dbdbdb 0, #e2e2e2 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);
+ background-repeat: repeat-x;
+ -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075)
+}
+
+.navbar-brand, .navbar-nav > li > a {
+ text-shadow: 0 1px 0 rgba(255, 255, 255, .25)
+}
+
+.navbar-inverse {
+ background-image: -webkit-linear-gradient(top, #3c3c3c 0, #222 100%);
+ background-image: -o-linear-gradient(top, #3c3c3c 0, #222 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222));
+ background-image: linear-gradient(to bottom, #3c3c3c 0, #222 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+ background-repeat: repeat-x;
+ border-radius: 4px
+}
+
+.navbar-inverse .navbar-nav > .active > a, .navbar-inverse .navbar-nav > .open > a {
+ background-image: -webkit-linear-gradient(top, #080808 0, #0f0f0f 100%);
+ background-image: -o-linear-gradient(top, #080808 0, #0f0f0f 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f));
+ background-image: linear-gradient(to bottom, #080808 0, #0f0f0f 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);
+ background-repeat: repeat-x;
+ -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
+ box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25)
+}
+
+.navbar-inverse .navbar-brand, .navbar-inverse .navbar-nav > li > a {
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, .25)
+}
+
+.navbar-fixed-bottom, .navbar-fixed-top, .navbar-static-top {
+ border-radius: 0
+}
+
+@media (max-width: 767px) {
+ .navbar .navbar-nav .open .dropdown-menu > .active > a, .navbar .navbar-nav .open .dropdown-menu > .active > a:focus, .navbar .navbar-nav .open .dropdown-menu > .active > a:hover {
+ color: #fff;
+ background-image: -webkit-linear-gradient(top, #337ab7 0, #2e6da4 100%);
+ background-image: -o-linear-gradient(top, #337ab7 0, #2e6da4 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
+ background-image: linear-gradient(to bottom, #337ab7 0, #2e6da4 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
+ background-repeat: repeat-x
+ }
+}
+
+.alert {
+ text-shadow: 0 1px 0 rgba(255, 255, 255, .2);
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05)
+}
+
+.alert-success {
+ background-image: -webkit-linear-gradient(top, #dff0d8 0, #c8e5bc 100%);
+ background-image: -o-linear-gradient(top, #dff0d8 0, #c8e5bc 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc));
+ background-image: linear-gradient(to bottom, #dff0d8 0, #c8e5bc 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);
+ background-repeat: repeat-x;
+ border-color: #b2dba1
+}
+
+.alert-info {
+ background-image: -webkit-linear-gradient(top, #d9edf7 0, #b9def0 100%);
+ background-image: -o-linear-gradient(top, #d9edf7 0, #b9def0 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0));
+ background-image: linear-gradient(to bottom, #d9edf7 0, #b9def0 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);
+ background-repeat: repeat-x;
+ border-color: #9acfea
+}
+
+.alert-warning {
+ background-image: -webkit-linear-gradient(top, #fcf8e3 0, #f8efc0 100%);
+ background-image: -o-linear-gradient(top, #fcf8e3 0, #f8efc0 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0));
+ background-image: linear-gradient(to bottom, #fcf8e3 0, #f8efc0 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);
+ background-repeat: repeat-x;
+ border-color: #f5e79e
+}
+
+.alert-danger {
+ background-image: -webkit-linear-gradient(top, #f2dede 0, #e7c3c3 100%);
+ background-image: -o-linear-gradient(top, #f2dede 0, #e7c3c3 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3));
+ background-image: linear-gradient(to bottom, #f2dede 0, #e7c3c3 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);
+ background-repeat: repeat-x;
+ border-color: #dca7a7
+}
+
+.progress {
+ background-image: -webkit-linear-gradient(top, #ebebeb 0, #f5f5f5 100%);
+ background-image: -o-linear-gradient(top, #ebebeb 0, #f5f5f5 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5));
+ background-image: linear-gradient(to bottom, #ebebeb 0, #f5f5f5 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);
+ background-repeat: repeat-x
+}
+
+.progress-bar {
+ background-image: -webkit-linear-gradient(top, #337ab7 0, #286090 100%);
+ background-image: -o-linear-gradient(top, #337ab7 0, #286090 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090));
+ background-image: linear-gradient(to bottom, #337ab7 0, #286090 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);
+ background-repeat: repeat-x
+}
+
+.progress-bar-success {
+ background-image: -webkit-linear-gradient(top, #5cb85c 0, #449d44 100%);
+ background-image: -o-linear-gradient(top, #5cb85c 0, #449d44 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44));
+ background-image: linear-gradient(to bottom, #5cb85c 0, #449d44 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);
+ background-repeat: repeat-x
+}
+
+.progress-bar-info {
+ background-image: -webkit-linear-gradient(top, #5bc0de 0, #31b0d5 100%);
+ background-image: -o-linear-gradient(top, #5bc0de 0, #31b0d5 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5));
+ background-image: linear-gradient(to bottom, #5bc0de 0, #31b0d5 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);
+ background-repeat: repeat-x
+}
+
+.progress-bar-warning {
+ background-image: -webkit-linear-gradient(top, #f0ad4e 0, #ec971f 100%);
+ background-image: -o-linear-gradient(top, #f0ad4e 0, #ec971f 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f));
+ background-image: linear-gradient(to bottom, #f0ad4e 0, #ec971f 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);
+ background-repeat: repeat-x
+}
+
+.progress-bar-danger {
+ background-image: -webkit-linear-gradient(top, #d9534f 0, #c9302c 100%);
+ background-image: -o-linear-gradient(top, #d9534f 0, #c9302c 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c));
+ background-image: linear-gradient(to bottom, #d9534f 0, #c9302c 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);
+ background-repeat: repeat-x
+}
+
+.progress-bar-striped {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent)
+}
+
+.list-group {
+ border-radius: 4px;
+ -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
+ box-shadow: 0 1px 2px rgba(0, 0, 0, .075)
+}
+
+.list-group-item.active, .list-group-item.active:focus, .list-group-item.active:hover {
+ text-shadow: 0 -1px 0 #286090;
+ background-image: -webkit-linear-gradient(top, #337ab7 0, #2b669a 100%);
+ background-image: -o-linear-gradient(top, #337ab7 0, #2b669a 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a));
+ background-image: linear-gradient(to bottom, #337ab7 0, #2b669a 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);
+ background-repeat: repeat-x;
+ border-color: #2b669a
+}
+
+.list-group-item.active .badge, .list-group-item.active:focus .badge, .list-group-item.active:hover .badge {
+ text-shadow: none
+}
+
+.panel {
+ -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
+ box-shadow: 0 1px 2px rgba(0, 0, 0, .05)
+}
+
+.panel-default > .panel-heading {
+ background-image: -webkit-linear-gradient(top, #f5f5f5 0, #e8e8e8 100%);
+ background-image: -o-linear-gradient(top, #f5f5f5 0, #e8e8e8 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
+ background-image: linear-gradient(to bottom, #f5f5f5 0, #e8e8e8 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
+ background-repeat: repeat-x
+}
+
+.panel-primary > .panel-heading {
+ background-image: -webkit-linear-gradient(top, #337ab7 0, #2e6da4 100%);
+ background-image: -o-linear-gradient(top, #337ab7 0, #2e6da4 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
+ background-image: linear-gradient(to bottom, #337ab7 0, #2e6da4 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
+ background-repeat: repeat-x
+}
+
+.panel-success > .panel-heading {
+ background-image: -webkit-linear-gradient(top, #dff0d8 0, #d0e9c6 100%);
+ background-image: -o-linear-gradient(top, #dff0d8 0, #d0e9c6 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6));
+ background-image: linear-gradient(to bottom, #dff0d8 0, #d0e9c6 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);
+ background-repeat: repeat-x
+}
+
+.panel-info > .panel-heading {
+ background-image: -webkit-linear-gradient(top, #d9edf7 0, #c4e3f3 100%);
+ background-image: -o-linear-gradient(top, #d9edf7 0, #c4e3f3 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3));
+ background-image: linear-gradient(to bottom, #d9edf7 0, #c4e3f3 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);
+ background-repeat: repeat-x
+}
+
+.panel-warning > .panel-heading {
+ background-image: -webkit-linear-gradient(top, #fcf8e3 0, #faf2cc 100%);
+ background-image: -o-linear-gradient(top, #fcf8e3 0, #faf2cc 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc));
+ background-image: linear-gradient(to bottom, #fcf8e3 0, #faf2cc 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);
+ background-repeat: repeat-x
+}
+
+.panel-danger > .panel-heading {
+ background-image: -webkit-linear-gradient(top, #f2dede 0, #ebcccc 100%);
+ background-image: -o-linear-gradient(top, #f2dede 0, #ebcccc 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc));
+ background-image: linear-gradient(to bottom, #f2dede 0, #ebcccc 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);
+ background-repeat: repeat-x
+}
+
+.well {
+ background-image: -webkit-linear-gradient(top, #e8e8e8 0, #f5f5f5 100%);
+ background-image: -o-linear-gradient(top, #e8e8e8 0, #f5f5f5 100%);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5));
+ background-image: linear-gradient(to bottom, #e8e8e8 0, #f5f5f5 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);
+ background-repeat: repeat-x;
+ border-color: #dcdcdc;
+ -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
+ box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1)
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/js/bootstrap/css/bootstrap.css
@@ -0,0 +1,8239 @@
+/*!
+ * Bootstrap v3.3.5 (http://getbootstrap.com)
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
+html {
+ font-family: sans-serif;
+ -webkit-text-size-adjust: 100%;
+ -ms-text-size-adjust: 100%;
+}
+
+body {
+ margin: 0;
+}
+
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+menu,
+nav,
+section,
+summary {
+ display: block;
+}
+
+audio,
+canvas,
+progress,
+video {
+ display: inline-block;
+ vertical-align: baseline;
+}
+
+audio:not([controls]) {
+ display: none;
+ height: 0;
+}
+
+[hidden],
+template {
+ display: none;
+}
+
+a {
+ background-color: transparent;
+}
+
+a:active,
+a:hover {
+ outline: 0;
+}
+
+abbr[title] {
+ border-bottom: 1px dotted;
+}
+
+b,
+strong {
+ font-weight: bold;
+}
+
+dfn {
+ font-style: italic;
+}
+
+h1 {
+ margin: .67em 0;
+ font-size: 2em;
+}
+
+mark {
+ color: #000;
+ background: #ff0;
+}
+
+small {
+ font-size: 80%;
+}
+
+sub,
+sup {
+ position: relative;
+ font-size: 75%;
+ line-height: 0;
+ vertical-align: baseline;
+}
+
+sup {
+ top: -.5em;
+}
+
+sub {
+ bottom: -.25em;
+}
+
+img {
+ border: 0;
+}
+
+svg:not(:root) {
+ overflow: hidden;
+}
+
+figure {
+ margin: 1em 40px;
+}
+
+hr {
+ height: 0;
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+}
+
+pre {
+ overflow: auto;
+}
+
+code,
+kbd,
+pre,
+samp {
+ font-family: monospace, monospace;
+ font-size: 1em;
+}
+
+button,
+input,
+optgroup,
+select,
+textarea {
+ margin: 0;
+ font: inherit;
+ color: inherit;
+}
+
+button {
+ overflow: visible;
+}
+
+button,
+select {
+ text-transform: none;
+}
+
+button,
+html input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+ -webkit-appearance: button;
+ cursor: pointer;
+}
+
+button[disabled],
+html input[disabled] {
+ cursor: default;
+}
+
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+ padding: 0;
+ border: 0;
+}
+
+input {
+ line-height: normal;
+}
+
+input[type="checkbox"],
+input[type="radio"] {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ padding: 0;
+}
+
+input[type="number"]::-webkit-inner-spin-button,
+input[type="number"]::-webkit-outer-spin-button {
+ height: auto;
+}
+
+input[type="search"] {
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+ -webkit-appearance: textfield;
+}
+
+input[type="search"]::-webkit-search-cancel-button,
+input[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+fieldset {
+ padding: .35em .625em .75em;
+ margin: 0 2px;
+ border: 1px solid #c0c0c0;
+}
+
+legend {
+ padding: 0;
+ border: 0;
+}
+
+textarea {
+ overflow: auto;
+}
+
+optgroup {
+ font-weight: bold;
+}
+
+table {
+ border-spacing: 0;
+ border-collapse: collapse;
+}
+
+td,
+th {
+ padding: 0;
+}
+
+/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */
+@media print {
+ *,
+ *:before,
+ *:after {
+ color: #000 !important;
+ text-shadow: none !important;
+ background: transparent !important;
+ -webkit-box-shadow: none !important;
+ box-shadow: none !important;
+ }
+
+ a,
+ a:visited {
+ text-decoration: underline;
+ }
+
+ a[href]:after {
+ content: " (" attr(href) ")";
+ }
+
+ abbr[title]:after {
+ content: " (" attr(title) ")";
+ }
+
+ a[href^="#"]:after,
+ a[href^="javascript:"]:after {
+ content: "";
+ }
+
+ pre,
+ blockquote {
+ border: 1px solid #999;
+
+ page-break-inside: avoid;
+ }
+
+ thead {
+ display: table-header-group;
+ }
+
+ tr,
+ img {
+ page-break-inside: avoid;
+ }
+
+ img {
+ max-width: 100% !important;
+ }
+
+ p,
+ h2,
+ h3 {
+ orphans: 3;
+ widows: 3;
+ }
+
+ h2,
+ h3 {
+ page-break-after: avoid;
+ }
+
+ .navbar {
+ display: none;
+ }
+
+ .btn > .caret,
+ .dropup > .btn > .caret {
+ border-top-color: #000 !important;
+ }
+
+ .label {
+ border: 1px solid #000;
+ }
+
+ .table {
+ border-collapse: collapse !important;
+ }
+
+ .table td,
+ .table th {
+ background-color: #fff !important;
+ }
+
+ .table-bordered th,
+ .table-bordered td {
+ border: 1px solid #ddd !important;
+ }
+}
+
+@font-face {
+ font-family: 'Glyphicons Halflings';
+
+ src: url('../fonts/glyphicons-halflings-regular.eot');
+ src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
+}
+
+.glyphicon {
+ position: relative;
+ top: 1px;
+ display: inline-block;
+ font-family: 'Glyphicons Halflings';
+ font-style: normal;
+ font-weight: normal;
+ line-height: 1;
+
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.glyphicon-asterisk:before {
+ content: "\2a";
+}
+
+.glyphicon-plus:before {
+ content: "\2b";
+}
+
+.glyphicon-euro:before,
+.glyphicon-eur:before {
+ content: "\20ac";
+}
+
+.glyphicon-minus:before {
+ content: "\2212";
+}
+
+.glyphicon-cloud:before {
+ content: "\2601";
+}
+
+.glyphicon-envelope:before {
+ content: "\2709";
+}
+
+.glyphicon-pencil:before {
+ content: "\270f";
+}
+
+.glyphicon-glass:before {
+ content: "\e001";
+}
+
+.glyphicon-music:before {
+ content: "\e002";
+}
+
+.glyphicon-search:before {
+ content: "\e003";
+}
+
+.glyphicon-heart:before {
+ content: "\e005";
+}
+
+.glyphicon-star:before {
+ content: "\e006";
+}
+
+.glyphicon-star-empty:before {
+ content: "\e007";
+}
+
+.glyphicon-user:before {
+ content: "\e008";
+}
+
+.glyphicon-film:before {
+ content: "\e009";
+}
+
+.glyphicon-th-large:before {
+ content: "\e010";
+}
+
+.glyphicon-th:before {
+ content: "\e011";
+}
+
+.glyphicon-th-list:before {
+ content: "\e012";
+}
+
+.glyphicon-ok:before {
+ content: "\e013";
+}
+
+.glyphicon-remove:before {
+ content: "\e014";
+}
+
+.glyphicon-zoom-in:before {
+ content: "\e015";
+}
+
+.glyphicon-zoom-out:before {
+ content: "\e016";
+}
+
+.glyphicon-off:before {
+ content: "\e017";
+}
+
+.glyphicon-signal:before {
+ content: "\e018";
+}
+
+.glyphicon-cog:before {
+ content: "\e019";
+}
+
+.glyphicon-trash:before {
+ content: "\e020";
+}
+
+.glyphicon-home:before {
+ content: "\e021";
+}
+
+.glyphicon-file:before {
+ content: "\e022";
+}
+
+.glyphicon-time:before {
+ content: "\e023";
+}
+
+.glyphicon-road:before {
+ content: "\e024";
+}
+
+.glyphicon-download-alt:before {
+ content: "\e025";
+}
+
+.glyphicon-download:before {
+ content: "\e026";
+}
+
+.glyphicon-upload:before {
+ content: "\e027";
+}
+
+.glyphicon-inbox:before {
+ content: "\e028";
+}
+
+.glyphicon-play-circle:before {
+ content: "\e029";
+}
+
+.glyphicon-repeat:before {
+ content: "\e030";
+}
+
+.glyphicon-refresh:before {
+ content: "\e031";
+}
+
+.glyphicon-list-alt:before {
+ content: "\e032";
+}
+
+.glyphicon-lock:before {
+ content: "\e033";
+}
+
+.glyphicon-flag:before {
+ content: "\e034";
+}
+
+.glyphicon-headphones:before {
+ content: "\e035";
+}
+
+.glyphicon-volume-off:before {
+ content: "\e036";
+}
+
+.glyphicon-volume-down:before {
+ content: "\e037";
+}
+
+.glyphicon-volume-up:before {
+ content: "\e038";
+}
+
+.glyphicon-qrcode:before {
+ content: "\e039";
+}
+
+.glyphicon-barcode:before {
+ content: "\e040";
+}
+
+.glyphicon-tag:before {
+ content: "\e041";
+}
+
+.glyphicon-tags:before {
+ content: "\e042";
+}
+
+.glyphicon-book:before {
+ content: "\e043";
+}
+
+.glyphicon-bookmark:before {
+ content: "\e044";
+}
+
+.glyphicon-print:before {
+ content: "\e045";
+}
+
+.glyphicon-camera:before {
+ content: "\e046";
+}
+
+.glyphicon-font:before {
+ content: "\e047";
+}
+
+.glyphicon-bold:before {
+ content: "\e048";
+}
+
+.glyphicon-italic:before {
+ content: "\e049";
+}
+
+.glyphicon-text-height:before {
+ content: "\e050";
+}
+
+.glyphicon-text-width:before {
+ content: "\e051";
+}
+
+.glyphicon-align-left:before {
+ content: "\e052";
+}
+
+.glyphicon-align-center:before {
+ content: "\e053";
+}
+
+.glyphicon-align-right:before {
+ content: "\e054";
+}
+
+.glyphicon-align-justify:before {
+ content: "\e055";
+}
+
+.glyphicon-list:before {
+ content: "\e056";
+}
+
+.glyphicon-indent-left:before {
+ content: "\e057";
+}
+
+.glyphicon-indent-right:before {
+ content: "\e058";
+}
+
+.glyphicon-facetime-video:before {
+ content: "\e059";
+}
+
+.glyphicon-picture:before {
+ content: "\e060";
+}
+
+.glyphicon-map-marker:before {
+ content: "\e062";
+}
+
+.glyphicon-adjust:before {
+ content: "\e063";
+}
+
+.glyphicon-tint:before {
+ content: "\e064";
+}
+
+.glyphicon-edit:before {
+ content: "\e065";
+}
+
+.glyphicon-share:before {
+ content: "\e066";
+}
+
+.glyphicon-check:before {
+ content: "\e067";
+}
+
+.glyphicon-move:before {
+ content: "\e068";
+}
+
+.glyphicon-step-backward:before {
+ content: "\e069";
+}
+
+.glyphicon-fast-backward:before {
+ content: "\e070";
+}
+
+.glyphicon-backward:before {
+ content: "\e071";
+}
+
+.glyphicon-play:before {
+ content: "\e072";
+}
+
+.glyphicon-pause:before {
+ content: "\e073";
+}
+
+.glyphicon-stop:before {
+ content: "\e074";
+}
+
+.glyphicon-forward:before {
+ content: "\e075";
+}
+
+.glyphicon-fast-forward:before {
+ content: "\e076";
+}
+
+.glyphicon-step-forward:before {
+ content: "\e077";
+}
+
+.glyphicon-eject:before {
+ content: "\e078";
+}
+
+.glyphicon-chevron-left:before {
+ content: "\e079";
+}
+
+.glyphicon-chevron-right:before {
+ content: "\e080";
+}
+
+.glyphicon-plus-sign:before {
+ content: "\e081";
+}
+
+.glyphicon-minus-sign:before {
+ content: "\e082";
+}
+
+.glyphicon-remove-sign:before {
+ content: "\e083";
+}
+
+.glyphicon-ok-sign:before {
+ content: "\e084";
+}
+
+.glyphicon-question-sign:before {
+ content: "\e085";
+}
+
+.glyphicon-info-sign:before {
+ content: "\e086";
+}
+
+.glyphicon-screenshot:before {
+ content: "\e087";
+}
+
+.glyphicon-remove-circle:before {
+ content: "\e088";
+}
+
+.glyphicon-ok-circle:before {
+ content: "\e089";
+}
+
+.glyphicon-ban-circle:before {
+ content: "\e090";
+}
+
+.glyphicon-arrow-left:before {
+ content: "\e091";
+}
+
+.glyphicon-arrow-right:before {
+ content: "\e092";
+}
+
+.glyphicon-arrow-up:before {
+ content: "\e093";
+}
+
+.glyphicon-arrow-down:before {
+ content: "\e094";
+}
+
+.glyphicon-share-alt:before {
+ content: "\e095";
+}
+
+.glyphicon-resize-full:before {
+ content: "\e096";
+}
+
+.glyphicon-resize-small:before {
+ content: "\e097";
+}
+
+.glyphicon-exclamation-sign:before {
+ content: "\e101";
+}
+
+.glyphicon-gift:before {
+ content: "\e102";
+}
+
+.glyphicon-leaf:before {
+ content: "\e103";
+}
+
+.glyphicon-fire:before {
+ content: "\e104";
+}
+
+.glyphicon-eye-open:before {
+ content: "\e105";
+}
+
+.glyphicon-eye-close:before {
+ content: "\e106";
+}
+
+.glyphicon-warning-sign:before {
+ content: "\e107";
+}
+
+.glyphicon-plane:before {
+ content: "\e108";
+}
+
+.glyphicon-calendar:before {
+ content: "\e109";
+}
+
+.glyphicon-random:before {
+ content: "\e110";
+}
+
+.glyphicon-comment:before {
+ content: "\e111";
+}
+
+.glyphicon-magnet:before {
+ content: "\e112";
+}
+
+.glyphicon-chevron-up:before {
+ content: "\e113";
+}
+
+.glyphicon-chevron-down:before {
+ content: "\e114";
+}
+
+.glyphicon-retweet:before {
+ content: "\e115";
+}
+
+.glyphicon-shopping-cart:before {
+ content: "\e116";
+}
+
+.glyphicon-folder-close:before {
+ content: "\e117";
+}
+
+.glyphicon-folder-open:before {
+ content: "\e118";
+}
+
+.glyphicon-resize-vertical:before {
+ content: "\e119";
+}
+
+.glyphicon-resize-horizontal:before {
+ content: "\e120";
+}
+
+.glyphicon-hdd:before {
+ content: "\e121";
+}
+
+.glyphicon-bullhorn:before {
+ content: "\e122";
+}
+
+.glyphicon-bell:before {
+ content: "\e123";
+}
+
+.glyphicon-certificate:before {
+ content: "\e124";
+}
+
+.glyphicon-thumbs-up:before {
+ content: "\e125";
+}
+
+.glyphicon-thumbs-down:before {
+ content: "\e126";
+}
+
+.glyphicon-hand-right:before {
+ content: "\e127";
+}
+
+.glyphicon-hand-left:before {
+ content: "\e128";
+}
+
+.glyphicon-hand-up:before {
+ content: "\e129";
+}
+
+.glyphicon-hand-down:before {
+ content: "\e130";
+}
+
+.glyphicon-circle-arrow-right:before {
+ content: "\e131";
+}
+
+.glyphicon-circle-arrow-left:before {
+ content: "\e132";
+}
+
+.glyphicon-circle-arrow-up:before {
+ content: "\e133";
+}
+
+.glyphicon-circle-arrow-down:before {
+ content: "\e134";
+}
+
+.glyphicon-globe:before {
+ content: "\e135";
+}
+
+.glyphicon-wrench:before {
+ content: "\e136";
+}
+
+.glyphicon-tasks:before {
+ content: "\e137";
+}
+
+.glyphicon-filter:before {
+ content: "\e138";
+}
+
+.glyphicon-briefcase:before {
+ content: "\e139";
+}
+
+.glyphicon-fullscreen:before {
+ content: "\e140";
+}
+
+.glyphicon-dashboard:before {
+ content: "\e141";
+}
+
+.glyphicon-paperclip:before {
+ content: "\e142";
+}
+
+.glyphicon-heart-empty:before {
+ content: "\e143";
+}
+
+.glyphicon-link:before {
+ content: "\e144";
+}
+
+.glyphicon-phone:before {
+ content: "\e145";
+}
+
+.glyphicon-pushpin:before {
+ content: "\e146";
+}
+
+.glyphicon-usd:before {
+ content: "\e148";
+}
+
+.glyphicon-gbp:before {
+ content: "\e149";
+}
+
+.glyphicon-sort:before {
+ content: "\e150";
+}
+
+.glyphicon-sort-by-alphabet:before {
+ content: "\e151";
+}
+
+.glyphicon-sort-by-alphabet-alt:before {
+ content: "\e152";
+}
+
+.glyphicon-sort-by-order:before {
+ content: "\e153";
+}
+
+.glyphicon-sort-by-order-alt:before {
+ content: "\e154";
+}
+
+.glyphicon-sort-by-attributes:before {
+ content: "\e155";
+}
+
+.glyphicon-sort-by-attributes-alt:before {
+ content: "\e156";
+}
+
+.glyphicon-unchecked:before {
+ content: "\e157";
+}
+
+.glyphicon-expand:before {
+ content: "\e158";
+}
+
+.glyphicon-collapse-down:before {
+ content: "\e159";
+}
+
+.glyphicon-collapse-up:before {
+ content: "\e160";
+}
+
+.glyphicon-log-in:before {
+ content: "\e161";
+}
+
+.glyphicon-flash:before {
+ content: "\e162";
+}
+
+.glyphicon-log-out:before {
+ content: "\e163";
+}
+
+.glyphicon-new-window:before {
+ content: "\e164";
+}
+
+.glyphicon-record:before {
+ content: "\e165";
+}
+
+.glyphicon-save:before {
+ content: "\e166";
+}
+
+.glyphicon-open:before {
+ content: "\e167";
+}
+
+.glyphicon-saved:before {
+ content: "\e168";
+}
+
+.glyphicon-import:before {
+ content: "\e169";
+}
+
+.glyphicon-export:before {
+ content: "\e170";
+}
+
+.glyphicon-send:before {
+ content: "\e171";
+}
+
+.glyphicon-floppy-disk:before {
+ content: "\e172";
+}
+
+.glyphicon-floppy-saved:before {
+ content: "\e173";
+}
+
+.glyphicon-floppy-remove:before {
+ content: "\e174";
+}
+
+.glyphicon-floppy-save:before {
+ content: "\e175";
+}
+
+.glyphicon-floppy-open:before {
+ content: "\e176";
+}
+
+.glyphicon-credit-card:before {
+ content: "\e177";
+}
+
+.glyphicon-transfer:before {
+ content: "\e178";
+}
+
+.glyphicon-cutlery:before {
+ content: "\e179";
+}
+
+.glyphicon-header:before {
+ content: "\e180";
+}
+
+.glyphicon-compressed:before {
+ content: "\e181";
+}
+
+.glyphicon-earphone:before {
+ content: "\e182";
+}
+
+.glyphicon-phone-alt:before {
+ content: "\e183";
+}
+
+.glyphicon-tower:before {
+ content: "\e184";
+}
+
+.glyphicon-stats:before {
+ content: "\e185";
+}
+
+.glyphicon-sd-video:before {
+ content: "\e186";
+}
+
+.glyphicon-hd-video:before {
+ content: "\e187";
+}
+
+.glyphicon-subtitles:before {
+ content: "\e188";
+}
+
+.glyphicon-sound-stereo:before {
+ content: "\e189";
+}
+
+.glyphicon-sound-dolby:before {
+ content: "\e190";
+}
+
+.glyphicon-sound-5-1:before {
+ content: "\e191";
+}
+
+.glyphicon-sound-6-1:before {
+ content: "\e192";
+}
+
+.glyphicon-sound-7-1:before {
+ content: "\e193";
+}
+
+.glyphicon-copyright-mark:before {
+ content: "\e194";
+}
+
+.glyphicon-registration-mark:before {
+ content: "\e195";
+}
+
+.glyphicon-cloud-download:before {
+ content: "\e197";
+}
+
+.glyphicon-cloud-upload:before {
+ content: "\e198";
+}
+
+.glyphicon-tree-conifer:before {
+ content: "\e199";
+}
+
+.glyphicon-tree-deciduous:before {
+ content: "\e200";
+}
+
+.glyphicon-cd:before {
+ content: "\e201";
+}
+
+.glyphicon-save-file:before {
+ content: "\e202";
+}
+
+.glyphicon-open-file:before {
+ content: "\e203";
+}
+
+.glyphicon-level-up:before {
+ content: "\e204";
+}
+
+.glyphicon-copy:before {
+ content: "\e205";
+}
+
+.glyphicon-paste:before {
+ content: "\e206";
+}
+
+.glyphicon-alert:before {
+ content: "\e209";
+}
+
+.glyphicon-equalizer:before {
+ content: "\e210";
+}
+
+.glyphicon-king:before {
+ content: "\e211";
+}
+
+.glyphicon-queen:before {
+ content: "\e212";
+}
+
+.glyphicon-pawn:before {
+ content: "\e213";
+}
+
+.glyphicon-bishop:before {
+ content: "\e214";
+}
+
+.glyphicon-knight:before {
+ content: "\e215";
+}
+
+.glyphicon-baby-formula:before {
+ content: "\e216";
+}
+
+.glyphicon-tent:before {
+ content: "\26fa";
+}
+
+.glyphicon-blackboard:before {
+ content: "\e218";
+}
+
+.glyphicon-bed:before {
+ content: "\e219";
+}
+
+.glyphicon-apple:before {
+ content: "\f8ff";
+}
+
+.glyphicon-erase:before {
+ content: "\e221";
+}
+
+.glyphicon-hourglass:before {
+ content: "\231b";
+}
+
+.glyphicon-lamp:before {
+ content: "\e223";
+}
+
+.glyphicon-duplicate:before {
+ content: "\e224";
+}
+
+.glyphicon-piggy-bank:before {
+ content: "\e225";
+}
+
+.glyphicon-scissors:before {
+ content: "\e226";
+}
+
+.glyphicon-bitcoin:before {
+ content: "\e227";
+}
+
+.glyphicon-btc:before {
+ content: "\e227";
+}
+
+.glyphicon-xbt:before {
+ content: "\e227";
+}
+
+.glyphicon-yen:before {
+ content: "\00a5";
+}
+
+.glyphicon-jpy:before {
+ content: "\00a5";
+}
+
+.glyphicon-ruble:before {
+ content: "\20bd";
+}
+
+.glyphicon-rub:before {
+ content: "\20bd";
+}
+
+.glyphicon-scale:before {
+ content: "\e230";
+}
+
+.glyphicon-ice-lolly:before {
+ content: "\e231";
+}
+
+.glyphicon-ice-lolly-tasted:before {
+ content: "\e232";
+}
+
+.glyphicon-education:before {
+ content: "\e233";
+}
+
+.glyphicon-option-horizontal:before {
+ content: "\e234";
+}
+
+.glyphicon-option-vertical:before {
+ content: "\e235";
+}
+
+.glyphicon-menu-hamburger:before {
+ content: "\e236";
+}
+
+.glyphicon-modal-window:before {
+ content: "\e237";
+}
+
+.glyphicon-oil:before {
+ content: "\e238";
+}
+
+.glyphicon-grain:before {
+ content: "\e239";
+}
+
+.glyphicon-sunglasses:before {
+ content: "\e240";
+}
+
+.glyphicon-text-size:before {
+ content: "\e241";
+}
+
+.glyphicon-text-color:before {
+ content: "\e242";
+}
+
+.glyphicon-text-background:before {
+ content: "\e243";
+}
+
+.glyphicon-object-align-top:before {
+ content: "\e244";
+}
+
+.glyphicon-object-align-bottom:before {
+ content: "\e245";
+}
+
+.glyphicon-object-align-horizontal:before {
+ content: "\e246";
+}
+
+.glyphicon-object-align-left:before {
+ content: "\e247";
+}
+
+.glyphicon-object-align-vertical:before {
+ content: "\e248";
+}
+
+.glyphicon-object-align-right:before {
+ content: "\e249";
+}
+
+.glyphicon-triangle-right:before {
+ content: "\e250";
+}
+
+.glyphicon-triangle-left:before {
+ content: "\e251";
+}
+
+.glyphicon-triangle-bottom:before {
+ content: "\e252";
+}
+
+.glyphicon-triangle-top:before {
+ content: "\e253";
+}
+
+.glyphicon-console:before {
+ content: "\e254";
+}
+
+.glyphicon-superscript:before {
+ content: "\e255";
+}
+
+.glyphicon-subscript:before {
+ content: "\e256";
+}
+
+.glyphicon-menu-left:before {
+ content: "\e257";
+}
+
+.glyphicon-menu-right:before {
+ content: "\e258";
+}
+
+.glyphicon-menu-down:before {
+ content: "\e259";
+}
+
+.glyphicon-menu-up:before {
+ content: "\e260";
+}
+
+* {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+*:before,
+*:after {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+html {
+ font-size: 10px;
+
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+
+body {
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #333;
+ background-color: #fff;
+}
+
+input,
+button,
+select,
+textarea {
+ font-family: inherit;
+ font-size: inherit;
+ line-height: inherit;
+}
+
+a {
+ color: #337ab7;
+ text-decoration: none;
+}
+
+a:hover,
+a:focus {
+ color: #23527c;
+ text-decoration: underline;
+}
+
+a:focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+
+figure {
+ margin: 0;
+}
+
+img {
+ vertical-align: middle;
+}
+
+.img-responsive,
+.thumbnail > img,
+.thumbnail a > img,
+.carousel-inner > .item > img,
+.carousel-inner > .item > a > img {
+ display: block;
+ max-width: 100%;
+ height: auto;
+}
+
+.img-rounded {
+ border-radius: 6px;
+}
+
+.img-thumbnail {
+ display: inline-block;
+ max-width: 100%;
+ height: auto;
+ padding: 4px;
+ line-height: 1.42857143;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ -webkit-transition: all .2s ease-in-out;
+ -o-transition: all .2s ease-in-out;
+ transition: all .2s ease-in-out;
+}
+
+.img-circle {
+ border-radius: 50%;
+}
+
+hr {
+ margin-top: 20px;
+ margin-bottom: 20px;
+ border: 0;
+ border-top: 1px solid #eee;
+}
+
+.sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ border: 0;
+}
+
+.sr-only-focusable:active,
+.sr-only-focusable:focus {
+ position: static;
+ width: auto;
+ height: auto;
+ margin: 0;
+ overflow: visible;
+ clip: auto;
+}
+
+[role="button"] {
+ cursor: pointer;
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+.h1,
+.h2,
+.h3,
+.h4,
+.h5,
+.h6 {
+ font-family: inherit;
+ font-weight: 500;
+ line-height: 1.1;
+ color: inherit;
+}
+
+h1 small,
+h2 small,
+h3 small,
+h4 small,
+h5 small,
+h6 small,
+.h1 small,
+.h2 small,
+.h3 small,
+.h4 small,
+.h5 small,
+.h6 small,
+h1 .small,
+h2 .small,
+h3 .small,
+h4 .small,
+h5 .small,
+h6 .small,
+.h1 .small,
+.h2 .small,
+.h3 .small,
+.h4 .small,
+.h5 .small,
+.h6 .small {
+ font-weight: normal;
+ line-height: 1;
+ color: #777;
+}
+
+h1,
+.h1,
+h2,
+.h2,
+h3,
+.h3 {
+ margin-top: 20px;
+ margin-bottom: 10px;
+}
+
+h1 small,
+.h1 small,
+h2 small,
+.h2 small,
+h3 small,
+.h3 small,
+h1 .small,
+.h1 .small,
+h2 .small,
+.h2 .small,
+h3 .small,
+.h3 .small {
+ font-size: 65%;
+}
+
+h4,
+.h4,
+h5,
+.h5,
+h6,
+.h6 {
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+
+h4 small,
+.h4 small,
+h5 small,
+.h5 small,
+h6 small,
+.h6 small,
+h4 .small,
+.h4 .small,
+h5 .small,
+.h5 .small,
+h6 .small,
+.h6 .small {
+ font-size: 75%;
+}
+
+h1,
+.h1 {
+ font-size: 36px;
+}
+
+h2,
+.h2 {
+ font-size: 30px;
+}
+
+h3,
+.h3 {
+ font-size: 24px;
+}
+
+h4,
+.h4 {
+ font-size: 18px;
+}
+
+h5,
+.h5 {
+ font-size: 14px;
+}
+
+h6,
+.h6 {
+ font-size: 12px;
+}
+
+p {
+ margin: 0 0 10px;
+}
+
+.lead {
+ margin-bottom: 20px;
+ font-size: 16px;
+ font-weight: 300;
+ line-height: 1.4;
+}
+
+@media (min-width: 768px) {
+ .lead {
+ font-size: 21px;
+ }
+}
+
+small,
+.small {
+ font-size: 85%;
+}
+
+mark,
+.mark {
+ padding: .2em;
+ background-color: #fcf8e3;
+}
+
+.text-left {
+ text-align: left;
+}
+
+.text-right {
+ text-align: right;
+}
+
+.text-center {
+ text-align: center;
+}
+
+.text-justify {
+ text-align: justify;
+}
+
+.text-nowrap {
+ white-space: nowrap;
+}
+
+.text-lowercase {
+ text-transform: lowercase;
+}
+
+.text-uppercase {
+ text-transform: uppercase;
+}
+
+.text-capitalize {
+ text-transform: capitalize;
+}
+
+.text-muted {
+ color: #777;
+}
+
+.text-primary {
+ color: #337ab7;
+}
+
+a.text-primary:hover,
+a.text-primary:focus {
+ color: #286090;
+}
+
+.text-success {
+ color: #3c763d;
+}
+
+a.text-success:hover,
+a.text-success:focus {
+ color: #2b542c;
+}
+
+.text-info {
+ color: #31708f;
+}
+
+a.text-info:hover,
+a.text-info:focus {
+ color: #245269;
+}
+
+.text-warning {
+ color: #8a6d3b;
+}
+
+a.text-warning:hover,
+a.text-warning:focus {
+ color: #66512c;
+}
+
+.text-danger {
+ color: #a94442;
+}
+
+a.text-danger:hover,
+a.text-danger:focus {
+ color: #843534;
+}
+
+.bg-primary {
+ color: #fff;
+ background-color: #337ab7;
+}
+
+a.bg-primary:hover,
+a.bg-primary:focus {
+ background-color: #286090;
+}
+
+.bg-success {
+ background-color: #dff0d8;
+}
+
+a.bg-success:hover,
+a.bg-success:focus {
+ background-color: #c1e2b3;
+}
+
+.bg-info {
+ background-color: #d9edf7;
+}
+
+a.bg-info:hover,
+a.bg-info:focus {
+ background-color: #afd9ee;
+}
+
+.bg-warning {
+ background-color: #fcf8e3;
+}
+
+a.bg-warning:hover,
+a.bg-warning:focus {
+ background-color: #f7ecb5;
+}
+
+.bg-danger {
+ background-color: #f2dede;
+}
+
+a.bg-danger:hover,
+a.bg-danger:focus {
+ background-color: #e4b9b9;
+}
+
+.page-header {
+ padding-bottom: 9px;
+ margin: 40px 0 20px;
+ border-bottom: 1px solid #eee;
+}
+
+ul,
+ol {
+ margin-top: 0;
+ margin-bottom: 10px;
+}
+
+ul ul,
+ol ul,
+ul ol,
+ol ol {
+ margin-bottom: 0;
+}
+
+.list-unstyled {
+ padding-left: 0;
+ list-style: none;
+}
+
+.list-inline {
+ padding-left: 0;
+ margin-left: -5px;
+ list-style: none;
+}
+
+.list-inline > li {
+ display: inline-block;
+ padding-right: 5px;
+ padding-left: 5px;
+}
+
+dl {
+ margin-top: 0;
+ margin-bottom: 20px;
+}
+
+dt,
+dd {
+ line-height: 1.42857143;
+}
+
+dt {
+ font-weight: bold;
+}
+
+dd {
+ margin-left: 0;
+}
+
+@media (min-width: 768px) {
+ .dl-horizontal dt {
+ float: left;
+ width: 160px;
+ overflow: hidden;
+ clear: left;
+ text-align: right;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
+ .dl-horizontal dd {
+ margin-left: 180px;
+ }
+}
+
+abbr[title],
+abbr[data-original-title] {
+ cursor: help;
+ border-bottom: 1px dotted #777;
+}
+
+.initialism {
+ font-size: 90%;
+ text-transform: uppercase;
+}
+
+blockquote {
+ padding: 10px 20px;
+ margin: 0 0 20px;
+ font-size: 17.5px;
+ border-left: 5px solid #eee;
+}
+
+blockquote p:last-child,
+blockquote ul:last-child,
+blockquote ol:last-child {
+ margin-bottom: 0;
+}
+
+blockquote footer,
+blockquote small,
+blockquote .small {
+ display: block;
+ font-size: 80%;
+ line-height: 1.42857143;
+ color: #777;
+}
+
+blockquote footer:before,
+blockquote small:before,
+blockquote .small:before {
+ content: '\2014 \00A0';
+}
+
+.blockquote-reverse,
+blockquote.pull-right {
+ padding-right: 15px;
+ padding-left: 0;
+ text-align: right;
+ border-right: 5px solid #eee;
+ border-left: 0;
+}
+
+.blockquote-reverse footer:before,
+blockquote.pull-right footer:before,
+.blockquote-reverse small:before,
+blockquote.pull-right small:before,
+.blockquote-reverse .small:before,
+blockquote.pull-right .small:before {
+ content: '';
+}
+
+.blockquote-reverse footer:after,
+blockquote.pull-right footer:after,
+.blockquote-reverse small:after,
+blockquote.pull-right small:after,
+.blockquote-reverse .small:after,
+blockquote.pull-right .small:after {
+ content: '\00A0 \2014';
+}
+
+address {
+ margin-bottom: 20px;
+ font-style: normal;
+ line-height: 1.42857143;
+}
+
+code,
+kbd,
+pre,
+samp {
+ font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
+}
+
+code {
+ padding: 2px 4px;
+ font-size: 90%;
+ color: #c7254e;
+ background-color: #f9f2f4;
+ border-radius: 4px;
+}
+
+kbd {
+ padding: 2px 4px;
+ font-size: 90%;
+ color: #fff;
+ background-color: #333;
+ border-radius: 3px;
+ -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);
+ box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);
+}
+
+kbd kbd {
+ padding: 0;
+ font-size: 100%;
+ font-weight: bold;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+
+pre {
+ display: block;
+ padding: 9.5px;
+ margin: 0 0 10px;
+ font-size: 13px;
+ line-height: 1.42857143;
+ color: #333;
+ word-break: break-all;
+ word-wrap: break-word;
+ background-color: #f5f5f5;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+}
+
+pre code {
+ padding: 0;
+ font-size: inherit;
+ color: inherit;
+ white-space: pre-wrap;
+ background-color: transparent;
+ border-radius: 0;
+}
+
+.pre-scrollable {
+ max-height: 340px;
+ overflow-y: scroll;
+}
+
+.container {
+ padding-right: 15px;
+ padding-left: 15px;
+ margin-right: auto;
+ margin-left: auto;
+}
+
+@media (min-width: 768px) {
+ .container {
+ width: 750px;
+ }
+}
+
+@media (min-width: 992px) {
+ .container {
+ width: 970px;
+ }
+}
+
+@media (min-width: 1200px) {
+ .container {
+ width: 1170px;
+ }
+}
+
+.container-fluid {
+ padding-right: 15px;
+ padding-left: 15px;
+ margin-right: auto;
+ margin-left: auto;
+}
+
+.row {
+ margin-right: -15px;
+ margin-left: -15px;
+}
+
+.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
+ position: relative;
+ min-height: 1px;
+ padding-right: 15px;
+ padding-left: 15px;
+}
+
+.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {
+ float: left;
+}
+
+.col-xs-12 {
+ width: 100%;
+}
+
+.col-xs-11 {
+ width: 91.66666667%;
+}
+
+.col-xs-10 {
+ width: 83.33333333%;
+}
+
+.col-xs-9 {
+ width: 75%;
+}
+
+.col-xs-8 {
+ width: 66.66666667%;
+}
+
+.col-xs-7 {
+ width: 58.33333333%;
+}
+
+.col-xs-6 {
+ width: 50%;
+}
+
+.col-xs-5 {
+ width: 41.66666667%;
+}
+
+.col-xs-4 {
+ width: 33.33333333%;
+}
+
+.col-xs-3 {
+ width: 25%;
+}
+
+.col-xs-2 {
+ width: 16.66666667%;
+}
+
+.col-xs-1 {
+ width: 8.33333333%;
+}
+
+.col-xs-pull-12 {
+ right: 100%;
+}
+
+.col-xs-pull-11 {
+ right: 91.66666667%;
+}
+
+.col-xs-pull-10 {
+ right: 83.33333333%;
+}
+
+.col-xs-pull-9 {
+ right: 75%;
+}
+
+.col-xs-pull-8 {
+ right: 66.66666667%;
+}
+
+.col-xs-pull-7 {
+ right: 58.33333333%;
+}
+
+.col-xs-pull-6 {
+ right: 50%;
+}
+
+.col-xs-pull-5 {
+ right: 41.66666667%;
+}
+
+.col-xs-pull-4 {
+ right: 33.33333333%;
+}
+
+.col-xs-pull-3 {
+ right: 25%;
+}
+
+.col-xs-pull-2 {
+ right: 16.66666667%;
+}
+
+.col-xs-pull-1 {
+ right: 8.33333333%;
+}
+
+.col-xs-pull-0 {
+ right: auto;
+}
+
+.col-xs-push-12 {
+ left: 100%;
+}
+
+.col-xs-push-11 {
+ left: 91.66666667%;
+}
+
+.col-xs-push-10 {
+ left: 83.33333333%;
+}
+
+.col-xs-push-9 {
+ left: 75%;
+}
+
+.col-xs-push-8 {
+ left: 66.66666667%;
+}
+
+.col-xs-push-7 {
+ left: 58.33333333%;
+}
+
+.col-xs-push-6 {
+ left: 50%;
+}
+
+.col-xs-push-5 {
+ left: 41.66666667%;
+}
+
+.col-xs-push-4 {
+ left: 33.33333333%;
+}
+
+.col-xs-push-3 {
+ left: 25%;
+}
+
+.col-xs-push-2 {
+ left: 16.66666667%;
+}
+
+.col-xs-push-1 {
+ left: 8.33333333%;
+}
+
+.col-xs-push-0 {
+ left: auto;
+}
+
+.col-xs-offset-12 {
+ margin-left: 100%;
+}
+
+.col-xs-offset-11 {
+ margin-left: 91.66666667%;
+}
+
+.col-xs-offset-10 {
+ margin-left: 83.33333333%;
+}
+
+.col-xs-offset-9 {
+ margin-left: 75%;
+}
+
+.col-xs-offset-8 {
+ margin-left: 66.66666667%;
+}
+
+.col-xs-offset-7 {
+ margin-left: 58.33333333%;
+}
+
+.col-xs-offset-6 {
+ margin-left: 50%;
+}
+
+.col-xs-offset-5 {
+ margin-left: 41.66666667%;
+}
+
+.col-xs-offset-4 {
+ margin-left: 33.33333333%;
+}
+
+.col-xs-offset-3 {
+ margin-left: 25%;
+}
+
+.col-xs-offset-2 {
+ margin-left: 16.66666667%;
+}
+
+.col-xs-offset-1 {
+ margin-left: 8.33333333%;
+}
+
+.col-xs-offset-0 {
+ margin-left: 0;
+}
+
+@media (min-width: 768px) {
+ .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
+ float: left;
+ }
+
+ .col-sm-12 {
+ width: 100%;
+ }
+
+ .col-sm-11 {
+ width: 91.66666667%;
+ }
+
+ .col-sm-10 {
+ width: 83.33333333%;
+ }
+
+ .col-sm-9 {
+ width: 75%;
+ }
+
+ .col-sm-8 {
+ width: 66.66666667%;
+ }
+
+ .col-sm-7 {
+ width: 58.33333333%;
+ }
+
+ .col-sm-6 {
+ width: 50%;
+ }
+
+ .col-sm-5 {
+ width: 41.66666667%;
+ }
+
+ .col-sm-4 {
+ width: 33.33333333%;
+ }
+
+ .col-sm-3 {
+ width: 25%;
+ }
+
+ .col-sm-2 {
+ width: 16.66666667%;
+ }
+
+ .col-sm-1 {
+ width: 8.33333333%;
+ }
+
+ .col-sm-pull-12 {
+ right: 100%;
+ }
+
+ .col-sm-pull-11 {
+ right: 91.66666667%;
+ }
+
+ .col-sm-pull-10 {
+ right: 83.33333333%;
+ }
+
+ .col-sm-pull-9 {
+ right: 75%;
+ }
+
+ .col-sm-pull-8 {
+ right: 66.66666667%;
+ }
+
+ .col-sm-pull-7 {
+ right: 58.33333333%;
+ }
+
+ .col-sm-pull-6 {
+ right: 50%;
+ }
+
+ .col-sm-pull-5 {
+ right: 41.66666667%;
+ }
+
+ .col-sm-pull-4 {
+ right: 33.33333333%;
+ }
+
+ .col-sm-pull-3 {
+ right: 25%;
+ }
+
+ .col-sm-pull-2 {
+ right: 16.66666667%;
+ }
+
+ .col-sm-pull-1 {
+ right: 8.33333333%;
+ }
+
+ .col-sm-pull-0 {
+ right: auto;
+ }
+
+ .col-sm-push-12 {
+ left: 100%;
+ }
+
+ .col-sm-push-11 {
+ left: 91.66666667%;
+ }
+
+ .col-sm-push-10 {
+ left: 83.33333333%;
+ }
+
+ .col-sm-push-9 {
+ left: 75%;
+ }
+
+ .col-sm-push-8 {
+ left: 66.66666667%;
+ }
+
+ .col-sm-push-7 {
+ left: 58.33333333%;
+ }
+
+ .col-sm-push-6 {
+ left: 50%;
+ }
+
+ .col-sm-push-5 {
+ left: 41.66666667%;
+ }
+
+ .col-sm-push-4 {
+ left: 33.33333333%;
+ }
+
+ .col-sm-push-3 {
+ left: 25%;
+ }
+
+ .col-sm-push-2 {
+ left: 16.66666667%;
+ }
+
+ .col-sm-push-1 {
+ left: 8.33333333%;
+ }
+
+ .col-sm-push-0 {
+ left: auto;
+ }
+
+ .col-sm-offset-12 {
+ margin-left: 100%;
+ }
+
+ .col-sm-offset-11 {
+ margin-left: 91.66666667%;
+ }
+
+ .col-sm-offset-10 {
+ margin-left: 83.33333333%;
+ }
+
+ .col-sm-offset-9 {
+ margin-left: 75%;
+ }
+
+ .col-sm-offset-8 {
+ margin-left: 66.66666667%;
+ }
+
+ .col-sm-offset-7 {
+ margin-left: 58.33333333%;
+ }
+
+ .col-sm-offset-6 {
+ margin-left: 50%;
+ }
+
+ .col-sm-offset-5 {
+ margin-left: 41.66666667%;
+ }
+
+ .col-sm-offset-4 {
+ margin-left: 33.33333333%;
+ }
+
+ .col-sm-offset-3 {
+ margin-left: 25%;
+ }
+
+ .col-sm-offset-2 {
+ margin-left: 16.66666667%;
+ }
+
+ .col-sm-offset-1 {
+ margin-left: 8.33333333%;
+ }
+
+ .col-sm-offset-0 {
+ margin-left: 0;
+ }
+}
+
+@media (min-width: 992px) {
+ .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {
+ float: left;
+ }
+
+ .col-md-12 {
+ width: 100%;
+ }
+
+ .col-md-11 {
+ width: 91.66666667%;
+ }
+
+ .col-md-10 {
+ width: 83.33333333%;
+ }
+
+ .col-md-9 {
+ width: 75%;
+ }
+
+ .col-md-8 {
+ width: 66.66666667%;
+ }
+
+ .col-md-7 {
+ width: 58.33333333%;
+ }
+
+ .col-md-6 {
+ width: 50%;
+ }
+
+ .col-md-5 {
+ width: 41.66666667%;
+ }
+
+ .col-md-4 {
+ width: 33.33333333%;
+ }
+
+ .col-md-3 {
+ width: 25%;
+ }
+
+ .col-md-2 {
+ width: 16.66666667%;
+ }
+
+ .col-md-1 {
+ width: 8.33333333%;
+ }
+
+ .col-md-pull-12 {
+ right: 100%;
+ }
+
+ .col-md-pull-11 {
+ right: 91.66666667%;
+ }
+
+ .col-md-pull-10 {
+ right: 83.33333333%;
+ }
+
+ .col-md-pull-9 {
+ right: 75%;
+ }
+
+ .col-md-pull-8 {
+ right: 66.66666667%;
+ }
+
+ .col-md-pull-7 {
+ right: 58.33333333%;
+ }
+
+ .col-md-pull-6 {
+ right: 50%;
+ }
+
+ .col-md-pull-5 {
+ right: 41.66666667%;
+ }
+
+ .col-md-pull-4 {
+ right: 33.33333333%;
+ }
+
+ .col-md-pull-3 {
+ right: 25%;
+ }
+
+ .col-md-pull-2 {
+ right: 16.66666667%;
+ }
+
+ .col-md-pull-1 {
+ right: 8.33333333%;
+ }
+
+ .col-md-pull-0 {
+ right: auto;
+ }
+
+ .col-md-push-12 {
+ left: 100%;
+ }
+
+ .col-md-push-11 {
+ left: 91.66666667%;
+ }
+
+ .col-md-push-10 {
+ left: 83.33333333%;
+ }
+
+ .col-md-push-9 {
+ left: 75%;
+ }
+
+ .col-md-push-8 {
+ left: 66.66666667%;
+ }
+
+ .col-md-push-7 {
+ left: 58.33333333%;
+ }
+
+ .col-md-push-6 {
+ left: 50%;
+ }
+
+ .col-md-push-5 {
+ left: 41.66666667%;
+ }
+
+ .col-md-push-4 {
+ left: 33.33333333%;
+ }
+
+ .col-md-push-3 {
+ left: 25%;
+ }
+
+ .col-md-push-2 {
+ left: 16.66666667%;
+ }
+
+ .col-md-push-1 {
+ left: 8.33333333%;
+ }
+
+ .col-md-push-0 {
+ left: auto;
+ }
+
+ .col-md-offset-12 {
+ margin-left: 100%;
+ }
+
+ .col-md-offset-11 {
+ margin-left: 91.66666667%;
+ }
+
+ .col-md-offset-10 {
+ margin-left: 83.33333333%;
+ }
+
+ .col-md-offset-9 {
+ margin-left: 75%;
+ }
+
+ .col-md-offset-8 {
+ margin-left: 66.66666667%;
+ }
+
+ .col-md-offset-7 {
+ margin-left: 58.33333333%;
+ }
+
+ .col-md-offset-6 {
+ margin-left: 50%;
+ }
+
+ .col-md-offset-5 {
+ margin-left: 41.66666667%;
+ }
+
+ .col-md-offset-4 {
+ margin-left: 33.33333333%;
+ }
+
+ .col-md-offset-3 {
+ margin-left: 25%;
+ }
+
+ .col-md-offset-2 {
+ margin-left: 16.66666667%;
+ }
+
+ .col-md-offset-1 {
+ margin-left: 8.33333333%;
+ }
+
+ .col-md-offset-0 {
+ margin-left: 0;
+ }
+}
+
+@media (min-width: 1200px) {
+ .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {
+ float: left;
+ }
+
+ .col-lg-12 {
+ width: 100%;
+ }
+
+ .col-lg-11 {
+ width: 91.66666667%;
+ }
+
+ .col-lg-10 {
+ width: 83.33333333%;
+ }
+
+ .col-lg-9 {
+ width: 75%;
+ }
+
+ .col-lg-8 {
+ width: 66.66666667%;
+ }
+
+ .col-lg-7 {
+ width: 58.33333333%;
+ }
+
+ .col-lg-6 {
+ width: 50%;
+ }
+
+ .col-lg-5 {
+ width: 41.66666667%;
+ }
+
+ .col-lg-4 {
+ width: 33.33333333%;
+ }
+
+ .col-lg-3 {
+ width: 25%;
+ }
+
+ .col-lg-2 {
+ width: 16.66666667%;
+ }
+
+ .col-lg-1 {
+ width: 8.33333333%;
+ }
+
+ .col-lg-pull-12 {
+ right: 100%;
+ }
+
+ .col-lg-pull-11 {
+ right: 91.66666667%;
+ }
+
+ .col-lg-pull-10 {
+ right: 83.33333333%;
+ }
+
+ .col-lg-pull-9 {
+ right: 75%;
+ }
+
+ .col-lg-pull-8 {
+ right: 66.66666667%;
+ }
+
+ .col-lg-pull-7 {
+ right: 58.33333333%;
+ }
+
+ .col-lg-pull-6 {
+ right: 50%;
+ }
+
+ .col-lg-pull-5 {
+ right: 41.66666667%;
+ }
+
+ .col-lg-pull-4 {
+ right: 33.33333333%;
+ }
+
+ .col-lg-pull-3 {
+ right: 25%;
+ }
+
+ .col-lg-pull-2 {
+ right: 16.66666667%;
+ }
+
+ .col-lg-pull-1 {
+ right: 8.33333333%;
+ }
+
+ .col-lg-pull-0 {
+ right: auto;
+ }
+
+ .col-lg-push-12 {
+ left: 100%;
+ }
+
+ .col-lg-push-11 {
+ left: 91.66666667%;
+ }
+
+ .col-lg-push-10 {
+ left: 83.33333333%;
+ }
+
+ .col-lg-push-9 {
+ left: 75%;
+ }
+
+ .col-lg-push-8 {
+ left: 66.66666667%;
+ }
+
+ .col-lg-push-7 {
+ left: 58.33333333%;
+ }
+
+ .col-lg-push-6 {
+ left: 50%;
+ }
+
+ .col-lg-push-5 {
+ left: 41.66666667%;
+ }
+
+ .col-lg-push-4 {
+ left: 33.33333333%;
+ }
+
+ .col-lg-push-3 {
+ left: 25%;
+ }
+
+ .col-lg-push-2 {
+ left: 16.66666667%;
+ }
+
+ .col-lg-push-1 {
+ left: 8.33333333%;
+ }
+
+ .col-lg-push-0 {
+ left: auto;
+ }
+
+ .col-lg-offset-12 {
+ margin-left: 100%;
+ }
+
+ .col-lg-offset-11 {
+ margin-left: 91.66666667%;
+ }
+
+ .col-lg-offset-10 {
+ margin-left: 83.33333333%;
+ }
+
+ .col-lg-offset-9 {
+ margin-left: 75%;
+ }
+
+ .col-lg-offset-8 {
+ margin-left: 66.66666667%;
+ }
+
+ .col-lg-offset-7 {
+ margin-left: 58.33333333%;
+ }
+
+ .col-lg-offset-6 {
+ margin-left: 50%;
+ }
+
+ .col-lg-offset-5 {
+ margin-left: 41.66666667%;
+ }
+
+ .col-lg-offset-4 {
+ margin-left: 33.33333333%;
+ }
+
+ .col-lg-offset-3 {
+ margin-left: 25%;
+ }
+
+ .col-lg-offset-2 {
+ margin-left: 16.66666667%;
+ }
+
+ .col-lg-offset-1 {
+ margin-left: 8.33333333%;
+ }
+
+ .col-lg-offset-0 {
+ margin-left: 0;
+ }
+}
+
+table {
+ background-color: transparent;
+}
+
+caption {
+ padding-top: 8px;
+ padding-bottom: 8px;
+ color: #777;
+ text-align: left;
+}
+
+th {
+ text-align: left;
+}
+
+.table {
+ width: 100%;
+ max-width: 100%;
+ margin-bottom: 20px;
+}
+
+.table > thead > tr > th,
+.table > tbody > tr > th,
+.table > tfoot > tr > th,
+.table > thead > tr > td,
+.table > tbody > tr > td,
+.table > tfoot > tr > td {
+ padding: 8px;
+ line-height: 1.42857143;
+ vertical-align: top;
+ border-top: 1px solid #ddd;
+}
+
+.table > thead > tr > th {
+ vertical-align: bottom;
+ border-bottom: 2px solid #ddd;
+}
+
+.table > caption + thead > tr:first-child > th,
+.table > colgroup + thead > tr:first-child > th,
+.table > thead:first-child > tr:first-child > th,
+.table > caption + thead > tr:first-child > td,
+.table > colgroup + thead > tr:first-child > td,
+.table > thead:first-child > tr:first-child > td {
+ border-top: 0;
+}
+
+.table > tbody + tbody {
+ border-top: 2px solid #ddd;
+}
+
+.table .table {
+ background-color: #fff;
+}
+
+.table-condensed > thead > tr > th,
+.table-condensed > tbody > tr > th,
+.table-condensed > tfoot > tr > th,
+.table-condensed > thead > tr > td,
+.table-condensed > tbody > tr > td,
+.table-condensed > tfoot > tr > td {
+ padding: 5px;
+}
+
+.table-bordered {
+ border: 1px solid #ddd;
+}
+
+.table-bordered > thead > tr > th,
+.table-bordered > tbody > tr > th,
+.table-bordered > tfoot > tr > th,
+.table-bordered > thead > tr > td,
+.table-bordered > tbody > tr > td,
+.table-bordered > tfoot > tr > td {
+ border: 1px solid #ddd;
+}
+
+.table-bordered > thead > tr > th,
+.table-bordered > thead > tr > td {
+ border-bottom-width: 2px;
+}
+
+.table-striped > tbody > tr:nth-of-type(odd) {
+ background-color: #f9f9f9;
+}
+
+.table-hover > tbody > tr:hover {
+ background-color: #f5f5f5;
+}
+
+table col[class*="col-"] {
+ position: static;
+ display: table-column;
+ float: none;
+}
+
+table td[class*="col-"],
+table th[class*="col-"] {
+ position: static;
+ display: table-cell;
+ float: none;
+}
+
+.table > thead > tr > td.active,
+.table > tbody > tr > td.active,
+.table > tfoot > tr > td.active,
+.table > thead > tr > th.active,
+.table > tbody > tr > th.active,
+.table > tfoot > tr > th.active,
+.table > thead > tr.active > td,
+.table > tbody > tr.active > td,
+.table > tfoot > tr.active > td,
+.table > thead > tr.active > th,
+.table > tbody > tr.active > th,
+.table > tfoot > tr.active > th {
+ background-color: #f5f5f5;
+}
+
+.table-hover > tbody > tr > td.active:hover,
+.table-hover > tbody > tr > th.active:hover,
+.table-hover > tbody > tr.active:hover > td,
+.table-hover > tbody > tr:hover > .active,
+.table-hover > tbody > tr.active:hover > th {
+ background-color: #e8e8e8;
+}
+
+.table > thead > tr > td.success,
+.table > tbody > tr > td.success,
+.table > tfoot > tr > td.success,
+.table > thead > tr > th.success,
+.table > tbody > tr > th.success,
+.table > tfoot > tr > th.success,
+.table > thead > tr.success > td,
+.table > tbody > tr.success > td,
+.table > tfoot > tr.success > td,
+.table > thead > tr.success > th,
+.table > tbody > tr.success > th,
+.table > tfoot > tr.success > th {
+ background-color: #dff0d8;
+}
+
+.table-hover > tbody > tr > td.success:hover,
+.table-hover > tbody > tr > th.success:hover,
+.table-hover > tbody > tr.success:hover > td,
+.table-hover > tbody > tr:hover > .success,
+.table-hover > tbody > tr.success:hover > th {
+ background-color: #d0e9c6;
+}
+
+.table > thead > tr > td.info,
+.table > tbody > tr > td.info,
+.table > tfoot > tr > td.info,
+.table > thead > tr > th.info,
+.table > tbody > tr > th.info,
+.table > tfoot > tr > th.info,
+.table > thead > tr.info > td,
+.table > tbody > tr.info > td,
+.table > tfoot > tr.info > td,
+.table > thead > tr.info > th,
+.table > tbody > tr.info > th,
+.table > tfoot > tr.info > th {
+ background-color: #d9edf7;
+}
+
+.table-hover > tbody > tr > td.info:hover,
+.table-hover > tbody > tr > th.info:hover,
+.table-hover > tbody > tr.info:hover > td,
+.table-hover > tbody > tr:hover > .info,
+.table-hover > tbody > tr.info:hover > th {
+ background-color: #c4e3f3;
+}
+
+.table > thead > tr > td.warning,
+.table > tbody > tr > td.warning,
+.table > tfoot > tr > td.warning,
+.table > thead > tr > th.warning,
+.table > tbody > tr > th.warning,
+.table > tfoot > tr > th.warning,
+.table > thead > tr.warning > td,
+.table > tbody > tr.warning > td,
+.table > tfoot > tr.warning > td,
+.table > thead > tr.warning > th,
+.table > tbody > tr.warning > th,
+.table > tfoot > tr.warning > th {
+ background-color: #fcf8e3;
+}
+
+.table-hover > tbody > tr > td.warning:hover,
+.table-hover > tbody > tr > th.warning:hover,
+.table-hover > tbody > tr.warning:hover > td,
+.table-hover > tbody > tr:hover > .warning,
+.table-hover > tbody > tr.warning:hover > th {
+ background-color: #faf2cc;
+}
+
+.table > thead > tr > td.danger,
+.table > tbody > tr > td.danger,
+.table > tfoot > tr > td.danger,
+.table > thead > tr > th.danger,
+.table > tbody > tr > th.danger,
+.table > tfoot > tr > th.danger,
+.table > thead > tr.danger > td,
+.table > tbody > tr.danger > td,
+.table > tfoot > tr.danger > td,
+.table > thead > tr.danger > th,
+.table > tbody > tr.danger > th,
+.table > tfoot > tr.danger > th {
+ background-color: #f2dede;
+}
+
+.table-hover > tbody > tr > td.danger:hover,
+.table-hover > tbody > tr > th.danger:hover,
+.table-hover > tbody > tr.danger:hover > td,
+.table-hover > tbody > tr:hover > .danger,
+.table-hover > tbody > tr.danger:hover > th {
+ background-color: #ebcccc;
+}
+
+.table-responsive {
+ min-height: .01%;
+ overflow-x: auto;
+}
+
+@media screen and (max-width: 767px) {
+ .table-responsive {
+ width: 100%;
+ margin-bottom: 15px;
+ overflow-y: hidden;
+ -ms-overflow-style: -ms-autohiding-scrollbar;
+ border: 1px solid #ddd;
+ }
+
+ .table-responsive > .table {
+ margin-bottom: 0;
+ }
+
+ .table-responsive > .table > thead > tr > th,
+ .table-responsive > .table > tbody > tr > th,
+ .table-responsive > .table > tfoot > tr > th,
+ .table-responsive > .table > thead > tr > td,
+ .table-responsive > .table > tbody > tr > td,
+ .table-responsive > .table > tfoot > tr > td {
+ white-space: nowrap;
+ }
+
+ .table-responsive > .table-bordered {
+ border: 0;
+ }
+
+ .table-responsive > .table-bordered > thead > tr > th:first-child,
+ .table-responsive > .table-bordered > tbody > tr > th:first-child,
+ .table-responsive > .table-bordered > tfoot > tr > th:first-child,
+ .table-responsive > .table-bordered > thead > tr > td:first-child,
+ .table-responsive > .table-bordered > tbody > tr > td:first-child,
+ .table-responsive > .table-bordered > tfoot > tr > td:first-child {
+ border-left: 0;
+ }
+
+ .table-responsive > .table-bordered > thead > tr > th:last-child,
+ .table-responsive > .table-bordered > tbody > tr > th:last-child,
+ .table-responsive > .table-bordered > tfoot > tr > th:last-child,
+ .table-responsive > .table-bordered > thead > tr > td:last-child,
+ .table-responsive > .table-bordered > tbody > tr > td:last-child,
+ .table-responsive > .table-bordered > tfoot > tr > td:last-child {
+ border-right: 0;
+ }
+
+ .table-responsive > .table-bordered > tbody > tr:last-child > th,
+ .table-responsive > .table-bordered > tfoot > tr:last-child > th,
+ .table-responsive > .table-bordered > tbody > tr:last-child > td,
+ .table-responsive > .table-bordered > tfoot > tr:last-child > td {
+ border-bottom: 0;
+ }
+}
+
+fieldset {
+ min-width: 0;
+ padding: 0;
+ margin: 0;
+ border: 0;
+}
+
+legend {
+ display: block;
+ width: 100%;
+ padding: 0;
+ margin-bottom: 20px;
+ font-size: 21px;
+ line-height: inherit;
+ color: #333;
+ border: 0;
+ border-bottom: 1px solid #e5e5e5;
+}
+
+label {
+ display: inline-block;
+ max-width: 100%;
+ margin-bottom: 5px;
+ font-weight: bold;
+}
+
+input[type="search"] {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+input[type="radio"],
+input[type="checkbox"] {
+ margin: 4px 0 0;
+ margin-top: 1px \9;
+ line-height: normal;
+}
+
+input[type="file"] {
+ display: block;
+}
+
+input[type="range"] {
+ display: block;
+ width: 100%;
+}
+
+select[multiple],
+select[size] {
+ height: auto;
+}
+
+input[type="file"]:focus,
+input[type="radio"]:focus,
+input[type="checkbox"]:focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+
+output {
+ display: block;
+ padding-top: 7px;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #555;
+}
+
+.form-control {
+ display: block;
+ width: 100%;
+ height: 34px;
+ padding: 6px 12px;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #555;
+ background-color: #fff;
+ background-image: none;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
+ -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+ transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+}
+
+.form-control:focus {
+ border-color: #66afe9;
+ outline: 0;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6);
+}
+
+.form-control::-moz-placeholder {
+ color: #999;
+ opacity: 1;
+}
+
+.form-control:-ms-input-placeholder {
+ color: #999;
+}
+
+.form-control::-webkit-input-placeholder {
+ color: #999;
+}
+
+.form-control[disabled],
+.form-control[readonly],
+fieldset[disabled] .form-control {
+ background-color: #eee;
+ opacity: 1;
+}
+
+.form-control[disabled],
+fieldset[disabled] .form-control {
+ cursor: not-allowed;
+}
+
+textarea.form-control {
+ height: auto;
+}
+
+input[type="search"] {
+ -webkit-appearance: none;
+}
+
+@media screen and (-webkit-min-device-pixel-ratio: 0) {
+ input[type="date"].form-control,
+ input[type="time"].form-control,
+ input[type="datetime-local"].form-control,
+ input[type="month"].form-control {
+ line-height: 34px;
+ }
+
+ input[type="date"].input-sm,
+ input[type="time"].input-sm,
+ input[type="datetime-local"].input-sm,
+ input[type="month"].input-sm,
+ .input-group-sm input[type="date"],
+ .input-group-sm input[type="time"],
+ .input-group-sm input[type="datetime-local"],
+ .input-group-sm input[type="month"] {
+ line-height: 30px;
+ }
+
+ input[type="date"].input-lg,
+ input[type="time"].input-lg,
+ input[type="datetime-local"].input-lg,
+ input[type="month"].input-lg,
+ .input-group-lg input[type="date"],
+ .input-group-lg input[type="time"],
+ .input-group-lg input[type="datetime-local"],
+ .input-group-lg input[type="month"] {
+ line-height: 46px;
+ }
+}
+
+.form-group {
+ margin-bottom: 15px;
+}
+
+.radio,
+.checkbox {
+ position: relative;
+ display: block;
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+
+.radio label,
+.checkbox label {
+ min-height: 20px;
+ padding-left: 20px;
+ margin-bottom: 0;
+ font-weight: normal;
+ cursor: pointer;
+}
+
+.radio input[type="radio"],
+.radio-inline input[type="radio"],
+.checkbox input[type="checkbox"],
+.checkbox-inline input[type="checkbox"] {
+ position: absolute;
+ margin-top: 4px \9;
+ margin-left: -20px;
+}
+
+.radio + .radio,
+.checkbox + .checkbox {
+ margin-top: -5px;
+}
+
+.radio-inline,
+.checkbox-inline {
+ position: relative;
+ display: inline-block;
+ padding-left: 20px;
+ margin-bottom: 0;
+ font-weight: normal;
+ vertical-align: middle;
+ cursor: pointer;
+}
+
+.radio-inline + .radio-inline,
+.checkbox-inline + .checkbox-inline {
+ margin-top: 0;
+ margin-left: 10px;
+}
+
+input[type="radio"][disabled],
+input[type="checkbox"][disabled],
+input[type="radio"].disabled,
+input[type="checkbox"].disabled,
+fieldset[disabled] input[type="radio"],
+fieldset[disabled] input[type="checkbox"] {
+ cursor: not-allowed;
+}
+
+.radio-inline.disabled,
+.checkbox-inline.disabled,
+fieldset[disabled] .radio-inline,
+fieldset[disabled] .checkbox-inline {
+ cursor: not-allowed;
+}
+
+.radio.disabled label,
+.checkbox.disabled label,
+fieldset[disabled] .radio label,
+fieldset[disabled] .checkbox label {
+ cursor: not-allowed;
+}
+
+.form-control-static {
+ min-height: 34px;
+ padding-top: 7px;
+ padding-bottom: 7px;
+ margin-bottom: 0;
+}
+
+.form-control-static.input-lg,
+.form-control-static.input-sm {
+ padding-right: 0;
+ padding-left: 0;
+}
+
+.input-sm {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+}
+
+select.input-sm {
+ height: 30px;
+ line-height: 30px;
+}
+
+textarea.input-sm,
+select[multiple].input-sm {
+ height: auto;
+}
+
+.form-group-sm .form-control {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+}
+
+.form-group-sm select.form-control {
+ height: 30px;
+ line-height: 30px;
+}
+
+.form-group-sm textarea.form-control,
+.form-group-sm select[multiple].form-control {
+ height: auto;
+}
+
+.form-group-sm .form-control-static {
+ height: 30px;
+ min-height: 32px;
+ padding: 6px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+}
+
+.input-lg {
+ height: 46px;
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 6px;
+}
+
+select.input-lg {
+ height: 46px;
+ line-height: 46px;
+}
+
+textarea.input-lg,
+select[multiple].input-lg {
+ height: auto;
+}
+
+.form-group-lg .form-control {
+ height: 46px;
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 6px;
+}
+
+.form-group-lg select.form-control {
+ height: 46px;
+ line-height: 46px;
+}
+
+.form-group-lg textarea.form-control,
+.form-group-lg select[multiple].form-control {
+ height: auto;
+}
+
+.form-group-lg .form-control-static {
+ height: 46px;
+ min-height: 38px;
+ padding: 11px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+}
+
+.has-feedback {
+ position: relative;
+}
+
+.has-feedback .form-control {
+ padding-right: 42.5px;
+}
+
+.form-control-feedback {
+ position: absolute;
+ top: 0;
+ right: 0;
+ z-index: 2;
+ display: block;
+ width: 34px;
+ height: 34px;
+ line-height: 34px;
+ text-align: center;
+ pointer-events: none;
+}
+
+.input-lg + .form-control-feedback,
+.input-group-lg + .form-control-feedback,
+.form-group-lg .form-control + .form-control-feedback {
+ width: 46px;
+ height: 46px;
+ line-height: 46px;
+}
+
+.input-sm + .form-control-feedback,
+.input-group-sm + .form-control-feedback,
+.form-group-sm .form-control + .form-control-feedback {
+ width: 30px;
+ height: 30px;
+ line-height: 30px;
+}
+
+.has-success .help-block,
+.has-success .control-label,
+.has-success .radio,
+.has-success .checkbox,
+.has-success .radio-inline,
+.has-success .checkbox-inline,
+.has-success.radio label,
+.has-success.checkbox label,
+.has-success.radio-inline label,
+.has-success.checkbox-inline label {
+ color: #3c763d;
+}
+
+.has-success .form-control {
+ border-color: #3c763d;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+}
+
+.has-success .form-control:focus {
+ border-color: #2b542c;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;
+}
+
+.has-success .input-group-addon {
+ color: #3c763d;
+ background-color: #dff0d8;
+ border-color: #3c763d;
+}
+
+.has-success .form-control-feedback {
+ color: #3c763d;
+}
+
+.has-warning .help-block,
+.has-warning .control-label,
+.has-warning .radio,
+.has-warning .checkbox,
+.has-warning .radio-inline,
+.has-warning .checkbox-inline,
+.has-warning.radio label,
+.has-warning.checkbox label,
+.has-warning.radio-inline label,
+.has-warning.checkbox-inline label {
+ color: #8a6d3b;
+}
+
+.has-warning .form-control {
+ border-color: #8a6d3b;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+}
+
+.has-warning .form-control:focus {
+ border-color: #66512c;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;
+}
+
+.has-warning .input-group-addon {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+ border-color: #8a6d3b;
+}
+
+.has-warning .form-control-feedback {
+ color: #8a6d3b;
+}
+
+.has-error .help-block,
+.has-error .control-label,
+.has-error .radio,
+.has-error .checkbox,
+.has-error .radio-inline,
+.has-error .checkbox-inline,
+.has-error.radio label,
+.has-error.checkbox label,
+.has-error.radio-inline label,
+.has-error.checkbox-inline label {
+ color: #a94442;
+}
+
+.has-error .form-control {
+ border-color: #a94442;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+}
+
+.has-error .form-control:focus {
+ border-color: #843534;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;
+}
+
+.has-error .input-group-addon {
+ color: #a94442;
+ background-color: #f2dede;
+ border-color: #a94442;
+}
+
+.has-error .form-control-feedback {
+ color: #a94442;
+}
+
+.has-feedback label ~ .form-control-feedback {
+ top: 25px;
+}
+
+.has-feedback label.sr-only ~ .form-control-feedback {
+ top: 0;
+}
+
+.help-block {
+ display: block;
+ margin-top: 5px;
+ margin-bottom: 10px;
+ color: #737373;
+}
+
+@media (min-width: 768px) {
+ .form-inline .form-group {
+ display: inline-block;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+
+ .form-inline .form-control {
+ display: inline-block;
+ width: auto;
+ vertical-align: middle;
+ }
+
+ .form-inline .form-control-static {
+ display: inline-block;
+ }
+
+ .form-inline .input-group {
+ display: inline-table;
+ vertical-align: middle;
+ }
+
+ .form-inline .input-group .input-group-addon,
+ .form-inline .input-group .input-group-btn,
+ .form-inline .input-group .form-control {
+ width: auto;
+ }
+
+ .form-inline .input-group > .form-control {
+ width: 100%;
+ }
+
+ .form-inline .control-label {
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+
+ .form-inline .radio,
+ .form-inline .checkbox {
+ display: inline-block;
+ margin-top: 0;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+
+ .form-inline .radio label,
+ .form-inline .checkbox label {
+ padding-left: 0;
+ }
+
+ .form-inline .radio input[type="radio"],
+ .form-inline .checkbox input[type="checkbox"] {
+ position: relative;
+ margin-left: 0;
+ }
+
+ .form-inline .has-feedback .form-control-feedback {
+ top: 0;
+ }
+}
+
+.form-horizontal .radio,
+.form-horizontal .checkbox,
+.form-horizontal .radio-inline,
+.form-horizontal .checkbox-inline {
+ padding-top: 7px;
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+.form-horizontal .radio,
+.form-horizontal .checkbox {
+ min-height: 27px;
+}
+
+.form-horizontal .form-group {
+ margin-right: -15px;
+ margin-left: -15px;
+}
+
+@media (min-width: 768px) {
+ .form-horizontal .control-label {
+ padding-top: 7px;
+ margin-bottom: 0;
+ text-align: right;
+ }
+}
+
+.form-horizontal .has-feedback .form-control-feedback {
+ right: 15px;
+}
+
+@media (min-width: 768px) {
+ .form-horizontal .form-group-lg .control-label {
+ padding-top: 14.333333px;
+ font-size: 18px;
+ }
+}
+
+@media (min-width: 768px) {
+ .form-horizontal .form-group-sm .control-label {
+ padding-top: 6px;
+ font-size: 12px;
+ }
+}
+
+.btn {
+ display: inline-block;
+ padding: 6px 12px;
+ margin-bottom: 0;
+ font-size: 14px;
+ font-weight: normal;
+ line-height: 1.42857143;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: middle;
+ -ms-touch-action: manipulation;
+ touch-action: manipulation;
+ cursor: pointer;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ background-image: none;
+ border: 1px solid transparent;
+ border-radius: 4px;
+}
+
+.btn:focus,
+.btn:active:focus,
+.btn.active:focus,
+.btn.focus,
+.btn:active.focus,
+.btn.active.focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+
+.btn:hover,
+.btn:focus,
+.btn.focus {
+ color: #333;
+ text-decoration: none;
+}
+
+.btn:active,
+.btn.active {
+ background-image: none;
+ outline: 0;
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+}
+
+.btn.disabled,
+.btn[disabled],
+fieldset[disabled] .btn {
+ cursor: not-allowed;
+ filter: alpha(opacity=65);
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ opacity: .65;
+}
+
+a.btn.disabled,
+fieldset[disabled] a.btn {
+ pointer-events: none;
+}
+
+.btn-default {
+ color: #333;
+ background-color: #fff;
+ border-color: #ccc;
+}
+
+.btn-default:focus,
+.btn-default.focus {
+ color: #333;
+ background-color: #e6e6e6;
+ border-color: #8c8c8c;
+}
+
+.btn-default:hover {
+ color: #333;
+ background-color: #e6e6e6;
+ border-color: #adadad;
+}
+
+.btn-default:active,
+.btn-default.active,
+.open > .dropdown-toggle.btn-default {
+ color: #333;
+ background-color: #e6e6e6;
+ border-color: #adadad;
+}
+
+.btn-default:active:hover,
+.btn-default.active:hover,
+.open > .dropdown-toggle.btn-default:hover,
+.btn-default:active:focus,
+.btn-default.active:focus,
+.open > .dropdown-toggle.btn-default:focus,
+.btn-default:active.focus,
+.btn-default.active.focus,
+.open > .dropdown-toggle.btn-default.focus {
+ color: #333;
+ background-color: #d4d4d4;
+ border-color: #8c8c8c;
+}
+
+.btn-default:active,
+.btn-default.active,
+.open > .dropdown-toggle.btn-default {
+ background-image: none;
+}
+
+.btn-default.disabled,
+.btn-default[disabled],
+fieldset[disabled] .btn-default,
+.btn-default.disabled:hover,
+.btn-default[disabled]:hover,
+fieldset[disabled] .btn-default:hover,
+.btn-default.disabled:focus,
+.btn-default[disabled]:focus,
+fieldset[disabled] .btn-default:focus,
+.btn-default.disabled.focus,
+.btn-default[disabled].focus,
+fieldset[disabled] .btn-default.focus,
+.btn-default.disabled:active,
+.btn-default[disabled]:active,
+fieldset[disabled] .btn-default:active,
+.btn-default.disabled.active,
+.btn-default[disabled].active,
+fieldset[disabled] .btn-default.active {
+ background-color: #fff;
+ border-color: #ccc;
+}
+
+.btn-default .badge {
+ color: #fff;
+ background-color: #333;
+}
+
+.btn-primary {
+ color: #fff;
+ background-color: #337ab7;
+ border-color: #2e6da4;
+}
+
+.btn-primary:focus,
+.btn-primary.focus {
+ color: #fff;
+ background-color: #286090;
+ border-color: #122b40;
+}
+
+.btn-primary:hover {
+ color: #fff;
+ background-color: #286090;
+ border-color: #204d74;
+}
+
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+ color: #fff;
+ background-color: #286090;
+ border-color: #204d74;
+}
+
+.btn-primary:active:hover,
+.btn-primary.active:hover,
+.open > .dropdown-toggle.btn-primary:hover,
+.btn-primary:active:focus,
+.btn-primary.active:focus,
+.open > .dropdown-toggle.btn-primary:focus,
+.btn-primary:active.focus,
+.btn-primary.active.focus,
+.open > .dropdown-toggle.btn-primary.focus {
+ color: #fff;
+ background-color: #204d74;
+ border-color: #122b40;
+}
+
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+ background-image: none;
+}
+
+.btn-primary.disabled,
+.btn-primary[disabled],
+fieldset[disabled] .btn-primary,
+.btn-primary.disabled:hover,
+.btn-primary[disabled]:hover,
+fieldset[disabled] .btn-primary:hover,
+.btn-primary.disabled:focus,
+.btn-primary[disabled]:focus,
+fieldset[disabled] .btn-primary:focus,
+.btn-primary.disabled.focus,
+.btn-primary[disabled].focus,
+fieldset[disabled] .btn-primary.focus,
+.btn-primary.disabled:active,
+.btn-primary[disabled]:active,
+fieldset[disabled] .btn-primary:active,
+.btn-primary.disabled.active,
+.btn-primary[disabled].active,
+fieldset[disabled] .btn-primary.active {
+ background-color: #337ab7;
+ border-color: #2e6da4;
+}
+
+.btn-primary .badge {
+ color: #337ab7;
+ background-color: #fff;
+}
+
+.btn-success {
+ color: #fff;
+ background-color: #5cb85c;
+ border-color: #4cae4c;
+}
+
+.btn-success:focus,
+.btn-success.focus {
+ color: #fff;
+ background-color: #449d44;
+ border-color: #255625;
+}
+
+.btn-success:hover {
+ color: #fff;
+ background-color: #449d44;
+ border-color: #398439;
+}
+
+.btn-success:active,
+.btn-success.active,
+.open > .dropdown-toggle.btn-success {
+ color: #fff;
+ background-color: #449d44;
+ border-color: #398439;
+}
+
+.btn-success:active:hover,
+.btn-success.active:hover,
+.open > .dropdown-toggle.btn-success:hover,
+.btn-success:active:focus,
+.btn-success.active:focus,
+.open > .dropdown-toggle.btn-success:focus,
+.btn-success:active.focus,
+.btn-success.active.focus,
+.open > .dropdown-toggle.btn-success.focus {
+ color: #fff;
+ background-color: #398439;
+ border-color: #255625;
+}
+
+.btn-success:active,
+.btn-success.active,
+.open > .dropdown-toggle.btn-success {
+ background-image: none;
+}
+
+.btn-success.disabled,
+.btn-success[disabled],
+fieldset[disabled] .btn-success,
+.btn-success.disabled:hover,
+.btn-success[disabled]:hover,
+fieldset[disabled] .btn-success:hover,
+.btn-success.disabled:focus,
+.btn-success[disabled]:focus,
+fieldset[disabled] .btn-success:focus,
+.btn-success.disabled.focus,
+.btn-success[disabled].focus,
+fieldset[disabled] .btn-success.focus,
+.btn-success.disabled:active,
+.btn-success[disabled]:active,
+fieldset[disabled] .btn-success:active,
+.btn-success.disabled.active,
+.btn-success[disabled].active,
+fieldset[disabled] .btn-success.active {
+ background-color: #5cb85c;
+ border-color: #4cae4c;
+}
+
+.btn-success .badge {
+ color: #5cb85c;
+ background-color: #fff;
+}
+
+.btn-info {
+ color: #fff;
+ background-color: #5bc0de;
+ border-color: #46b8da;
+}
+
+.btn-info:focus,
+.btn-info.focus {
+ color: #fff;
+ background-color: #31b0d5;
+ border-color: #1b6d85;
+}
+
+.btn-info:hover {
+ color: #fff;
+ background-color: #31b0d5;
+ border-color: #269abc;
+}
+
+.btn-info:active,
+.btn-info.active,
+.open > .dropdown-toggle.btn-info {
+ color: #fff;
+ background-color: #31b0d5;
+ border-color: #269abc;
+}
+
+.btn-info:active:hover,
+.btn-info.active:hover,
+.open > .dropdown-toggle.btn-info:hover,
+.btn-info:active:focus,
+.btn-info.active:focus,
+.open > .dropdown-toggle.btn-info:focus,
+.btn-info:active.focus,
+.btn-info.active.focus,
+.open > .dropdown-toggle.btn-info.focus {
+ color: #fff;
+ background-color: #269abc;
+ border-color: #1b6d85;
+}
+
+.btn-info:active,
+.btn-info.active,
+.open > .dropdown-toggle.btn-info {
+ background-image: none;
+}
+
+.btn-info.disabled,
+.btn-info[disabled],
+fieldset[disabled] .btn-info,
+.btn-info.disabled:hover,
+.btn-info[disabled]:hover,
+fieldset[disabled] .btn-info:hover,
+.btn-info.disabled:focus,
+.btn-info[disabled]:focus,
+fieldset[disabled] .btn-info:focus,
+.btn-info.disabled.focus,
+.btn-info[disabled].focus,
+fieldset[disabled] .btn-info.focus,
+.btn-info.disabled:active,
+.btn-info[disabled]:active,
+fieldset[disabled] .btn-info:active,
+.btn-info.disabled.active,
+.btn-info[disabled].active,
+fieldset[disabled] .btn-info.active {
+ background-color: #5bc0de;
+ border-color: #46b8da;
+}
+
+.btn-info .badge {
+ color: #5bc0de;
+ background-color: #fff;
+}
+
+.btn-warning {
+ color: #fff;
+ background-color: #f0ad4e;
+ border-color: #eea236;
+}
+
+.btn-warning:focus,
+.btn-warning.focus {
+ color: #fff;
+ background-color: #ec971f;
+ border-color: #985f0d;
+}
+
+.btn-warning:hover {
+ color: #fff;
+ background-color: #ec971f;
+ border-color: #d58512;
+}
+
+.btn-warning:active,
+.btn-warning.active,
+.open > .dropdown-toggle.btn-warning {
+ color: #fff;
+ background-color: #ec971f;
+ border-color: #d58512;
+}
+
+.btn-warning:active:hover,
+.btn-warning.active:hover,
+.open > .dropdown-toggle.btn-warning:hover,
+.btn-warning:active:focus,
+.btn-warning.active:focus,
+.open > .dropdown-toggle.btn-warning:focus,
+.btn-warning:active.focus,
+.btn-warning.active.focus,
+.open > .dropdown-toggle.btn-warning.focus {
+ color: #fff;
+ background-color: #d58512;
+ border-color: #985f0d;
+}
+
+.btn-warning:active,
+.btn-warning.active,
+.open > .dropdown-toggle.btn-warning {
+ background-image: none;
+}
+
+.btn-warning.disabled,
+.btn-warning[disabled],
+fieldset[disabled] .btn-warning,
+.btn-warning.disabled:hover,
+.btn-warning[disabled]:hover,
+fieldset[disabled] .btn-warning:hover,
+.btn-warning.disabled:focus,
+.btn-warning[disabled]:focus,
+fieldset[disabled] .btn-warning:focus,
+.btn-warning.disabled.focus,
+.btn-warning[disabled].focus,
+fieldset[disabled] .btn-warning.focus,
+.btn-warning.disabled:active,
+.btn-warning[disabled]:active,
+fieldset[disabled] .btn-warning:active,
+.btn-warning.disabled.active,
+.btn-warning[disabled].active,
+fieldset[disabled] .btn-warning.active {
+ background-color: #f0ad4e;
+ border-color: #eea236;
+}
+
+.btn-warning .badge {
+ color: #f0ad4e;
+ background-color: #fff;
+}
+
+.btn-danger {
+ color: #fff;
+ background-color: #d9534f;
+ border-color: #d43f3a;
+}
+
+.btn-danger:focus,
+.btn-danger.focus {
+ color: #fff;
+ background-color: #c9302c;
+ border-color: #761c19;
+}
+
+.btn-danger:hover {
+ color: #fff;
+ background-color: #c9302c;
+ border-color: #ac2925;
+}
+
+.btn-danger:active,
+.btn-danger.active,
+.open > .dropdown-toggle.btn-danger {
+ color: #fff;
+ background-color: #c9302c;
+ border-color: #ac2925;
+}
+
+.btn-danger:active:hover,
+.btn-danger.active:hover,
+.open > .dropdown-toggle.btn-danger:hover,
+.btn-danger:active:focus,
+.btn-danger.active:focus,
+.open > .dropdown-toggle.btn-danger:focus,
+.btn-danger:active.focus,
+.btn-danger.active.focus,
+.open > .dropdown-toggle.btn-danger.focus {
+ color: #fff;
+ background-color: #ac2925;
+ border-color: #761c19;
+}
+
+.btn-danger:active,
+.btn-danger.active,
+.open > .dropdown-toggle.btn-danger {
+ background-image: none;
+}
+
+.btn-danger.disabled,
+.btn-danger[disabled],
+fieldset[disabled] .btn-danger,
+.btn-danger.disabled:hover,
+.btn-danger[disabled]:hover,
+fieldset[disabled] .btn-danger:hover,
+.btn-danger.disabled:focus,
+.btn-danger[disabled]:focus,
+fieldset[disabled] .btn-danger:focus,
+.btn-danger.disabled.focus,
+.btn-danger[disabled].focus,
+fieldset[disabled] .btn-danger.focus,
+.btn-danger.disabled:active,
+.btn-danger[disabled]:active,
+fieldset[disabled] .btn-danger:active,
+.btn-danger.disabled.active,
+.btn-danger[disabled].active,
+fieldset[disabled] .btn-danger.active {
+ background-color: #d9534f;
+ border-color: #d43f3a;
+}
+
+.btn-danger .badge {
+ color: #d9534f;
+ background-color: #fff;
+}
+
+.btn-link {
+ font-weight: normal;
+ color: #337ab7;
+ border-radius: 0;
+}
+
+.btn-link,
+.btn-link:active,
+.btn-link.active,
+.btn-link[disabled],
+fieldset[disabled] .btn-link {
+ background-color: transparent;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+
+.btn-link,
+.btn-link:hover,
+.btn-link:focus,
+.btn-link:active {
+ border-color: transparent;
+}
+
+.btn-link:hover,
+.btn-link:focus {
+ color: #23527c;
+ text-decoration: underline;
+ background-color: transparent;
+}
+
+.btn-link[disabled]:hover,
+fieldset[disabled] .btn-link:hover,
+.btn-link[disabled]:focus,
+fieldset[disabled] .btn-link:focus {
+ color: #777;
+ text-decoration: none;
+}
+
+.btn-lg,
+.btn-group-lg > .btn {
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 6px;
+}
+
+.btn-sm,
+.btn-group-sm > .btn {
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+}
+
+.btn-xs,
+.btn-group-xs > .btn {
+ padding: 1px 5px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+}
+
+.btn-block {
+ display: block;
+ width: 100%;
+}
+
+.btn-block + .btn-block {
+ margin-top: 5px;
+}
+
+input[type="submit"].btn-block,
+input[type="reset"].btn-block,
+input[type="button"].btn-block {
+ width: 100%;
+}
+
+.fade {
+ opacity: 0;
+ -webkit-transition: opacity .15s linear;
+ -o-transition: opacity .15s linear;
+ transition: opacity .15s linear;
+}
+
+.fade.in {
+ opacity: 1;
+}
+
+.collapse {
+ display: none;
+}
+
+.collapse.in {
+ display: block;
+}
+
+tr.collapse.in {
+ display: table-row;
+}
+
+tbody.collapse.in {
+ display: table-row-group;
+}
+
+.collapsing {
+ position: relative;
+ height: 0;
+ overflow: hidden;
+ -webkit-transition-timing-function: ease;
+ -o-transition-timing-function: ease;
+ transition-timing-function: ease;
+ -webkit-transition-duration: .35s;
+ -o-transition-duration: .35s;
+ transition-duration: .35s;
+ -webkit-transition-property: height, visibility;
+ -o-transition-property: height, visibility;
+ transition-property: height, visibility;
+}
+
+.caret {
+ display: inline-block;
+ width: 0;
+ height: 0;
+ margin-left: 2px;
+ vertical-align: middle;
+ border-top: 4px dashed;
+ border-top: 4px solid \9;
+ border-right: 4px solid transparent;
+ border-left: 4px solid transparent;
+}
+
+.dropup,
+.dropdown {
+ position: relative;
+}
+
+.dropdown-toggle:focus {
+ outline: 0;
+}
+
+.dropdown-menu {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ z-index: 1000;
+ display: none;
+ float: left;
+ min-width: 160px;
+ padding: 5px 0;
+ margin: 2px 0 0;
+ font-size: 14px;
+ text-align: left;
+ list-style: none;
+ background-color: #fff;
+ -webkit-background-clip: padding-box;
+ background-clip: padding-box;
+ border: 1px solid #ccc;
+ border: 1px solid rgba(0, 0, 0, .15);
+ border-radius: 4px;
+ -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
+ box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
+}
+
+.dropdown-menu.pull-right {
+ right: 0;
+ left: auto;
+}
+
+.dropdown-menu .divider {
+ height: 1px;
+ margin: 9px 0;
+ overflow: hidden;
+ background-color: #e5e5e5;
+}
+
+.dropdown-menu > li > a {
+ display: block;
+ padding: 3px 20px;
+ clear: both;
+ font-weight: normal;
+ line-height: 1.42857143;
+ color: #333;
+ white-space: nowrap;
+}
+
+.dropdown-menu > li > a:hover,
+.dropdown-menu > li > a:focus {
+ color: #262626;
+ text-decoration: none;
+ background-color: #f5f5f5;
+}
+
+.dropdown-menu > .active > a,
+.dropdown-menu > .active > a:hover,
+.dropdown-menu > .active > a:focus {
+ color: #fff;
+ text-decoration: none;
+ background-color: #337ab7;
+ outline: 0;
+}
+
+.dropdown-menu > .disabled > a,
+.dropdown-menu > .disabled > a:hover,
+.dropdown-menu > .disabled > a:focus {
+ color: #777;
+}
+
+.dropdown-menu > .disabled > a:hover,
+.dropdown-menu > .disabled > a:focus {
+ text-decoration: none;
+ cursor: not-allowed;
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+}
+
+.open > .dropdown-menu {
+ display: block;
+}
+
+.open > a {
+ outline: 0;
+}
+
+.dropdown-menu-right {
+ right: 0;
+ left: auto;
+}
+
+.dropdown-menu-left {
+ right: auto;
+ left: 0;
+}
+
+.dropdown-header {
+ display: block;
+ padding: 3px 20px;
+ font-size: 12px;
+ line-height: 1.42857143;
+ color: #777;
+ white-space: nowrap;
+}
+
+.dropdown-backdrop {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 990;
+}
+
+.pull-right > .dropdown-menu {
+ right: 0;
+ left: auto;
+}
+
+.dropup .caret,
+.navbar-fixed-bottom .dropdown .caret {
+ content: "";
+ border-top: 0;
+ border-bottom: 4px dashed;
+ border-bottom: 4px solid \9;
+}
+
+.dropup .dropdown-menu,
+.navbar-fixed-bottom .dropdown .dropdown-menu {
+ top: auto;
+ bottom: 100%;
+ margin-bottom: 2px;
+}
+
+@media (min-width: 768px) {
+ .navbar-right .dropdown-menu {
+ right: 0;
+ left: auto;
+ }
+
+ .navbar-right .dropdown-menu-left {
+ right: auto;
+ left: 0;
+ }
+}
+
+.btn-group,
+.btn-group-vertical {
+ position: relative;
+ display: inline-block;
+ vertical-align: middle;
+}
+
+.btn-group > .btn,
+.btn-group-vertical > .btn {
+ position: relative;
+ float: left;
+}
+
+.btn-group > .btn:hover,
+.btn-group-vertical > .btn:hover,
+.btn-group > .btn:focus,
+.btn-group-vertical > .btn:focus,
+.btn-group > .btn:active,
+.btn-group-vertical > .btn:active,
+.btn-group > .btn.active,
+.btn-group-vertical > .btn.active {
+ z-index: 2;
+}
+
+.btn-group .btn + .btn,
+.btn-group .btn + .btn-group,
+.btn-group .btn-group + .btn,
+.btn-group .btn-group + .btn-group {
+ margin-left: -1px;
+}
+
+.btn-toolbar {
+ margin-left: -5px;
+}
+
+.btn-toolbar .btn,
+.btn-toolbar .btn-group,
+.btn-toolbar .input-group {
+ float: left;
+}
+
+.btn-toolbar > .btn,
+.btn-toolbar > .btn-group,
+.btn-toolbar > .input-group {
+ margin-left: 5px;
+}
+
+.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
+ border-radius: 0;
+}
+
+.btn-group > .btn:first-child {
+ margin-left: 0;
+}
+
+.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+
+.btn-group > .btn:last-child:not(:first-child),
+.btn-group > .dropdown-toggle:not(:first-child) {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+
+.btn-group > .btn-group {
+ float: left;
+}
+
+.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
+ border-radius: 0;
+}
+
+.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,
+.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+
+.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+
+.btn-group .dropdown-toggle:active,
+.btn-group.open .dropdown-toggle {
+ outline: 0;
+}
+
+.btn-group > .btn + .dropdown-toggle {
+ padding-right: 8px;
+ padding-left: 8px;
+}
+
+.btn-group > .btn-lg + .dropdown-toggle {
+ padding-right: 12px;
+ padding-left: 12px;
+}
+
+.btn-group.open .dropdown-toggle {
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+}
+
+.btn-group.open .dropdown-toggle.btn-link {
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+
+.btn .caret {
+ margin-left: 0;
+}
+
+.btn-lg .caret {
+ border-width: 5px 5px 0;
+ border-bottom-width: 0;
+}
+
+.dropup .btn-lg .caret {
+ border-width: 0 5px 5px;
+}
+
+.btn-group-vertical > .btn,
+.btn-group-vertical > .btn-group,
+.btn-group-vertical > .btn-group > .btn {
+ display: block;
+ float: none;
+ width: 100%;
+ max-width: 100%;
+}
+
+.btn-group-vertical > .btn-group > .btn {
+ float: none;
+}
+
+.btn-group-vertical > .btn + .btn,
+.btn-group-vertical > .btn + .btn-group,
+.btn-group-vertical > .btn-group + .btn,
+.btn-group-vertical > .btn-group + .btn-group {
+ margin-top: -1px;
+ margin-left: 0;
+}
+
+.btn-group-vertical > .btn:not(:first-child):not(:last-child) {
+ border-radius: 0;
+}
+
+.btn-group-vertical > .btn:first-child:not(:last-child) {
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+
+.btn-group-vertical > .btn:last-child:not(:first-child) {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ border-bottom-left-radius: 4px;
+}
+
+.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
+ border-radius: 0;
+}
+
+.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,
+.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+
+.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+
+.btn-group-justified {
+ display: table;
+ width: 100%;
+ table-layout: fixed;
+ border-collapse: separate;
+}
+
+.btn-group-justified > .btn,
+.btn-group-justified > .btn-group {
+ display: table-cell;
+ float: none;
+ width: 1%;
+}
+
+.btn-group-justified > .btn-group .btn {
+ width: 100%;
+}
+
+.btn-group-justified > .btn-group .dropdown-menu {
+ left: auto;
+}
+
+[data-toggle="buttons"] > .btn input[type="radio"],
+[data-toggle="buttons"] > .btn-group > .btn input[type="radio"],
+[data-toggle="buttons"] > .btn input[type="checkbox"],
+[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] {
+ position: absolute;
+ clip: rect(0, 0, 0, 0);
+ pointer-events: none;
+}
+
+.input-group {
+ position: relative;
+ display: table;
+ border-collapse: separate;
+}
+
+.input-group[class*="col-"] {
+ float: none;
+ padding-right: 0;
+ padding-left: 0;
+}
+
+.input-group .form-control {
+ position: relative;
+ z-index: 2;
+ float: left;
+ width: 100%;
+ margin-bottom: 0;
+}
+
+.input-group-lg > .form-control,
+.input-group-lg > .input-group-addon,
+.input-group-lg > .input-group-btn > .btn {
+ height: 46px;
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 6px;
+}
+
+select.input-group-lg > .form-control,
+select.input-group-lg > .input-group-addon,
+select.input-group-lg > .input-group-btn > .btn {
+ height: 46px;
+ line-height: 46px;
+}
+
+textarea.input-group-lg > .form-control,
+textarea.input-group-lg > .input-group-addon,
+textarea.input-group-lg > .input-group-btn > .btn,
+select[multiple].input-group-lg > .form-control,
+select[multiple].input-group-lg > .input-group-addon,
+select[multiple].input-group-lg > .input-group-btn > .btn {
+ height: auto;
+}
+
+.input-group-sm > .form-control,
+.input-group-sm > .input-group-addon,
+.input-group-sm > .input-group-btn > .btn {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+}
+
+select.input-group-sm > .form-control,
+select.input-group-sm > .input-group-addon,
+select.input-group-sm > .input-group-btn > .btn {
+ height: 30px;
+ line-height: 30px;
+}
+
+textarea.input-group-sm > .form-control,
+textarea.input-group-sm > .input-group-addon,
+textarea.input-group-sm > .input-group-btn > .btn,
+select[multiple].input-group-sm > .form-control,
+select[multiple].input-group-sm > .input-group-addon,
+select[multiple].input-group-sm > .input-group-btn > .btn {
+ height: auto;
+}
+
+.input-group-addon,
+.input-group-btn,
+.input-group .form-control {
+ display: table-cell;
+}
+
+.input-group-addon:not(:first-child):not(:last-child),
+.input-group-btn:not(:first-child):not(:last-child),
+.input-group .form-control:not(:first-child):not(:last-child) {
+ border-radius: 0;
+}
+
+.input-group-addon,
+.input-group-btn {
+ width: 1%;
+ white-space: nowrap;
+ vertical-align: middle;
+}
+
+.input-group-addon {
+ padding: 6px 12px;
+ font-size: 14px;
+ font-weight: normal;
+ line-height: 1;
+ color: #555;
+ text-align: center;
+ background-color: #eee;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+}
+
+.input-group-addon.input-sm {
+ padding: 5px 10px;
+ font-size: 12px;
+ border-radius: 3px;
+}
+
+.input-group-addon.input-lg {
+ padding: 10px 16px;
+ font-size: 18px;
+ border-radius: 6px;
+}
+
+.input-group-addon input[type="radio"],
+.input-group-addon input[type="checkbox"] {
+ margin-top: 0;
+}
+
+.input-group .form-control:first-child,
+.input-group-addon:first-child,
+.input-group-btn:first-child > .btn,
+.input-group-btn:first-child > .btn-group > .btn,
+.input-group-btn:first-child > .dropdown-toggle,
+.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),
+.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+
+.input-group-addon:first-child {
+ border-right: 0;
+}
+
+.input-group .form-control:last-child,
+.input-group-addon:last-child,
+.input-group-btn:last-child > .btn,
+.input-group-btn:last-child > .btn-group > .btn,
+.input-group-btn:last-child > .dropdown-toggle,
+.input-group-btn:first-child > .btn:not(:first-child),
+.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+
+.input-group-addon:last-child {
+ border-left: 0;
+}
+
+.input-group-btn {
+ position: relative;
+ font-size: 0;
+ white-space: nowrap;
+}
+
+.input-group-btn > .btn {
+ position: relative;
+}
+
+.input-group-btn > .btn + .btn {
+ margin-left: -1px;
+}
+
+.input-group-btn > .btn:hover,
+.input-group-btn > .btn:focus,
+.input-group-btn > .btn:active {
+ z-index: 2;
+}
+
+.input-group-btn:first-child > .btn,
+.input-group-btn:first-child > .btn-group {
+ margin-right: -1px;
+}
+
+.input-group-btn:last-child > .btn,
+.input-group-btn:last-child > .btn-group {
+ z-index: 2;
+ margin-left: -1px;
+}
+
+.nav {
+ padding-left: 0;
+ margin-bottom: 0;
+ list-style: none;
+}
+
+.nav > li {
+ position: relative;
+ display: block;
+}
+
+.nav > li > a {
+ position: relative;
+ display: block;
+ padding: 10px 15px;
+}
+
+.nav > li > a:hover,
+.nav > li > a:focus {
+ text-decoration: none;
+ background-color: #eee;
+}
+
+.nav > li.disabled > a {
+ color: #777;
+}
+
+.nav > li.disabled > a:hover,
+.nav > li.disabled > a:focus {
+ color: #777;
+ text-decoration: none;
+ cursor: not-allowed;
+ background-color: transparent;
+}
+
+.nav .open > a,
+.nav .open > a:hover,
+.nav .open > a:focus {
+ background-color: #eee;
+ border-color: #337ab7;
+}
+
+.nav .nav-divider {
+ height: 1px;
+ margin: 9px 0;
+ overflow: hidden;
+ background-color: #e5e5e5;
+}
+
+.nav > li > a > img {
+ max-width: none;
+}
+
+.nav-tabs {
+ border-bottom: 1px solid #ddd;
+}
+
+.nav-tabs > li {
+ float: left;
+ margin-bottom: -1px;
+}
+
+.nav-tabs > li > a {
+ margin-right: 2px;
+ line-height: 1.42857143;
+ border: 1px solid transparent;
+ border-radius: 4px 4px 0 0;
+}
+
+.nav-tabs > li > a:hover {
+ border-color: #eee #eee #ddd;
+}
+
+.nav-tabs > li.active > a,
+.nav-tabs > li.active > a:hover,
+.nav-tabs > li.active > a:focus {
+ color: #555;
+ cursor: default;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-bottom-color: transparent;
+}
+
+.nav-tabs.nav-justified {
+ width: 100%;
+ border-bottom: 0;
+}
+
+.nav-tabs.nav-justified > li {
+ float: none;
+}
+
+.nav-tabs.nav-justified > li > a {
+ margin-bottom: 5px;
+ text-align: center;
+}
+
+.nav-tabs.nav-justified > .dropdown .dropdown-menu {
+ top: auto;
+ left: auto;
+}
+
+@media (min-width: 768px) {
+ .nav-tabs.nav-justified > li {
+ display: table-cell;
+ width: 1%;
+ }
+
+ .nav-tabs.nav-justified > li > a {
+ margin-bottom: 0;
+ }
+}
+
+.nav-tabs.nav-justified > li > a {
+ margin-right: 0;
+ border-radius: 4px;
+}
+
+.nav-tabs.nav-justified > .active > a,
+.nav-tabs.nav-justified > .active > a:hover,
+.nav-tabs.nav-justified > .active > a:focus {
+ border: 1px solid #ddd;
+}
+
+@media (min-width: 768px) {
+ .nav-tabs.nav-justified > li > a {
+ border-bottom: 1px solid #ddd;
+ border-radius: 4px 4px 0 0;
+ }
+
+ .nav-tabs.nav-justified > .active > a,
+ .nav-tabs.nav-justified > .active > a:hover,
+ .nav-tabs.nav-justified > .active > a:focus {
+ border-bottom-color: #fff;
+ }
+}
+
+.nav-pills > li {
+ float: left;
+}
+
+.nav-pills > li > a {
+ border-radius: 4px;
+}
+
+.nav-pills > li + li {
+ margin-left: 2px;
+}
+
+.nav-pills > li.active > a,
+.nav-pills > li.active > a:hover,
+.nav-pills > li.active > a:focus {
+ color: #fff;
+ background-color: #337ab7;
+}
+
+.nav-stacked > li {
+ float: none;
+}
+
+.nav-stacked > li + li {
+ margin-top: 2px;
+ margin-left: 0;
+}
+
+.nav-justified {
+ width: 100%;
+}
+
+.nav-justified > li {
+ float: none;
+}
+
+.nav-justified > li > a {
+ margin-bottom: 5px;
+ text-align: center;
+}
+
+.nav-justified > .dropdown .dropdown-menu {
+ top: auto;
+ left: auto;
+}
+
+@media (min-width: 768px) {
+ .nav-justified > li {
+ display: table-cell;
+ width: 1%;
+ }
+
+ .nav-justified > li > a {
+ margin-bottom: 0;
+ }
+}
+
+.nav-tabs-justified {
+ border-bottom: 0;
+}
+
+.nav-tabs-justified > li > a {
+ margin-right: 0;
+ border-radius: 4px;
+}
+
+.nav-tabs-justified > .active > a,
+.nav-tabs-justified > .active > a:hover,
+.nav-tabs-justified > .active > a:focus {
+ border: 1px solid #ddd;
+}
+
+@media (min-width: 768px) {
+ .nav-tabs-justified > li > a {
+ border-bottom: 1px solid #ddd;
+ border-radius: 4px 4px 0 0;
+ }
+
+ .nav-tabs-justified > .active > a,
+ .nav-tabs-justified > .active > a:hover,
+ .nav-tabs-justified > .active > a:focus {
+ border-bottom-color: #fff;
+ }
+}
+
+.tab-content > .tab-pane {
+ display: none;
+}
+
+.tab-content > .active {
+ display: block;
+}
+
+.nav-tabs .dropdown-menu {
+ margin-top: -1px;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+
+.navbar {
+ position: relative;
+ min-height: 50px;
+ margin-bottom: 20px;
+ border: 1px solid transparent;
+}
+
+@media (min-width: 768px) {
+ .navbar {
+ border-radius: 4px;
+ }
+}
+
+@media (min-width: 768px) {
+ .navbar-header {
+ float: left;
+ }
+}
+
+.navbar-collapse {
+ padding-right: 15px;
+ padding-left: 15px;
+ overflow-x: visible;
+ -webkit-overflow-scrolling: touch;
+ border-top: 1px solid transparent;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
+}
+
+.navbar-collapse.in {
+ overflow-y: auto;
+}
+
+@media (min-width: 768px) {
+ .navbar-collapse {
+ width: auto;
+ border-top: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ }
+
+ .navbar-collapse.collapse {
+ display: block !important;
+ height: auto !important;
+ padding-bottom: 0;
+ overflow: visible !important;
+ }
+
+ .navbar-collapse.in {
+ overflow-y: visible;
+ }
+
+ .navbar-fixed-top .navbar-collapse,
+ .navbar-static-top .navbar-collapse,
+ .navbar-fixed-bottom .navbar-collapse {
+ padding-right: 0;
+ padding-left: 0;
+ }
+}
+
+.navbar-fixed-top .navbar-collapse,
+.navbar-fixed-bottom .navbar-collapse {
+ max-height: 340px;
+}
+
+@media (max-device-width: 480px) and (orientation: landscape) {
+ .navbar-fixed-top .navbar-collapse,
+ .navbar-fixed-bottom .navbar-collapse {
+ max-height: 200px;
+ }
+}
+
+.container > .navbar-header,
+.container-fluid > .navbar-header,
+.container > .navbar-collapse,
+.container-fluid > .navbar-collapse {
+ margin-right: -15px;
+ margin-left: -15px;
+}
+
+@media (min-width: 768px) {
+ .container > .navbar-header,
+ .container-fluid > .navbar-header,
+ .container > .navbar-collapse,
+ .container-fluid > .navbar-collapse {
+ margin-right: 0;
+ margin-left: 0;
+ }
+}
+
+.navbar-static-top {
+ z-index: 1000;
+ border-width: 0 0 1px;
+}
+
+@media (min-width: 768px) {
+ .navbar-static-top {
+ border-radius: 0;
+ }
+}
+
+.navbar-fixed-top,
+.navbar-fixed-bottom {
+ position: fixed;
+ right: 0;
+ left: 0;
+ z-index: 1030;
+}
+
+@media (min-width: 768px) {
+ .navbar-fixed-top,
+ .navbar-fixed-bottom {
+ border-radius: 0;
+ }
+}
+
+.navbar-fixed-top {
+ top: 0;
+ border-width: 0 0 1px;
+}
+
+.navbar-fixed-bottom {
+ bottom: 0;
+ margin-bottom: 0;
+ border-width: 1px 0 0;
+}
+
+.navbar-brand {
+ float: left;
+ height: 50px;
+ padding: 15px 15px;
+ font-size: 18px;
+ line-height: 20px;
+}
+
+.navbar-brand:hover,
+.navbar-brand:focus {
+ text-decoration: none;
+}
+
+.navbar-brand > img {
+ display: block;
+}
+
+@media (min-width: 768px) {
+ .navbar > .container .navbar-brand,
+ .navbar > .container-fluid .navbar-brand {
+ margin-left: -15px;
+ }
+}
+
+.navbar-toggle {
+ position: relative;
+ float: right;
+ padding: 9px 10px;
+ margin-top: 8px;
+ margin-right: 15px;
+ margin-bottom: 8px;
+ background-color: transparent;
+ background-image: none;
+ border: 1px solid transparent;
+ border-radius: 4px;
+}
+
+.navbar-toggle:focus {
+ outline: 0;
+}
+
+.navbar-toggle .icon-bar {
+ display: block;
+ width: 22px;
+ height: 2px;
+ border-radius: 1px;
+}
+
+.navbar-toggle .icon-bar + .icon-bar {
+ margin-top: 4px;
+}
+
+@media (min-width: 768px) {
+ .navbar-toggle {
+ display: none;
+ }
+}
+
+.navbar-nav {
+ margin: 7.5px -15px;
+}
+
+.navbar-nav > li > a {
+ padding-top: 10px;
+ padding-bottom: 10px;
+ line-height: 20px;
+}
+
+@media (max-width: 767px) {
+ .navbar-nav .open .dropdown-menu {
+ position: static;
+ float: none;
+ width: auto;
+ margin-top: 0;
+ background-color: transparent;
+ border: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ }
+
+ .navbar-nav .open .dropdown-menu > li > a,
+ .navbar-nav .open .dropdown-menu .dropdown-header {
+ padding: 5px 15px 5px 25px;
+ }
+
+ .navbar-nav .open .dropdown-menu > li > a {
+ line-height: 20px;
+ }
+
+ .navbar-nav .open .dropdown-menu > li > a:hover,
+ .navbar-nav .open .dropdown-menu > li > a:focus {
+ background-image: none;
+ }
+}
+
+@media (min-width: 768px) {
+ .navbar-nav {
+ float: left;
+ margin: 0;
+ }
+
+ .navbar-nav > li {
+ float: left;
+ }
+
+ .navbar-nav > li > a {
+ padding-top: 15px;
+ padding-bottom: 15px;
+ }
+}
+
+.navbar-form {
+ padding: 10px 15px;
+ margin-top: 8px;
+ margin-right: -15px;
+ margin-bottom: 8px;
+ margin-left: -15px;
+ border-top: 1px solid transparent;
+ border-bottom: 1px solid transparent;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);
+}
+
+@media (min-width: 768px) {
+ .navbar-form .form-group {
+ display: inline-block;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+
+ .navbar-form .form-control {
+ display: inline-block;
+ width: auto;
+ vertical-align: middle;
+ }
+
+ .navbar-form .form-control-static {
+ display: inline-block;
+ }
+
+ .navbar-form .input-group {
+ display: inline-table;
+ vertical-align: middle;
+ }
+
+ .navbar-form .input-group .input-group-addon,
+ .navbar-form .input-group .input-group-btn,
+ .navbar-form .input-group .form-control {
+ width: auto;
+ }
+
+ .navbar-form .input-group > .form-control {
+ width: 100%;
+ }
+
+ .navbar-form .control-label {
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+
+ .navbar-form .radio,
+ .navbar-form .checkbox {
+ display: inline-block;
+ margin-top: 0;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+
+ .navbar-form .radio label,
+ .navbar-form .checkbox label {
+ padding-left: 0;
+ }
+
+ .navbar-form .radio input[type="radio"],
+ .navbar-form .checkbox input[type="checkbox"] {
+ position: relative;
+ margin-left: 0;
+ }
+
+ .navbar-form .has-feedback .form-control-feedback {
+ top: 0;
+ }
+}
+
+@media (max-width: 767px) {
+ .navbar-form .form-group {
+ margin-bottom: 5px;
+ }
+
+ .navbar-form .form-group:last-child {
+ margin-bottom: 0;
+ }
+}
+
+@media (min-width: 768px) {
+ .navbar-form {
+ width: auto;
+ padding-top: 0;
+ padding-bottom: 0;
+ margin-right: 0;
+ margin-left: 0;
+ border: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ }
+}
+
+.navbar-nav > li > .dropdown-menu {
+ margin-top: 0;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+
+.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {
+ margin-bottom: 0;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+
+.navbar-btn {
+ margin-top: 8px;
+ margin-bottom: 8px;
+}
+
+.navbar-btn.btn-sm {
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+
+.navbar-btn.btn-xs {
+ margin-top: 14px;
+ margin-bottom: 14px;
+}
+
+.navbar-text {
+ margin-top: 15px;
+ margin-bottom: 15px;
+}
+
+@media (min-width: 768px) {
+ .navbar-text {
+ float: left;
+ margin-right: 15px;
+ margin-left: 15px;
+ }
+}
+
+@media (min-width: 768px) {
+ .navbar-left {
+ float: left !important;
+ }
+
+ .navbar-right {
+ float: right !important;
+ margin-right: -15px;
+ }
+
+ .navbar-right ~ .navbar-right {
+ margin-right: 0;
+ }
+}
+
+.navbar-default {
+ background-color: #f8f8f8;
+ border-color: #e7e7e7;
+}
+
+.navbar-default .navbar-brand {
+ color: #777;
+}
+
+.navbar-default .navbar-brand:hover,
+.navbar-default .navbar-brand:focus {
+ color: #5e5e5e;
+ background-color: transparent;
+}
+
+.navbar-default .navbar-text {
+ color: #777;
+}
+
+.navbar-default .navbar-nav > li > a {
+ color: #777;
+}
+
+.navbar-default .navbar-nav > li > a:hover,
+.navbar-default .navbar-nav > li > a:focus {
+ color: #333;
+ background-color: transparent;
+}
+
+.navbar-default .navbar-nav > .active > a,
+.navbar-default .navbar-nav > .active > a:hover,
+.navbar-default .navbar-nav > .active > a:focus {
+ color: #555;
+ background-color: #e7e7e7;
+}
+
+.navbar-default .navbar-nav > .disabled > a,
+.navbar-default .navbar-nav > .disabled > a:hover,
+.navbar-default .navbar-nav > .disabled > a:focus {
+ color: #ccc;
+ background-color: transparent;
+}
+
+.navbar-default .navbar-toggle {
+ border-color: #ddd;
+}
+
+.navbar-default .navbar-toggle:hover,
+.navbar-default .navbar-toggle:focus {
+ background-color: #ddd;
+}
+
+.navbar-default .navbar-toggle .icon-bar {
+ background-color: #888;
+}
+
+.navbar-default .navbar-collapse,
+.navbar-default .navbar-form {
+ border-color: #e7e7e7;
+}
+
+.navbar-default .navbar-nav > .open > a,
+.navbar-default .navbar-nav > .open > a:hover,
+.navbar-default .navbar-nav > .open > a:focus {
+ color: #555;
+ background-color: #e7e7e7;
+}
+
+@media (max-width: 767px) {
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a {
+ color: #777;
+ }
+
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
+ color: #333;
+ background-color: transparent;
+ }
+
+ .navbar-default .navbar-nav .open .dropdown-menu > .active > a,
+ .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
+ .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
+ color: #555;
+ background-color: #e7e7e7;
+ }
+
+ .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,
+ .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,
+ .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {
+ color: #ccc;
+ background-color: transparent;
+ }
+}
+
+.navbar-default .navbar-link {
+ color: #777;
+}
+
+.navbar-default .navbar-link:hover {
+ color: #333;
+}
+
+.navbar-default .btn-link {
+ color: #777;
+}
+
+.navbar-default .btn-link:hover,
+.navbar-default .btn-link:focus {
+ color: #333;
+}
+
+.navbar-default .btn-link[disabled]:hover,
+fieldset[disabled] .navbar-default .btn-link:hover,
+.navbar-default .btn-link[disabled]:focus,
+fieldset[disabled] .navbar-default .btn-link:focus {
+ color: #ccc;
+}
+
+.navbar-inverse {
+ background-color: #222;
+ border-color: #080808;
+}
+
+.navbar-inverse .navbar-brand {
+ color: #9d9d9d;
+}
+
+.navbar-inverse .navbar-brand:hover,
+.navbar-inverse .navbar-brand:focus {
+ color: #fff;
+ background-color: transparent;
+}
+
+.navbar-inverse .navbar-text {
+ color: #9d9d9d;
+}
+
+.navbar-inverse .navbar-nav > li > a {
+ color: #9d9d9d;
+}
+
+.navbar-inverse .navbar-nav > li > a:hover,
+.navbar-inverse .navbar-nav > li > a:focus {
+ color: #fff;
+ background-color: transparent;
+}
+
+.navbar-inverse .navbar-nav > .active > a,
+.navbar-inverse .navbar-nav > .active > a:hover,
+.navbar-inverse .navbar-nav > .active > a:focus {
+ color: #fff;
+ background-color: #080808;
+}
+
+.navbar-inverse .navbar-nav > .disabled > a,
+.navbar-inverse .navbar-nav > .disabled > a:hover,
+.navbar-inverse .navbar-nav > .disabled > a:focus {
+ color: #444;
+ background-color: transparent;
+}
+
+.navbar-inverse .navbar-toggle {
+ border-color: #333;
+}
+
+.navbar-inverse .navbar-toggle:hover,
+.navbar-inverse .navbar-toggle:focus {
+ background-color: #333;
+}
+
+.navbar-inverse .navbar-toggle .icon-bar {
+ background-color: #fff;
+}
+
+.navbar-inverse .navbar-collapse,
+.navbar-inverse .navbar-form {
+ border-color: #101010;
+}
+
+.navbar-inverse .navbar-nav > .open > a,
+.navbar-inverse .navbar-nav > .open > a:hover,
+.navbar-inverse .navbar-nav > .open > a:focus {
+ color: #fff;
+ background-color: #080808;
+}
+
+@media (max-width: 767px) {
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {
+ border-color: #080808;
+ }
+
+ .navbar-inverse .navbar-nav .open .dropdown-menu .divider {
+ background-color: #080808;
+ }
+
+ .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {
+ color: #9d9d9d;
+ }
+
+ .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {
+ color: #fff;
+ background-color: transparent;
+ }
+
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {
+ color: #fff;
+ background-color: #080808;
+ }
+
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {
+ color: #444;
+ background-color: transparent;
+ }
+}
+
+.navbar-inverse .navbar-link {
+ color: #9d9d9d;
+}
+
+.navbar-inverse .navbar-link:hover {
+ color: #fff;
+}
+
+.navbar-inverse .btn-link {
+ color: #9d9d9d;
+}
+
+.navbar-inverse .btn-link:hover,
+.navbar-inverse .btn-link:focus {
+ color: #fff;
+}
+
+.navbar-inverse .btn-link[disabled]:hover,
+fieldset[disabled] .navbar-inverse .btn-link:hover,
+.navbar-inverse .btn-link[disabled]:focus,
+fieldset[disabled] .navbar-inverse .btn-link:focus {
+ color: #444;
+}
+
+.breadcrumb {
+ padding: 8px 15px;
+ margin-bottom: 20px;
+ list-style: none;
+ background-color: #f5f5f5;
+ border-radius: 4px;
+}
+
+.breadcrumb > li {
+ display: inline-block;
+}
+
+.breadcrumb > li + li:before {
+ padding: 0 5px;
+ color: #ccc;
+ content: "/\00a0";
+}
+
+.breadcrumb > .active {
+ color: #777;
+}
+
+.pagination {
+ display: inline-block;
+ padding-left: 0;
+ margin: 20px 0;
+ border-radius: 4px;
+}
+
+.pagination > li {
+ display: inline;
+}
+
+.pagination > li > a,
+.pagination > li > span {
+ position: relative;
+ float: left;
+ padding: 6px 12px;
+ margin-left: -1px;
+ line-height: 1.42857143;
+ color: #337ab7;
+ text-decoration: none;
+ background-color: #fff;
+ border: 1px solid #ddd;
+}
+
+.pagination > li:first-child > a,
+.pagination > li:first-child > span {
+ margin-left: 0;
+ border-top-left-radius: 4px;
+ border-bottom-left-radius: 4px;
+}
+
+.pagination > li:last-child > a,
+.pagination > li:last-child > span {
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+}
+
+.pagination > li > a:hover,
+.pagination > li > span:hover,
+.pagination > li > a:focus,
+.pagination > li > span:focus {
+ z-index: 3;
+ color: #23527c;
+ background-color: #eee;
+ border-color: #ddd;
+}
+
+.pagination > .active > a,
+.pagination > .active > span,
+.pagination > .active > a:hover,
+.pagination > .active > span:hover,
+.pagination > .active > a:focus,
+.pagination > .active > span:focus {
+ z-index: 2;
+ color: #fff;
+ cursor: default;
+ background-color: #337ab7;
+ border-color: #337ab7;
+}
+
+.pagination > .disabled > span,
+.pagination > .disabled > span:hover,
+.pagination > .disabled > span:focus,
+.pagination > .disabled > a,
+.pagination > .disabled > a:hover,
+.pagination > .disabled > a:focus {
+ color: #777;
+ cursor: not-allowed;
+ background-color: #fff;
+ border-color: #ddd;
+}
+
+.pagination-lg > li > a,
+.pagination-lg > li > span {
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+}
+
+.pagination-lg > li:first-child > a,
+.pagination-lg > li:first-child > span {
+ border-top-left-radius: 6px;
+ border-bottom-left-radius: 6px;
+}
+
+.pagination-lg > li:last-child > a,
+.pagination-lg > li:last-child > span {
+ border-top-right-radius: 6px;
+ border-bottom-right-radius: 6px;
+}
+
+.pagination-sm > li > a,
+.pagination-sm > li > span {
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+}
+
+.pagination-sm > li:first-child > a,
+.pagination-sm > li:first-child > span {
+ border-top-left-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+
+.pagination-sm > li:last-child > a,
+.pagination-sm > li:last-child > span {
+ border-top-right-radius: 3px;
+ border-bottom-right-radius: 3px;
+}
+
+.pager {
+ padding-left: 0;
+ margin: 20px 0;
+ text-align: center;
+ list-style: none;
+}
+
+.pager li {
+ display: inline;
+}
+
+.pager li > a,
+.pager li > span {
+ display: inline-block;
+ padding: 5px 14px;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-radius: 15px;
+}
+
+.pager li > a:hover,
+.pager li > a:focus {
+ text-decoration: none;
+ background-color: #eee;
+}
+
+.pager .next > a,
+.pager .next > span {
+ float: right;
+}
+
+.pager .previous > a,
+.pager .previous > span {
+ float: left;
+}
+
+.pager .disabled > a,
+.pager .disabled > a:hover,
+.pager .disabled > a:focus,
+.pager .disabled > span {
+ color: #777;
+ cursor: not-allowed;
+ background-color: #fff;
+}
+
+.label {
+ display: inline;
+ padding: .2em .6em .3em;
+ font-size: 75%;
+ font-weight: bold;
+ line-height: 1;
+ color: #fff;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: baseline;
+ border-radius: .25em;
+}
+
+a.label:hover,
+a.label:focus {
+ color: #fff;
+ text-decoration: none;
+ cursor: pointer;
+}
+
+.label:empty {
+ display: none;
+}
+
+.btn .label {
+ position: relative;
+ top: -1px;
+}
+
+.label-default {
+ background-color: #777;
+}
+
+.label-default[href]:hover,
+.label-default[href]:focus {
+ background-color: #5e5e5e;
+}
+
+.label-primary {
+ background-color: #337ab7;
+}
+
+.label-primary[href]:hover,
+.label-primary[href]:focus {
+ background-color: #286090;
+}
+
+.label-success {
+ background-color: #5cb85c;
+}
+
+.label-success[href]:hover,
+.label-success[href]:focus {
+ background-color: #449d44;
+}
+
+.label-info {
+ background-color: #5bc0de;
+}
+
+.label-info[href]:hover,
+.label-info[href]:focus {
+ background-color: #31b0d5;
+}
+
+.label-warning {
+ background-color: #f0ad4e;
+}
+
+.label-warning[href]:hover,
+.label-warning[href]:focus {
+ background-color: #ec971f;
+}
+
+.label-danger {
+ background-color: #d9534f;
+}
+
+.label-danger[href]:hover,
+.label-danger[href]:focus {
+ background-color: #c9302c;
+}
+
+.badge {
+ display: inline-block;
+ min-width: 10px;
+ padding: 3px 7px;
+ font-size: 12px;
+ font-weight: bold;
+ line-height: 1;
+ color: #fff;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: middle;
+ background-color: #777;
+ border-radius: 10px;
+}
+
+.badge:empty {
+ display: none;
+}
+
+.btn .badge {
+ position: relative;
+ top: -1px;
+}
+
+.btn-xs .badge,
+.btn-group-xs > .btn .badge {
+ top: 0;
+ padding: 1px 5px;
+}
+
+a.badge:hover,
+a.badge:focus {
+ color: #fff;
+ text-decoration: none;
+ cursor: pointer;
+}
+
+.list-group-item.active > .badge,
+.nav-pills > .active > a > .badge {
+ color: #337ab7;
+ background-color: #fff;
+}
+
+.list-group-item > .badge {
+ float: right;
+}
+
+.list-group-item > .badge + .badge {
+ margin-right: 5px;
+}
+
+.nav-pills > li > a > .badge {
+ margin-left: 3px;
+}
+
+.jumbotron {
+ padding-top: 30px;
+ padding-bottom: 30px;
+ margin-bottom: 30px;
+ color: inherit;
+ background-color: #eee;
+}
+
+.jumbotron h1,
+.jumbotron .h1 {
+ color: inherit;
+}
+
+.jumbotron p {
+ margin-bottom: 15px;
+ font-size: 21px;
+ font-weight: 200;
+}
+
+.jumbotron > hr {
+ border-top-color: #d5d5d5;
+}
+
+.container .jumbotron,
+.container-fluid .jumbotron {
+ border-radius: 6px;
+}
+
+.jumbotron .container {
+ max-width: 100%;
+}
+
+@media screen and (min-width: 768px) {
+ .jumbotron {
+ padding-top: 48px;
+ padding-bottom: 48px;
+ }
+
+ .container .jumbotron,
+ .container-fluid .jumbotron {
+ padding-right: 60px;
+ padding-left: 60px;
+ }
+
+ .jumbotron h1,
+ .jumbotron .h1 {
+ font-size: 63px;
+ }
+}
+
+.thumbnail {
+ display: block;
+ padding: 4px;
+ margin-bottom: 20px;
+ line-height: 1.42857143;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ -webkit-transition: border .2s ease-in-out;
+ -o-transition: border .2s ease-in-out;
+ transition: border .2s ease-in-out;
+}
+
+.thumbnail > img,
+.thumbnail a > img {
+ margin-right: auto;
+ margin-left: auto;
+}
+
+a.thumbnail:hover,
+a.thumbnail:focus,
+a.thumbnail.active {
+ border-color: #337ab7;
+}
+
+.thumbnail .caption {
+ padding: 9px;
+ color: #333;
+}
+
+.alert {
+ padding: 15px;
+ margin-bottom: 20px;
+ border: 1px solid transparent;
+ border-radius: 4px;
+}
+
+.alert h4 {
+ margin-top: 0;
+ color: inherit;
+}
+
+.alert .alert-link {
+ font-weight: bold;
+}
+
+.alert > p,
+.alert > ul {
+ margin-bottom: 0;
+}
+
+.alert > p + p {
+ margin-top: 5px;
+}
+
+.alert-dismissable,
+.alert-dismissible {
+ padding-right: 35px;
+}
+
+.alert-dismissable .close,
+.alert-dismissible .close {
+ position: relative;
+ top: -2px;
+ right: -21px;
+ color: inherit;
+}
+
+.alert-success {
+ color: #3c763d;
+ background-color: #dff0d8;
+ border-color: #d6e9c6;
+}
+
+.alert-success hr {
+ border-top-color: #c9e2b3;
+}
+
+.alert-success .alert-link {
+ color: #2b542c;
+}
+
+.alert-info {
+ color: #31708f;
+ background-color: #d9edf7;
+ border-color: #bce8f1;
+}
+
+.alert-info hr {
+ border-top-color: #a6e1ec;
+}
+
+.alert-info .alert-link {
+ color: #245269;
+}
+
+.alert-warning {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+ border-color: #faebcc;
+}
+
+.alert-warning hr {
+ border-top-color: #f7e1b5;
+}
+
+.alert-warning .alert-link {
+ color: #66512c;
+}
+
+.alert-danger {
+ color: #a94442;
+ background-color: #f2dede;
+ border-color: #ebccd1;
+}
+
+.alert-danger hr {
+ border-top-color: #e4b9c0;
+}
+
+.alert-danger .alert-link {
+ color: #843534;
+}
+
+@-webkit-keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+
+@-o-keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+
+@keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+
+.progress {
+ height: 20px;
+ margin-bottom: 20px;
+ overflow: hidden;
+ background-color: #f5f5f5;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
+}
+
+.progress-bar {
+ float: left;
+ width: 0;
+ height: 100%;
+ font-size: 12px;
+ line-height: 20px;
+ color: #fff;
+ text-align: center;
+ background-color: #337ab7;
+ -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);
+ box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);
+ -webkit-transition: width .6s ease;
+ -o-transition: width .6s ease;
+ transition: width .6s ease;
+}
+
+.progress-striped .progress-bar,
+.progress-bar-striped {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ -webkit-background-size: 40px 40px;
+ background-size: 40px 40px;
+}
+
+.progress.active .progress-bar,
+.progress-bar.active {
+ -webkit-animation: progress-bar-stripes 2s linear infinite;
+ -o-animation: progress-bar-stripes 2s linear infinite;
+ animation: progress-bar-stripes 2s linear infinite;
+}
+
+.progress-bar-success {
+ background-color: #5cb85c;
+}
+
+.progress-striped .progress-bar-success {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+}
+
+.progress-bar-info {
+ background-color: #5bc0de;
+}
+
+.progress-striped .progress-bar-info {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+}
+
+.progress-bar-warning {
+ background-color: #f0ad4e;
+}
+
+.progress-striped .progress-bar-warning {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+}
+
+.progress-bar-danger {
+ background-color: #d9534f;
+}
+
+.progress-striped .progress-bar-danger {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+}
+
+.media {
+ margin-top: 15px;
+}
+
+.media:first-child {
+ margin-top: 0;
+}
+
+.media,
+.media-body {
+ overflow: hidden;
+ zoom: 1;
+}
+
+.media-body {
+ width: 10000px;
+}
+
+.media-object {
+ display: block;
+}
+
+.media-object.img-thumbnail {
+ max-width: none;
+}
+
+.media-right,
+.media > .pull-right {
+ padding-left: 10px;
+}
+
+.media-left,
+.media > .pull-left {
+ padding-right: 10px;
+}
+
+.media-left,
+.media-right,
+.media-body {
+ display: table-cell;
+ vertical-align: top;
+}
+
+.media-middle {
+ vertical-align: middle;
+}
+
+.media-bottom {
+ vertical-align: bottom;
+}
+
+.media-heading {
+ margin-top: 0;
+ margin-bottom: 5px;
+}
+
+.media-list {
+ padding-left: 0;
+ list-style: none;
+}
+
+.list-group {
+ padding-left: 0;
+ margin-bottom: 20px;
+}
+
+.list-group-item {
+ position: relative;
+ display: block;
+ padding: 10px 15px;
+ margin-bottom: -1px;
+ background-color: #fff;
+ border: 1px solid #ddd;
+}
+
+.list-group-item:first-child {
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+}
+
+.list-group-item:last-child {
+ margin-bottom: 0;
+ border-bottom-right-radius: 4px;
+ border-bottom-left-radius: 4px;
+}
+
+a.list-group-item,
+button.list-group-item {
+ color: #555;
+}
+
+a.list-group-item .list-group-item-heading,
+button.list-group-item .list-group-item-heading {
+ color: #333;
+}
+
+a.list-group-item:hover,
+button.list-group-item:hover,
+a.list-group-item:focus,
+button.list-group-item:focus {
+ color: #555;
+ text-decoration: none;
+ background-color: #f5f5f5;
+}
+
+button.list-group-item {
+ width: 100%;
+ text-align: left;
+}
+
+.list-group-item.disabled,
+.list-group-item.disabled:hover,
+.list-group-item.disabled:focus {
+ color: #777;
+ cursor: not-allowed;
+ background-color: #eee;
+}
+
+.list-group-item.disabled .list-group-item-heading,
+.list-group-item.disabled:hover .list-group-item-heading,
+.list-group-item.disabled:focus .list-group-item-heading {
+ color: inherit;
+}
+
+.list-group-item.disabled .list-group-item-text,
+.list-group-item.disabled:hover .list-group-item-text,
+.list-group-item.disabled:focus .list-group-item-text {
+ color: #777;
+}
+
+.list-group-item.active,
+.list-group-item.active:hover,
+.list-group-item.active:focus {
+ z-index: 2;
+ color: #fff;
+ background-color: #337ab7;
+ border-color: #337ab7;
+}
+
+.list-group-item.active .list-group-item-heading,
+.list-group-item.active:hover .list-group-item-heading,
+.list-group-item.active:focus .list-group-item-heading,
+.list-group-item.active .list-group-item-heading > small,
+.list-group-item.active:hover .list-group-item-heading > small,
+.list-group-item.active:focus .list-group-item-heading > small,
+.list-group-item.active .list-group-item-heading > .small,
+.list-group-item.active:hover .list-group-item-heading > .small,
+.list-group-item.active:focus .list-group-item-heading > .small {
+ color: inherit;
+}
+
+.list-group-item.active .list-group-item-text,
+.list-group-item.active:hover .list-group-item-text,
+.list-group-item.active:focus .list-group-item-text {
+ color: #c7ddef;
+}
+
+.list-group-item-success {
+ color: #3c763d;
+ background-color: #dff0d8;
+}
+
+a.list-group-item-success,
+button.list-group-item-success {
+ color: #3c763d;
+}
+
+a.list-group-item-success .list-group-item-heading,
+button.list-group-item-success .list-group-item-heading {
+ color: inherit;
+}
+
+a.list-group-item-success:hover,
+button.list-group-item-success:hover,
+a.list-group-item-success:focus,
+button.list-group-item-success:focus {
+ color: #3c763d;
+ background-color: #d0e9c6;
+}
+
+a.list-group-item-success.active,
+button.list-group-item-success.active,
+a.list-group-item-success.active:hover,
+button.list-group-item-success.active:hover,
+a.list-group-item-success.active:focus,
+button.list-group-item-success.active:focus {
+ color: #fff;
+ background-color: #3c763d;
+ border-color: #3c763d;
+}
+
+.list-group-item-info {
+ color: #31708f;
+ background-color: #d9edf7;
+}
+
+a.list-group-item-info,
+button.list-group-item-info {
+ color: #31708f;
+}
+
+a.list-group-item-info .list-group-item-heading,
+button.list-group-item-info .list-group-item-heading {
+ color: inherit;
+}
+
+a.list-group-item-info:hover,
+button.list-group-item-info:hover,
+a.list-group-item-info:focus,
+button.list-group-item-info:focus {
+ color: #31708f;
+ background-color: #c4e3f3;
+}
+
+a.list-group-item-info.active,
+button.list-group-item-info.active,
+a.list-group-item-info.active:hover,
+button.list-group-item-info.active:hover,
+a.list-group-item-info.active:focus,
+button.list-group-item-info.active:focus {
+ color: #fff;
+ background-color: #31708f;
+ border-color: #31708f;
+}
+
+.list-group-item-warning {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+}
+
+a.list-group-item-warning,
+button.list-group-item-warning {
+ color: #8a6d3b;
+}
+
+a.list-group-item-warning .list-group-item-heading,
+button.list-group-item-warning .list-group-item-heading {
+ color: inherit;
+}
+
+a.list-group-item-warning:hover,
+button.list-group-item-warning:hover,
+a.list-group-item-warning:focus,
+button.list-group-item-warning:focus {
+ color: #8a6d3b;
+ background-color: #faf2cc;
+}
+
+a.list-group-item-warning.active,
+button.list-group-item-warning.active,
+a.list-group-item-warning.active:hover,
+button.list-group-item-warning.active:hover,
+a.list-group-item-warning.active:focus,
+button.list-group-item-warning.active:focus {
+ color: #fff;
+ background-color: #8a6d3b;
+ border-color: #8a6d3b;
+}
+
+.list-group-item-danger {
+ color: #a94442;
+ background-color: #f2dede;
+}
+
+a.list-group-item-danger,
+button.list-group-item-danger {
+ color: #a94442;
+}
+
+a.list-group-item-danger .list-group-item-heading,
+button.list-group-item-danger .list-group-item-heading {
+ color: inherit;
+}
+
+a.list-group-item-danger:hover,
+button.list-group-item-danger:hover,
+a.list-group-item-danger:focus,
+button.list-group-item-danger:focus {
+ color: #a94442;
+ background-color: #ebcccc;
+}
+
+a.list-group-item-danger.active,
+button.list-group-item-danger.active,
+a.list-group-item-danger.active:hover,
+button.list-group-item-danger.active:hover,
+a.list-group-item-danger.active:focus,
+button.list-group-item-danger.active:focus {
+ color: #fff;
+ background-color: #a94442;
+ border-color: #a94442;
+}
+
+.list-group-item-heading {
+ margin-top: 0;
+ margin-bottom: 5px;
+}
+
+.list-group-item-text {
+ margin-bottom: 0;
+ line-height: 1.3;
+}
+
+.panel {
+ margin-bottom: 20px;
+ background-color: #fff;
+ border: 1px solid transparent;
+ border-radius: 4px;
+ -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
+ box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
+}
+
+.panel-body {
+ padding: 15px;
+}
+
+.panel-heading {
+ padding: 10px 15px;
+ border-bottom: 1px solid transparent;
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+}
+
+.panel-heading > .dropdown .dropdown-toggle {
+ color: inherit;
+}
+
+.panel-title {
+ margin-top: 0;
+ margin-bottom: 0;
+ font-size: 16px;
+ color: inherit;
+}
+
+.panel-title > a,
+.panel-title > small,
+.panel-title > .small,
+.panel-title > small > a,
+.panel-title > .small > a {
+ color: inherit;
+}
+
+.panel-footer {
+ padding: 10px 15px;
+ background-color: #f5f5f5;
+ border-top: 1px solid #ddd;
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+
+.panel > .list-group,
+.panel > .panel-collapse > .list-group {
+ margin-bottom: 0;
+}
+
+.panel > .list-group .list-group-item,
+.panel > .panel-collapse > .list-group .list-group-item {
+ border-width: 1px 0;
+ border-radius: 0;
+}
+
+.panel > .list-group:first-child .list-group-item:first-child,
+.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {
+ border-top: 0;
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+}
+
+.panel > .list-group:last-child .list-group-item:last-child,
+.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {
+ border-bottom: 0;
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+
+.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+
+.panel-heading + .list-group .list-group-item:first-child {
+ border-top-width: 0;
+}
+
+.list-group + .panel-footer {
+ border-top-width: 0;
+}
+
+.panel > .table,
+.panel > .table-responsive > .table,
+.panel > .panel-collapse > .table {
+ margin-bottom: 0;
+}
+
+.panel > .table caption,
+.panel > .table-responsive > .table caption,
+.panel > .panel-collapse > .table caption {
+ padding-right: 15px;
+ padding-left: 15px;
+}
+
+.panel > .table:first-child,
+.panel > .table-responsive:first-child > .table:first-child {
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+}
+
+.panel > .table:first-child > thead:first-child > tr:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+}
+
+.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,
+.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {
+ border-top-left-radius: 3px;
+}
+
+.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,
+.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {
+ border-top-right-radius: 3px;
+}
+
+.panel > .table:last-child,
+.panel > .table-responsive:last-child > .table:last-child {
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+
+.panel > .table:last-child > tbody:last-child > tr:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+
+.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
+.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {
+ border-bottom-left-radius: 3px;
+}
+
+.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
+.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {
+ border-bottom-right-radius: 3px;
+}
+
+.panel > .panel-body + .table,
+.panel > .panel-body + .table-responsive,
+.panel > .table + .panel-body,
+.panel > .table-responsive + .panel-body {
+ border-top: 1px solid #ddd;
+}
+
+.panel > .table > tbody:first-child > tr:first-child th,
+.panel > .table > tbody:first-child > tr:first-child td {
+ border-top: 0;
+}
+
+.panel > .table-bordered,
+.panel > .table-responsive > .table-bordered {
+ border: 0;
+}
+
+.panel > .table-bordered > thead > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,
+.panel > .table-bordered > tbody > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,
+.panel > .table-bordered > tfoot > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,
+.panel > .table-bordered > thead > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,
+.panel > .table-bordered > tbody > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,
+.panel > .table-bordered > tfoot > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {
+ border-left: 0;
+}
+
+.panel > .table-bordered > thead > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,
+.panel > .table-bordered > tbody > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,
+.panel > .table-bordered > tfoot > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,
+.panel > .table-bordered > thead > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,
+.panel > .table-bordered > tbody > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,
+.panel > .table-bordered > tfoot > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {
+ border-right: 0;
+}
+
+.panel > .table-bordered > thead > tr:first-child > td,
+.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,
+.panel > .table-bordered > tbody > tr:first-child > td,
+.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,
+.panel > .table-bordered > thead > tr:first-child > th,
+.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,
+.panel > .table-bordered > tbody > tr:first-child > th,
+.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {
+ border-bottom: 0;
+}
+
+.panel > .table-bordered > tbody > tr:last-child > td,
+.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,
+.panel > .table-bordered > tfoot > tr:last-child > td,
+.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,
+.panel > .table-bordered > tbody > tr:last-child > th,
+.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,
+.panel > .table-bordered > tfoot > tr:last-child > th,
+.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {
+ border-bottom: 0;
+}
+
+.panel > .table-responsive {
+ margin-bottom: 0;
+ border: 0;
+}
+
+.panel-group {
+ margin-bottom: 20px;
+}
+
+.panel-group .panel {
+ margin-bottom: 0;
+ border-radius: 4px;
+}
+
+.panel-group .panel + .panel {
+ margin-top: 5px;
+}
+
+.panel-group .panel-heading {
+ border-bottom: 0;
+}
+
+.panel-group .panel-heading + .panel-collapse > .panel-body,
+.panel-group .panel-heading + .panel-collapse > .list-group {
+ border-top: 1px solid #ddd;
+}
+
+.panel-group .panel-footer {
+ border-top: 0;
+}
+
+.panel-group .panel-footer + .panel-collapse .panel-body {
+ border-bottom: 1px solid #ddd;
+}
+
+.panel-default {
+ border-color: #ddd;
+}
+
+.panel-default > .panel-heading {
+ color: #333;
+ background-color: #f5f5f5;
+ border-color: #ddd;
+}
+
+.panel-default > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #ddd;
+}
+
+.panel-default > .panel-heading .badge {
+ color: #f5f5f5;
+ background-color: #333;
+}
+
+.panel-default > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #ddd;
+}
+
+.panel-primary {
+ border-color: #337ab7;
+}
+
+.panel-primary > .panel-heading {
+ color: #fff;
+ background-color: #337ab7;
+ border-color: #337ab7;
+}
+
+.panel-primary > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #337ab7;
+}
+
+.panel-primary > .panel-heading .badge {
+ color: #337ab7;
+ background-color: #fff;
+}
+
+.panel-primary > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #337ab7;
+}
+
+.panel-success {
+ border-color: #d6e9c6;
+}
+
+.panel-success > .panel-heading {
+ color: #3c763d;
+ background-color: #dff0d8;
+ border-color: #d6e9c6;
+}
+
+.panel-success > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #d6e9c6;
+}
+
+.panel-success > .panel-heading .badge {
+ color: #dff0d8;
+ background-color: #3c763d;
+}
+
+.panel-success > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #d6e9c6;
+}
+
+.panel-info {
+ border-color: #bce8f1;
+}
+
+.panel-info > .panel-heading {
+ color: #31708f;
+ background-color: #d9edf7;
+ border-color: #bce8f1;
+}
+
+.panel-info > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #bce8f1;
+}
+
+.panel-info > .panel-heading .badge {
+ color: #d9edf7;
+ background-color: #31708f;
+}
+
+.panel-info > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #bce8f1;
+}
+
+.panel-warning {
+ border-color: #faebcc;
+}
+
+.panel-warning > .panel-heading {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+ border-color: #faebcc;
+}
+
+.panel-warning > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #faebcc;
+}
+
+.panel-warning > .panel-heading .badge {
+ color: #fcf8e3;
+ background-color: #8a6d3b;
+}
+
+.panel-warning > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #faebcc;
+}
+
+.panel-danger {
+ border-color: #ebccd1;
+}
+
+.panel-danger > .panel-heading {
+ color: #a94442;
+ background-color: #f2dede;
+ border-color: #ebccd1;
+}
+
+.panel-danger > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #ebccd1;
+}
+
+.panel-danger > .panel-heading .badge {
+ color: #f2dede;
+ background-color: #a94442;
+}
+
+.panel-danger > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #ebccd1;
+}
+
+.embed-responsive {
+ position: relative;
+ display: block;
+ height: 0;
+ padding: 0;
+ overflow: hidden;
+}
+
+.embed-responsive .embed-responsive-item,
+.embed-responsive iframe,
+.embed-responsive embed,
+.embed-responsive object,
+.embed-responsive video {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ border: 0;
+}
+
+.embed-responsive-16by9 {
+ padding-bottom: 56.25%;
+}
+
+.embed-responsive-4by3 {
+ padding-bottom: 75%;
+}
+
+.well {
+ min-height: 20px;
+ padding: 19px;
+ margin-bottom: 20px;
+ background-color: #f5f5f5;
+ border: 1px solid #e3e3e3;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
+}
+
+.well blockquote {
+ border-color: #ddd;
+ border-color: rgba(0, 0, 0, .15);
+}
+
+.well-lg {
+ padding: 24px;
+ border-radius: 6px;
+}
+
+.well-sm {
+ padding: 9px;
+ border-radius: 3px;
+}
+
+.close {
+ float: right;
+ font-size: 21px;
+ font-weight: bold;
+ line-height: 1;
+ color: #000;
+ text-shadow: 0 1px 0 #fff;
+ filter: alpha(opacity=20);
+ opacity: .2;
+}
+
+.close:hover,
+.close:focus {
+ color: #000;
+ text-decoration: none;
+ cursor: pointer;
+ filter: alpha(opacity=50);
+ opacity: .5;
+}
+
+button.close {
+ -webkit-appearance: none;
+ padding: 0;
+ cursor: pointer;
+ background: transparent;
+ border: 0;
+}
+
+.modal-open {
+ overflow: hidden;
+}
+
+.modal {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1050;
+ display: none;
+ overflow: hidden;
+ -webkit-overflow-scrolling: touch;
+ outline: 0;
+}
+
+.modal.fade .modal-dialog {
+ -webkit-transition: -webkit-transform .3s ease-out;
+ -o-transition: -o-transform .3s ease-out;
+ transition: transform .3s ease-out;
+ -webkit-transform: translate(0, -25%);
+ -ms-transform: translate(0, -25%);
+ -o-transform: translate(0, -25%);
+ transform: translate(0, -25%);
+}
+
+.modal.in .modal-dialog {
+ -webkit-transform: translate(0, 0);
+ -ms-transform: translate(0, 0);
+ -o-transform: translate(0, 0);
+ transform: translate(0, 0);
+}
+
+.modal-open .modal {
+ overflow-x: hidden;
+ overflow-y: auto;
+}
+
+.modal-dialog {
+ position: relative;
+ width: auto;
+ margin: 10px;
+}
+
+.modal-content {
+ position: relative;
+ background-color: #fff;
+ -webkit-background-clip: padding-box;
+ background-clip: padding-box;
+ border: 1px solid #999;
+ border: 1px solid rgba(0, 0, 0, .2);
+ border-radius: 6px;
+ outline: 0;
+ -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5);
+ box-shadow: 0 3px 9px rgba(0, 0, 0, .5);
+}
+
+.modal-backdrop {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1040;
+ background-color: #000;
+}
+
+.modal-backdrop.fade {
+ filter: alpha(opacity=0);
+ opacity: 0;
+}
+
+.modal-backdrop.in {
+ filter: alpha(opacity=50);
+ opacity: .5;
+}
+
+.modal-header {
+ min-height: 16.42857143px;
+ padding: 15px;
+ border-bottom: 1px solid #e5e5e5;
+}
+
+.modal-header .close {
+ margin-top: -2px;
+}
+
+.modal-title {
+ margin: 0;
+ line-height: 1.42857143;
+}
+
+.modal-body {
+ position: relative;
+ padding: 15px;
+}
+
+.modal-footer {
+ padding: 15px;
+ text-align: right;
+ border-top: 1px solid #e5e5e5;
+}
+
+.modal-footer .btn + .btn {
+ margin-bottom: 0;
+ margin-left: 5px;
+}
+
+.modal-footer .btn-group .btn + .btn {
+ margin-left: -1px;
+}
+
+.modal-footer .btn-block + .btn-block {
+ margin-left: 0;
+}
+
+.modal-scrollbar-measure {
+ position: absolute;
+ top: -9999px;
+ width: 50px;
+ height: 50px;
+ overflow: scroll;
+}
+
+@media (min-width: 768px) {
+ .modal-dialog {
+ width: 600px;
+ margin: 30px auto;
+ }
+
+ .modal-content {
+ -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
+ box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
+ }
+
+ .modal-sm {
+ width: 300px;
+ }
+}
+
+@media (min-width: 992px) {
+ .modal-lg {
+ width: 900px;
+ }
+}
+
+.tooltip {
+ position: absolute;
+ z-index: 1070;
+ display: block;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 12px;
+ font-style: normal;
+ font-weight: normal;
+ line-height: 1.42857143;
+ text-align: left;
+ text-align: start;
+ text-decoration: none;
+ text-shadow: none;
+ text-transform: none;
+ letter-spacing: normal;
+ word-break: normal;
+ word-spacing: normal;
+ word-wrap: normal;
+ white-space: normal;
+ filter: alpha(opacity=0);
+ opacity: 0;
+
+ line-break: auto;
+}
+
+.tooltip.in {
+ filter: alpha(opacity=90);
+ opacity: .9;
+}
+
+.tooltip.top {
+ padding: 5px 0;
+ margin-top: -3px;
+}
+
+.tooltip.right {
+ padding: 0 5px;
+ margin-left: 3px;
+}
+
+.tooltip.bottom {
+ padding: 5px 0;
+ margin-top: 3px;
+}
+
+.tooltip.left {
+ padding: 0 5px;
+ margin-left: -3px;
+}
+
+.tooltip-inner {
+ max-width: 200px;
+ padding: 3px 8px;
+ color: #fff;
+ text-align: center;
+ background-color: #000;
+ border-radius: 4px;
+}
+
+.tooltip-arrow {
+ position: absolute;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid;
+}
+
+.tooltip.top .tooltip-arrow {
+ bottom: 0;
+ left: 50%;
+ margin-left: -5px;
+ border-width: 5px 5px 0;
+ border-top-color: #000;
+}
+
+.tooltip.top-left .tooltip-arrow {
+ right: 5px;
+ bottom: 0;
+ margin-bottom: -5px;
+ border-width: 5px 5px 0;
+ border-top-color: #000;
+}
+
+.tooltip.top-right .tooltip-arrow {
+ bottom: 0;
+ left: 5px;
+ margin-bottom: -5px;
+ border-width: 5px 5px 0;
+ border-top-color: #000;
+}
+
+.tooltip.right .tooltip-arrow {
+ top: 50%;
+ left: 0;
+ margin-top: -5px;
+ border-width: 5px 5px 5px 0;
+ border-right-color: #000;
+}
+
+.tooltip.left .tooltip-arrow {
+ top: 50%;
+ right: 0;
+ margin-top: -5px;
+ border-width: 5px 0 5px 5px;
+ border-left-color: #000;
+}
+
+.tooltip.bottom .tooltip-arrow {
+ top: 0;
+ left: 50%;
+ margin-left: -5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000;
+}
+
+.tooltip.bottom-left .tooltip-arrow {
+ top: 0;
+ right: 5px;
+ margin-top: -5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000;
+}
+
+.tooltip.bottom-right .tooltip-arrow {
+ top: 0;
+ left: 5px;
+ margin-top: -5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000;
+}
+
+.popover {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 1060;
+ display: none;
+ max-width: 276px;
+ padding: 1px;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 14px;
+ font-style: normal;
+ font-weight: normal;
+ line-height: 1.42857143;
+ text-align: left;
+ text-align: start;
+ text-decoration: none;
+ text-shadow: none;
+ text-transform: none;
+ letter-spacing: normal;
+ word-break: normal;
+ word-spacing: normal;
+ word-wrap: normal;
+ white-space: normal;
+ background-color: #fff;
+ -webkit-background-clip: padding-box;
+ background-clip: padding-box;
+ border: 1px solid #ccc;
+ border: 1px solid rgba(0, 0, 0, .2);
+ border-radius: 6px;
+ -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
+ box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
+
+ line-break: auto;
+}
+
+.popover.top {
+ margin-top: -10px;
+}
+
+.popover.right {
+ margin-left: 10px;
+}
+
+.popover.bottom {
+ margin-top: 10px;
+}
+
+.popover.left {
+ margin-left: -10px;
+}
+
+.popover-title {
+ padding: 8px 14px;
+ margin: 0;
+ font-size: 14px;
+ background-color: #f7f7f7;
+ border-bottom: 1px solid #ebebeb;
+ border-radius: 5px 5px 0 0;
+}
+
+.popover-content {
+ padding: 9px 14px;
+}
+
+.popover > .arrow,
+.popover > .arrow:after {
+ position: absolute;
+ display: block;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid;
+}
+
+.popover > .arrow {
+ border-width: 11px;
+}
+
+.popover > .arrow:after {
+ content: "";
+ border-width: 10px;
+}
+
+.popover.top > .arrow {
+ bottom: -11px;
+ left: 50%;
+ margin-left: -11px;
+ border-top-color: #999;
+ border-top-color: rgba(0, 0, 0, .25);
+ border-bottom-width: 0;
+}
+
+.popover.top > .arrow:after {
+ bottom: 1px;
+ margin-left: -10px;
+ content: " ";
+ border-top-color: #fff;
+ border-bottom-width: 0;
+}
+
+.popover.right > .arrow {
+ top: 50%;
+ left: -11px;
+ margin-top: -11px;
+ border-right-color: #999;
+ border-right-color: rgba(0, 0, 0, .25);
+ border-left-width: 0;
+}
+
+.popover.right > .arrow:after {
+ bottom: -10px;
+ left: 1px;
+ content: " ";
+ border-right-color: #fff;
+ border-left-width: 0;
+}
+
+.popover.bottom > .arrow {
+ top: -11px;
+ left: 50%;
+ margin-left: -11px;
+ border-top-width: 0;
+ border-bottom-color: #999;
+ border-bottom-color: rgba(0, 0, 0, .25);
+}
+
+.popover.bottom > .arrow:after {
+ top: 1px;
+ margin-left: -10px;
+ content: " ";
+ border-top-width: 0;
+ border-bottom-color: #fff;
+}
+
+.popover.left > .arrow {
+ top: 50%;
+ right: -11px;
+ margin-top: -11px;
+ border-right-width: 0;
+ border-left-color: #999;
+ border-left-color: rgba(0, 0, 0, .25);
+}
+
+.popover.left > .arrow:after {
+ right: 1px;
+ bottom: -10px;
+ content: " ";
+ border-right-width: 0;
+ border-left-color: #fff;
+}
+
+.carousel {
+ position: relative;
+}
+
+.carousel-inner {
+ position: relative;
+ width: 100%;
+ overflow: hidden;
+}
+
+.carousel-inner > .item {
+ position: relative;
+ display: none;
+ -webkit-transition: .6s ease-in-out left;
+ -o-transition: .6s ease-in-out left;
+ transition: .6s ease-in-out left;
+}
+
+.carousel-inner > .item > img,
+.carousel-inner > .item > a > img {
+ line-height: 1;
+}
+
+@media all and (transform-3d), (-webkit-transform-3d) {
+ .carousel-inner > .item {
+ -webkit-transition: -webkit-transform .6s ease-in-out;
+ -o-transition: -o-transform .6s ease-in-out;
+ transition: transform .6s ease-in-out;
+
+ -webkit-backface-visibility: hidden;
+ backface-visibility: hidden;
+ -webkit-perspective: 1000px;
+ perspective: 1000px;
+ }
+
+ .carousel-inner > .item.next,
+ .carousel-inner > .item.active.right {
+ left: 0;
+ -webkit-transform: translate3d(100%, 0, 0);
+ transform: translate3d(100%, 0, 0);
+ }
+
+ .carousel-inner > .item.prev,
+ .carousel-inner > .item.active.left {
+ left: 0;
+ -webkit-transform: translate3d(-100%, 0, 0);
+ transform: translate3d(-100%, 0, 0);
+ }
+
+ .carousel-inner > .item.next.left,
+ .carousel-inner > .item.prev.right,
+ .carousel-inner > .item.active {
+ left: 0;
+ -webkit-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+ }
+}
+
+.carousel-inner > .active,
+.carousel-inner > .next,
+.carousel-inner > .prev {
+ display: block;
+}
+
+.carousel-inner > .active {
+ left: 0;
+}
+
+.carousel-inner > .next,
+.carousel-inner > .prev {
+ position: absolute;
+ top: 0;
+ width: 100%;
+}
+
+.carousel-inner > .next {
+ left: 100%;
+}
+
+.carousel-inner > .prev {
+ left: -100%;
+}
+
+.carousel-inner > .next.left,
+.carousel-inner > .prev.right {
+ left: 0;
+}
+
+.carousel-inner > .active.left {
+ left: -100%;
+}
+
+.carousel-inner > .active.right {
+ left: 100%;
+}
+
+.carousel-control {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ width: 15%;
+ font-size: 20px;
+ color: #fff;
+ text-align: center;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
+ filter: alpha(opacity=50);
+ opacity: .5;
+}
+
+.carousel-control.left {
+ background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
+ background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
+ background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001)));
+ background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);
+ background-repeat: repeat-x;
+}
+
+.carousel-control.right {
+ right: 0;
+ left: auto;
+ background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
+ background-image: -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
+ background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5)));
+ background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);
+ background-repeat: repeat-x;
+}
+
+.carousel-control:hover,
+.carousel-control:focus {
+ color: #fff;
+ text-decoration: none;
+ filter: alpha(opacity=90);
+ outline: 0;
+ opacity: .9;
+}
+
+.carousel-control .icon-prev,
+.carousel-control .icon-next,
+.carousel-control .glyphicon-chevron-left,
+.carousel-control .glyphicon-chevron-right {
+ position: absolute;
+ top: 50%;
+ z-index: 5;
+ display: inline-block;
+ margin-top: -10px;
+}
+
+.carousel-control .icon-prev,
+.carousel-control .glyphicon-chevron-left {
+ left: 50%;
+ margin-left: -10px;
+}
+
+.carousel-control .icon-next,
+.carousel-control .glyphicon-chevron-right {
+ right: 50%;
+ margin-right: -10px;
+}
+
+.carousel-control .icon-prev,
+.carousel-control .icon-next {
+ width: 20px;
+ height: 20px;
+ font-family: serif;
+ line-height: 1;
+}
+
+.carousel-control .icon-prev:before {
+ content: '\2039';
+}
+
+.carousel-control .icon-next:before {
+ content: '\203a';
+}
+
+.carousel-indicators {
+ position: absolute;
+ bottom: 10px;
+ left: 50%;
+ z-index: 15;
+ width: 60%;
+ padding-left: 0;
+ margin-left: -30%;
+ text-align: center;
+ list-style: none;
+}
+
+.carousel-indicators li {
+ display: inline-block;
+ width: 10px;
+ height: 10px;
+ margin: 1px;
+ text-indent: -999px;
+ cursor: pointer;
+ background-color: #000 \9;
+ background-color: rgba(0, 0, 0, 0);
+ border: 1px solid #fff;
+ border-radius: 10px;
+}
+
+.carousel-indicators .active {
+ width: 12px;
+ height: 12px;
+ margin: 0;
+ background-color: #fff;
+}
+
+.carousel-caption {
+ position: absolute;
+ right: 15%;
+ bottom: 20px;
+ left: 15%;
+ z-index: 10;
+ padding-top: 20px;
+ padding-bottom: 20px;
+ color: #fff;
+ text-align: center;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
+}
+
+.carousel-caption .btn {
+ text-shadow: none;
+}
+
+@media screen and (min-width: 768px) {
+ .carousel-control .glyphicon-chevron-left,
+ .carousel-control .glyphicon-chevron-right,
+ .carousel-control .icon-prev,
+ .carousel-control .icon-next {
+ width: 30px;
+ height: 30px;
+ margin-top: -15px;
+ font-size: 30px;
+ }
+
+ .carousel-control .glyphicon-chevron-left,
+ .carousel-control .icon-prev {
+ margin-left: -15px;
+ }
+
+ .carousel-control .glyphicon-chevron-right,
+ .carousel-control .icon-next {
+ margin-right: -15px;
+ }
+
+ .carousel-caption {
+ right: 20%;
+ left: 20%;
+ padding-bottom: 30px;
+ }
+
+ .carousel-indicators {
+ bottom: 20px;
+ }
+}
+
+.clearfix:before,
+.clearfix:after,
+.dl-horizontal dd:before,
+.dl-horizontal dd:after,
+.container:before,
+.container:after,
+.container-fluid:before,
+.container-fluid:after,
+.row:before,
+.row:after,
+.form-horizontal .form-group:before,
+.form-horizontal .form-group:after,
+.btn-toolbar:before,
+.btn-toolbar:after,
+.btn-group-vertical > .btn-group:before,
+.btn-group-vertical > .btn-group:after,
+.nav:before,
+.nav:after,
+.navbar:before,
+.navbar:after,
+.navbar-header:before,
+.navbar-header:after,
+.navbar-collapse:before,
+.navbar-collapse:after,
+.pager:before,
+.pager:after,
+.panel-body:before,
+.panel-body:after,
+.modal-footer:before,
+.modal-footer:after {
+ display: table;
+ content: " ";
+}
+
+.clearfix:after,
+.dl-horizontal dd:after,
+.container:after,
+.container-fluid:after,
+.row:after,
+.form-horizontal .form-group:after,
+.btn-toolbar:after,
+.btn-group-vertical > .btn-group:after,
+.nav:after,
+.navbar:after,
+.navbar-header:after,
+.navbar-collapse:after,
+.pager:after,
+.panel-body:after,
+.modal-footer:after {
+ clear: both;
+}
+
+.center-block {
+ display: block;
+ margin-right: auto;
+ margin-left: auto;
+}
+
+.pull-right {
+ float: right !important;
+}
+
+.pull-left {
+ float: left !important;
+}
+
+.hide {
+ display: none !important;
+}
+
+.show {
+ display: block !important;
+}
+
+.invisible {
+ visibility: hidden;
+}
+
+.text-hide {
+ font: 0/0 a;
+ color: transparent;
+ text-shadow: none;
+ background-color: transparent;
+ border: 0;
+}
+
+.hidden {
+ display: none !important;
+}
+
+.affix {
+ position: fixed;
+}
+
+@-ms-viewport {
+ width: device-width;
+}
+
+.visible-xs,
+.visible-sm,
+.visible-md,
+.visible-lg {
+ display: none !important;
+}
+
+.visible-xs-block,
+.visible-xs-inline,
+.visible-xs-inline-block,
+.visible-sm-block,
+.visible-sm-inline,
+.visible-sm-inline-block,
+.visible-md-block,
+.visible-md-inline,
+.visible-md-inline-block,
+.visible-lg-block,
+.visible-lg-inline,
+.visible-lg-inline-block {
+ display: none !important;
+}
+
+@media (max-width: 767px) {
+ .visible-xs {
+ display: block !important;
+ }
+
+ table.visible-xs {
+ display: table !important;
+ }
+
+ tr.visible-xs {
+ display: table-row !important;
+ }
+
+ th.visible-xs,
+ td.visible-xs {
+ display: table-cell !important;
+ }
+}
+
+@media (max-width: 767px) {
+ .visible-xs-block {
+ display: block !important;
+ }
+}
+
+@media (max-width: 767px) {
+ .visible-xs-inline {
+ display: inline !important;
+ }
+}
+
+@media (max-width: 767px) {
+ .visible-xs-inline-block {
+ display: inline-block !important;
+ }
+}
+
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm {
+ display: block !important;
+ }
+
+ table.visible-sm {
+ display: table !important;
+ }
+
+ tr.visible-sm {
+ display: table-row !important;
+ }
+
+ th.visible-sm,
+ td.visible-sm {
+ display: table-cell !important;
+ }
+}
+
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-block {
+ display: block !important;
+ }
+}
+
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-inline {
+ display: inline !important;
+ }
+}
+
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-inline-block {
+ display: inline-block !important;
+ }
+}
+
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md {
+ display: block !important;
+ }
+
+ table.visible-md {
+ display: table !important;
+ }
+
+ tr.visible-md {
+ display: table-row !important;
+ }
+
+ th.visible-md,
+ td.visible-md {
+ display: table-cell !important;
+ }
+}
+
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-block {
+ display: block !important;
+ }
+}
+
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-inline {
+ display: inline !important;
+ }
+}
+
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-inline-block {
+ display: inline-block !important;
+ }
+}
+
+@media (min-width: 1200px) {
+ .visible-lg {
+ display: block !important;
+ }
+
+ table.visible-lg {
+ display: table !important;
+ }
+
+ tr.visible-lg {
+ display: table-row !important;
+ }
+
+ th.visible-lg,
+ td.visible-lg {
+ display: table-cell !important;
+ }
+}
+
+@media (min-width: 1200px) {
+ .visible-lg-block {
+ display: block !important;
+ }
+}
+
+@media (min-width: 1200px) {
+ .visible-lg-inline {
+ display: inline !important;
+ }
+}
+
+@media (min-width: 1200px) {
+ .visible-lg-inline-block {
+ display: inline-block !important;
+ }
+}
+
+@media (max-width: 767px) {
+ .hidden-xs {
+ display: none !important;
+ }
+}
+
+@media (min-width: 768px) and (max-width: 991px) {
+ .hidden-sm {
+ display: none !important;
+ }
+}
+
+@media (min-width: 992px) and (max-width: 1199px) {
+ .hidden-md {
+ display: none !important;
+ }
+}
+
+@media (min-width: 1200px) {
+ .hidden-lg {
+ display: none !important;
+ }
+}
+
+.visible-print {
+ display: none !important;
+}
+
+@media print {
+ .visible-print {
+ display: block !important;
+ }
+
+ table.visible-print {
+ display: table !important;
+ }
+
+ tr.visible-print {
+ display: table-row !important;
+ }
+
+ th.visible-print,
+ td.visible-print {
+ display: table-cell !important;
+ }
+}
+
+.visible-print-block {
+ display: none !important;
+}
+
+@media print {
+ .visible-print-block {
+ display: block !important;
+ }
+}
+
+.visible-print-inline {
+ display: none !important;
+}
+
+@media print {
+ .visible-print-inline {
+ display: inline !important;
+ }
+}
+
+.visible-print-inline-block {
+ display: none !important;
+}
+
+@media print {
+ .visible-print-inline-block {
+ display: inline-block !important;
+ }
+}
+
+@media print {
+ .hidden-print {
+ display: none !important;
+ }
+}
+
+/*# sourceMappingURL=bootstrap.css.map */
new file mode 100644
--- /dev/null
+++ b/js/bootstrap/css/bootstrap.css.map
@@ -0,0 +1,142 @@
+{
+ "version": 3,
+ "sources": [
+ "bootstrap.css",
+ "less/normalize.less",
+ "less/print.less",
+ "less/glyphicons.less",
+ "less/scaffolding.less",
+ "less/mixins/vendor-prefixes.less",
+ "less/mixins/tab-focus.less",
+ "less/mixins/image.less",
+ "less/type.less",
+ "less/mixins/text-emphasis.less",
+ "less/mixins/background-variant.less",
+ "less/mixins/text-overflow.less",
+ "less/code.less",
+ "less/grid.less",
+ "less/mixins/grid.less",
+ "less/mixins/grid-framework.less",
+ "less/tables.less",
+ "less/mixins/table-row.less",
+ "less/forms.less",
+ "less/mixins/forms.less",
+ "less/buttons.less",
+ "less/mixins/buttons.less",
+ "less/mixins/opacity.less",
+ "less/component-animations.less",
+ "less/dropdowns.less",
+ "less/mixins/nav-divider.less",
+ "less/mixins/reset-filter.less",
+ "less/button-groups.less",
+ "less/mixins/border-radius.less",
+ "less/input-groups.less",
+ "less/navs.less",
+ "less/navbar.less",
+ "less/mixins/nav-vertical-align.less",
+ "less/utilities.less",
+ "less/breadcrumbs.less",
+ "less/pagination.less",
+ "less/mixins/pagination.less",
+ "less/pager.less",
+ "less/labels.less",
+ "less/mixins/labels.less",
+ "less/badges.less",
+ "less/jumbotron.less",
+ "less/thumbnails.less",
+ "less/alerts.less",
+ "less/mixins/alerts.less",
+ "less/progress-bars.less",
+ "less/mixins/gradients.less",
+ "less/mixins/progress-bar.less",
+ "less/media.less",
+ "less/list-group.less",
+ "less/mixins/list-group.less",
+ "less/panels.less",
+ "less/mixins/panels.less",
+ "less/responsive-embed.less",
+ "less/wells.less",
+ "less/close.less",
+ "less/modals.less",
+ "less/tooltip.less",
+ "less/mixins/reset-text.less",
+ "less/popovers.less",
+ "less/carousel.less",
+ "less/mixins/clearfix.less",
+ "less/mixins/center-block.less",
+ "less/mixins/hide-text.less",
+ "less/responsive-utilities.less",
+ "less/mixins/responsive-visibility.less"
+ ],
+ "names": [],
+ "mappings": "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,iBAAA;CHsR9C;AGrRmC;EAAW,iBAAA;CHwR9C;AGvRmC;EAAW,iBAAA;CH0R9C;AGzRmC;EAAW,iBAAA;CH4R9C;AG3RmC;EAAW,iBAAA;CH8R9C;AG7RmC;EAAW,iBAAA;CHgS9C;AG/RmC;EAAW,iBAAA;CHkS9C;AGjSmC;EAAW,iBAAA;CHoS9C;AGnSmC;EAAW,iBAAA;CHsS9C;AGrSmC;EAAW,iBAAA;CHwS9C;AGvSmC;EAAW,iBAAA;CH0S9C;AGzSmC;EAAW,iBAAA;CH4S9C;AG3SmC;EAAW,iBAAA;CH8S9C;AG7SmC;EAAW,iBAAA;CHgT9C;AG/SmC;EAAW,iBAAA;CHkT9C;AGjTmC;EAAW,iBAAA;CHoT9C;AGnTmC;EAAW,iBAAA;CHsT9C;AGrTmC;EAAW,iBAAA;CHwT9C;AGvTmC;EAAW,iBAAA;CH0T9C;AGzTmC;EAAW,iBAAA;CH4T9C;AG3TmC;EAAW,iBAAA;CH8T9C;AG7TmC;EAAW,iBAAA;CHgU9C;AG/TmC;EAAW,iBAAA;CHkU9C;AGjUmC;EAAW,iBAAA;CHoU9C;AGnUmC;EAAW,iBAAA;CHsU9C;AGrUmC;EAAW,iBAAA;CHwU9C;AGvUmC;EAAW,iBAAA;CH0U9C;AGzUmC;EAAW,iBAAA;CH4U9C;AG3UmC;EAAW,iBAAA;CH8U9C;AG7UmC;EAAW,iBAAA;CHgV9C;AG/UmC;EAAW,iBAAA;CHkV9C;AGjVmC;EAAW,iBAAA;CHoV9C;AGnVmC;EAAW,iBAAA;CHsV9C;AGrVmC;EAAW,iBAAA;CHwV9C;AGvVmC;EAAW,iBAAA;CH0V9C;AGzVmC;EAAW,iBAAA;CH4V9C;AG3VmC;EAAW,iBAAA;CH8V9C;AG7VmC;EAAW,iBAAA;CHgW9C;AG/VmC;EAAW,iBAAA;CHkW9C;AGjWmC;EAAW,iBAAA;CHoW9C;AGnWmC;EAAW,iBAAA;CHsW9C;AGrWmC;EAAW,iBAAA;CHwW9C;AGvWmC;EAAW,iBAAA;CH0W9C;AGzWmC;EAAW,iBAAA;CH4W9C;AG3WmC;EAAW,iBAAA;CH8W9C;AG7WmC;EAAW,iBAAA;CHgX9C;AG/WmC;EAAW,iBAAA;CHkX9C;AGjXmC;EAAW,iBAAA;CHoX9C;AGnXmC;EAAW,iBAAA;CHsX9C;AGrXmC;EAAW,iBAAA;CHwX9C;AGvXmC;EAAW,iBAAA;CH0X9C;AGzXmC;EAAW,iBAAA;CH4X9C;AG3XmC;EAAW,iBAAA;CH8X9C;AG7XmC;EAAW,iBAAA;CHgY9C;AG/XmC;EAAW,iBAAA;CHkY9C;AGjYmC;EAAW,iBAAA;CHoY9C;AGnYmC;EAAW,iBAAA;CHsY9C;AGrYmC;EAAW,iBAAA;CHwY9C;AGvYmC;EAAW,iBAAA;CH0Y9C;AGzYmC;EAAW,iBAAA;CH4Y9C;AG3YmC;EAAW,iBAAA;CH8Y9C;AG7YmC;EAAW,iBAAA;CHgZ9C;AG/YmC;EAAW,iBAAA;CHkZ9C;AGjZmC;EAAW,iBAAA;CHoZ9C;AGnZmC;EAAW,iBAAA;CHsZ9C;AGrZmC;EAAW,iBAAA;CHwZ9C;AGvZmC;EAAW,iBAAA;CH0Z9C;AGzZmC;EAAW,iBAAA;CH4Z9C;AG3ZmC;EAAW,iBAAA;CH8Z9C;AG7ZmC;EAAW,iBAAA;CHga9C;AG/ZmC;EAAW,iBAAA;CHka9C;AGjamC;EAAW,iBAAA;CHoa9C;AGnamC;EAAW,iBAAA;CHsa9C;AGramC;EAAW,iBAAA;CHwa9C;AGvamC;EAAW,iBAAA;CH0a9C;AGzamC;EAAW,iBAAA;CH4a9C;AG3amC;EAAW,iBAAA;CH8a9C;AG7amC;EAAW,iBAAA;CHgb9C;AG/amC;EAAW,iBAAA;CHkb9C;AGjbmC;EAAW,iBAAA;CHob9C;AGnbmC;EAAW,iBAAA;CHsb9C;AGrbmC;EAAW,iBAAA;CHwb9C;AGvbmC;EAAW,iBAAA;CH0b9C;AGzbmC;EAAW,iBAAA;CH4b9C;AG3bmC;EAAW,iBAAA;CH8b9C;AG7bmC;EAAW,iBAAA;CHgc9C;AG/bmC;EAAW,iBAAA;CHkc9C;AGjcmC;EAAW,iBAAA;CHoc9C;AGncmC;EAAW,iBAAA;CHsc9C;AGrcmC;EAAW,iBAAA;CHwc9C;AGvcmC;EAAW,iBAAA;CH0c9C;AGzcmC;EAAW,iBAAA;CH4c9C;AG3cmC;EAAW,iBAAA;CH8c9C;AG7cmC;EAAW,iBAAA;CHgd9C;AG/cmC;EAAW,iBAAA;CHkd9C;AGjdmC;EAAW,iBAAA;CHod9C;AGndmC;EAAW,iBAAA;CHsd9C;AGrdmC;EAAW,iBAAA;CHwd9C;AGvdmC;EAAW,iBAAA;CH0d9C;AGzdmC;EAAW,iBAAA;CH4d9C;AG3dmC;EAAW,iBAAA;CH8d9C;AG7dmC;EAAW,iBAAA;CHge9C;AG/dmC;EAAW,iBAAA;CHke9C;AGjemC;EAAW,iBAAA;CHoe9C;AGnemC;EAAW,iBAAA;CHse9C;AGremC;EAAW,iBAAA;CHwe9C;AGvemC;EAAW,iBAAA;CH0e9C;AGzemC;EAAW,iBAAA;CH4e9C;AG3emC;EAAW,iBAAA;CH8e9C;AG7emC;EAAW,iBAAA;CHgf9C;AG/emC;EAAW,iBAAA;CHkf9C;AGjfmC;EAAW,iBAAA;CHof9C;AGnfmC;EAAW,iBAAA;CHsf9C;AGrfmC;EAAW,iBAAA;CHwf9C;AGvfmC;EAAW,iBAAA;CH0f9C;AGzfmC;EAAW,iBAAA;CH4f9C;AG3fmC;EAAW,iBAAA;CH8f9C;AG7fmC;EAAW,iBAAA;CHggB9C;AG/fmC;EAAW,iBAAA;CHkgB9C;AGjgBmC;EAAW,iBAAA;CHogB9C;AGngBmC;EAAW,iBAAA;CHsgB9C;AGrgBmC;EAAW,iBAAA;CHwgB9C;AGvgBmC;EAAW,iBAAA;CH0gB9C;AGzgBmC;EAAW,iBAAA;CH4gB9C;AG3gBmC;EAAW,iBAAA;CH8gB9C;AG7gBmC;EAAW,iBAAA;CHghB9C;AG/gBmC;EAAW,iBAAA;CHkhB9C;AGjhBmC;EAAW,iBAAA;CHohB9C;AGnhBmC;EAAW,iBAAA;CHshB9C;AGrhBmC;EAAW,iBAAA;CHwhB9C;AGvhBmC;EAAW,iBAAA;CH0hB9C;AGzhBmC;EAAW,iBAAA;CH4hB9C;AG3hBmC;EAAW,iBAAA;CH8hB9C;AG7hBmC;EAAW,iBAAA;CHgiB9C;AG/hBmC;EAAW,iBAAA;CHkiB9C;AGjiBmC;EAAW,iBAAA;CHoiB9C;AGniBmC;EAAW,iBAAA;CHsiB9C;AGriBmC;EAAW,iBAAA;CHwiB9C;AGviBmC;EAAW,iBAAA;CH0iB9C;AGziBmC;EAAW,iBAAA;CH4iB9C;AG3iBmC;EAAW,iBAAA;CH8iB9C;AG7iBmC;EAAW,iBAAA;CHgjB9C;AG/iBmC;EAAW,iBAAA;CHkjB9C;AGjjBmC;EAAW,iBAAA;CHojB9C;AGnjBmC;EAAW,iBAAA;CHsjB9C;AGrjBmC;EAAW,iBAAA;CHwjB9C;AGvjBmC;EAAW,iBAAA;CH0jB9C;AGzjBmC;EAAW,iBAAA;CH4jB9C;AG3jBmC;EAAW,iBAAA;CH8jB9C;AG7jBmC;EAAW,iBAAA;CHgkB9C;AG/jBmC;EAAW,iBAAA;CHkkB9C;AGjkBmC;EAAW,iBAAA;CHokB9C;AGnkBmC;EAAW,iBAAA;CHskB9C;AGrkBmC;EAAW,iBAAA;CHwkB9C;AGvkBmC;EAAW,iBAAA;CH0kB9C;AGzkBmC;EAAW,iBAAA;CH4kB9C;AG3kBmC;EAAW,iBAAA;CH8kB9C;AG7kBmC;EAAW,iBAAA;CHglB9C;AG/kBmC;EAAW,iBAAA;CHklB9C;AGjlBmC;EAAW,iBAAA;CHolB9C;AGnlBmC;EAAW,iBAAA;CHslB9C;AGrlBmC;EAAW,iBAAA;CHwlB9C;AGvlBmC;EAAW,iBAAA;CH0lB9C;AGzlBmC;EAAW,iBAAA;CH4lB9C;AG3lBmC;EAAW,iBAAA;CH8lB9C;AG7lBmC;EAAW,iBAAA;CHgmB9C;AG/lBmC;EAAW,iBAAA;CHkmB9C;AGjmBmC;EAAW,iBAAA;CHomB9C;AGnmBmC;EAAW,iBAAA;CHsmB9C;AGrmBmC;EAAW,iBAAA;CHwmB9C;AGvmBmC;EAAW,iBAAA;CH0mB9C;AGzmBmC;EAAW,iBAAA;CH4mB9C;AG3mBmC;EAAW,iBAAA;CH8mB9C;AG7mBmC;EAAW,iBAAA;CHgnB9C;AG/mBmC;EAAW,iBAAA;CHknB9C;AGjnBmC;EAAW,iBAAA;CHonB9C;AGnnBmC;EAAW,iBAAA;CHsnB9C;AGrnBmC;EAAW,iBAAA;CHwnB9C;AGvnBmC;EAAW,iBAAA;CH0nB9C;AGznBmC;EAAW,iBAAA;CH4nB9C;AG3nBmC;EAAW,iBAAA;CH8nB9C;AG7nBmC;EAAW,iBAAA;CHgoB9C;AG/nBmC;EAAW,iBAAA;CHkoB9C;AGjoBmC;EAAW,iBAAA;CHooB9C;AGnoBmC;EAAW,iBAAA;CHsoB9C;AGroBmC;EAAW,iBAAA;CHwoB9C;AG/nBmC;EAAW,iBAAA;CHkoB9C;AGjoBmC;EAAW,iBAAA;CHooB9C;AGnoBmC;EAAW,iBAAA;CHsoB9C;AGroBmC;EAAW,iBAAA;CHwoB9C;AGvoBmC;EAAW,iBAAA;CH0oB9C;AGzoBmC;EAAW,iBAAA;CH4oB9C;AG3oBmC;EAAW,iBAAA;CH8oB9C;AG7oBmC;EAAW,iBAAA;CHgpB9C;AG/oBmC;EAAW,iBAAA;CHkpB9C;AGjpBmC;EAAW,iBAAA;CHopB9C;AGnpBmC;EAAW,iBAAA;CHspB9C;AGrpBmC;EAAW,iBAAA;CHwpB9C;AGvpBmC;EAAW,iBAAA;CH0pB9C;AGzpBmC;EAAW,iBAAA;CH4pB9C;AG3pBmC;EAAW,iBAAA;CH8pB9C;AG7pBmC;EAAW,iBAAA;CHgqB9C;AG/pBmC;EAAW,iBAAA;CHkqB9C;AGjqBmC;EAAW,iBAAA;CHoqB9C;AGnqBmC;EAAW,iBAAA;CHsqB9C;AGrqBmC;EAAW,iBAAA;CHwqB9C;AGvqBmC;EAAW,iBAAA;CH0qB9C;AGzqBmC;EAAW,iBAAA;CH4qB9C;AG3qBmC;EAAW,iBAAA;CH8qB9C;AG7qBmC;EAAW,iBAAA;CHgrB9C;AG/qBmC;EAAW,iBAAA;CHkrB9C;AGjrBmC;EAAW,iBAAA;CHorB9C;AGnrBmC;EAAW,iBAAA;CHsrB9C;AGrrBmC;EAAW,iBAAA;CHwrB9C;AGvrBmC;EAAW,iBAAA;CH0rB9C;AGzrBmC;EAAW,iBAAA;CH4rB9C;AG3rBmC;EAAW,iBAAA;CH8rB9C;AG7rBmC;EAAW,iBAAA;CHgsB9C;AG/rBmC;EAAW,iBAAA;CHksB9C;AGjsBmC;EAAW,iBAAA;CHosB9C;AGnsBmC;EAAW,iBAAA;CHssB9C;AGrsBmC;EAAW,iBAAA;CHwsB9C;AGvsBmC;EAAW,iBAAA;CH0sB9C;AGzsBmC;EAAW,iBAAA;CH4sB9C;AG3sBmC;EAAW,iBAAA;CH8sB9C;AG7sBmC;EAAW,iBAAA;CHgtB9C;AG/sBmC;EAAW,iBAAA;CHktB9C;AGjtBmC;EAAW,iBAAA;CHotB9C;AGntBmC;EAAW,iBAAA;CHstB9C;AGrtBmC;EAAW,iBAAA;CHwtB9C;AGvtBmC;EAAW,iBAAA;CH0tB9C;AGztBmC;EA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DH;AezkDC;EACE,oBAAA;Cf2kDH;Ae5kDC;EACE,WAAA;Cf8kDH;Ae/kDC;EACE,oBAAA;CfilDH;AellDC;EACE,mBAAA;CfolDH;AehlDC;EACE,YAAA;CfklDH;AelmDC;EACE,WAAA;CfomDH;AermDC;EACE,mBAAA;CfumDH;AexmDC;EACE,mBAAA;Cf0mDH;Ae3mDC;EACE,UAAA;Cf6mDH;Ae9mDC;EACE,mBAAA;CfgnDH;AejnDC;EACE,mBAAA;CfmnDH;AepnDC;EACE,UAAA;CfsnDH;AevnDC;EACE,mBAAA;CfynDH;Ae1nDC;EACE,mBAAA;Cf4nDH;Ae7nDC;EACE,UAAA;Cf+nDH;AehoDC;EACE,mBAAA;CfkoDH;AenoDC;EACE,kBAAA;CfqoDH;AejoDC;EACE,WAAA;CfmoDH;AernDC;EACE,kBAAA;CfunDH;AexnDC;EACE,0BAAA;Cf0nDH;Ae3nDC;EACE,0BAAA;Cf6nDH;Ae9nDC;EACE,iBAAA;CfgoDH;AejoDC;EACE,0BAAA;CfmoDH;AepoDC;EACE,0BAAA;CfsoDH;AevoDC;EACE,iBAAA;CfyoDH;Ae1oDC;EACE,0BAAA;Cf4oDH;Ae7oDC;EACE,0BAAA;Cf+oDH;AehpDC;EACE,iBAAA;CfkpDH;AenpDC;EACE,0BAAA;CfqpDH;AetpDC;EACE,yBAAA;CfwpDH;AezpDC;EACE,gBAAA;Cf2pDH;Aa3pDD;EElCI;IACE,YAAA;GfgsDH;EezrDD;IACE,YAAA;Gf2rDD;Ee5rDD;IACE,oBAAA;Gf8rDD;Ee/rDD;IACE,oBAAA;GfisDD;EelsDD;IACE,WAAA;GfosDD;EersDD;IACE,oBAAA;GfusDD;EexsDD;IACE,oBAAA;Gf0sDD;Ee3sDD;IACE,WAAA;Gf6sDD;Ee9sDD;IACE,oBAAA;GfgtDD;EejtDD;IACE,oBAAA;GfmtDD;EeptDD;IACE,WAAA;GfstDD;EevtDD;IACE,oBAAA;GfytDD;Ee1tDD;IACE,mBAAA;Gf4tDD;Ee9sDD;IACE,YAAA;GfgtDD;EejtDD;IACE,oBAAA;GfmtDD;EeptDD;IACE,oBAAA;GfstDD;EevtDD;IACE,WAAA;GfytDD;Ee1tDD;IACE,oBAAA;Gf4tDD;Ee7tDD;IACE,oBAAA;Gf+tDD;EehuDD;IACE,WAAA;GfkuDD;EenuDD;IACE,oBAAA;GfquDD;EetuDD;IACE,oBAAA;GfwuDD;EezuDD;IACE,WAAA;Gf2uDD;Ee5uDD;IACE,oBAAA;Gf8uDD;Ee/uDD;IACE,mBAAA;GfivDD;Ee7uDD;IACE,YAAA;Gf+uDD;Ee/vDD;IACE,WAAA;GfiwDD;EelwDD;IACE,mBAAA;GfowDD;EerwDD;IACE,mBAAA;GfuwDD;EexwDD;IACE,UAAA;Gf0wDD;Ee3wDD;IACE,mBAAA;Gf6wDD;Ee9wDD;IACE,mBAAA;GfgxDD;EejxDD;IACE,UAAA;GfmxDD;EepxDD;IACE,mBAAA;GfsxDD;EevxDD;IACE,mBAAA;GfyxDD;Ee1xDD;IACE,UAAA;Gf4xDD;Ee7xDD;IACE,mBAAA;Gf+xDD;EehyDD;IACE,kBAAA;GfkyDD;Ee9xDD;IACE,WAAA;GfgyDD;EelxDD;IACE,kBAAA;GfoxDD;EerxDD;IACE,0BAAA;GfuxDD;EexxDD;IACE,0BAAA;Gf0xDD;Ee3xDD;IACE,iBAAA;Gf6xDD;Ee9xDD;IACE,0BAAA;GfgyDD;EejyDD;IACE,0BAAA;GfmyDD;EepyDD;IACE,iBAAA;GfsyDD;EevyDD;IACE,0BAAA;GfyyDD;Ee1yDD;IACE,0BAAA;Gf4yDD;Ee7yDD;IACE,iBAAA;Gf+yDD;EehzDD;IACE,0BAAA;GfkzDD;EenzDD;IACE,yBAAA;GfqzDD;EetzDD;IACE,gBAAA;GfwzDD;CACF;AahzDD;EE3CI;IACE,YAAA;Gf81DH;Eev1DD;IACE,YAAA;Gfy1DD;Ee11DD;IACE,oBAAA;Gf41DD;Ee71DD;IACE,oBAAA;Gf+1DD;Eeh2DD;IACE,WAAA;Gfk2DD;Een2DD;IACE,oBAAA;Gfq2DD;Eet2DD;IACE,oBAAA;Gfw2DD;Eez2DD;IACE,WAAA;Gf22DD;Ee52DD;IACE,oBAAA;Gf82DD;Ee/2DD;IACE,oBAAA;Gfi3DD;Eel3DD;IACE,WAAA;Gfo3DD;Eer3DD;IACE,oBAAA;Gfu3DD;Eex3DD;IACE,mBAAA;Gf03DD;Ee52DD;IACE,YAAA;Gf82DD;Ee/2DD;IACE,oBAAA;Gfi3DD;Eel3DD;IACE,oBAAA;Gfo3DD;Eer3DD;IACE,WAAA;Gfu3DD;Eex3DD;IACE,oBAAA;Gf03DD;Ee33DD;IACE,oBAAA;Gf63DD;Ee93DD;IACE,WAAA;Gfg4DD;Eej4DD;IACE,oBAAA;Gfm4DD;Eep4DD;IACE,oBAAA;Gfs4DD;Eev4DD;IACE,WAAA;Gfy4DD;Ee14DD;IACE,oBAAA;Gf44DD;Ee74DD;IACE,mBAAA;Gf+4DD;Ee34DD;IACE,YAAA;Gf64DD;Ee75DD;IACE,WAAA;Gf+5DD;Eeh6DD;IACE,mBAAA;Gfk6DD;Een6DD;IACE,mBAAA;Gfq6DD;Eet6DD;IACE,UAAA;Gfw6DD;Eez6DD;IACE,mBAAA;Gf26DD;Ee56DD;IACE,mBAAA;Gf86DD;Ee/6DD;IACE,UAAA;Gfi7DD;Eel7DD;IACE,mBAAA;Gfo7DD;Eer7DD;IACE,mBAAA;Gfu7DD;Eex7DD;IACE,UAAA;Gf07DD;Ee37DD;IACE,mBAAA;Gf67DD;Ee97DD;IACE,kBAAA;Gfg8DD;Ee57DD;IACE,WAAA;Gf87DD;Eeh7DD;IACE,kBAAA;Gfk7DD;Een7DD;IACE,0BAAA;Gfq7DD;Eet7DD;IACE,0BAAA;Gfw7DD;Eez7DD;IACE,iBAAA;Gf27DD;Ee57DD;IACE,0BAAA;Gf87DD;Ee/7DD;IACE,0BAAA;Gfi8DD;Eel8DD;IACE,iBAAA;Gfo8DD;Eer8DD;IACE,0BAAA;Gfu8DD;Eex8DD;IACE,0BAAA;Gf08DD;Ee38DD;IACE,iBAAA;Gf68DD;Ee98DD;IACE,0BAAA;Gfg9DD;Eej9DD;IACE,yBAAA;Gfm9DD;Eep9DD;IACE,gBAAA;Gfs9DD;CACF;Aa38DD;EE9CI;IACE,YAAA;Gf4/DH;Eer/DD;IACE,YAAA;Gfu/DD;Eex/DD;IACE,oBAAA;Gf0/DD;Ee3/DD;IACE,oBAAA;Gf6/DD;Ee9/DD;IACE,WAAA;GfggED;EejgED;IACE,oBAAA;GfmgED;EepgED;IACE,oBAAA;GfsgED;EevgED;IACE,WAAA;GfygED;Ee1gED;IACE,oBAAA;Gf4gED;Ee7gED;IACE,oBAAA;Gf+gED;EehhED;IACE,WAAA;GfkhED;EenhED;IACE,oBAAA;GfqhED;EethED;IACE,mBAAA;GfwhED;Ee1gED;IACE,YAAA;Gf4gED;Ee7gED;IACE,oBAAA;Gf+gED;EehhED;IACE,oBAAA;GfkhED;EenhED;IACE,WAAA;GfqhED;EethED;IACE,oBAAA;GfwhED;EezhED;IACE,oBAAA;Gf2hED;Ee5hED;IACE,WAAA;Gf8hED;Ee/hED;IACE,oBAAA;GfiiED;EeliED;IACE,oBAAA;GfoiED;EeriED;IACE,WAAA;GfuiED;EexiED;IACE,oBAAA;Gf0iED;Ee3iED;IACE,mBAAA;Gf6iED;EeziED;IACE,YAAA;Gf2iED;Ee3jED;IACE,WAAA;Gf6jED;Ee9jED;IACE,mBAAA;GfgkED;EejkED;IACE,mBAAA;GfmkED;EepkED;IACE,UAAA;GfskED;EevkED;IACE,mBAAA;GfykED;Ee1kED;IACE,mBAAA;Gf4kED;Ee7kED;IACE,UAAA;Gf+kED;EehlED;IACE,mBAAA;GfklED;EenlED;IACE,mBAAA;GfqlED;EetlED;IACE,UAAA;GfwlED;EezlED;IACE,mBAAA;Gf2lED;Ee5lED;IACE,kBAAA;Gf8lED;Ee1lED;IACE,WAAA;Gf4lED;Ee9kED;IACE,kBAAA;GfglED;EejlED;IACE,0BAAA;GfmlED;EeplED;IACE,0BAAA;GfslED;EevlED;IACE,iBAAA;GfylED;Ee1lED;IACE,0BAAA;Gf4lED;Ee7lED;IACE,0BAAA;Gf+lED;EehmED;IACE,iBAAA;GfkmED;EenmED;IACE,0BAAA;GfqmED;EetmED;IACE,0BAAA;GfwmED;EezmED;IACE,iBAAA;Gf2mED;Ee5mED;IACE,0BAAA;Gf8mED;Ee/mED;IACE,yBAAA;GfinED;EelnED;IACE,gBAAA;GfonED;CACF;AgBxrED;EACE,8BAAA;ChB0rED;AgBxrED;EACE,iBAAA;EACA,oBAAA;EACA,eAAA;EACA,iBAAA;ChB0rED;AgBxrED;EACE,iBAAA;ChB0rED;AgBprED;EACE,YAAA;EACA,gBAAA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",
+ "file": "bootstrap.css",
+ "sourcesContent": [
+ "/*!\n * Bootstrap v3.3.5 (http://getbootstrap.com)\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\nhtml {\n font-family: sans-serif;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n}\nbody {\n margin: 0;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block;\n vertical-align: baseline;\n}\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n[hidden],\ntemplate {\n display: none;\n}\na {\n background-color: transparent;\n}\na:active,\na:hover {\n outline: 0;\n}\nabbr[title] {\n border-bottom: 1px dotted;\n}\nb,\nstrong {\n font-weight: bold;\n}\ndfn {\n font-style: italic;\n}\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\nmark {\n background: #ff0;\n color: #000;\n}\nsmall {\n font-size: 80%;\n}\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\nsup {\n top: -0.5em;\n}\nsub {\n bottom: -0.25em;\n}\nimg {\n border: 0;\n}\nsvg:not(:root) {\n overflow: hidden;\n}\nfigure {\n margin: 1em 40px;\n}\nhr {\n box-sizing: content-box;\n height: 0;\n}\npre {\n overflow: auto;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit;\n font: inherit;\n margin: 0;\n}\nbutton {\n overflow: visible;\n}\nbutton,\nselect {\n text-transform: none;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button;\n cursor: pointer;\n}\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\ninput {\n line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box;\n padding: 0;\n}\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: textfield;\n box-sizing: content-box;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\nlegend {\n border: 0;\n padding: 0;\n}\ntextarea {\n overflow: auto;\n}\noptgroup {\n font-weight: bold;\n}\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\ntd,\nth {\n padding: 0;\n}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print {\n *,\n *:before,\n *:after {\n background: transparent !important;\n color: #000 !important;\n box-shadow: none !important;\n text-shadow: none !important;\n }\n a,\n a:visited {\n text-decoration: underline;\n }\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n img {\n max-width: 100% !important;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n .navbar {\n display: none;\n }\n .btn > .caret,\n .dropup > .btn > .caret {\n border-top-color: #000 !important;\n }\n .label {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #ddd !important;\n }\n}\n@font-face {\n font-family: 'Glyphicons Halflings';\n src: url('../fonts/glyphicons-halflings-regular.eot');\n src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');\n}\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n content: \"\\2a\";\n}\n.glyphicon-plus:before {\n content: \"\\2b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n content: \"\\270f\";\n}\n.glyphicon-glass:before {\n content: \"\\e001\";\n}\n.glyphicon-music:before {\n content: \"\\e002\";\n}\n.glyphicon-search:before {\n content: \"\\e003\";\n}\n.glyphicon-heart:before {\n content: \"\\e005\";\n}\n.glyphicon-star:before {\n content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n content: \"\\e007\";\n}\n.glyphicon-user:before {\n content: \"\\e008\";\n}\n.glyphicon-film:before {\n content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n content: \"\\e010\";\n}\n.glyphicon-th:before {\n content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n content: \"\\e012\";\n}\n.glyphicon-ok:before {\n content: \"\\e013\";\n}\n.glyphicon-remove:before {\n content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n content: \"\\e016\";\n}\n.glyphicon-off:before {\n content: \"\\e017\";\n}\n.glyphicon-signal:before {\n content: \"\\e018\";\n}\n.glyphicon-cog:before {\n content: \"\\e019\";\n}\n.glyphicon-trash:before {\n content: \"\\e020\";\n}\n.glyphicon-home:before {\n content: \"\\e021\";\n}\n.glyphicon-file:before {\n content: \"\\e022\";\n}\n.glyphicon-time:before {\n content: \"\\e023\";\n}\n.glyphicon-road:before {\n content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n content: \"\\e025\";\n}\n.glyphicon-download:before {\n content: \"\\e026\";\n}\n.glyphicon-upload:before {\n content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n content: \"\\e032\";\n}\n.glyphicon-lock:before {\n content: \"\\e033\";\n}\n.glyphicon-flag:before {\n content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n content: \"\\e040\";\n}\n.glyphicon-tag:before {\n content: \"\\e041\";\n}\n.glyphicon-tags:before {\n content: \"\\e042\";\n}\n.glyphicon-book:before {\n content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n content: \"\\e044\";\n}\n.glyphicon-print:before {\n content: \"\\e045\";\n}\n.glyphicon-camera:before {\n content: \"\\e046\";\n}\n.glyphicon-font:before {\n content: \"\\e047\";\n}\n.glyphicon-bold:before {\n content: \"\\e048\";\n}\n.glyphicon-italic:before {\n content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n content: \"\\e055\";\n}\n.glyphicon-list:before {\n content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n content: \"\\e059\";\n}\n.glyphicon-picture:before {\n content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n content: \"\\e063\";\n}\n.glyphicon-tint:before {\n content: \"\\e064\";\n}\n.glyphicon-edit:before {\n content: \"\\e065\";\n}\n.glyphicon-share:before {\n content: \"\\e066\";\n}\n.glyphicon-check:before {\n content: \"\\e067\";\n}\n.glyphicon-move:before {\n content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n content: \"\\e070\";\n}\n.glyphicon-backward:before {\n content: \"\\e071\";\n}\n.glyphicon-play:before {\n content: \"\\e072\";\n}\n.glyphicon-pause:before {\n content: \"\\e073\";\n}\n.glyphicon-stop:before {\n content: \"\\e074\";\n}\n.glyphicon-forward:before {\n content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n content: \"\\e077\";\n}\n.glyphicon-eject:before {\n content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n content: \"\\e101\";\n}\n.glyphicon-gift:before {\n content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n content: \"\\e103\";\n}\n.glyphicon-fire:before {\n content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n content: \"\\e107\";\n}\n.glyphicon-plane:before {\n content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n content: \"\\e109\";\n}\n.glyphicon-random:before {\n content: \"\\e110\";\n}\n.glyphicon-comment:before {\n content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n content: \"\\e122\";\n}\n.glyphicon-bell:before {\n content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n content: \"\\e134\";\n}\n.glyphicon-globe:before {\n content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n content: \"\\e137\";\n}\n.glyphicon-filter:before {\n content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n content: \"\\e143\";\n}\n.glyphicon-link:before {\n content: \"\\e144\";\n}\n.glyphicon-phone:before {\n content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n content: \"\\e146\";\n}\n.glyphicon-usd:before {\n content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n content: \"\\e149\";\n}\n.glyphicon-sort:before {\n content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n content: \"\\e157\";\n}\n.glyphicon-expand:before {\n content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n content: \"\\e161\";\n}\n.glyphicon-flash:before {\n content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n content: \"\\e164\";\n}\n.glyphicon-record:before {\n content: \"\\e165\";\n}\n.glyphicon-save:before {\n content: \"\\e166\";\n}\n.glyphicon-open:before {\n content: \"\\e167\";\n}\n.glyphicon-saved:before {\n content: \"\\e168\";\n}\n.glyphicon-import:before {\n content: \"\\e169\";\n}\n.glyphicon-export:before {\n content: \"\\e170\";\n}\n.glyphicon-send:before {\n content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n content: \"\\e179\";\n}\n.glyphicon-header:before {\n content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n content: \"\\e183\";\n}\n.glyphicon-tower:before {\n content: \"\\e184\";\n}\n.glyphicon-stats:before {\n content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n content: \"\\e200\";\n}\n.glyphicon-cd:before {\n content: \"\\e201\";\n}\n.glyphicon-save-file:before {\n content: \"\\e202\";\n}\n.glyphicon-open-file:before {\n content: \"\\e203\";\n}\n.glyphicon-level-up:before {\n content: \"\\e204\";\n}\n.glyphicon-copy:before {\n content: \"\\e205\";\n}\n.glyphicon-paste:before {\n content: \"\\e206\";\n}\n.glyphicon-alert:before {\n content: \"\\e209\";\n}\n.glyphicon-equalizer:before {\n content: \"\\e210\";\n}\n.glyphicon-king:before {\n content: \"\\e211\";\n}\n.glyphicon-queen:before {\n content: \"\\e212\";\n}\n.glyphicon-pawn:before {\n content: \"\\e213\";\n}\n.glyphicon-bishop:before {\n content: \"\\e214\";\n}\n.glyphicon-knight:before {\n content: \"\\e215\";\n}\n.glyphicon-baby-formula:before {\n content: \"\\e216\";\n}\n.glyphicon-tent:before {\n content: \"\\26fa\";\n}\n.glyphicon-blackboard:before {\n content: \"\\e218\";\n}\n.glyphicon-bed:before {\n content: \"\\e219\";\n}\n.glyphicon-apple:before {\n content: \"\\f8ff\";\n}\n.glyphicon-erase:before {\n content: \"\\e221\";\n}\n.glyphicon-hourglass:before {\n content: \"\\231b\";\n}\n.glyphicon-lamp:before {\n content: \"\\e223\";\n}\n.glyphicon-duplicate:before {\n content: \"\\e224\";\n}\n.glyphicon-piggy-bank:before {\n content: \"\\e225\";\n}\n.glyphicon-scissors:before {\n content: \"\\e226\";\n}\n.glyphicon-bitcoin:before {\n content: \"\\e227\";\n}\n.glyphicon-btc:before {\n content: \"\\e227\";\n}\n.glyphicon-xbt:before {\n content: \"\\e227\";\n}\n.glyphicon-yen:before {\n content: \"\\00a5\";\n}\n.glyphicon-jpy:before {\n content: \"\\00a5\";\n}\n.glyphicon-ruble:before {\n content: \"\\20bd\";\n}\n.glyphicon-rub:before {\n content: \"\\20bd\";\n}\n.glyphicon-scale:before {\n content: \"\\e230\";\n}\n.glyphicon-ice-lolly:before {\n content: \"\\e231\";\n}\n.glyphicon-ice-lolly-tasted:before {\n content: \"\\e232\";\n}\n.glyphicon-education:before {\n content: \"\\e233\";\n}\n.glyphicon-option-horizontal:before {\n content: \"\\e234\";\n}\n.glyphicon-option-vertical:before {\n content: \"\\e235\";\n}\n.glyphicon-menu-hamburger:before {\n content: \"\\e236\";\n}\n.glyphicon-modal-window:before {\n content: \"\\e237\";\n}\n.glyphicon-oil:before {\n content: \"\\e238\";\n}\n.glyphicon-grain:before {\n content: \"\\e239\";\n}\n.glyphicon-sunglasses:before {\n content: \"\\e240\";\n}\n.glyphicon-text-size:before {\n content: \"\\e241\";\n}\n.glyphicon-text-color:before {\n content: \"\\e242\";\n}\n.glyphicon-text-background:before {\n content: \"\\e243\";\n}\n.glyphicon-object-align-top:before {\n content: \"\\e244\";\n}\n.glyphicon-object-align-bottom:before {\n content: \"\\e245\";\n}\n.glyphicon-object-align-horizontal:before {\n content: \"\\e246\";\n}\n.glyphicon-object-align-left:before {\n content: \"\\e247\";\n}\n.glyphicon-object-align-vertical:before {\n content: \"\\e248\";\n}\n.glyphicon-object-align-right:before {\n content: \"\\e249\";\n}\n.glyphicon-triangle-right:before {\n content: \"\\e250\";\n}\n.glyphicon-triangle-left:before {\n content: \"\\e251\";\n}\n.glyphicon-triangle-bottom:before {\n content: \"\\e252\";\n}\n.glyphicon-triangle-top:before {\n content: \"\\e253\";\n}\n.glyphicon-console:before {\n content: \"\\e254\";\n}\n.glyphicon-superscript:before {\n content: \"\\e255\";\n}\n.glyphicon-subscript:before {\n content: \"\\e256\";\n}\n.glyphicon-menu-left:before {\n content: \"\\e257\";\n}\n.glyphicon-menu-right:before {\n content: \"\\e258\";\n}\n.glyphicon-menu-down:before {\n content: \"\\e259\";\n}\n.glyphicon-menu-up:before {\n content: \"\\e260\";\n}\n* {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n*:before,\n*:after {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\nbody {\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 14px;\n line-height: 1.42857143;\n color: #333333;\n background-color: #ffffff;\n}\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\na {\n color: #337ab7;\n text-decoration: none;\n}\na:hover,\na:focus {\n color: #23527c;\n text-decoration: underline;\n}\na:focus {\n outline: thin dotted;\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\nfigure {\n margin: 0;\n}\nimg {\n vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n display: block;\n max-width: 100%;\n height: auto;\n}\n.img-rounded {\n border-radius: 6px;\n}\n.img-thumbnail {\n padding: 4px;\n line-height: 1.42857143;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n border-radius: 4px;\n -webkit-transition: all 0.2s ease-in-out;\n -o-transition: all 0.2s ease-in-out;\n transition: all 0.2s ease-in-out;\n display: inline-block;\n max-width: 100%;\n height: auto;\n}\n.img-circle {\n border-radius: 50%;\n}\nhr {\n margin-top: 20px;\n margin-bottom: 20px;\n border: 0;\n border-top: 1px solid #eeeeee;\n}\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n}\n[role=\"button\"] {\n cursor: pointer;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n font-family: inherit;\n font-weight: 500;\n line-height: 1.1;\n color: inherit;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n font-weight: normal;\n line-height: 1;\n color: #777777;\n}\nh1,\n.h1,\nh2,\n.h2,\nh3,\n.h3 {\n margin-top: 20px;\n margin-bottom: 10px;\n}\nh1 small,\n.h1 small,\nh2 small,\n.h2 small,\nh3 small,\n.h3 small,\nh1 .small,\n.h1 .small,\nh2 .small,\n.h2 .small,\nh3 .small,\n.h3 .small {\n font-size: 65%;\n}\nh4,\n.h4,\nh5,\n.h5,\nh6,\n.h6 {\n margin-top: 10px;\n margin-bottom: 10px;\n}\nh4 small,\n.h4 small,\nh5 small,\n.h5 small,\nh6 small,\n.h6 small,\nh4 .small,\n.h4 .small,\nh5 .small,\n.h5 .small,\nh6 .small,\n.h6 .small {\n font-size: 75%;\n}\nh1,\n.h1 {\n font-size: 36px;\n}\nh2,\n.h2 {\n font-size: 30px;\n}\nh3,\n.h3 {\n font-size: 24px;\n}\nh4,\n.h4 {\n font-size: 18px;\n}\nh5,\n.h5 {\n font-size: 14px;\n}\nh6,\n.h6 {\n font-size: 12px;\n}\np {\n margin: 0 0 10px;\n}\n.lead {\n margin-bottom: 20px;\n font-size: 16px;\n font-weight: 300;\n line-height: 1.4;\n}\n@media (min-width: 768px) {\n .lead {\n font-size: 21px;\n }\n}\nsmall,\n.small {\n font-size: 85%;\n}\nmark,\n.mark {\n background-color: #fcf8e3;\n padding: .2em;\n}\n.text-left {\n text-align: left;\n}\n.text-right {\n text-align: right;\n}\n.text-center {\n text-align: center;\n}\n.text-justify {\n text-align: justify;\n}\n.text-nowrap {\n white-space: nowrap;\n}\n.text-lowercase {\n text-transform: lowercase;\n}\n.text-uppercase {\n text-transform: uppercase;\n}\n.text-capitalize {\n text-transform: capitalize;\n}\n.text-muted {\n color: #777777;\n}\n.text-primary {\n color: #337ab7;\n}\na.text-primary:hover,\na.text-primary:focus {\n color: #286090;\n}\n.text-success {\n color: #3c763d;\n}\na.text-success:hover,\na.text-success:focus {\n color: #2b542c;\n}\n.text-info {\n color: #31708f;\n}\na.text-info:hover,\na.text-info:focus {\n color: #245269;\n}\n.text-warning {\n color: #8a6d3b;\n}\na.text-warning:hover,\na.text-warning:focus {\n color: #66512c;\n}\n.text-danger {\n color: #a94442;\n}\na.text-danger:hover,\na.text-danger:focus {\n color: #843534;\n}\n.bg-primary {\n color: #fff;\n background-color: #337ab7;\n}\na.bg-primary:hover,\na.bg-primary:focus {\n background-color: #286090;\n}\n.bg-success {\n background-color: #dff0d8;\n}\na.bg-success:hover,\na.bg-success:focus {\n background-color: #c1e2b3;\n}\n.bg-info {\n background-color: #d9edf7;\n}\na.bg-info:hover,\na.bg-info:focus {\n background-color: #afd9ee;\n}\n.bg-warning {\n background-color: #fcf8e3;\n}\na.bg-warning:hover,\na.bg-warning:focus {\n background-color: #f7ecb5;\n}\n.bg-danger {\n background-color: #f2dede;\n}\na.bg-danger:hover,\na.bg-danger:focus {\n background-color: #e4b9b9;\n}\n.page-header {\n padding-bottom: 9px;\n margin: 40px 0 20px;\n border-bottom: 1px solid #eeeeee;\n}\nul,\nol {\n margin-top: 0;\n margin-bottom: 10px;\n}\nul ul,\nol ul,\nul ol,\nol ol {\n margin-bottom: 0;\n}\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n.list-inline {\n padding-left: 0;\n list-style: none;\n margin-left: -5px;\n}\n.list-inline > li {\n display: inline-block;\n padding-left: 5px;\n padding-right: 5px;\n}\ndl {\n margin-top: 0;\n margin-bottom: 20px;\n}\ndt,\ndd {\n line-height: 1.42857143;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0;\n}\n@media (min-width: 768px) {\n .dl-horizontal dt {\n float: left;\n width: 160px;\n clear: left;\n text-align: right;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .dl-horizontal dd {\n margin-left: 180px;\n }\n}\nabbr[title],\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted #777777;\n}\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\nblockquote {\n padding: 10px 20px;\n margin: 0 0 20px;\n font-size: 17.5px;\n border-left: 5px solid #eeeeee;\n}\nblockquote p:last-child,\nblockquote ul:last-child,\nblockquote ol:last-child {\n margin-bottom: 0;\n}\nblockquote footer,\nblockquote small,\nblockquote .small {\n display: block;\n font-size: 80%;\n line-height: 1.42857143;\n color: #777777;\n}\nblockquote footer:before,\nblockquote small:before,\nblockquote .small:before {\n content: '\\2014 \\00A0';\n}\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n border-right: 5px solid #eeeeee;\n border-left: 0;\n text-align: right;\n}\n.blockquote-reverse footer:before,\nblockquote.pull-right footer:before,\n.blockquote-reverse small:before,\nblockquote.pull-right small:before,\n.blockquote-reverse .small:before,\nblockquote.pull-right .small:before {\n content: '';\n}\n.blockquote-reverse footer:after,\nblockquote.pull-right footer:after,\n.blockquote-reverse small:after,\nblockquote.pull-right small:after,\n.blockquote-reverse .small:after,\nblockquote.pull-right .small:after {\n content: '\\00A0 \\2014';\n}\naddress {\n margin-bottom: 20px;\n font-style: normal;\n line-height: 1.42857143;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: #c7254e;\n background-color: #f9f2f4;\n border-radius: 4px;\n}\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: #ffffff;\n background-color: #333333;\n border-radius: 3px;\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: bold;\n box-shadow: none;\n}\npre {\n display: block;\n padding: 9.5px;\n margin: 0 0 10px;\n font-size: 13px;\n line-height: 1.42857143;\n word-break: break-all;\n word-wrap: break-word;\n color: #333333;\n background-color: #f5f5f5;\n border: 1px solid #cccccc;\n border-radius: 4px;\n}\npre code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n}\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n.container {\n margin-right: auto;\n margin-left: auto;\n padding-left: 15px;\n padding-right: 15px;\n}\n@media (min-width: 768px) {\n .container {\n width: 750px;\n }\n}\n@media (min-width: 992px) {\n .container {\n width: 970px;\n }\n}\n@media (min-width: 1200px) {\n .container {\n width: 1170px;\n }\n}\n.container-fluid {\n margin-right: auto;\n margin-left: auto;\n padding-left: 15px;\n padding-right: 15px;\n}\n.row {\n margin-left: -15px;\n margin-right: -15px;\n}\n.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {\n position: relative;\n min-height: 1px;\n padding-left: 15px;\n padding-right: 15px;\n}\n.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {\n float: left;\n}\n.col-xs-12 {\n width: 100%;\n}\n.col-xs-11 {\n width: 91.66666667%;\n}\n.col-xs-10 {\n width: 83.33333333%;\n}\n.col-xs-9 {\n width: 75%;\n}\n.col-xs-8 {\n width: 66.66666667%;\n}\n.col-xs-7 {\n width: 58.33333333%;\n}\n.col-xs-6 {\n width: 50%;\n}\n.col-xs-5 {\n width: 41.66666667%;\n}\n.col-xs-4 {\n width: 33.33333333%;\n}\n.col-xs-3 {\n width: 25%;\n}\n.col-xs-2 {\n width: 16.66666667%;\n}\n.col-xs-1 {\n width: 8.33333333%;\n}\n.col-xs-pull-12 {\n right: 100%;\n}\n.col-xs-pull-11 {\n right: 91.66666667%;\n}\n.col-xs-pull-10 {\n right: 83.33333333%;\n}\n.col-xs-pull-9 {\n right: 75%;\n}\n.col-xs-pull-8 {\n right: 66.66666667%;\n}\n.col-xs-pull-7 {\n right: 58.33333333%;\n}\n.col-xs-pull-6 {\n right: 50%;\n}\n.col-xs-pull-5 {\n right: 41.66666667%;\n}\n.col-xs-pull-4 {\n right: 33.33333333%;\n}\n.col-xs-pull-3 {\n right: 25%;\n}\n.col-xs-pull-2 {\n right: 16.66666667%;\n}\n.col-xs-pull-1 {\n right: 8.33333333%;\n}\n.col-xs-pull-0 {\n right: auto;\n}\n.col-xs-push-12 {\n left: 100%;\n}\n.col-xs-push-11 {\n left: 91.66666667%;\n}\n.col-xs-push-10 {\n left: 83.33333333%;\n}\n.col-xs-push-9 {\n left: 75%;\n}\n.col-xs-push-8 {\n left: 66.66666667%;\n}\n.col-xs-push-7 {\n left: 58.33333333%;\n}\n.col-xs-push-6 {\n left: 50%;\n}\n.col-xs-push-5 {\n left: 41.66666667%;\n}\n.col-xs-push-4 {\n left: 33.33333333%;\n}\n.col-xs-push-3 {\n left: 25%;\n}\n.col-xs-push-2 {\n left: 16.66666667%;\n}\n.col-xs-push-1 {\n left: 8.33333333%;\n}\n.col-xs-push-0 {\n left: auto;\n}\n.col-xs-offset-12 {\n margin-left: 100%;\n}\n.col-xs-offset-11 {\n margin-left: 91.66666667%;\n}\n.col-xs-offset-10 {\n margin-left: 83.33333333%;\n}\n.col-xs-offset-9 {\n margin-left: 75%;\n}\n.col-xs-offset-8 {\n margin-left: 66.66666667%;\n}\n.col-xs-offset-7 {\n margin-left: 58.33333333%;\n}\n.col-xs-offset-6 {\n margin-left: 50%;\n}\n.col-xs-offset-5 {\n margin-left: 41.66666667%;\n}\n.col-xs-offset-4 {\n margin-left: 33.33333333%;\n}\n.col-xs-offset-3 {\n margin-left: 25%;\n}\n.col-xs-offset-2 {\n margin-left: 16.66666667%;\n}\n.col-xs-offset-1 {\n margin-left: 8.33333333%;\n}\n.col-xs-offset-0 {\n margin-left: 0%;\n}\n@media (min-width: 768px) {\n .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {\n float: left;\n }\n .col-sm-12 {\n width: 100%;\n }\n .col-sm-11 {\n width: 91.66666667%;\n }\n .col-sm-10 {\n width: 83.33333333%;\n }\n .col-sm-9 {\n width: 75%;\n }\n .col-sm-8 {\n width: 66.66666667%;\n }\n .col-sm-7 {\n width: 58.33333333%;\n }\n .col-sm-6 {\n width: 50%;\n }\n .col-sm-5 {\n width: 41.66666667%;\n }\n .col-sm-4 {\n width: 33.33333333%;\n }\n .col-sm-3 {\n width: 25%;\n }\n .col-sm-2 {\n width: 16.66666667%;\n }\n .col-sm-1 {\n width: 8.33333333%;\n }\n .col-sm-pull-12 {\n right: 100%;\n }\n .col-sm-pull-11 {\n right: 91.66666667%;\n }\n .col-sm-pull-10 {\n right: 83.33333333%;\n }\n .col-sm-pull-9 {\n right: 75%;\n }\n .col-sm-pull-8 {\n right: 66.66666667%;\n }\n .col-sm-pull-7 {\n right: 58.33333333%;\n }\n .col-sm-pull-6 {\n right: 50%;\n }\n .col-sm-pull-5 {\n right: 41.66666667%;\n }\n .col-sm-pull-4 {\n right: 33.33333333%;\n }\n .col-sm-pull-3 {\n right: 25%;\n }\n .col-sm-pull-2 {\n right: 16.66666667%;\n }\n .col-sm-pull-1 {\n right: 8.33333333%;\n }\n .col-sm-pull-0 {\n right: auto;\n }\n .col-sm-push-12 {\n left: 100%;\n }\n .col-sm-push-11 {\n left: 91.66666667%;\n }\n .col-sm-push-10 {\n left: 83.33333333%;\n }\n .col-sm-push-9 {\n left: 75%;\n }\n .col-sm-push-8 {\n left: 66.66666667%;\n }\n .col-sm-push-7 {\n left: 58.33333333%;\n }\n .col-sm-push-6 {\n left: 50%;\n }\n .col-sm-push-5 {\n left: 41.66666667%;\n }\n .col-sm-push-4 {\n left: 33.33333333%;\n }\n .col-sm-push-3 {\n left: 25%;\n }\n .col-sm-push-2 {\n left: 16.66666667%;\n }\n .col-sm-push-1 {\n left: 8.33333333%;\n }\n .col-sm-push-0 {\n left: auto;\n }\n .col-sm-offset-12 {\n margin-left: 100%;\n }\n .col-sm-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-sm-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-sm-offset-9 {\n margin-left: 75%;\n }\n .col-sm-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-sm-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-sm-offset-6 {\n margin-left: 50%;\n }\n .col-sm-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-sm-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-sm-offset-3 {\n margin-left: 25%;\n }\n .col-sm-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-sm-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-sm-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 992px) {\n .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {\n float: left;\n }\n .col-md-12 {\n width: 100%;\n }\n .col-md-11 {\n width: 91.66666667%;\n }\n .col-md-10 {\n width: 83.33333333%;\n }\n .col-md-9 {\n width: 75%;\n }\n .col-md-8 {\n width: 66.66666667%;\n }\n .col-md-7 {\n width: 58.33333333%;\n }\n .col-md-6 {\n width: 50%;\n }\n .col-md-5 {\n width: 41.66666667%;\n }\n .col-md-4 {\n width: 33.33333333%;\n }\n .col-md-3 {\n width: 25%;\n }\n .col-md-2 {\n width: 16.66666667%;\n }\n .col-md-1 {\n width: 8.33333333%;\n }\n .col-md-pull-12 {\n right: 100%;\n }\n .col-md-pull-11 {\n right: 91.66666667%;\n }\n .col-md-pull-10 {\n right: 83.33333333%;\n }\n .col-md-pull-9 {\n right: 75%;\n }\n .col-md-pull-8 {\n right: 66.66666667%;\n }\n .col-md-pull-7 {\n right: 58.33333333%;\n }\n .col-md-pull-6 {\n right: 50%;\n }\n .col-md-pull-5 {\n right: 41.66666667%;\n }\n .col-md-pull-4 {\n right: 33.33333333%;\n }\n .col-md-pull-3 {\n right: 25%;\n }\n .col-md-pull-2 {\n right: 16.66666667%;\n }\n .col-md-pull-1 {\n right: 8.33333333%;\n }\n .col-md-pull-0 {\n right: auto;\n }\n .col-md-push-12 {\n left: 100%;\n }\n .col-md-push-11 {\n left: 91.66666667%;\n }\n .col-md-push-10 {\n left: 83.33333333%;\n }\n .col-md-push-9 {\n left: 75%;\n }\n .col-md-push-8 {\n left: 66.66666667%;\n }\n .col-md-push-7 {\n left: 58.33333333%;\n }\n .col-md-push-6 {\n left: 50%;\n }\n .col-md-push-5 {\n left: 41.66666667%;\n }\n .col-md-push-4 {\n left: 33.33333333%;\n }\n .col-md-push-3 {\n left: 25%;\n }\n .col-md-push-2 {\n left: 16.66666667%;\n }\n .col-md-push-1 {\n left: 8.33333333%;\n }\n .col-md-push-0 {\n left: auto;\n }\n .col-md-offset-12 {\n margin-left: 100%;\n }\n .col-md-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-md-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-md-offset-9 {\n margin-left: 75%;\n }\n .col-md-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-md-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-md-offset-6 {\n margin-left: 50%;\n }\n .col-md-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-md-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-md-offset-3 {\n margin-left: 25%;\n }\n .col-md-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-md-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-md-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 1200px) {\n .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {\n float: left;\n }\n .col-lg-12 {\n width: 100%;\n }\n .col-lg-11 {\n width: 91.66666667%;\n }\n .col-lg-10 {\n width: 83.33333333%;\n }\n .col-lg-9 {\n width: 75%;\n }\n .col-lg-8 {\n width: 66.66666667%;\n }\n .col-lg-7 {\n width: 58.33333333%;\n }\n .col-lg-6 {\n width: 50%;\n }\n .col-lg-5 {\n width: 41.66666667%;\n }\n .col-lg-4 {\n width: 33.33333333%;\n }\n .col-lg-3 {\n width: 25%;\n }\n .col-lg-2 {\n width: 16.66666667%;\n }\n .col-lg-1 {\n width: 8.33333333%;\n }\n .col-lg-pull-12 {\n right: 100%;\n }\n .col-lg-pull-11 {\n right: 91.66666667%;\n }\n .col-lg-pull-10 {\n right: 83.33333333%;\n }\n .col-lg-pull-9 {\n right: 75%;\n }\n .col-lg-pull-8 {\n right: 66.66666667%;\n }\n .col-lg-pull-7 {\n right: 58.33333333%;\n }\n .col-lg-pull-6 {\n right: 50%;\n }\n .col-lg-pull-5 {\n right: 41.66666667%;\n }\n .col-lg-pull-4 {\n right: 33.33333333%;\n }\n .col-lg-pull-3 {\n right: 25%;\n }\n .col-lg-pull-2 {\n right: 16.66666667%;\n }\n .col-lg-pull-1 {\n right: 8.33333333%;\n }\n .col-lg-pull-0 {\n right: auto;\n }\n .col-lg-push-12 {\n left: 100%;\n }\n .col-lg-push-11 {\n left: 91.66666667%;\n }\n .col-lg-push-10 {\n left: 83.33333333%;\n }\n .col-lg-push-9 {\n left: 75%;\n }\n .col-lg-push-8 {\n left: 66.66666667%;\n }\n .col-lg-push-7 {\n left: 58.33333333%;\n }\n .col-lg-push-6 {\n left: 50%;\n }\n .col-lg-push-5 {\n left: 41.66666667%;\n }\n .col-lg-push-4 {\n left: 33.33333333%;\n }\n .col-lg-push-3 {\n left: 25%;\n }\n .col-lg-push-2 {\n left: 16.66666667%;\n }\n .col-lg-push-1 {\n left: 8.33333333%;\n }\n .col-lg-push-0 {\n left: auto;\n }\n .col-lg-offset-12 {\n margin-left: 100%;\n }\n .col-lg-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-lg-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-lg-offset-9 {\n margin-left: 75%;\n }\n .col-lg-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-lg-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-lg-offset-6 {\n margin-left: 50%;\n }\n .col-lg-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-lg-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-lg-offset-3 {\n margin-left: 25%;\n }\n .col-lg-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-lg-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-lg-offset-0 {\n margin-left: 0%;\n }\n}\ntable {\n background-color: transparent;\n}\ncaption {\n padding-top: 8px;\n padding-bottom: 8px;\n color: #777777;\n text-align: left;\n}\nth {\n text-align: left;\n}\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 20px;\n}\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n padding: 8px;\n line-height: 1.42857143;\n vertical-align: top;\n border-top: 1px solid #dddddd;\n}\n.table > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid #dddddd;\n}\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n border-top: 0;\n}\n.table > tbody + tbody {\n border-top: 2px solid #dddddd;\n}\n.table .table {\n background-color: #ffffff;\n}\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n padding: 5px;\n}\n.table-bordered {\n border: 1px solid #dddddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n border: 1px solid #dddddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n border-bottom-width: 2px;\n}\n.table-striped > tbody > tr:nth-of-type(odd) {\n background-color: #f9f9f9;\n}\n.table-hover > tbody > tr:hover {\n background-color: #f5f5f5;\n}\ntable col[class*=\"col-\"] {\n position: static;\n float: none;\n display: table-column;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n position: static;\n float: none;\n display: table-cell;\n}\n.table > thead > tr > td.active,\n.table > tbody > tr > td.active,\n.table > tfoot > tr > td.active,\n.table > thead > tr > th.active,\n.table > tbody > tr > th.active,\n.table > tfoot > tr > th.active,\n.table > thead > tr.active > td,\n.table > tbody > tr.active > td,\n.table > tfoot > tr.active > td,\n.table > thead > tr.active > th,\n.table > tbody > tr.active > th,\n.table > tfoot > tr.active > th {\n background-color: #f5f5f5;\n}\n.table-hover > tbody > tr > td.active:hover,\n.table-hover > tbody > tr > th.active:hover,\n.table-hover > tbody > tr.active:hover > td,\n.table-hover > tbody > tr:hover > .active,\n.table-hover > tbody > tr.active:hover > th {\n background-color: #e8e8e8;\n}\n.table > thead > tr > td.success,\n.table > tbody > tr > td.success,\n.table > tfoot > tr > td.success,\n.table > thead > tr > th.success,\n.table > tbody > tr > th.success,\n.table > tfoot > tr > th.success,\n.table > thead > tr.success > td,\n.table > tbody > tr.success > td,\n.table > tfoot > tr.success > td,\n.table > thead > tr.success > th,\n.table > tbody > tr.success > th,\n.table > tfoot > tr.success > th {\n background-color: #dff0d8;\n}\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td,\n.table-hover > tbody > tr:hover > .success,\n.table-hover > tbody > tr.success:hover > th {\n background-color: #d0e9c6;\n}\n.table > thead > tr > td.info,\n.table > tbody > tr > td.info,\n.table > tfoot > tr > td.info,\n.table > thead > tr > th.info,\n.table > tbody > tr > th.info,\n.table > tfoot > tr > th.info,\n.table > thead > tr.info > td,\n.table > tbody > tr.info > td,\n.table > tfoot > tr.info > td,\n.table > thead > tr.info > th,\n.table > tbody > tr.info > th,\n.table > tfoot > tr.info > th {\n background-color: #d9edf7;\n}\n.table-hover > tbody > tr > td.info:hover,\n.table-hover > tbody > tr > th.info:hover,\n.table-hover > tbody > tr.info:hover > td,\n.table-hover > tbody > tr:hover > .info,\n.table-hover > tbody > tr.info:hover > th {\n background-color: #c4e3f3;\n}\n.table > thead > tr > td.warning,\n.table > tbody > tr > td.warning,\n.table > tfoot > tr > td.warning,\n.table > thead > tr > th.warning,\n.table > tbody > tr > th.warning,\n.table > tfoot > tr > th.warning,\n.table > thead > tr.warning > td,\n.table > tbody > tr.warning > td,\n.table > tfoot > tr.warning > td,\n.table > thead > tr.warning > th,\n.table > tbody > tr.warning > th,\n.table > tfoot > tr.warning > th {\n background-color: #fcf8e3;\n}\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td,\n.table-hover > tbody > tr:hover > .warning,\n.table-hover > tbody > tr.warning:hover > th {\n background-color: #faf2cc;\n}\n.table > thead > tr > td.danger,\n.table > tbody > tr > td.danger,\n.table > tfoot > tr > td.danger,\n.table > thead > tr > th.danger,\n.table > tbody > tr > th.danger,\n.table > tfoot > tr > th.danger,\n.table > thead > tr.danger > td,\n.table > tbody > tr.danger > td,\n.table > tfoot > tr.danger > td,\n.table > thead > tr.danger > th,\n.table > tbody > tr.danger > th,\n.table > tfoot > tr.danger > th {\n background-color: #f2dede;\n}\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td,\n.table-hover > tbody > tr:hover > .danger,\n.table-hover > tbody > tr.danger:hover > th {\n background-color: #ebcccc;\n}\n.table-responsive {\n overflow-x: auto;\n min-height: 0.01%;\n}\n@media screen and (max-width: 767px) {\n .table-responsive {\n width: 100%;\n margin-bottom: 15px;\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid #dddddd;\n }\n .table-responsive > .table {\n margin-bottom: 0;\n }\n .table-responsive > .table > thead > tr > th,\n .table-responsive > .table > tbody > tr > th,\n .table-responsive > .table > tfoot > tr > th,\n .table-responsive > .table > thead > tr > td,\n .table-responsive > .table > tbody > tr > td,\n .table-responsive > .table > tfoot > tr > td {\n white-space: nowrap;\n }\n .table-responsive > .table-bordered {\n border: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:first-child,\n .table-responsive > .table-bordered > tbody > tr > th:first-child,\n .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n .table-responsive > .table-bordered > thead > tr > td:first-child,\n .table-responsive > .table-bordered > tbody > tr > td:first-child,\n .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:last-child,\n .table-responsive > .table-bordered > tbody > tr > th:last-child,\n .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n .table-responsive > .table-bordered > thead > tr > td:last-child,\n .table-responsive > .table-bordered > tbody > tr > td:last-child,\n .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n }\n .table-responsive > .table-bordered > tbody > tr:last-child > th,\n .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n .table-responsive > .table-bordered > tbody > tr:last-child > td,\n .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n border-bottom: 0;\n }\n}\nfieldset {\n padding: 0;\n margin: 0;\n border: 0;\n min-width: 0;\n}\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: 20px;\n font-size: 21px;\n line-height: inherit;\n color: #333333;\n border: 0;\n border-bottom: 1px solid #e5e5e5;\n}\nlabel {\n display: inline-block;\n max-width: 100%;\n margin-bottom: 5px;\n font-weight: bold;\n}\ninput[type=\"search\"] {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9;\n line-height: normal;\n}\ninput[type=\"file\"] {\n display: block;\n}\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\nselect[multiple],\nselect[size] {\n height: auto;\n}\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n outline: thin dotted;\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\noutput {\n display: block;\n padding-top: 7px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n}\n.form-control {\n display: block;\n width: 100%;\n height: 34px;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n background-color: #ffffff;\n background-image: none;\n border: 1px solid #cccccc;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.form-control:focus {\n border-color: #66afe9;\n outline: 0;\n -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n}\n.form-control::-moz-placeholder {\n color: #999999;\n opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n color: #999999;\n}\n.form-control::-webkit-input-placeholder {\n color: #999999;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n background-color: #eeeeee;\n opacity: 1;\n}\n.form-control[disabled],\nfieldset[disabled] .form-control {\n cursor: not-allowed;\n}\ntextarea.form-control {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: none;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n input[type=\"date\"].form-control,\n input[type=\"time\"].form-control,\n input[type=\"datetime-local\"].form-control,\n input[type=\"month\"].form-control {\n line-height: 34px;\n }\n input[type=\"date\"].input-sm,\n input[type=\"time\"].input-sm,\n input[type=\"datetime-local\"].input-sm,\n input[type=\"month\"].input-sm,\n .input-group-sm input[type=\"date\"],\n .input-group-sm input[type=\"time\"],\n .input-group-sm input[type=\"datetime-local\"],\n .input-group-sm input[type=\"month\"] {\n line-height: 30px;\n }\n input[type=\"date\"].input-lg,\n input[type=\"time\"].input-lg,\n input[type=\"datetime-local\"].input-lg,\n input[type=\"month\"].input-lg,\n .input-group-lg input[type=\"date\"],\n .input-group-lg input[type=\"time\"],\n .input-group-lg input[type=\"datetime-local\"],\n .input-group-lg input[type=\"month\"] {\n line-height: 46px;\n }\n}\n.form-group {\n margin-bottom: 15px;\n}\n.radio,\n.checkbox {\n position: relative;\n display: block;\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.radio label,\n.checkbox label {\n min-height: 20px;\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: normal;\n cursor: pointer;\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n position: absolute;\n margin-left: -20px;\n margin-top: 4px \\9;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n position: relative;\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n vertical-align: middle;\n font-weight: normal;\n cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px;\n}\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"].disabled,\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n cursor: not-allowed;\n}\n.radio-inline.disabled,\n.checkbox-inline.disabled,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox-inline {\n cursor: not-allowed;\n}\n.radio.disabled label,\n.checkbox.disabled label,\nfieldset[disabled] .radio label,\nfieldset[disabled] .checkbox label {\n cursor: not-allowed;\n}\n.form-control-static {\n padding-top: 7px;\n padding-bottom: 7px;\n margin-bottom: 0;\n min-height: 34px;\n}\n.form-control-static.input-lg,\n.form-control-static.input-sm {\n padding-left: 0;\n padding-right: 0;\n}\n.input-sm {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-sm {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-sm,\nselect[multiple].input-sm {\n height: auto;\n}\n.form-group-sm .form-control {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.form-group-sm select.form-control {\n height: 30px;\n line-height: 30px;\n}\n.form-group-sm textarea.form-control,\n.form-group-sm select[multiple].form-control {\n height: auto;\n}\n.form-group-sm .form-control-static {\n height: 30px;\n min-height: 32px;\n padding: 6px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.input-lg {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-lg {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-lg,\nselect[multiple].input-lg {\n height: auto;\n}\n.form-group-lg .form-control {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.form-group-lg select.form-control {\n height: 46px;\n line-height: 46px;\n}\n.form-group-lg textarea.form-control,\n.form-group-lg select[multiple].form-control {\n height: auto;\n}\n.form-group-lg .form-control-static {\n height: 46px;\n min-height: 38px;\n padding: 11px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.has-feedback {\n position: relative;\n}\n.has-feedback .form-control {\n padding-right: 42.5px;\n}\n.form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n display: block;\n width: 34px;\n height: 34px;\n line-height: 34px;\n text-align: center;\n pointer-events: none;\n}\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n width: 46px;\n height: 46px;\n line-height: 46px;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback {\n width: 30px;\n height: 30px;\n line-height: 30px;\n}\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label {\n color: #3c763d;\n}\n.has-success .form-control {\n border-color: #3c763d;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-success .form-control:focus {\n border-color: #2b542c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n color: #3c763d;\n border-color: #3c763d;\n background-color: #dff0d8;\n}\n.has-success .form-control-feedback {\n color: #3c763d;\n}\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label {\n color: #8a6d3b;\n}\n.has-warning .form-control {\n border-color: #8a6d3b;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-warning .form-control:focus {\n border-color: #66512c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n color: #8a6d3b;\n border-color: #8a6d3b;\n background-color: #fcf8e3;\n}\n.has-warning .form-control-feedback {\n color: #8a6d3b;\n}\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label {\n color: #a94442;\n}\n.has-error .form-control {\n border-color: #a94442;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-error .form-control:focus {\n border-color: #843534;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n color: #a94442;\n border-color: #a94442;\n background-color: #f2dede;\n}\n.has-error .form-control-feedback {\n color: #a94442;\n}\n.has-feedback label ~ .form-control-feedback {\n top: 25px;\n}\n.has-feedback label.sr-only ~ .form-control-feedback {\n top: 0;\n}\n.help-block {\n display: block;\n margin-top: 5px;\n margin-bottom: 10px;\n color: #737373;\n}\n@media (min-width: 768px) {\n .form-inline .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-static {\n display: inline-block;\n }\n .form-inline .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .form-inline .input-group .input-group-addon,\n .form-inline .input-group .input-group-btn,\n .form-inline .input-group .form-control {\n width: auto;\n }\n .form-inline .input-group > .form-control {\n width: 100%;\n }\n .form-inline .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio,\n .form-inline .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio label,\n .form-inline .checkbox label {\n padding-left: 0;\n }\n .form-inline .radio input[type=\"radio\"],\n .form-inline .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .form-inline .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n margin-top: 0;\n margin-bottom: 0;\n padding-top: 7px;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n min-height: 27px;\n}\n.form-horizontal .form-group {\n margin-left: -15px;\n margin-right: -15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .control-label {\n text-align: right;\n margin-bottom: 0;\n padding-top: 7px;\n }\n}\n.form-horizontal .has-feedback .form-control-feedback {\n right: 15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-lg .control-label {\n padding-top: 14.333333px;\n font-size: 18px;\n }\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-sm .control-label {\n padding-top: 6px;\n font-size: 12px;\n }\n}\n.btn {\n display: inline-block;\n margin-bottom: 0;\n font-weight: normal;\n text-align: center;\n vertical-align: middle;\n touch-action: manipulation;\n cursor: pointer;\n background-image: none;\n border: 1px solid transparent;\n white-space: nowrap;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n border-radius: 4px;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n.btn:focus,\n.btn:active:focus,\n.btn.active:focus,\n.btn.focus,\n.btn:active.focus,\n.btn.active.focus {\n outline: thin dotted;\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n color: #333333;\n text-decoration: none;\n}\n.btn:active,\n.btn.active {\n outline: 0;\n background-image: none;\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n cursor: not-allowed;\n opacity: 0.65;\n filter: alpha(opacity=65);\n -webkit-box-shadow: none;\n box-shadow: none;\n}\na.btn.disabled,\nfieldset[disabled] a.btn {\n pointer-events: none;\n}\n.btn-default {\n color: #333333;\n background-color: #ffffff;\n border-color: #cccccc;\n}\n.btn-default:focus,\n.btn-default.focus {\n color: #333333;\n background-color: #e6e6e6;\n border-color: #8c8c8c;\n}\n.btn-default:hover {\n color: #333333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n color: #333333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active:hover,\n.btn-default.active:hover,\n.open > .dropdown-toggle.btn-default:hover,\n.btn-default:active:focus,\n.btn-default.active:focus,\n.open > .dropdown-toggle.btn-default:focus,\n.btn-default:active.focus,\n.btn-default.active.focus,\n.open > .dropdown-toggle.btn-default.focus {\n color: #333333;\n background-color: #d4d4d4;\n border-color: #8c8c8c;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n background-image: none;\n}\n.btn-default.disabled,\n.btn-default[disabled],\nfieldset[disabled] .btn-default,\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus,\n.btn-default.disabled:active,\n.btn-default[disabled]:active,\nfieldset[disabled] .btn-default:active,\n.btn-default.disabled.active,\n.btn-default[disabled].active,\nfieldset[disabled] .btn-default.active {\n background-color: #ffffff;\n border-color: #cccccc;\n}\n.btn-default .badge {\n color: #ffffff;\n background-color: #333333;\n}\n.btn-primary {\n color: #ffffff;\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary:focus,\n.btn-primary.focus {\n color: #ffffff;\n background-color: #286090;\n border-color: #122b40;\n}\n.btn-primary:hover {\n color: #ffffff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n color: #ffffff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active:hover,\n.btn-primary.active:hover,\n.open > .dropdown-toggle.btn-primary:hover,\n.btn-primary:active:focus,\n.btn-primary.active:focus,\n.open > .dropdown-toggle.btn-primary:focus,\n.btn-primary:active.focus,\n.btn-primary.active.focus,\n.open > .dropdown-toggle.btn-primary.focus {\n color: #ffffff;\n background-color: #204d74;\n border-color: #122b40;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n background-image: none;\n}\n.btn-primary.disabled,\n.btn-primary[disabled],\nfieldset[disabled] .btn-primary,\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus,\n.btn-primary.disabled:active,\n.btn-primary[disabled]:active,\nfieldset[disabled] .btn-primary:active,\n.btn-primary.disabled.active,\n.btn-primary[disabled].active,\nfieldset[disabled] .btn-primary.active {\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary .badge {\n color: #337ab7;\n background-color: #ffffff;\n}\n.btn-success {\n color: #ffffff;\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success:focus,\n.btn-success.focus {\n color: #ffffff;\n background-color: #449d44;\n border-color: #255625;\n}\n.btn-success:hover {\n color: #ffffff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n color: #ffffff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active:hover,\n.btn-success.active:hover,\n.open > .dropdown-toggle.btn-success:hover,\n.btn-success:active:focus,\n.btn-success.active:focus,\n.open > .dropdown-toggle.btn-success:focus,\n.btn-success:active.focus,\n.btn-success.active.focus,\n.open > .dropdown-toggle.btn-success.focus {\n color: #ffffff;\n background-color: #398439;\n border-color: #255625;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n background-image: none;\n}\n.btn-success.disabled,\n.btn-success[disabled],\nfieldset[disabled] .btn-success,\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus,\n.btn-success.disabled:active,\n.btn-success[disabled]:active,\nfieldset[disabled] .btn-success:active,\n.btn-success.disabled.active,\n.btn-success[disabled].active,\nfieldset[disabled] .btn-success.active {\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success .badge {\n color: #5cb85c;\n background-color: #ffffff;\n}\n.btn-info {\n color: #ffffff;\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info:focus,\n.btn-info.focus {\n color: #ffffff;\n background-color: #31b0d5;\n border-color: #1b6d85;\n}\n.btn-info:hover {\n color: #ffffff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n color: #ffffff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active:hover,\n.btn-info.active:hover,\n.open > .dropdown-toggle.btn-info:hover,\n.btn-info:active:focus,\n.btn-info.active:focus,\n.open > .dropdown-toggle.btn-info:focus,\n.btn-info:active.focus,\n.btn-info.active.focus,\n.open > .dropdown-toggle.btn-info.focus {\n color: #ffffff;\n background-color: #269abc;\n border-color: #1b6d85;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n background-image: none;\n}\n.btn-info.disabled,\n.btn-info[disabled],\nfieldset[disabled] .btn-info,\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus,\n.btn-info.disabled:active,\n.btn-info[disabled]:active,\nfieldset[disabled] .btn-info:active,\n.btn-info.disabled.active,\n.btn-info[disabled].active,\nfieldset[disabled] .btn-info.active {\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info .badge {\n color: #5bc0de;\n background-color: #ffffff;\n}\n.btn-warning {\n color: #ffffff;\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning:focus,\n.btn-warning.focus {\n color: #ffffff;\n background-color: #ec971f;\n border-color: #985f0d;\n}\n.btn-warning:hover {\n color: #ffffff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n color: #ffffff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active:hover,\n.btn-warning.active:hover,\n.open > .dropdown-toggle.btn-warning:hover,\n.btn-warning:active:focus,\n.btn-warning.active:focus,\n.open > .dropdown-toggle.btn-warning:focus,\n.btn-warning:active.focus,\n.btn-warning.active.focus,\n.open > .dropdown-toggle.btn-warning.focus {\n color: #ffffff;\n background-color: #d58512;\n border-color: #985f0d;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n background-image: none;\n}\n.btn-warning.disabled,\n.btn-warning[disabled],\nfieldset[disabled] .btn-warning,\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus,\n.btn-warning.disabled:active,\n.btn-warning[disabled]:active,\nfieldset[disabled] .btn-warning:active,\n.btn-warning.disabled.active,\n.btn-warning[disabled].active,\nfieldset[disabled] .btn-warning.active {\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning .badge {\n color: #f0ad4e;\n background-color: #ffffff;\n}\n.btn-danger {\n color: #ffffff;\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger:focus,\n.btn-danger.focus {\n color: #ffffff;\n background-color: #c9302c;\n border-color: #761c19;\n}\n.btn-danger:hover {\n color: #ffffff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n color: #ffffff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active:hover,\n.btn-danger.active:hover,\n.open > .dropdown-toggle.btn-danger:hover,\n.btn-danger:active:focus,\n.btn-danger.active:focus,\n.open > .dropdown-toggle.btn-danger:focus,\n.btn-danger:active.focus,\n.btn-danger.active.focus,\n.open > .dropdown-toggle.btn-danger.focus {\n color: #ffffff;\n background-color: #ac2925;\n border-color: #761c19;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n background-image: none;\n}\n.btn-danger.disabled,\n.btn-danger[disabled],\nfieldset[disabled] .btn-danger,\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus,\n.btn-danger.disabled:active,\n.btn-danger[disabled]:active,\nfieldset[disabled] .btn-danger:active,\n.btn-danger.disabled.active,\n.btn-danger[disabled].active,\nfieldset[disabled] .btn-danger.active {\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger .badge {\n color: #d9534f;\n background-color: #ffffff;\n}\n.btn-link {\n color: #337ab7;\n font-weight: normal;\n border-radius: 0;\n}\n.btn-link,\n.btn-link:active,\n.btn-link.active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n background-color: transparent;\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n border-color: transparent;\n}\n.btn-link:hover,\n.btn-link:focus {\n color: #23527c;\n text-decoration: underline;\n background-color: transparent;\n}\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n color: #777777;\n text-decoration: none;\n}\n.btn-lg,\n.btn-group-lg > .btn {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.btn-sm,\n.btn-group-sm > .btn {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-xs,\n.btn-group-xs > .btn {\n padding: 1px 5px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-block {\n display: block;\n width: 100%;\n}\n.btn-block + .btn-block {\n margin-top: 5px;\n}\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n.fade {\n opacity: 0;\n -webkit-transition: opacity 0.15s linear;\n -o-transition: opacity 0.15s linear;\n transition: opacity 0.15s linear;\n}\n.fade.in {\n opacity: 1;\n}\n.collapse {\n display: none;\n}\n.collapse.in {\n display: block;\n}\ntr.collapse.in {\n display: table-row;\n}\ntbody.collapse.in {\n display: table-row-group;\n}\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n -webkit-transition-property: height, visibility;\n transition-property: height, visibility;\n -webkit-transition-duration: 0.35s;\n transition-duration: 0.35s;\n -webkit-transition-timing-function: ease;\n transition-timing-function: ease;\n}\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: 4px dashed;\n border-top: 4px solid \\9;\n border-right: 4px solid transparent;\n border-left: 4px solid transparent;\n}\n.dropup,\n.dropdown {\n position: relative;\n}\n.dropdown-toggle:focus {\n outline: 0;\n}\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0;\n list-style: none;\n font-size: 14px;\n text-align: left;\n background-color: #ffffff;\n border: 1px solid #cccccc;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 4px;\n -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n background-clip: padding-box;\n}\n.dropdown-menu.pull-right {\n right: 0;\n left: auto;\n}\n.dropdown-menu .divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.dropdown-menu > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: 1.42857143;\n color: #333333;\n white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n text-decoration: none;\n color: #262626;\n background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n color: #ffffff;\n text-decoration: none;\n outline: 0;\n background-color: #337ab7;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n color: #777777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n text-decoration: none;\n background-color: transparent;\n background-image: none;\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n cursor: not-allowed;\n}\n.open > .dropdown-menu {\n display: block;\n}\n.open > a {\n outline: 0;\n}\n.dropdown-menu-right {\n left: auto;\n right: 0;\n}\n.dropdown-menu-left {\n left: 0;\n right: auto;\n}\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: 12px;\n line-height: 1.42857143;\n color: #777777;\n white-space: nowrap;\n}\n.dropdown-backdrop {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n top: 0;\n z-index: 990;\n}\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n border-top: 0;\n border-bottom: 4px dashed;\n border-bottom: 4px solid \\9;\n content: \"\";\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 2px;\n}\n@media (min-width: 768px) {\n .navbar-right .dropdown-menu {\n left: auto;\n right: 0;\n }\n .navbar-right .dropdown-menu-left {\n left: 0;\n right: auto;\n }\n}\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n float: left;\n}\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n z-index: 2;\n}\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n margin-left: -1px;\n}\n.btn-toolbar {\n margin-left: -5px;\n}\n.btn-toolbar .btn,\n.btn-toolbar .btn-group,\n.btn-toolbar .input-group {\n float: left;\n}\n.btn-toolbar > .btn,\n.btn-toolbar > .btn-group,\n.btn-toolbar > .input-group {\n margin-left: 5px;\n}\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n.btn-group > .btn:first-child {\n margin-left: 0;\n}\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n.btn-group > .btn + .dropdown-toggle {\n padding-left: 8px;\n padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-left: 12px;\n padding-right: 12px;\n}\n.btn-group.open .dropdown-toggle {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-group.open .dropdown-toggle.btn-link {\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn .caret {\n margin-left: 0;\n}\n.btn-lg .caret {\n border-width: 5px 5px 0;\n border-bottom-width: 0;\n}\n.dropup .btn-lg .caret {\n border-width: 0 5px 5px;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n}\n.btn-group-vertical > .btn-group > .btn {\n float: none;\n}\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n}\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n border-top-right-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n border-bottom-left-radius: 4px;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n}\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n float: none;\n display: table-cell;\n width: 1%;\n}\n.btn-group-justified > .btn-group .btn {\n width: 100%;\n}\n.btn-group-justified > .btn-group .dropdown-menu {\n left: auto;\n}\n[data-toggle=\"buttons\"] > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn input[type=\"checkbox\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n.input-group {\n position: relative;\n display: table;\n border-collapse: separate;\n}\n.input-group[class*=\"col-\"] {\n float: none;\n padding-left: 0;\n padding-right: 0;\n}\n.input-group .form-control {\n position: relative;\n z-index: 2;\n float: left;\n width: 100%;\n margin-bottom: 0;\n}\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn,\nselect[multiple].input-group-lg > .form-control,\nselect[multiple].input-group-lg > .input-group-addon,\nselect[multiple].input-group-lg > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn,\nselect[multiple].input-group-sm > .form-control,\nselect[multiple].input-group-sm > .input-group-addon,\nselect[multiple].input-group-sm > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n}\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle;\n}\n.input-group-addon {\n padding: 6px 12px;\n font-size: 14px;\n font-weight: normal;\n line-height: 1;\n color: #555555;\n text-align: center;\n background-color: #eeeeee;\n border: 1px solid #cccccc;\n border-radius: 4px;\n}\n.input-group-addon.input-sm {\n padding: 5px 10px;\n font-size: 12px;\n border-radius: 3px;\n}\n.input-group-addon.input-lg {\n padding: 10px 16px;\n font-size: 18px;\n border-radius: 6px;\n}\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n margin-top: 0;\n}\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n.input-group-btn {\n position: relative;\n font-size: 0;\n white-space: nowrap;\n}\n.input-group-btn > .btn {\n position: relative;\n}\n.input-group-btn > .btn + .btn {\n margin-left: -1px;\n}\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:focus,\n.input-group-btn > .btn:active {\n z-index: 2;\n}\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group {\n margin-right: -1px;\n}\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group {\n z-index: 2;\n margin-left: -1px;\n}\n.nav {\n margin-bottom: 0;\n padding-left: 0;\n list-style: none;\n}\n.nav > li {\n position: relative;\n display: block;\n}\n.nav > li > a {\n position: relative;\n display: block;\n padding: 10px 15px;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.nav > li.disabled > a {\n color: #777777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n color: #777777;\n text-decoration: none;\n background-color: transparent;\n cursor: not-allowed;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n background-color: #eeeeee;\n border-color: #337ab7;\n}\n.nav .nav-divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.nav > li > a > img {\n max-width: none;\n}\n.nav-tabs {\n border-bottom: 1px solid #dddddd;\n}\n.nav-tabs > li {\n float: left;\n margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n margin-right: 2px;\n line-height: 1.42857143;\n border: 1px solid transparent;\n border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover {\n border-color: #eeeeee #eeeeee #dddddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n color: #555555;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n border-bottom-color: transparent;\n cursor: default;\n}\n.nav-tabs.nav-justified {\n width: 100%;\n border-bottom: 0;\n}\n.nav-tabs.nav-justified > li {\n float: none;\n}\n.nav-tabs.nav-justified > li > a {\n text-align: center;\n margin-bottom: 5px;\n}\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-tabs.nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs.nav-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n border: 1px solid #dddddd;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li > a {\n border-bottom: 1px solid #dddddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs.nav-justified > .active > a,\n .nav-tabs.nav-justified > .active > a:hover,\n .nav-tabs.nav-justified > .active > a:focus {\n border-bottom-color: #ffffff;\n }\n}\n.nav-pills > li {\n float: left;\n}\n.nav-pills > li > a {\n border-radius: 4px;\n}\n.nav-pills > li + li {\n margin-left: 2px;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n color: #ffffff;\n background-color: #337ab7;\n}\n.nav-stacked > li {\n float: none;\n}\n.nav-stacked > li + li {\n margin-top: 2px;\n margin-left: 0;\n}\n.nav-justified {\n width: 100%;\n}\n.nav-justified > li {\n float: none;\n}\n.nav-justified > li > a {\n text-align: center;\n margin-bottom: 5px;\n}\n.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs-justified {\n border-bottom: 0;\n}\n.nav-tabs-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n border: 1px solid #dddddd;\n}\n@media (min-width: 768px) {\n .nav-tabs-justified > li > a {\n border-bottom: 1px solid #dddddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs-justified > .active > a,\n .nav-tabs-justified > .active > a:hover,\n .nav-tabs-justified > .active > a:focus {\n border-bottom-color: #ffffff;\n }\n}\n.tab-content > .tab-pane {\n display: none;\n}\n.tab-content > .active {\n display: block;\n}\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.navbar {\n position: relative;\n min-height: 50px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n}\n@media (min-width: 768px) {\n .navbar {\n border-radius: 4px;\n }\n}\n@media (min-width: 768px) {\n .navbar-header {\n float: left;\n }\n}\n.navbar-collapse {\n overflow-x: visible;\n padding-right: 15px;\n padding-left: 15px;\n border-top: 1px solid transparent;\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);\n -webkit-overflow-scrolling: touch;\n}\n.navbar-collapse.in {\n overflow-y: auto;\n}\n@media (min-width: 768px) {\n .navbar-collapse {\n width: auto;\n border-top: 0;\n box-shadow: none;\n }\n .navbar-collapse.collapse {\n display: block !important;\n height: auto !important;\n padding-bottom: 0;\n overflow: visible !important;\n }\n .navbar-collapse.in {\n overflow-y: visible;\n }\n .navbar-fixed-top .navbar-collapse,\n .navbar-static-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n padding-left: 0;\n padding-right: 0;\n }\n}\n.navbar-fixed-top .navbar-collapse,\n.navbar-fixed-bottom .navbar-collapse {\n max-height: 340px;\n}\n@media (max-device-width: 480px) and (orientation: landscape) {\n .navbar-fixed-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n max-height: 200px;\n }\n}\n.container > .navbar-header,\n.container-fluid > .navbar-header,\n.container > .navbar-collapse,\n.container-fluid > .navbar-collapse {\n margin-right: -15px;\n margin-left: -15px;\n}\n@media (min-width: 768px) {\n .container > .navbar-header,\n .container-fluid > .navbar-header,\n .container > .navbar-collapse,\n .container-fluid > .navbar-collapse {\n margin-right: 0;\n margin-left: 0;\n }\n}\n.navbar-static-top {\n z-index: 1000;\n border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n .navbar-static-top {\n border-radius: 0;\n }\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n@media (min-width: 768px) {\n .navbar-fixed-top,\n .navbar-fixed-bottom {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0;\n border-width: 1px 0 0;\n}\n.navbar-brand {\n float: left;\n padding: 15px 15px;\n font-size: 18px;\n line-height: 20px;\n height: 50px;\n}\n.navbar-brand:hover,\n.navbar-brand:focus {\n text-decoration: none;\n}\n.navbar-brand > img {\n display: block;\n}\n@media (min-width: 768px) {\n .navbar > .container .navbar-brand,\n .navbar > .container-fluid .navbar-brand {\n margin-left: -15px;\n }\n}\n.navbar-toggle {\n position: relative;\n float: right;\n margin-right: 15px;\n padding: 9px 10px;\n margin-top: 8px;\n margin-bottom: 8px;\n background-color: transparent;\n background-image: none;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.navbar-toggle:focus {\n outline: 0;\n}\n.navbar-toggle .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n}\n.navbar-toggle .icon-bar + .icon-bar {\n margin-top: 4px;\n}\n@media (min-width: 768px) {\n .navbar-toggle {\n display: none;\n }\n}\n.navbar-nav {\n margin: 7.5px -15px;\n}\n.navbar-nav > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: 20px;\n}\n@media (max-width: 767px) {\n .navbar-nav .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n }\n .navbar-nav .open .dropdown-menu > li > a,\n .navbar-nav .open .dropdown-menu .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n .navbar-nav .open .dropdown-menu > li > a {\n line-height: 20px;\n }\n .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-nav .open .dropdown-menu > li > a:focus {\n background-image: none;\n }\n}\n@media (min-width: 768px) {\n .navbar-nav {\n float: left;\n margin: 0;\n }\n .navbar-nav > li {\n float: left;\n }\n .navbar-nav > li > a {\n padding-top: 15px;\n padding-bottom: 15px;\n }\n}\n.navbar-form {\n margin-left: -15px;\n margin-right: -15px;\n padding: 10px 15px;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n margin-top: 8px;\n margin-bottom: 8px;\n}\n@media (min-width: 768px) {\n .navbar-form .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .navbar-form .form-control-static {\n display: inline-block;\n }\n .navbar-form .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .navbar-form .input-group .input-group-addon,\n .navbar-form .input-group .input-group-btn,\n .navbar-form .input-group .form-control {\n width: auto;\n }\n .navbar-form .input-group > .form-control {\n width: 100%;\n }\n .navbar-form .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio,\n .navbar-form .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio label,\n .navbar-form .checkbox label {\n padding-left: 0;\n }\n .navbar-form .radio input[type=\"radio\"],\n .navbar-form .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .navbar-form .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n@media (max-width: 767px) {\n .navbar-form .form-group {\n margin-bottom: 5px;\n }\n .navbar-form .form-group:last-child {\n margin-bottom: 0;\n }\n}\n@media (min-width: 768px) {\n .navbar-form {\n width: auto;\n border: 0;\n margin-left: 0;\n margin-right: 0;\n padding-top: 0;\n padding-bottom: 0;\n -webkit-box-shadow: none;\n box-shadow: none;\n }\n}\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n margin-bottom: 0;\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.navbar-btn {\n margin-top: 8px;\n margin-bottom: 8px;\n}\n.navbar-btn.btn-sm {\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.navbar-btn.btn-xs {\n margin-top: 14px;\n margin-bottom: 14px;\n}\n.navbar-text {\n margin-top: 15px;\n margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n .navbar-text {\n float: left;\n margin-left: 15px;\n margin-right: 15px;\n }\n}\n@media (min-width: 768px) {\n .navbar-left {\n float: left !important;\n }\n .navbar-right {\n float: right !important;\n margin-right: -15px;\n }\n .navbar-right ~ .navbar-right {\n margin-right: 0;\n }\n}\n.navbar-default {\n background-color: #f8f8f8;\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-brand {\n color: #777777;\n}\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n color: #5e5e5e;\n background-color: transparent;\n}\n.navbar-default .navbar-text {\n color: #777777;\n}\n.navbar-default .navbar-nav > li > a {\n color: #777777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n color: #333333;\n background-color: transparent;\n}\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n color: #555555;\n background-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n color: #cccccc;\n background-color: transparent;\n}\n.navbar-default .navbar-toggle {\n border-color: #dddddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n background-color: #dddddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n background-color: #888888;\n}\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n background-color: #e7e7e7;\n color: #555555;\n}\n@media (max-width: 767px) {\n .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n color: #777777;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #333333;\n background-color: transparent;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #555555;\n background-color: #e7e7e7;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #cccccc;\n background-color: transparent;\n }\n}\n.navbar-default .navbar-link {\n color: #777777;\n}\n.navbar-default .navbar-link:hover {\n color: #333333;\n}\n.navbar-default .btn-link {\n color: #777777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n color: #333333;\n}\n.navbar-default .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-default .btn-link:hover,\n.navbar-default .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-default .btn-link:focus {\n color: #cccccc;\n}\n.navbar-inverse {\n background-color: #222222;\n border-color: #080808;\n}\n.navbar-inverse .navbar-brand {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n color: #ffffff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-text {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n color: #ffffff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n color: #ffffff;\n background-color: #080808;\n}\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n color: #444444;\n background-color: transparent;\n}\n.navbar-inverse .navbar-toggle {\n border-color: #333333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n background-color: #333333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n background-color: #ffffff;\n}\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n border-color: #101010;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n background-color: #080808;\n color: #ffffff;\n}\n@media (max-width: 767px) {\n .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n border-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n color: #9d9d9d;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #ffffff;\n background-color: transparent;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #ffffff;\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #444444;\n background-color: transparent;\n }\n}\n.navbar-inverse .navbar-link {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n color: #ffffff;\n}\n.navbar-inverse .btn-link {\n color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n color: #ffffff;\n}\n.navbar-inverse .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-inverse .btn-link:focus {\n color: #444444;\n}\n.breadcrumb {\n padding: 8px 15px;\n margin-bottom: 20px;\n list-style: none;\n background-color: #f5f5f5;\n border-radius: 4px;\n}\n.breadcrumb > li {\n display: inline-block;\n}\n.breadcrumb > li + li:before {\n content: \"/\\00a0\";\n padding: 0 5px;\n color: #cccccc;\n}\n.breadcrumb > .active {\n color: #777777;\n}\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: 20px 0;\n border-radius: 4px;\n}\n.pagination > li {\n display: inline;\n}\n.pagination > li > a,\n.pagination > li > span {\n position: relative;\n float: left;\n padding: 6px 12px;\n line-height: 1.42857143;\n text-decoration: none;\n color: #337ab7;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n margin-left: -1px;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n margin-left: 0;\n border-bottom-left-radius: 4px;\n border-top-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n border-bottom-right-radius: 4px;\n border-top-right-radius: 4px;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n z-index: 3;\n color: #23527c;\n background-color: #eeeeee;\n border-color: #dddddd;\n}\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n z-index: 2;\n color: #ffffff;\n background-color: #337ab7;\n border-color: #337ab7;\n cursor: default;\n}\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n color: #777777;\n background-color: #ffffff;\n border-color: #dddddd;\n cursor: not-allowed;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n border-bottom-left-radius: 6px;\n border-top-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n border-bottom-right-radius: 6px;\n border-top-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n border-bottom-left-radius: 3px;\n border-top-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n border-bottom-right-radius: 3px;\n border-top-right-radius: 3px;\n}\n.pager {\n padding-left: 0;\n margin: 20px 0;\n list-style: none;\n text-align: center;\n}\n.pager li {\n display: inline;\n}\n.pager li > a,\n.pager li > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.pager .next > a,\n.pager .next > span {\n float: right;\n}\n.pager .previous > a,\n.pager .previous > span {\n float: left;\n}\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n color: #777777;\n background-color: #ffffff;\n cursor: not-allowed;\n}\n.label {\n display: inline;\n padding: .2em .6em .3em;\n font-size: 75%;\n font-weight: bold;\n line-height: 1;\n color: #ffffff;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: .25em;\n}\na.label:hover,\na.label:focus {\n color: #ffffff;\n text-decoration: none;\n cursor: pointer;\n}\n.label:empty {\n display: none;\n}\n.btn .label {\n position: relative;\n top: -1px;\n}\n.label-default {\n background-color: #777777;\n}\n.label-default[href]:hover,\n.label-default[href]:focus {\n background-color: #5e5e5e;\n}\n.label-primary {\n background-color: #337ab7;\n}\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n background-color: #286090;\n}\n.label-success {\n background-color: #5cb85c;\n}\n.label-success[href]:hover,\n.label-success[href]:focus {\n background-color: #449d44;\n}\n.label-info {\n background-color: #5bc0de;\n}\n.label-info[href]:hover,\n.label-info[href]:focus {\n background-color: #31b0d5;\n}\n.label-warning {\n background-color: #f0ad4e;\n}\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n background-color: #ec971f;\n}\n.label-danger {\n background-color: #d9534f;\n}\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n background-color: #c9302c;\n}\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: 12px;\n font-weight: bold;\n color: #ffffff;\n line-height: 1;\n vertical-align: middle;\n white-space: nowrap;\n text-align: center;\n background-color: #777777;\n border-radius: 10px;\n}\n.badge:empty {\n display: none;\n}\n.btn .badge {\n position: relative;\n top: -1px;\n}\n.btn-xs .badge,\n.btn-group-xs > .btn .badge {\n top: 0;\n padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n color: #ffffff;\n text-decoration: none;\n cursor: pointer;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n color: #337ab7;\n background-color: #ffffff;\n}\n.list-group-item > .badge {\n float: right;\n}\n.list-group-item > .badge + .badge {\n margin-right: 5px;\n}\n.nav-pills > li > a > .badge {\n margin-left: 3px;\n}\n.jumbotron {\n padding-top: 30px;\n padding-bottom: 30px;\n margin-bottom: 30px;\n color: inherit;\n background-color: #eeeeee;\n}\n.jumbotron h1,\n.jumbotron .h1 {\n color: inherit;\n}\n.jumbotron p {\n margin-bottom: 15px;\n font-size: 21px;\n font-weight: 200;\n}\n.jumbotron > hr {\n border-top-color: #d5d5d5;\n}\n.container .jumbotron,\n.container-fluid .jumbotron {\n border-radius: 6px;\n}\n.jumbotron .container {\n max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n .jumbotron {\n padding-top: 48px;\n padding-bottom: 48px;\n }\n .container .jumbotron,\n .container-fluid .jumbotron {\n padding-left: 60px;\n padding-right: 60px;\n }\n .jumbotron h1,\n .jumbotron .h1 {\n font-size: 63px;\n }\n}\n.thumbnail {\n display: block;\n padding: 4px;\n margin-bottom: 20px;\n line-height: 1.42857143;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n border-radius: 4px;\n -webkit-transition: border 0.2s ease-in-out;\n -o-transition: border 0.2s ease-in-out;\n transition: border 0.2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n margin-left: auto;\n margin-right: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n border-color: #337ab7;\n}\n.thumbnail .caption {\n padding: 9px;\n color: #333333;\n}\n.alert {\n padding: 15px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.alert h4 {\n margin-top: 0;\n color: inherit;\n}\n.alert .alert-link {\n font-weight: bold;\n}\n.alert > p,\n.alert > ul {\n margin-bottom: 0;\n}\n.alert > p + p {\n margin-top: 5px;\n}\n.alert-dismissable,\n.alert-dismissible {\n padding-right: 35px;\n}\n.alert-dismissable .close,\n.alert-dismissible .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n}\n.alert-success {\n background-color: #dff0d8;\n border-color: #d6e9c6;\n color: #3c763d;\n}\n.alert-success hr {\n border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n color: #2b542c;\n}\n.alert-info {\n background-color: #d9edf7;\n border-color: #bce8f1;\n color: #31708f;\n}\n.alert-info hr {\n border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n color: #245269;\n}\n.alert-warning {\n background-color: #fcf8e3;\n border-color: #faebcc;\n color: #8a6d3b;\n}\n.alert-warning hr {\n border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n color: #66512c;\n}\n.alert-danger {\n background-color: #f2dede;\n border-color: #ebccd1;\n color: #a94442;\n}\n.alert-danger hr {\n border-top-color: #e4b9c0;\n}\n.alert-danger .alert-link {\n color: #843534;\n}\n@-webkit-keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n@keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n.progress {\n overflow: hidden;\n height: 20px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n.progress-bar {\n float: left;\n width: 0%;\n height: 100%;\n font-size: 12px;\n line-height: 20px;\n color: #ffffff;\n text-align: center;\n background-color: #337ab7;\n -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n -webkit-transition: width 0.6s ease;\n -o-transition: width 0.6s ease;\n transition: width 0.6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-size: 40px 40px;\n}\n.progress.active .progress-bar,\n.progress-bar.active {\n -webkit-animation: progress-bar-stripes 2s linear infinite;\n -o-animation: progress-bar-stripes 2s linear infinite;\n animation: progress-bar-stripes 2s linear infinite;\n}\n.progress-bar-success {\n background-color: #5cb85c;\n}\n.progress-striped .progress-bar-success {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-info {\n background-color: #5bc0de;\n}\n.progress-striped .progress-bar-info {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-warning {\n background-color: #f0ad4e;\n}\n.progress-striped .progress-bar-warning {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-danger {\n background-color: #d9534f;\n}\n.progress-striped .progress-bar-danger {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.media {\n margin-top: 15px;\n}\n.media:first-child {\n margin-top: 0;\n}\n.media,\n.media-body {\n zoom: 1;\n overflow: hidden;\n}\n.media-body {\n width: 10000px;\n}\n.media-object {\n display: block;\n}\n.media-object.img-thumbnail {\n max-width: none;\n}\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n.media-middle {\n vertical-align: middle;\n}\n.media-bottom {\n vertical-align: bottom;\n}\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n.list-group {\n margin-bottom: 20px;\n padding-left: 0;\n}\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n margin-bottom: -1px;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n}\n.list-group-item:first-child {\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n}\n.list-group-item:last-child {\n margin-bottom: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\na.list-group-item,\nbutton.list-group-item {\n color: #555555;\n}\na.list-group-item .list-group-item-heading,\nbutton.list-group-item .list-group-item-heading {\n color: #333333;\n}\na.list-group-item:hover,\nbutton.list-group-item:hover,\na.list-group-item:focus,\nbutton.list-group-item:focus {\n text-decoration: none;\n color: #555555;\n background-color: #f5f5f5;\n}\nbutton.list-group-item {\n width: 100%;\n text-align: left;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n background-color: #eeeeee;\n color: #777777;\n cursor: not-allowed;\n}\n.list-group-item.disabled .list-group-item-heading,\n.list-group-item.disabled:hover .list-group-item-heading,\n.list-group-item.disabled:focus .list-group-item-heading {\n color: inherit;\n}\n.list-group-item.disabled .list-group-item-text,\n.list-group-item.disabled:hover .list-group-item-text,\n.list-group-item.disabled:focus .list-group-item-text {\n color: #777777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n z-index: 2;\n color: #ffffff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.list-group-item.active .list-group-item-heading,\n.list-group-item.active:hover .list-group-item-heading,\n.list-group-item.active:focus .list-group-item-heading,\n.list-group-item.active .list-group-item-heading > small,\n.list-group-item.active:hover .list-group-item-heading > small,\n.list-group-item.active:focus .list-group-item-heading > small,\n.list-group-item.active .list-group-item-heading > .small,\n.list-group-item.active:hover .list-group-item-heading > .small,\n.list-group-item.active:focus .list-group-item-heading > .small {\n color: inherit;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text {\n color: #c7ddef;\n}\n.list-group-item-success {\n color: #3c763d;\n background-color: #dff0d8;\n}\na.list-group-item-success,\nbutton.list-group-item-success {\n color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading,\nbutton.list-group-item-success .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-success:hover,\nbutton.list-group-item-success:hover,\na.list-group-item-success:focus,\nbutton.list-group-item-success:focus {\n color: #3c763d;\n background-color: #d0e9c6;\n}\na.list-group-item-success.active,\nbutton.list-group-item-success.active,\na.list-group-item-success.active:hover,\nbutton.list-group-item-success.active:hover,\na.list-group-item-success.active:focus,\nbutton.list-group-item-success.active:focus {\n color: #fff;\n background-color: #3c763d;\n border-color: #3c763d;\n}\n.list-group-item-info {\n color: #31708f;\n background-color: #d9edf7;\n}\na.list-group-item-info,\nbutton.list-group-item-info {\n color: #31708f;\n}\na.list-group-item-info .list-group-item-heading,\nbutton.list-group-item-info .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-info:hover,\nbutton.list-group-item-info:hover,\na.list-group-item-info:focus,\nbutton.list-group-item-info:focus {\n color: #31708f;\n background-color: #c4e3f3;\n}\na.list-group-item-info.active,\nbutton.list-group-item-info.active,\na.list-group-item-info.active:hover,\nbutton.list-group-item-info.active:hover,\na.list-group-item-info.active:focus,\nbutton.list-group-item-info.active:focus {\n color: #fff;\n background-color: #31708f;\n border-color: #31708f;\n}\n.list-group-item-warning {\n color: #8a6d3b;\n background-color: #fcf8e3;\n}\na.list-group-item-warning,\nbutton.list-group-item-warning {\n color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading,\nbutton.list-group-item-warning .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-warning:hover,\nbutton.list-group-item-warning:hover,\na.list-group-item-warning:focus,\nbutton.list-group-item-warning:focus {\n color: #8a6d3b;\n background-color: #faf2cc;\n}\na.list-group-item-warning.active,\nbutton.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\nbutton.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus,\nbutton.list-group-item-warning.active:focus {\n color: #fff;\n background-color: #8a6d3b;\n border-color: #8a6d3b;\n}\n.list-group-item-danger {\n color: #a94442;\n background-color: #f2dede;\n}\na.list-group-item-danger,\nbutton.list-group-item-danger {\n color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading,\nbutton.list-group-item-danger .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-danger:hover,\nbutton.list-group-item-danger:hover,\na.list-group-item-danger:focus,\nbutton.list-group-item-danger:focus {\n color: #a94442;\n background-color: #ebcccc;\n}\na.list-group-item-danger.active,\nbutton.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\nbutton.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus,\nbutton.list-group-item-danger.active:focus {\n color: #fff;\n background-color: #a94442;\n border-color: #a94442;\n}\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n.panel {\n margin-bottom: 20px;\n background-color: #ffffff;\n border: 1px solid transparent;\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.panel-body {\n padding: 15px;\n}\n.panel-heading {\n padding: 10px 15px;\n border-bottom: 1px solid transparent;\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel-heading > .dropdown .dropdown-toggle {\n color: inherit;\n}\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: 16px;\n color: inherit;\n}\n.panel-title > a,\n.panel-title > small,\n.panel-title > .small,\n.panel-title > small > a,\n.panel-title > .small > a {\n color: inherit;\n}\n.panel-footer {\n padding: 10px 15px;\n background-color: #f5f5f5;\n border-top: 1px solid #dddddd;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .list-group,\n.panel > .panel-collapse > .list-group {\n margin-bottom: 0;\n}\n.panel > .list-group .list-group-item,\n.panel > .panel-collapse > .list-group .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n}\n.panel > .list-group:first-child .list-group-item:first-child,\n.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {\n border-top: 0;\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel > .list-group:last-child .list-group-item:last-child,\n.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {\n border-bottom: 0;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.panel-heading + .list-group .list-group-item:first-child {\n border-top-width: 0;\n}\n.list-group + .panel-footer {\n border-top-width: 0;\n}\n.panel > .table,\n.panel > .table-responsive > .table,\n.panel > .panel-collapse > .table {\n margin-bottom: 0;\n}\n.panel > .table caption,\n.panel > .table-responsive > .table caption,\n.panel > .panel-collapse > .table caption {\n padding-left: 15px;\n padding-right: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table:first-child {\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {\n border-top-right-radius: 3px;\n}\n.panel > .table:last-child,\n.panel > .table-responsive:last-child > .table:last-child {\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {\n border-bottom-left-radius: 3px;\n border-bottom-right-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {\n border-bottom-right-radius: 3px;\n}\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive,\n.panel > .table + .panel-body,\n.panel > .table-responsive + .panel-body {\n border-top: 1px solid #dddddd;\n}\n.panel > .table > tbody:first-child > tr:first-child th,\n.panel > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n}\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n border: 0;\n}\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n}\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n}\n.panel > .table-bordered > thead > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,\n.panel > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-bordered > thead > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,\n.panel > .table-bordered > tbody > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {\n border-bottom: 0;\n}\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {\n border-bottom: 0;\n}\n.panel > .table-responsive {\n border: 0;\n margin-bottom: 0;\n}\n.panel-group {\n margin-bottom: 20px;\n}\n.panel-group .panel {\n margin-bottom: 0;\n border-radius: 4px;\n}\n.panel-group .panel + .panel {\n margin-top: 5px;\n}\n.panel-group .panel-heading {\n border-bottom: 0;\n}\n.panel-group .panel-heading + .panel-collapse > .panel-body,\n.panel-group .panel-heading + .panel-collapse > .list-group {\n border-top: 1px solid #dddddd;\n}\n.panel-group .panel-footer {\n border-top: 0;\n}\n.panel-group .panel-footer + .panel-collapse .panel-body {\n border-bottom: 1px solid #dddddd;\n}\n.panel-default {\n border-color: #dddddd;\n}\n.panel-default > .panel-heading {\n color: #333333;\n background-color: #f5f5f5;\n border-color: #dddddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #dddddd;\n}\n.panel-default > .panel-heading .badge {\n color: #f5f5f5;\n background-color: #333333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #dddddd;\n}\n.panel-primary {\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n color: #ffffff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #337ab7;\n}\n.panel-primary > .panel-heading .badge {\n color: #337ab7;\n background-color: #ffffff;\n}\n.panel-primary > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #337ab7;\n}\n.panel-success {\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #d6e9c6;\n}\n.panel-success > .panel-heading .badge {\n color: #dff0d8;\n background-color: #3c763d;\n}\n.panel-success > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #d6e9c6;\n}\n.panel-info {\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading {\n color: #31708f;\n background-color: #d9edf7;\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #bce8f1;\n}\n.panel-info > .panel-heading .badge {\n color: #d9edf7;\n background-color: #31708f;\n}\n.panel-info > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #bce8f1;\n}\n.panel-warning {\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #faebcc;\n}\n.panel-warning > .panel-heading .badge {\n color: #fcf8e3;\n background-color: #8a6d3b;\n}\n.panel-warning > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #faebcc;\n}\n.panel-danger {\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ebccd1;\n}\n.panel-danger > .panel-heading .badge {\n color: #f2dede;\n background-color: #a94442;\n}\n.panel-danger > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ebccd1;\n}\n.embed-responsive {\n position: relative;\n display: block;\n height: 0;\n padding: 0;\n overflow: hidden;\n}\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n height: 100%;\n width: 100%;\n border: 0;\n}\n.embed-responsive-16by9 {\n padding-bottom: 56.25%;\n}\n.embed-responsive-4by3 {\n padding-bottom: 75%;\n}\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border: 1px solid #e3e3e3;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.well blockquote {\n border-color: #ddd;\n border-color: rgba(0, 0, 0, 0.15);\n}\n.well-lg {\n padding: 24px;\n border-radius: 6px;\n}\n.well-sm {\n padding: 9px;\n border-radius: 3px;\n}\n.close {\n float: right;\n font-size: 21px;\n font-weight: bold;\n line-height: 1;\n color: #000000;\n text-shadow: 0 1px 0 #ffffff;\n opacity: 0.2;\n filter: alpha(opacity=20);\n}\n.close:hover,\n.close:focus {\n color: #000000;\n text-decoration: none;\n cursor: pointer;\n opacity: 0.5;\n filter: alpha(opacity=50);\n}\nbutton.close {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n}\n.modal-open {\n overflow: hidden;\n}\n.modal {\n display: none;\n overflow: hidden;\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1050;\n -webkit-overflow-scrolling: touch;\n outline: 0;\n}\n.modal.fade .modal-dialog {\n -webkit-transform: translate(0, -25%);\n -ms-transform: translate(0, -25%);\n -o-transform: translate(0, -25%);\n transform: translate(0, -25%);\n -webkit-transition: -webkit-transform 0.3s ease-out;\n -moz-transition: -moz-transform 0.3s ease-out;\n -o-transition: -o-transform 0.3s ease-out;\n transition: transform 0.3s ease-out;\n}\n.modal.in .modal-dialog {\n -webkit-transform: translate(0, 0);\n -ms-transform: translate(0, 0);\n -o-transform: translate(0, 0);\n transform: translate(0, 0);\n}\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n.modal-content {\n position: relative;\n background-color: #ffffff;\n border: 1px solid #999999;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n background-clip: padding-box;\n outline: 0;\n}\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1040;\n background-color: #000000;\n}\n.modal-backdrop.fade {\n opacity: 0;\n filter: alpha(opacity=0);\n}\n.modal-backdrop.in {\n opacity: 0.5;\n filter: alpha(opacity=50);\n}\n.modal-header {\n padding: 15px;\n border-bottom: 1px solid #e5e5e5;\n min-height: 16.42857143px;\n}\n.modal-header .close {\n margin-top: -2px;\n}\n.modal-title {\n margin: 0;\n line-height: 1.42857143;\n}\n.modal-body {\n position: relative;\n padding: 15px;\n}\n.modal-footer {\n padding: 15px;\n text-align: right;\n border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n margin-left: 5px;\n margin-bottom: 0;\n}\n.modal-footer .btn-group .btn + .btn {\n margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n margin-left: 0;\n}\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n@media (min-width: 768px) {\n .modal-dialog {\n width: 600px;\n margin: 30px auto;\n }\n .modal-content {\n -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n }\n .modal-sm {\n width: 300px;\n }\n}\n@media (min-width: 992px) {\n .modal-lg {\n width: 900px;\n }\n}\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-style: normal;\n font-weight: normal;\n letter-spacing: normal;\n line-break: auto;\n line-height: 1.42857143;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n white-space: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n font-size: 12px;\n opacity: 0;\n filter: alpha(opacity=0);\n}\n.tooltip.in {\n opacity: 0.9;\n filter: alpha(opacity=90);\n}\n.tooltip.top {\n margin-top: -3px;\n padding: 5px 0;\n}\n.tooltip.right {\n margin-left: 3px;\n padding: 0 5px;\n}\n.tooltip.bottom {\n margin-top: 3px;\n padding: 5px 0;\n}\n.tooltip.left {\n margin-left: -3px;\n padding: 0 5px;\n}\n.tooltip-inner {\n max-width: 200px;\n padding: 3px 8px;\n color: #ffffff;\n text-align: center;\n background-color: #000000;\n border-radius: 4px;\n}\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.tooltip.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000000;\n}\n.tooltip.top-left .tooltip-arrow {\n bottom: 0;\n right: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000000;\n}\n.tooltip.top-right .tooltip-arrow {\n bottom: 0;\n left: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000000;\n}\n.tooltip.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -5px;\n border-width: 5px 5px 5px 0;\n border-right-color: #000000;\n}\n.tooltip.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -5px;\n border-width: 5px 0 5px 5px;\n border-left-color: #000000;\n}\n.tooltip.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n top: 0;\n right: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n top: 0;\n left: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000000;\n}\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: none;\n max-width: 276px;\n padding: 1px;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-style: normal;\n font-weight: normal;\n letter-spacing: normal;\n line-break: auto;\n line-height: 1.42857143;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n white-space: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n font-size: 14px;\n background-color: #ffffff;\n background-clip: padding-box;\n border: 1px solid #cccccc;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n}\n.popover.top {\n margin-top: -10px;\n}\n.popover.right {\n margin-left: 10px;\n}\n.popover.bottom {\n margin-top: 10px;\n}\n.popover.left {\n margin-left: -10px;\n}\n.popover-title {\n margin: 0;\n padding: 8px 14px;\n font-size: 14px;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-radius: 5px 5px 0 0;\n}\n.popover-content {\n padding: 9px 14px;\n}\n.popover > .arrow,\n.popover > .arrow:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.popover > .arrow {\n border-width: 11px;\n}\n.popover > .arrow:after {\n border-width: 10px;\n content: \"\";\n}\n.popover.top > .arrow {\n left: 50%;\n margin-left: -11px;\n border-bottom-width: 0;\n border-top-color: #999999;\n border-top-color: rgba(0, 0, 0, 0.25);\n bottom: -11px;\n}\n.popover.top > .arrow:after {\n content: \" \";\n bottom: 1px;\n margin-left: -10px;\n border-bottom-width: 0;\n border-top-color: #ffffff;\n}\n.popover.right > .arrow {\n top: 50%;\n left: -11px;\n margin-top: -11px;\n border-left-width: 0;\n border-right-color: #999999;\n border-right-color: rgba(0, 0, 0, 0.25);\n}\n.popover.right > .arrow:after {\n content: \" \";\n left: 1px;\n bottom: -10px;\n border-left-width: 0;\n border-right-color: #ffffff;\n}\n.popover.bottom > .arrow {\n left: 50%;\n margin-left: -11px;\n border-top-width: 0;\n border-bottom-color: #999999;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n top: -11px;\n}\n.popover.bottom > .arrow:after {\n content: \" \";\n top: 1px;\n margin-left: -10px;\n border-top-width: 0;\n border-bottom-color: #ffffff;\n}\n.popover.left > .arrow {\n top: 50%;\n right: -11px;\n margin-top: -11px;\n border-right-width: 0;\n border-left-color: #999999;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n.popover.left > .arrow:after {\n content: \" \";\n right: 1px;\n border-right-width: 0;\n border-left-color: #ffffff;\n bottom: -10px;\n}\n.carousel {\n position: relative;\n}\n.carousel-inner {\n position: relative;\n overflow: hidden;\n width: 100%;\n}\n.carousel-inner > .item {\n display: none;\n position: relative;\n -webkit-transition: 0.6s ease-in-out left;\n -o-transition: 0.6s ease-in-out left;\n transition: 0.6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n line-height: 1;\n}\n@media all and (transform-3d), (-webkit-transform-3d) {\n .carousel-inner > .item {\n -webkit-transition: -webkit-transform 0.6s ease-in-out;\n -moz-transition: -moz-transform 0.6s ease-in-out;\n -o-transition: -o-transform 0.6s ease-in-out;\n transition: transform 0.6s ease-in-out;\n -webkit-backface-visibility: hidden;\n -moz-backface-visibility: hidden;\n backface-visibility: hidden;\n -webkit-perspective: 1000px;\n -moz-perspective: 1000px;\n perspective: 1000px;\n }\n .carousel-inner > .item.next,\n .carousel-inner > .item.active.right {\n -webkit-transform: translate3d(100%, 0, 0);\n transform: translate3d(100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.prev,\n .carousel-inner > .item.active.left {\n -webkit-transform: translate3d(-100%, 0, 0);\n transform: translate3d(-100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.next.left,\n .carousel-inner > .item.prev.right,\n .carousel-inner > .item.active {\n -webkit-transform: translate3d(0, 0, 0);\n transform: translate3d(0, 0, 0);\n left: 0;\n }\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n display: block;\n}\n.carousel-inner > .active {\n left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n}\n.carousel-inner > .next {\n left: 100%;\n}\n.carousel-inner > .prev {\n left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n left: 0;\n}\n.carousel-inner > .active.left {\n left: -100%;\n}\n.carousel-inner > .active.right {\n left: 100%;\n}\n.carousel-control {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n width: 15%;\n opacity: 0.5;\n filter: alpha(opacity=50);\n font-size: 20px;\n color: #ffffff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n.carousel-control.left {\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n}\n.carousel-control.right {\n left: auto;\n right: 0;\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n}\n.carousel-control:hover,\n.carousel-control:focus {\n outline: 0;\n color: #ffffff;\n text-decoration: none;\n opacity: 0.9;\n filter: alpha(opacity=90);\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n margin-top: -10px;\n z-index: 5;\n display: inline-block;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n left: 50%;\n margin-left: -10px;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n right: 50%;\n margin-right: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n width: 20px;\n height: 20px;\n line-height: 1;\n font-family: serif;\n}\n.carousel-control .icon-prev:before {\n content: '\\2039';\n}\n.carousel-control .icon-next:before {\n content: '\\203a';\n}\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n margin-left: -30%;\n padding-left: 0;\n list-style: none;\n text-align: center;\n}\n.carousel-indicators li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n border: 1px solid #ffffff;\n border-radius: 10px;\n cursor: pointer;\n background-color: #000 \\9;\n background-color: rgba(0, 0, 0, 0);\n}\n.carousel-indicators .active {\n margin: 0;\n width: 12px;\n height: 12px;\n background-color: #ffffff;\n}\n.carousel-caption {\n position: absolute;\n left: 15%;\n right: 15%;\n bottom: 20px;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #ffffff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n.carousel-caption .btn {\n text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-prev,\n .carousel-control .icon-next {\n width: 30px;\n height: 30px;\n margin-top: -15px;\n font-size: 30px;\n }\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .icon-prev {\n margin-left: -15px;\n }\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-next {\n margin-right: -15px;\n }\n .carousel-caption {\n left: 20%;\n right: 20%;\n padding-bottom: 30px;\n }\n .carousel-indicators {\n bottom: 20px;\n }\n}\n.clearfix:before,\n.clearfix:after,\n.dl-horizontal dd:before,\n.dl-horizontal dd:after,\n.container:before,\n.container:after,\n.container-fluid:before,\n.container-fluid:after,\n.row:before,\n.row:after,\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after,\n.btn-toolbar:before,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after,\n.nav:before,\n.nav:after,\n.navbar:before,\n.navbar:after,\n.navbar-header:before,\n.navbar-header:after,\n.navbar-collapse:before,\n.navbar-collapse:after,\n.pager:before,\n.pager:after,\n.panel-body:before,\n.panel-body:after,\n.modal-footer:before,\n.modal-footer:after {\n content: \" \";\n display: table;\n}\n.clearfix:after,\n.dl-horizontal dd:after,\n.container:after,\n.container-fluid:after,\n.row:after,\n.form-horizontal .form-group:after,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:after,\n.nav:after,\n.navbar:after,\n.navbar-header:after,\n.navbar-collapse:after,\n.pager:after,\n.panel-body:after,\n.modal-footer:after {\n clear: both;\n}\n.center-block {\n display: block;\n margin-left: auto;\n margin-right: auto;\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n.hidden {\n display: none !important;\n}\n.affix {\n position: fixed;\n}\n@-ms-viewport {\n width: device-width;\n}\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n display: none !important;\n}\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n display: none !important;\n}\n@media (max-width: 767px) {\n .visible-xs {\n display: block !important;\n }\n table.visible-xs {\n display: table !important;\n }\n tr.visible-xs {\n display: table-row !important;\n }\n th.visible-xs,\n td.visible-xs {\n display: table-cell !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-block {\n display: block !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline {\n display: inline !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm {\n display: block !important;\n }\n table.visible-sm {\n display: table !important;\n }\n tr.visible-sm {\n display: table-row !important;\n }\n th.visible-sm,\n td.visible-sm {\n display: table-cell !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-block {\n display: block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline {\n display: inline !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md {\n display: block !important;\n }\n table.visible-md {\n display: table !important;\n }\n tr.visible-md {\n display: table-row !important;\n }\n th.visible-md,\n td.visible-md {\n display: table-cell !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-block {\n display: block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline {\n display: inline !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg {\n display: block !important;\n }\n table.visible-lg {\n display: table !important;\n }\n tr.visible-lg {\n display: table-row !important;\n }\n th.visible-lg,\n td.visible-lg {\n display: table-cell !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-block {\n display: block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline {\n display: inline !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline-block {\n display: inline-block !important;\n }\n}\n@media (max-width: 767px) {\n .hidden-xs {\n display: none !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .hidden-sm {\n display: none !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .hidden-md {\n display: none !important;\n }\n}\n@media (min-width: 1200px) {\n .hidden-lg {\n display: none !important;\n }\n}\n.visible-print {\n display: none !important;\n}\n@media print {\n .visible-print {\n display: block !important;\n }\n table.visible-print {\n display: table !important;\n }\n tr.visible-print {\n display: table-row !important;\n }\n th.visible-print,\n td.visible-print {\n display: table-cell !important;\n }\n}\n.visible-print-block {\n display: none !important;\n}\n@media print {\n .visible-print-block {\n display: block !important;\n }\n}\n.visible-print-inline {\n display: none !important;\n}\n@media print {\n .visible-print-inline {\n display: inline !important;\n }\n}\n.visible-print-inline-block {\n display: none !important;\n}\n@media print {\n .visible-print-inline-block {\n display: inline-block !important;\n }\n}\n@media print {\n .hidden-print {\n display: none !important;\n }\n}\n/*# sourceMappingURL=bootstrap.css.map */",
+ "/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\n\n//\n// 1. Set default font family to sans-serif.\n// 2. Prevent iOS and IE text size adjust after device orientation change,\n// without disabling user zoom.\n//\n\nhtml {\n font-family: sans-serif; // 1\n -ms-text-size-adjust: 100%; // 2\n -webkit-text-size-adjust: 100%; // 2\n}\n\n//\n// Remove default margin.\n//\n\nbody {\n margin: 0;\n}\n\n// HTML5 display definitions\n// ==========================================================================\n\n//\n// Correct `block` display not defined for any HTML5 element in IE 8/9.\n// Correct `block` display not defined for `details` or `summary` in IE 10/11\n// and Firefox.\n// Correct `block` display not defined for `main` in IE 11.\n//\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\n\n//\n// 1. Correct `inline-block` display not defined in IE 8/9.\n// 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n//\n\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block; // 1\n vertical-align: baseline; // 2\n}\n\n//\n// Prevent modern browsers from displaying `audio` without controls.\n// Remove excess height in iOS 5 devices.\n//\n\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n\n//\n// Address `[hidden]` styling not present in IE 8/9/10.\n// Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22.\n//\n\n[hidden],\ntemplate {\n display: none;\n}\n\n// Links\n// ==========================================================================\n\n//\n// Remove the gray background color from active links in IE 10.\n//\n\na {\n background-color: transparent;\n}\n\n//\n// Improve readability of focused elements when they are also in an\n// active/hover state.\n//\n\na:active,\na:hover {\n outline: 0;\n}\n\n// Text-level semantics\n// ==========================================================================\n\n//\n// Address styling not present in IE 8/9/10/11, Safari, and Chrome.\n//\n\nabbr[title] {\n border-bottom: 1px dotted;\n}\n\n//\n// Address style set to `bolder` in Firefox 4+, Safari, and Chrome.\n//\n\nb,\nstrong {\n font-weight: bold;\n}\n\n//\n// Address styling not present in Safari and Chrome.\n//\n\ndfn {\n font-style: italic;\n}\n\n//\n// Address variable `h1` font-size and margin within `section` and `article`\n// contexts in Firefox 4+, Safari, and Chrome.\n//\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n//\n// Address styling not present in IE 8/9.\n//\n\nmark {\n background: #ff0;\n color: #000;\n}\n\n//\n// Address inconsistent and variable font size in all browsers.\n//\n\nsmall {\n font-size: 80%;\n}\n\n//\n// Prevent `sub` and `sup` affecting `line-height` in all browsers.\n//\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsup {\n top: -0.5em;\n}\n\nsub {\n bottom: -0.25em;\n}\n\n// Embedded content\n// ==========================================================================\n\n//\n// Remove border when inside `a` element in IE 8/9/10.\n//\n\nimg {\n border: 0;\n}\n\n//\n// Correct overflow not hidden in IE 9/10/11.\n//\n\nsvg:not(:root) {\n overflow: hidden;\n}\n\n// Grouping content\n// ==========================================================================\n\n//\n// Address margin not present in IE 8/9 and Safari.\n//\n\nfigure {\n margin: 1em 40px;\n}\n\n//\n// Address differences between Firefox and other browsers.\n//\n\nhr {\n box-sizing: content-box;\n height: 0;\n}\n\n//\n// Contain overflow in all browsers.\n//\n\npre {\n overflow: auto;\n}\n\n//\n// Address odd `em`-unit font size rendering in all browsers.\n//\n\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\n\n// Forms\n// ==========================================================================\n\n//\n// Known limitation: by default, Chrome and Safari on OS X allow very limited\n// styling of `select`, unless a `border` property is set.\n//\n\n//\n// 1. Correct color not being inherited.\n// Known issue: affects color of disabled elements.\n// 2. Correct font properties not being inherited.\n// 3. Address margins set differently in Firefox 4+, Safari, and Chrome.\n//\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit; // 1\n font: inherit; // 2\n margin: 0; // 3\n}\n\n//\n// Address `overflow` set to `hidden` in IE 8/9/10/11.\n//\n\nbutton {\n overflow: visible;\n}\n\n//\n// Address inconsistent `text-transform` inheritance for `button` and `select`.\n// All other form control elements do not inherit `text-transform` values.\n// Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.\n// Correct `select` style inheritance in Firefox.\n//\n\nbutton,\nselect {\n text-transform: none;\n}\n\n//\n// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n// and `video` controls.\n// 2. Correct inability to style clickable `input` types in iOS.\n// 3. Improve usability and consistency of cursor style between image-type\n// `input` and others.\n//\n\nbutton,\nhtml input[type=\"button\"], // 1\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button; // 2\n cursor: pointer; // 3\n}\n\n//\n// Re-set default cursor for disabled elements.\n//\n\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\n\n//\n// Remove inner padding and border in Firefox 4+.\n//\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\n\n//\n// Address Firefox 4+ setting `line-height` on `input` using `!important` in\n// the UA stylesheet.\n//\n\ninput {\n line-height: normal;\n}\n\n//\n// It's recommended that you don't attempt to style these elements.\n// Firefox's implementation doesn't respect box-sizing, padding, or width.\n//\n// 1. Address box sizing set to `content-box` in IE 8/9/10.\n// 2. Remove excess padding in IE 8/9/10.\n//\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box; // 1\n padding: 0; // 2\n}\n\n//\n// Fix the cursor style for Chrome's increment/decrement buttons. For certain\n// `font-size` values of the `input`, it causes the cursor style of the\n// decrement button to change from `default` to `text`.\n//\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n//\n// 1. Address `appearance` set to `searchfield` in Safari and Chrome.\n// 2. Address `box-sizing` set to `border-box` in Safari and Chrome.\n//\n\ninput[type=\"search\"] {\n -webkit-appearance: textfield; // 1\n box-sizing: content-box; //2\n}\n\n//\n// Remove inner padding and search cancel button in Safari and Chrome on OS X.\n// Safari (but not Chrome) clips the cancel button when the search input has\n// padding (and `textfield` appearance).\n//\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// Define consistent border, margin, and padding.\n//\n\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\n\n//\n// 1. Correct `color` not being inherited in IE 8/9/10/11.\n// 2. Remove padding so people aren't caught out if they zero out fieldsets.\n//\n\nlegend {\n border: 0; // 1\n padding: 0; // 2\n}\n\n//\n// Remove default vertical scrollbar in IE 8/9/10/11.\n//\n\ntextarea {\n overflow: auto;\n}\n\n//\n// Don't inherit the `font-weight` (applied by a rule above).\n// NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n//\n\noptgroup {\n font-weight: bold;\n}\n\n// Tables\n// ==========================================================================\n\n//\n// Remove most spacing between table cells.\n//\n\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\n\ntd,\nth {\n padding: 0;\n}\n",
+ "/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n\n// ==========================================================================\n// Print styles.\n// Inlined to avoid the additional HTTP request: h5bp.com/r\n// ==========================================================================\n\n@media print {\n *,\n *:before,\n *:after {\n background: transparent !important;\n color: #000 !important; // Black prints faster: h5bp.com/s\n box-shadow: none !important;\n text-shadow: none !important;\n }\n\n a,\n a:visited {\n text-decoration: underline;\n }\n\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n\n // Don't show links that are fragment identifiers,\n // or use the `javascript:` pseudo protocol\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n\n thead {\n display: table-header-group; // h5bp.com/t\n }\n\n tr,\n img {\n page-break-inside: avoid;\n }\n\n img {\n max-width: 100% !important;\n }\n\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n\n h2,\n h3 {\n page-break-after: avoid;\n }\n\n // Bootstrap specific changes start\n\n // Bootstrap components\n .navbar {\n display: none;\n }\n .btn,\n .dropup > .btn {\n > .caret {\n border-top-color: #000 !important;\n }\n }\n .label {\n border: 1px solid #000;\n }\n\n .table {\n border-collapse: collapse !important;\n\n td,\n th {\n background-color: #fff !important;\n }\n }\n .table-bordered {\n th,\n td {\n border: 1px solid #ddd !important;\n }\n }\n\n // Bootstrap specific changes end\n}\n",
+ "//\n// Glyphicons for Bootstrap\n//\n// Since icons are fonts, they can be placed anywhere text is placed and are\n// thus automatically sized to match the surrounding child. To use, create an\n// inline element with the appropriate classes, like so:\n//\n// <a href=\"#\"><span class=\"glyphicon glyphicon-star\"></span> Star</a>\n\n// Import the fonts\n@font-face {\n font-family: 'Glyphicons Halflings';\n src: url('@{icon-font-path}@{icon-font-name}.eot');\n src: url('@{icon-font-path}@{icon-font-name}.eot?#iefix') format('embedded-opentype'),\n url('@{icon-font-path}@{icon-font-name}.woff2') format('woff2'),\n url('@{icon-font-path}@{icon-font-name}.woff') format('woff'),\n url('@{icon-font-path}@{icon-font-name}.ttf') format('truetype'),\n url('@{icon-font-path}@{icon-font-name}.svg#@{icon-font-svg-id}') format('svg');\n}\n\n// Catchall baseclass\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n// Individual icons\n.glyphicon-asterisk { &:before { content: \"\\2a\"; } }\n.glyphicon-plus { &:before { content: \"\\2b\"; } }\n.glyphicon-euro,\n.glyphicon-eur { &:before { content: \"\\20ac\"; } }\n.glyphicon-minus { &:before { content: \"\\2212\"; } }\n.glyphicon-cloud { &:before { content: \"\\2601\"; } }\n.glyphicon-envelope { &:before { content: \"\\2709\"; } }\n.glyphicon-pencil { &:before { content: \"\\270f\"; } }\n.glyphicon-glass { &:before { content: \"\\e001\"; } }\n.glyphicon-music { &:before { content: \"\\e002\"; } }\n.glyphicon-search { &:before { content: \"\\e003\"; } }\n.glyphicon-heart { &:before { content: \"\\e005\"; } }\n.glyphicon-star { &:before { content: \"\\e006\"; } }\n.glyphicon-star-empty { &:before { content: \"\\e007\"; } }\n.glyphicon-user { &:before { content: \"\\e008\"; } }\n.glyphicon-film { &:before { content: \"\\e009\"; } }\n.glyphicon-th-large { &:before { content: \"\\e010\"; } }\n.glyphicon-th { &:before { content: \"\\e011\"; } }\n.glyphicon-th-list { &:before { content: \"\\e012\"; } }\n.glyphicon-ok { &:before { content: \"\\e013\"; } }\n.glyphicon-remove { &:before { content: \"\\e014\"; } }\n.glyphicon-zoom-in { &:before { content: \"\\e015\"; } }\n.glyphicon-zoom-out { &:before { content: \"\\e016\"; } }\n.glyphicon-off { &:before { content: \"\\e017\"; } }\n.glyphicon-signal { &:before { content: \"\\e018\"; } }\n.glyphicon-cog { &:before { content: \"\\e019\"; } }\n.glyphicon-trash { &:before { content: \"\\e020\"; } }\n.glyphicon-home { &:before { content: \"\\e021\"; } }\n.glyphicon-file { &:before { content: \"\\e022\"; } }\n.glyphicon-time { &:before { content: \"\\e023\"; } }\n.glyphicon-road { &:before { content: \"\\e024\"; } }\n.glyphicon-download-alt { &:before { content: \"\\e025\"; } }\n.glyphicon-download { &:before { content: \"\\e026\"; } }\n.glyphicon-upload { &:before { content: \"\\e027\"; } }\n.glyphicon-inbox { &:before { content: \"\\e028\"; } }\n.glyphicon-play-circle { &:before { content: \"\\e029\"; } }\n.glyphicon-repeat { &:before { content: \"\\e030\"; } }\n.glyphicon-refresh { &:before { content: \"\\e031\"; } }\n.glyphicon-list-alt { &:before { content: \"\\e032\"; } }\n.glyphicon-lock { &:before { content: \"\\e033\"; } }\n.glyphicon-flag { &:before { content: \"\\e034\"; } }\n.glyphicon-headphones { &:before { content: \"\\e035\"; } }\n.glyphicon-volume-off { &:before { content: \"\\e036\"; } }\n.glyphicon-volume-down { &:before { content: \"\\e037\"; } }\n.glyphicon-volume-up { &:before { content: \"\\e038\"; } }\n.glyphicon-qrcode { &:before { content: \"\\e039\"; } }\n.glyphicon-barcode { &:before { content: \"\\e040\"; } }\n.glyphicon-tag { &:before { content: \"\\e041\"; } }\n.glyphicon-tags { &:before { content: \"\\e042\"; } }\n.glyphicon-book { &:before { content: \"\\e043\"; } }\n.glyphicon-bookmark { &:before { content: \"\\e044\"; } }\n.glyphicon-print { &:before { content: \"\\e045\"; } }\n.glyphicon-camera { &:before { content: \"\\e046\"; } }\n.glyphicon-font { &:before { content: \"\\e047\"; } }\n.glyphicon-bold { &:before { content: \"\\e048\"; } }\n.glyphicon-italic { &:before { content: \"\\e049\"; } }\n.glyphicon-text-height { &:before { content: \"\\e050\"; } }\n.glyphicon-text-width { &:before { content: \"\\e051\"; } }\n.glyphicon-align-left { &:before { content: \"\\e052\"; } }\n.glyphicon-align-center { &:before { content: \"\\e053\"; } }\n.glyphicon-align-right { &:before { content: \"\\e054\"; } }\n.glyphicon-align-justify { &:before { content: \"\\e055\"; } }\n.glyphicon-list { &:before { content: \"\\e056\"; } }\n.glyphicon-indent-left { &:before { content: \"\\e057\"; } }\n.glyphicon-indent-right { &:before { content: \"\\e058\"; } }\n.glyphicon-facetime-video { &:before { content: \"\\e059\"; } }\n.glyphicon-picture { &:before { content: \"\\e060\"; } }\n.glyphicon-map-marker { &:before { content: \"\\e062\"; } }\n.glyphicon-adjust { &:before { content: \"\\e063\"; } }\n.glyphicon-tint { &:before { content: \"\\e064\"; } }\n.glyphicon-edit { &:before { content: \"\\e065\"; } }\n.glyphicon-share { &:before { content: \"\\e066\"; } }\n.glyphicon-check { &:before { content: \"\\e067\"; } }\n.glyphicon-move { &:before { content: \"\\e068\"; } }\n.glyphicon-step-backward { &:before { content: \"\\e069\"; } }\n.glyphicon-fast-backward { &:before { content: \"\\e070\"; } }\n.glyphicon-backward { &:before { content: \"\\e071\"; } }\n.glyphicon-play { &:before { content: \"\\e072\"; } }\n.glyphicon-pause { &:before { content: \"\\e073\"; } }\n.glyphicon-stop { &:before { content: \"\\e074\"; } }\n.glyphicon-forward { &:before { content: \"\\e075\"; } }\n.glyphicon-fast-forward { &:before { content: \"\\e076\"; } }\n.glyphicon-step-forward { &:before { content: \"\\e077\"; } }\n.glyphicon-eject { &:before { content: \"\\e078\"; } }\n.glyphicon-chevron-left { &:before { content: \"\\e079\"; } }\n.glyphicon-chevron-right { &:before { content: \"\\e080\"; } }\n.glyphicon-plus-sign { &:before { content: \"\\e081\"; } }\n.glyphicon-minus-sign { &:before { content: \"\\e082\"; } }\n.glyphicon-remove-sign { &:before { content: \"\\e083\"; } }\n.glyphicon-ok-sign { &:before { content: \"\\e084\"; } }\n.glyphicon-question-sign { &:before { content: \"\\e085\"; } }\n.glyphicon-info-sign { &:before { content: \"\\e086\"; } }\n.glyphicon-screenshot { &:before { content: \"\\e087\"; } }\n.glyphicon-remove-circle { &:before { content: \"\\e088\"; } }\n.glyphicon-ok-circle { &:before { content: \"\\e089\"; } }\n.glyphicon-ban-circle { &:before { content: \"\\e090\"; } }\n.glyphicon-arrow-left { &:before { content: \"\\e091\"; } }\n.glyphicon-arrow-right { &:before { content: \"\\e092\"; } }\n.glyphicon-arrow-up { &:before { content: \"\\e093\"; } }\n.glyphicon-arrow-down { &:before { content: \"\\e094\"; } }\n.glyphicon-share-alt { &:before { content: \"\\e095\"; } }\n.glyphicon-resize-full { &:before { content: \"\\e096\"; } }\n.glyphicon-resize-small { &:before { content: \"\\e097\"; } }\n.glyphicon-exclamation-sign { &:before { content: \"\\e101\"; } }\n.glyphicon-gift { &:before { content: \"\\e102\"; } }\n.glyphicon-leaf { &:before { content: \"\\e103\"; } }\n.glyphicon-fire { &:before { content: \"\\e104\"; } }\n.glyphicon-eye-open { &:before { content: \"\\e105\"; } }\n.glyphicon-eye-close { &:before { content: \"\\e106\"; } }\n.glyphicon-warning-sign { &:before { content: \"\\e107\"; } }\n.glyphicon-plane { &:before { content: \"\\e108\"; } }\n.glyphicon-calendar { &:before { content: \"\\e109\"; } }\n.glyphicon-random { &:before { content: \"\\e110\"; } }\n.glyphicon-comment { &:before { content: \"\\e111\"; } }\n.glyphicon-magnet { &:before { content: \"\\e112\"; } }\n.glyphicon-chevron-up { &:before { content: \"\\e113\"; } }\n.glyphicon-chevron-down { &:before { content: \"\\e114\"; } }\n.glyphicon-retweet { &:before { content: \"\\e115\"; } }\n.glyphicon-shopping-cart { &:before { content: \"\\e116\"; } }\n.glyphicon-folder-close { &:before { content: \"\\e117\"; } }\n.glyphicon-folder-open { &:before { content: \"\\e118\"; } }\n.glyphicon-resize-vertical { &:before { content: \"\\e119\"; } }\n.glyphicon-resize-horizontal { &:before { content: \"\\e120\"; } }\n.glyphicon-hdd { &:before { content: \"\\e121\"; } }\n.glyphicon-bullhorn { &:before { content: \"\\e122\"; } }\n.glyphicon-bell { &:before { content: \"\\e123\"; } }\n.glyphicon-certificate { &:before { content: \"\\e124\"; } }\n.glyphicon-thumbs-up { &:before { content: \"\\e125\"; } }\n.glyphicon-thumbs-down { &:before { content: \"\\e126\"; } }\n.glyphicon-hand-right { &:before { content: \"\\e127\"; } }\n.glyphicon-hand-left { &:before { content: \"\\e128\"; } }\n.glyphicon-hand-up { &:before { content: \"\\e129\"; } }\n.glyphicon-hand-down { &:before { content: \"\\e130\"; } }\n.glyphicon-circle-arrow-right { &:before { content: \"\\e131\"; } }\n.glyphicon-circle-arrow-left { &:before { content: \"\\e132\"; } }\n.glyphicon-circle-arrow-up { &:before { content: \"\\e133\"; } }\n.glyphicon-circle-arrow-down { &:before { content: \"\\e134\"; } }\n.glyphicon-globe { &:before { content: \"\\e135\"; } }\n.glyphicon-wrench { &:before { content: \"\\e136\"; } }\n.glyphicon-tasks { &:before { content: \"\\e137\"; } }\n.glyphicon-filter { &:before { content: \"\\e138\"; } }\n.glyphicon-briefcase { &:before { content: \"\\e139\"; } }\n.glyphicon-fullscreen { &:before { content: \"\\e140\"; } }\n.glyphicon-dashboard { &:before { content: \"\\e141\"; } }\n.glyphicon-paperclip { &:before { content: \"\\e142\"; } }\n.glyphicon-heart-empty { &:before { content: \"\\e143\"; } }\n.glyphicon-link { &:before { content: \"\\e144\"; } }\n.glyphicon-phone { &:before { content: \"\\e145\"; } }\n.glyphicon-pushpin { &:before { content: \"\\e146\"; } }\n.glyphicon-usd { &:before { content: \"\\e148\"; } }\n.glyphicon-gbp { &:before { content: \"\\e149\"; } }\n.glyphicon-sort { &:before { content: \"\\e150\"; } }\n.glyphicon-sort-by-alphabet { &:before { content: \"\\e151\"; } }\n.glyphicon-sort-by-alphabet-alt { &:before { content: \"\\e152\"; } }\n.glyphicon-sort-by-order { &:before { content: \"\\e153\"; } }\n.glyphicon-sort-by-order-alt { &:before { content: \"\\e154\"; } }\n.glyphicon-sort-by-attributes { &:before { content: \"\\e155\"; } }\n.glyphicon-sort-by-attributes-alt { &:before { content: \"\\e156\"; } }\n.glyphicon-unchecked { &:before { content: \"\\e157\"; } }\n.glyphicon-expand { &:before { content: \"\\e158\"; } }\n.glyphicon-collapse-down { &:before { content: \"\\e159\"; } }\n.glyphicon-collapse-up { &:before { content: \"\\e160\"; } }\n.glyphicon-log-in { &:before { content: \"\\e161\"; } }\n.glyphicon-flash { &:before { content: \"\\e162\"; } }\n.glyphicon-log-out { &:before { content: \"\\e163\"; } }\n.glyphicon-new-window { &:before { content: \"\\e164\"; } }\n.glyphicon-record { &:before { content: \"\\e165\"; } }\n.glyphicon-save { &:before { content: \"\\e166\"; } }\n.glyphicon-open { &:before { content: \"\\e167\"; } }\n.glyphicon-saved { &:before { content: \"\\e168\"; } }\n.glyphicon-import { &:before { content: \"\\e169\"; } }\n.glyphicon-export { &:before { content: \"\\e170\"; } }\n.glyphicon-send { &:before { content: \"\\e171\"; } }\n.glyphicon-floppy-disk { &:before { content: \"\\e172\"; } }\n.glyphicon-floppy-saved { &:before { content: \"\\e173\"; } }\n.glyphicon-floppy-remove { &:before { content: \"\\e174\"; } }\n.glyphicon-floppy-save { &:before { content: \"\\e175\"; } }\n.glyphicon-floppy-open { &:before { content: \"\\e176\"; } }\n.glyphicon-credit-card { &:before { content: \"\\e177\"; } }\n.glyphicon-transfer { &:before { content: \"\\e178\"; } }\n.glyphicon-cutlery { &:before { content: \"\\e179\"; } }\n.glyphicon-header { &:before { content: \"\\e180\"; } }\n.glyphicon-compressed { &:before { content: \"\\e181\"; } }\n.glyphicon-earphone { &:before { content: \"\\e182\"; } }\n.glyphicon-phone-alt { &:before { content: \"\\e183\"; } }\n.glyphicon-tower { &:before { content: \"\\e184\"; } }\n.glyphicon-stats { &:before { content: \"\\e185\"; } }\n.glyphicon-sd-video { &:before { content: \"\\e186\"; } }\n.glyphicon-hd-video { &:before { content: \"\\e187\"; } }\n.glyphicon-subtitles { &:before { content: \"\\e188\"; } }\n.glyphicon-sound-stereo { &:before { content: \"\\e189\"; } }\n.glyphicon-sound-dolby { &:before { content: \"\\e190\"; } }\n.glyphicon-sound-5-1 { &:before { content: \"\\e191\"; } }\n.glyphicon-sound-6-1 { &:before { content: \"\\e192\"; } }\n.glyphicon-sound-7-1 { &:before { content: \"\\e193\"; } }\n.glyphicon-copyright-mark { &:before { content: \"\\e194\"; } }\n.glyphicon-registration-mark { &:before { content: \"\\e195\"; } }\n.glyphicon-cloud-download { &:before { content: \"\\e197\"; } }\n.glyphicon-cloud-upload { &:before { content: \"\\e198\"; } }\n.glyphicon-tree-conifer { &:before { content: \"\\e199\"; } }\n.glyphicon-tree-deciduous { &:before { content: \"\\e200\"; } }\n.glyphicon-cd { &:before { content: \"\\e201\"; } }\n.glyphicon-save-file { &:before { content: \"\\e202\"; } }\n.glyphicon-open-file { &:before { content: \"\\e203\"; } }\n.glyphicon-level-up { &:before { content: \"\\e204\"; } }\n.glyphicon-copy { &:before { content: \"\\e205\"; } }\n.glyphicon-paste { &:before { content: \"\\e206\"; } }\n// The following 2 Glyphicons are omitted for the time being because\n// they currently use Unicode codepoints that are outside the\n// Basic Multilingual Plane (BMP). Older buggy versions of WebKit can't handle\n// non-BMP codepoints in CSS string escapes, and thus can't display these two icons.\n// Notably, the bug affects some older versions of the Android Browser.\n// More info: https://github.com/twbs/bootstrap/issues/10106\n// .glyphicon-door { &:before { content: \"\\1f6aa\"; } }\n// .glyphicon-key { &:before { content: \"\\1f511\"; } }\n.glyphicon-alert { &:before { content: \"\\e209\"; } }\n.glyphicon-equalizer { &:before { content: \"\\e210\"; } }\n.glyphicon-king { &:before { content: \"\\e211\"; } }\n.glyphicon-queen { &:before { content: \"\\e212\"; } }\n.glyphicon-pawn { &:before { content: \"\\e213\"; } }\n.glyphicon-bishop { &:before { content: \"\\e214\"; } }\n.glyphicon-knight { &:before { content: \"\\e215\"; } }\n.glyphicon-baby-formula { &:before { content: \"\\e216\"; } }\n.glyphicon-tent { &:before { content: \"\\26fa\"; } }\n.glyphicon-blackboard { &:before { content: \"\\e218\"; } }\n.glyphicon-bed { &:before { content: \"\\e219\"; } }\n.glyphicon-apple { &:before { content: \"\\f8ff\"; } }\n.glyphicon-erase { &:before { content: \"\\e221\"; } }\n.glyphicon-hourglass { &:before { content: \"\\231b\"; } }\n.glyphicon-lamp { &:before { content: \"\\e223\"; } }\n.glyphicon-duplicate { &:before { content: \"\\e224\"; } }\n.glyphicon-piggy-bank { &:before { content: \"\\e225\"; } }\n.glyphicon-scissors { &:before { content: \"\\e226\"; } }\n.glyphicon-bitcoin { &:before { content: \"\\e227\"; } }\n.glyphicon-btc { &:before { content: \"\\e227\"; } }\n.glyphicon-xbt { &:before { content: \"\\e227\"; } }\n.glyphicon-yen { &:before { content: \"\\00a5\"; } }\n.glyphicon-jpy { &:before { content: \"\\00a5\"; } }\n.glyphicon-ruble { &:before { content: \"\\20bd\"; } }\n.glyphicon-rub { &:before { content: \"\\20bd\"; } }\n.glyphicon-scale { &:before { content: \"\\e230\"; } }\n.glyphicon-ice-lolly { &:before { content: \"\\e231\"; } }\n.glyphicon-ice-lolly-tasted { &:before { content: \"\\e232\"; } }\n.glyphicon-education { &:before { content: \"\\e233\"; } }\n.glyphicon-option-horizontal { &:before { content: \"\\e234\"; } }\n.glyphicon-option-vertical { &:before { content: \"\\e235\"; } }\n.glyphicon-menu-hamburger { &:before { content: \"\\e236\"; } }\n.glyphicon-modal-window { &:before { content: \"\\e237\"; } }\n.glyphicon-oil { &:before { content: \"\\e238\"; } }\n.glyphicon-grain { &:before { content: \"\\e239\"; } }\n.glyphicon-sunglasses { &:before { content: \"\\e240\"; } }\n.glyphicon-text-size { &:before { content: \"\\e241\"; } }\n.glyphicon-text-color { &:before { content: \"\\e242\"; } }\n.glyphicon-text-background { &:before { content: \"\\e243\"; } }\n.glyphicon-object-align-top { &:before { content: \"\\e244\"; } }\n.glyphicon-object-align-bottom { &:before { content: \"\\e245\"; } }\n.glyphicon-object-align-horizontal{ &:before { content: \"\\e246\"; } }\n.glyphicon-object-align-left { &:before { content: \"\\e247\"; } }\n.glyphicon-object-align-vertical { &:before { content: \"\\e248\"; } }\n.glyphicon-object-align-right { &:before { content: \"\\e249\"; } }\n.glyphicon-triangle-right { &:before { content: \"\\e250\"; } }\n.glyphicon-triangle-left { &:before { content: \"\\e251\"; } }\n.glyphicon-triangle-bottom { &:before { content: \"\\e252\"; } }\n.glyphicon-triangle-top { &:before { content: \"\\e253\"; } }\n.glyphicon-console { &:before { content: \"\\e254\"; } }\n.glyphicon-superscript { &:before { content: \"\\e255\"; } }\n.glyphicon-subscript { &:before { content: \"\\e256\"; } }\n.glyphicon-menu-left { &:before { content: \"\\e257\"; } }\n.glyphicon-menu-right { &:before { content: \"\\e258\"; } }\n.glyphicon-menu-down { &:before { content: \"\\e259\"; } }\n.glyphicon-menu-up { &:before { content: \"\\e260\"; } }\n",
+ "//\n// Scaffolding\n// --------------------------------------------------\n\n\n// Reset the box-sizing\n//\n// Heads up! This reset may cause conflicts with some third-party widgets.\n// For recommendations on resolving such conflicts, see\n// http://getbootstrap.com/getting-started/#third-box-sizing\n* {\n .box-sizing(border-box);\n}\n*:before,\n*:after {\n .box-sizing(border-box);\n}\n\n\n// Body reset\n\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0,0,0,0);\n}\n\nbody {\n font-family: @font-family-base;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @text-color;\n background-color: @body-bg;\n}\n\n// Reset fonts for relevant elements\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\n\n// Links\n\na {\n color: @link-color;\n text-decoration: none;\n\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: @link-hover-decoration;\n }\n\n &:focus {\n .tab-focus();\n }\n}\n\n\n// Figures\n//\n// We reset this here because previously Normalize had no `figure` margins. This\n// ensures we don't break anyone's use of the element.\n\nfigure {\n margin: 0;\n}\n\n\n// Images\n\nimg {\n vertical-align: middle;\n}\n\n// Responsive images (ensure images don't scale beyond their parents)\n.img-responsive {\n .img-responsive();\n}\n\n// Rounded corners\n.img-rounded {\n border-radius: @border-radius-large;\n}\n\n// Image thumbnails\n//\n// Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`.\n.img-thumbnail {\n padding: @thumbnail-padding;\n line-height: @line-height-base;\n background-color: @thumbnail-bg;\n border: 1px solid @thumbnail-border;\n border-radius: @thumbnail-border-radius;\n .transition(all .2s ease-in-out);\n\n // Keep them at most 100% wide\n .img-responsive(inline-block);\n}\n\n// Perfect circle\n.img-circle {\n border-radius: 50%; // set radius in percents\n}\n\n\n// Horizontal rules\n\nhr {\n margin-top: @line-height-computed;\n margin-bottom: @line-height-computed;\n border: 0;\n border-top: 1px solid @hr-border;\n}\n\n\n// Only display content to screen readers\n//\n// See: http://a11yproject.com/posts/how-to-hide-content/\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0,0,0,0);\n border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n// Useful for \"Skip to main content\" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n// Credit: HTML5 Boilerplate\n\n.sr-only-focusable {\n &:active,\n &:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n }\n}\n\n\n// iOS \"clickable elements\" fix for role=\"button\"\n//\n// Fixes \"clickability\" issue (and more generally, the firing of events such as focus as well)\n// for traditionally non-focusable elements with role=\"button\"\n// see https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n\n[role=\"button\"] {\n cursor: pointer;\n}\n",
+ "// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They will be removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility){\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n",
+ "// WebKit-style focus\n\n.tab-focus() {\n // Default\n outline: thin dotted;\n // WebKit\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n",
+ "// Image Mixins\n// - Responsive image\n// - Retina image\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n.img-responsive(@display: block) {\n display: @display;\n max-width: 100%; // Part 1: Set a maximum relative to the parent\n height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching\n}\n\n\n// Retina image\n//\n// Short retina mixin for setting background-image and -size. Note that the\n// spelling of `min--moz-device-pixel-ratio` is intentional.\n.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {\n background-image: url(\"@{file-1x}\");\n\n @media\n only screen and (-webkit-min-device-pixel-ratio: 2),\n only screen and ( min--moz-device-pixel-ratio: 2),\n only screen and ( -o-min-device-pixel-ratio: 2/1),\n only screen and ( min-device-pixel-ratio: 2),\n only screen and ( min-resolution: 192dpi),\n only screen and ( min-resolution: 2dppx) {\n background-image: url(\"@{file-2x}\");\n background-size: @width-1x @height-1x;\n }\n}\n",
+ "//\n// Typography\n// --------------------------------------------------\n\n\n// Headings\n// -------------------------\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n font-family: @headings-font-family;\n font-weight: @headings-font-weight;\n line-height: @headings-line-height;\n color: @headings-color;\n\n small,\n .small {\n font-weight: normal;\n line-height: 1;\n color: @headings-small-color;\n }\n}\n\nh1, .h1,\nh2, .h2,\nh3, .h3 {\n margin-top: @line-height-computed;\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 65%;\n }\n}\nh4, .h4,\nh5, .h5,\nh6, .h6 {\n margin-top: (@line-height-computed / 2);\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 75%;\n }\n}\n\nh1, .h1 { font-size: @font-size-h1; }\nh2, .h2 { font-size: @font-size-h2; }\nh3, .h3 { font-size: @font-size-h3; }\nh4, .h4 { font-size: @font-size-h4; }\nh5, .h5 { font-size: @font-size-h5; }\nh6, .h6 { font-size: @font-size-h6; }\n\n\n// Body text\n// -------------------------\n\np {\n margin: 0 0 (@line-height-computed / 2);\n}\n\n.lead {\n margin-bottom: @line-height-computed;\n font-size: floor((@font-size-base * 1.15));\n font-weight: 300;\n line-height: 1.4;\n\n @media (min-width: @screen-sm-min) {\n font-size: (@font-size-base * 1.5);\n }\n}\n\n\n// Emphasis & misc\n// -------------------------\n\n// Ex: (12px small font / 14px base font) * 100% = about 85%\nsmall,\n.small {\n font-size: floor((100% * @font-size-small / @font-size-base));\n}\n\nmark,\n.mark {\n background-color: @state-warning-bg;\n padding: .2em;\n}\n\n// Alignment\n.text-left { text-align: left; }\n.text-right { text-align: right; }\n.text-center { text-align: center; }\n.text-justify { text-align: justify; }\n.text-nowrap { white-space: nowrap; }\n\n// Transformation\n.text-lowercase { text-transform: lowercase; }\n.text-uppercase { text-transform: uppercase; }\n.text-capitalize { text-transform: capitalize; }\n\n// Contextual colors\n.text-muted {\n color: @text-muted;\n}\n.text-primary {\n .text-emphasis-variant(@brand-primary);\n}\n.text-success {\n .text-emphasis-variant(@state-success-text);\n}\n.text-info {\n .text-emphasis-variant(@state-info-text);\n}\n.text-warning {\n .text-emphasis-variant(@state-warning-text);\n}\n.text-danger {\n .text-emphasis-variant(@state-danger-text);\n}\n\n// Contextual backgrounds\n// For now we'll leave these alongside the text classes until v4 when we can\n// safely shift things around (per SemVer rules).\n.bg-primary {\n // Given the contrast here, this is the only class to have its color inverted\n // automatically.\n color: #fff;\n .bg-variant(@brand-primary);\n}\n.bg-success {\n .bg-variant(@state-success-bg);\n}\n.bg-info {\n .bg-variant(@state-info-bg);\n}\n.bg-warning {\n .bg-variant(@state-warning-bg);\n}\n.bg-danger {\n .bg-variant(@state-danger-bg);\n}\n\n\n// Page header\n// -------------------------\n\n.page-header {\n padding-bottom: ((@line-height-computed / 2) - 1);\n margin: (@line-height-computed * 2) 0 @line-height-computed;\n border-bottom: 1px solid @page-header-border-color;\n}\n\n\n// Lists\n// -------------------------\n\n// Unordered and Ordered lists\nul,\nol {\n margin-top: 0;\n margin-bottom: (@line-height-computed / 2);\n ul,\n ol {\n margin-bottom: 0;\n }\n}\n\n// List options\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n .list-unstyled();\n margin-left: -5px;\n\n > li {\n display: inline-block;\n padding-left: 5px;\n padding-right: 5px;\n }\n}\n\n// Description Lists\ndl {\n margin-top: 0; // Remove browser default\n margin-bottom: @line-height-computed;\n}\ndt,\ndd {\n line-height: @line-height-base;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0; // Undo browser default\n}\n\n// Horizontal description lists\n//\n// Defaults to being stacked without any of the below styles applied, until the\n// grid breakpoint is reached (default of ~768px).\n\n.dl-horizontal {\n dd {\n &:extend(.clearfix all); // Clear the floated `dt` if an empty `dd` is present\n }\n\n @media (min-width: @grid-float-breakpoint) {\n dt {\n float: left;\n width: (@dl-horizontal-offset - 20);\n clear: left;\n text-align: right;\n .text-overflow();\n }\n dd {\n margin-left: @dl-horizontal-offset;\n }\n }\n}\n\n\n// Misc\n// -------------------------\n\n// Abbreviations and acronyms\nabbr[title],\n// Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted @abbr-border-color;\n}\n.initialism {\n font-size: 90%;\n .text-uppercase();\n}\n\n// Blockquotes\nblockquote {\n padding: (@line-height-computed / 2) @line-height-computed;\n margin: 0 0 @line-height-computed;\n font-size: @blockquote-font-size;\n border-left: 5px solid @blockquote-border-color;\n\n p,\n ul,\n ol {\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n // Note: Deprecated small and .small as of v3.1.0\n // Context: https://github.com/twbs/bootstrap/issues/11660\n footer,\n small,\n .small {\n display: block;\n font-size: 80%; // back to default font-size\n line-height: @line-height-base;\n color: @blockquote-small-color;\n\n &:before {\n content: '\\2014 \\00A0'; // em dash, nbsp\n }\n }\n}\n\n// Opposite alignment of blockquote\n//\n// Heads up: `blockquote.pull-right` has been deprecated as of v3.1.0.\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n border-right: 5px solid @blockquote-border-color;\n border-left: 0;\n text-align: right;\n\n // Account for citation\n footer,\n small,\n .small {\n &:before { content: ''; }\n &:after {\n content: '\\00A0 \\2014'; // nbsp, em dash\n }\n }\n}\n\n// Addresses\naddress {\n margin-bottom: @line-height-computed;\n font-style: normal;\n line-height: @line-height-base;\n}\n",
+ "// Typography\n\n.text-emphasis-variant(@color) {\n color: @color;\n a&:hover,\n a&:focus {\n color: darken(@color, 10%);\n }\n}\n",
+ "// Contextual backgrounds\n\n.bg-variant(@color) {\n background-color: @color;\n a&:hover,\n a&:focus {\n background-color: darken(@color, 10%);\n }\n}\n",
+ "// Text overflow\n// Requires inline-block or block for proper styling\n\n.text-overflow() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n",
+ "//\n// Code (inline and block)\n// --------------------------------------------------\n\n\n// Inline and block code styles\ncode,\nkbd,\npre,\nsamp {\n font-family: @font-family-monospace;\n}\n\n// Inline code\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: @code-color;\n background-color: @code-bg;\n border-radius: @border-radius-base;\n}\n\n// User input typically entered via keyboard\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: @kbd-color;\n background-color: @kbd-bg;\n border-radius: @border-radius-small;\n box-shadow: inset 0 -1px 0 rgba(0,0,0,.25);\n\n kbd {\n padding: 0;\n font-size: 100%;\n font-weight: bold;\n box-shadow: none;\n }\n}\n\n// Blocks of code\npre {\n display: block;\n padding: ((@line-height-computed - 1) / 2);\n margin: 0 0 (@line-height-computed / 2);\n font-size: (@font-size-base - 1); // 14px to 13px\n line-height: @line-height-base;\n word-break: break-all;\n word-wrap: break-word;\n color: @pre-color;\n background-color: @pre-bg;\n border: 1px solid @pre-border-color;\n border-radius: @border-radius-base;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n max-height: @pre-scrollable-max-height;\n overflow-y: scroll;\n}\n",
+ "//\n// Grid system\n// --------------------------------------------------\n\n\n// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n.container {\n .container-fixed();\n\n @media (min-width: @screen-sm-min) {\n width: @container-sm;\n }\n @media (min-width: @screen-md-min) {\n width: @container-md;\n }\n @media (min-width: @screen-lg-min) {\n width: @container-lg;\n }\n}\n\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but without any defined\n// width for fluid, full width layouts.\n\n.container-fluid {\n .container-fixed();\n}\n\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n.row {\n .make-row();\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n.make-grid-columns();\n\n\n// Extra small grid\n//\n// Columns, offsets, pushes, and pulls for extra small devices like\n// smartphones.\n\n.make-grid(xs);\n\n\n// Small grid\n//\n// Columns, offsets, pushes, and pulls for the small device range, from phones\n// to tablets.\n\n@media (min-width: @screen-sm-min) {\n .make-grid(sm);\n}\n\n\n// Medium grid\n//\n// Columns, offsets, pushes, and pulls for the desktop device range.\n\n@media (min-width: @screen-md-min) {\n .make-grid(md);\n}\n\n\n// Large grid\n//\n// Columns, offsets, pushes, and pulls for the large desktop device range.\n\n@media (min-width: @screen-lg-min) {\n .make-grid(lg);\n}\n",
+ "// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n// Centered container element\n.container-fixed(@gutter: @grid-gutter-width) {\n margin-right: auto;\n margin-left: auto;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n &:extend(.clearfix all);\n}\n\n// Creates a wrapper for a series of columns\n.make-row(@gutter: @grid-gutter-width) {\n margin-left: ceil((@gutter / -2));\n margin-right: floor((@gutter / -2));\n &:extend(.clearfix all);\n}\n\n// Generate the extra small columns\n.make-xs-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n float: left;\n width: percentage((@columns / @grid-columns));\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n}\n.make-xs-column-offset(@columns) {\n margin-left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-push(@columns) {\n left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-pull(@columns) {\n right: percentage((@columns / @grid-columns));\n}\n\n// Generate the small columns\n.make-sm-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-sm-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-offset(@columns) {\n @media (min-width: @screen-sm-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-push(@columns) {\n @media (min-width: @screen-sm-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-pull(@columns) {\n @media (min-width: @screen-sm-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the medium columns\n.make-md-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-md-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-offset(@columns) {\n @media (min-width: @screen-md-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-push(@columns) {\n @media (min-width: @screen-md-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-pull(@columns) {\n @media (min-width: @screen-md-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the large columns\n.make-lg-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-lg-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-offset(@columns) {\n @media (min-width: @screen-lg-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-push(@columns) {\n @media (min-width: @screen-lg-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-pull(@columns) {\n @media (min-width: @screen-lg-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n",
+ "// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `@grid-columns`.\n\n.make-grid-columns() {\n // Common styles for all sizes of grid columns, widths 1-12\n .col(@index) { // initial\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general; \"=<\" isn't a typo\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n position: relative;\n // Prevent columns from collapsing when empty\n min-height: 1px;\n // Inner gutter via padding\n padding-left: ceil((@grid-gutter-width / 2));\n padding-right: floor((@grid-gutter-width / 2));\n }\n }\n .col(1); // kickstart it\n}\n\n.float-grid-columns(@class) {\n .col(@index) { // initial\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n float: left;\n }\n }\n .col(1); // kickstart it\n}\n\n.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {\n .col-@{class}-@{index} {\n width: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index > 0) {\n .col-@{class}-push-@{index} {\n left: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index = 0) {\n .col-@{class}-push-0 {\n left: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index > 0) {\n .col-@{class}-pull-@{index} {\n right: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index = 0) {\n .col-@{class}-pull-0 {\n right: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = offset) {\n .col-@{class}-offset-@{index} {\n margin-left: percentage((@index / @grid-columns));\n }\n}\n\n// Basic looping in LESS\n.loop-grid-columns(@index, @class, @type) when (@index >= 0) {\n .calc-grid-column(@index, @class, @type);\n // next iteration\n .loop-grid-columns((@index - 1), @class, @type);\n}\n\n// Create grid for specific class\n.make-grid(@class) {\n .float-grid-columns(@class);\n .loop-grid-columns(@grid-columns, @class, width);\n .loop-grid-columns(@grid-columns, @class, pull);\n .loop-grid-columns(@grid-columns, @class, push);\n .loop-grid-columns(@grid-columns, @class, offset);\n}\n",
+ "//\n// Tables\n// --------------------------------------------------\n\n\ntable {\n background-color: @table-bg;\n}\ncaption {\n padding-top: @table-cell-padding;\n padding-bottom: @table-cell-padding;\n color: @text-muted;\n text-align: left;\n}\nth {\n text-align: left;\n}\n\n\n// Baseline styles\n\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: @line-height-computed;\n // Cells\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-cell-padding;\n line-height: @line-height-base;\n vertical-align: top;\n border-top: 1px solid @table-border-color;\n }\n }\n }\n // Bottom align for column headings\n > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid @table-border-color;\n }\n // Remove top border from thead by default\n > caption + thead,\n > colgroup + thead,\n > thead:first-child {\n > tr:first-child {\n > th,\n > td {\n border-top: 0;\n }\n }\n }\n // Account for multiple tbody instances\n > tbody + tbody {\n border-top: 2px solid @table-border-color;\n }\n\n // Nesting\n .table {\n background-color: @body-bg;\n }\n}\n\n\n// Condensed table w/ half padding\n\n.table-condensed {\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-condensed-cell-padding;\n }\n }\n }\n}\n\n\n// Bordered version\n//\n// Add borders all around the table and between all the columns.\n\n.table-bordered {\n border: 1px solid @table-border-color;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n border: 1px solid @table-border-color;\n }\n }\n }\n > thead > tr {\n > th,\n > td {\n border-bottom-width: 2px;\n }\n }\n}\n\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n > tbody > tr:nth-of-type(odd) {\n background-color: @table-bg-accent;\n }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n > tbody > tr:hover {\n background-color: @table-bg-hover;\n }\n}\n\n\n// Table cell sizing\n//\n// Reset default table behavior\n\ntable col[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-column;\n}\ntable {\n td,\n th {\n &[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-cell;\n }\n }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n// Generate the contextual variants\n.table-row-variant(active; @table-bg-active);\n.table-row-variant(success; @state-success-bg);\n.table-row-variant(info; @state-info-bg);\n.table-row-variant(warning; @state-warning-bg);\n.table-row-variant(danger; @state-danger-bg);\n\n\n// Responsive tables\n//\n// Wrap your tables in `.table-responsive` and we'll make them mobile friendly\n// by enabling horizontal scrolling. Only applies <768px. Everything above that\n// will display normally.\n\n.table-responsive {\n overflow-x: auto;\n min-height: 0.01%; // Workaround for IE9 bug (see https://github.com/twbs/bootstrap/issues/14837)\n\n @media screen and (max-width: @screen-xs-max) {\n width: 100%;\n margin-bottom: (@line-height-computed * 0.75);\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid @table-border-color;\n\n // Tighten up spacing\n > .table {\n margin-bottom: 0;\n\n // Ensure the content doesn't wrap\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n white-space: nowrap;\n }\n }\n }\n }\n\n // Special overrides for the bordered tables\n > .table-bordered {\n border: 0;\n\n // Nuke the appropriate borders so that the parent can handle them\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n\n // Only nuke the last row's bottom-border in `tbody` and `tfoot` since\n // chances are there will be only one `tr` in a `thead` and that would\n // remove the border altogether.\n > tbody,\n > tfoot {\n > tr:last-child {\n > th,\n > td {\n border-bottom: 0;\n }\n }\n }\n\n }\n }\n}\n",
+ "// Tables\n\n.table-row-variant(@state; @background) {\n // Exact selectors below required to override `.table-striped` and prevent\n // inheritance to nested tables.\n .table > thead > tr,\n .table > tbody > tr,\n .table > tfoot > tr {\n > td.@{state},\n > th.@{state},\n &.@{state} > td,\n &.@{state} > th {\n background-color: @background;\n }\n }\n\n // Hover states for `.table-hover`\n // Note: this is not available for cells or rows within `thead` or `tfoot`.\n .table-hover > tbody > tr {\n > td.@{state}:hover,\n > th.@{state}:hover,\n &.@{state}:hover > td,\n &:hover > .@{state},\n &.@{state}:hover > th {\n background-color: darken(@background, 5%);\n }\n }\n}\n",
+ "//\n// Forms\n// --------------------------------------------------\n\n\n// Normalize non-controls\n//\n// Restyle and baseline non-control form elements.\n\nfieldset {\n padding: 0;\n margin: 0;\n border: 0;\n // Chrome and Firefox set a `min-width: min-content;` on fieldsets,\n // so we reset that to ensure it behaves more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359.\n min-width: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: @line-height-computed;\n font-size: (@font-size-base * 1.5);\n line-height: inherit;\n color: @legend-color;\n border: 0;\n border-bottom: 1px solid @legend-border-color;\n}\n\nlabel {\n display: inline-block;\n max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141)\n margin-bottom: 5px;\n font-weight: bold;\n}\n\n\n// Normalize form controls\n//\n// While most of our form styles require extra classes, some basic normalization\n// is required to ensure optimum display with or without those classes to better\n// address browser inconsistencies.\n\n// Override content-box in Normalize (* isn't specific enough)\ninput[type=\"search\"] {\n .box-sizing(border-box);\n}\n\n// Position radios and checkboxes better\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9; // IE8-9\n line-height: normal;\n}\n\ninput[type=\"file\"] {\n display: block;\n}\n\n// Make range inputs behave like textual form controls\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\n\n// Make multiple select elements height not fixed\nselect[multiple],\nselect[size] {\n height: auto;\n}\n\n// Focus for file, radio, and checkbox\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n .tab-focus();\n}\n\n// Adjust output element\noutput {\n display: block;\n padding-top: (@padding-base-vertical + 1);\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n}\n\n\n// Common form controls\n//\n// Shared size and type resets for form controls. Apply `.form-control` to any\n// of the following form controls:\n//\n// select\n// textarea\n// input[type=\"text\"]\n// input[type=\"password\"]\n// input[type=\"datetime\"]\n// input[type=\"datetime-local\"]\n// input[type=\"date\"]\n// input[type=\"month\"]\n// input[type=\"time\"]\n// input[type=\"week\"]\n// input[type=\"number\"]\n// input[type=\"email\"]\n// input[type=\"url\"]\n// input[type=\"search\"]\n// input[type=\"tel\"]\n// input[type=\"color\"]\n\n.form-control {\n display: block;\n width: 100%;\n height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n background-color: @input-bg;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid @input-border;\n border-radius: @input-border-radius; // Note: This has no effect on <select>s in some browsers, due to the limited stylability of <select>s in CSS.\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));\n .transition(~\"border-color ease-in-out .15s, box-shadow ease-in-out .15s\");\n\n // Customize the `:focus` state to imitate native WebKit styles.\n .form-control-focus();\n\n // Placeholder\n .placeholder();\n\n // Disabled and read-only inputs\n //\n // HTML5 says that controls under a fieldset > legend:first-child won't be\n // disabled if the fieldset is disabled. Due to implementation difficulty, we\n // don't honor that edge case; we style them as disabled anyway.\n &[disabled],\n &[readonly],\n fieldset[disabled] & {\n background-color: @input-bg-disabled;\n opacity: 1; // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655\n }\n\n &[disabled],\n fieldset[disabled] & {\n cursor: @cursor-disabled;\n }\n\n // Reset height for `textarea`s\n textarea& {\n height: auto;\n }\n}\n\n\n// Search inputs in iOS\n//\n// This overrides the extra rounded corners on search inputs in iOS so that our\n// `.form-control` class can properly style them. Note that this cannot simply\n// be added to `.form-control` as it's not specific enough. For details, see\n// https://github.com/twbs/bootstrap/issues/11586.\n\ninput[type=\"search\"] {\n -webkit-appearance: none;\n}\n\n\n// Special styles for iOS temporal inputs\n//\n// In Mobile Safari, setting `display: block` on temporal inputs causes the\n// text within the input to become vertically misaligned. As a workaround, we\n// set a pixel line-height that matches the given height of the input, but only\n// for Safari. See https://bugs.webkit.org/show_bug.cgi?id=139848\n//\n// Note that as of 8.3, iOS doesn't support `datetime` or `week`.\n\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n input[type=\"date\"],\n input[type=\"time\"],\n input[type=\"datetime-local\"],\n input[type=\"month\"] {\n &.form-control {\n line-height: @input-height-base;\n }\n\n &.input-sm,\n .input-group-sm & {\n line-height: @input-height-small;\n }\n\n &.input-lg,\n .input-group-lg & {\n line-height: @input-height-large;\n }\n }\n}\n\n\n// Form groups\n//\n// Designed to help with the organization and spacing of vertical forms. For\n// horizontal forms, use the predefined grid classes.\n\n.form-group {\n margin-bottom: @form-group-margin-bottom;\n}\n\n\n// Checkboxes and radios\n//\n// Indent the labels to position radios/checkboxes as hanging controls.\n\n.radio,\n.checkbox {\n position: relative;\n display: block;\n margin-top: 10px;\n margin-bottom: 10px;\n\n label {\n min-height: @line-height-computed; // Ensure the input doesn't jump when there is no text\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: normal;\n cursor: pointer;\n }\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n position: absolute;\n margin-left: -20px;\n margin-top: 4px \\9;\n}\n\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing\n}\n\n// Radios and checkboxes on same line\n.radio-inline,\n.checkbox-inline {\n position: relative;\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n vertical-align: middle;\n font-weight: normal;\n cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px; // space out consecutive inline controls\n}\n\n// Apply same disabled cursor tweak as for inputs\n// Some special care is needed because <label>s don't inherit their parent's `cursor`.\n//\n// Note: Neither radios nor checkboxes can be readonly.\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n &[disabled],\n &.disabled,\n fieldset[disabled] & {\n cursor: @cursor-disabled;\n }\n}\n// These classes are used directly on <label>s\n.radio-inline,\n.checkbox-inline {\n &.disabled,\n fieldset[disabled] & {\n cursor: @cursor-disabled;\n }\n}\n// These classes are used on elements with <label> descendants\n.radio,\n.checkbox {\n &.disabled,\n fieldset[disabled] & {\n label {\n cursor: @cursor-disabled;\n }\n }\n}\n\n\n// Static form control text\n//\n// Apply class to a `p` element to make any string of text align with labels in\n// a horizontal form layout.\n\n.form-control-static {\n // Size it appropriately next to real form controls\n padding-top: (@padding-base-vertical + 1);\n padding-bottom: (@padding-base-vertical + 1);\n // Remove default margin from `p`\n margin-bottom: 0;\n min-height: (@line-height-computed + @font-size-base);\n\n &.input-lg,\n &.input-sm {\n padding-left: 0;\n padding-right: 0;\n }\n}\n\n\n// Form control sizing\n//\n// Build on `.form-control` with modifier classes to decrease or increase the\n// height and font-size of form controls.\n//\n// The `.form-group-* form-control` variations are sadly duplicated to avoid the\n// issue documented in https://github.com/twbs/bootstrap/issues/15074.\n\n.input-sm {\n .input-size(@input-height-small; @padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @input-border-radius-small);\n}\n.form-group-sm {\n .form-control {\n height: @input-height-small;\n padding: @padding-small-vertical @padding-small-horizontal;\n font-size: @font-size-small;\n line-height: @line-height-small;\n border-radius: @input-border-radius-small;\n }\n select.form-control {\n height: @input-height-small;\n line-height: @input-height-small;\n }\n textarea.form-control,\n select[multiple].form-control {\n height: auto;\n }\n .form-control-static {\n height: @input-height-small;\n min-height: (@line-height-computed + @font-size-small);\n padding: (@padding-small-vertical + 1) @padding-small-horizontal;\n font-size: @font-size-small;\n line-height: @line-height-small;\n }\n}\n\n.input-lg {\n .input-size(@input-height-large; @padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @input-border-radius-large);\n}\n.form-group-lg {\n .form-control {\n height: @input-height-large;\n padding: @padding-large-vertical @padding-large-horizontal;\n font-size: @font-size-large;\n line-height: @line-height-large;\n border-radius: @input-border-radius-large;\n }\n select.form-control {\n height: @input-height-large;\n line-height: @input-height-large;\n }\n textarea.form-control,\n select[multiple].form-control {\n height: auto;\n }\n .form-control-static {\n height: @input-height-large;\n min-height: (@line-height-computed + @font-size-large);\n padding: (@padding-large-vertical + 1) @padding-large-horizontal;\n font-size: @font-size-large;\n line-height: @line-height-large;\n }\n}\n\n\n// Form control feedback states\n//\n// Apply contextual and semantic states to individual form controls.\n\n.has-feedback {\n // Enable absolute positioning\n position: relative;\n\n // Ensure icons don't overlap text\n .form-control {\n padding-right: (@input-height-base * 1.25);\n }\n}\n// Feedback icon (requires .glyphicon classes)\n.form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2; // Ensure icon is above input groups\n display: block;\n width: @input-height-base;\n height: @input-height-base;\n line-height: @input-height-base;\n text-align: center;\n pointer-events: none;\n}\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n width: @input-height-large;\n height: @input-height-large;\n line-height: @input-height-large;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback {\n width: @input-height-small;\n height: @input-height-small;\n line-height: @input-height-small;\n}\n\n// Feedback states\n.has-success {\n .form-control-validation(@state-success-text; @state-success-text; @state-success-bg);\n}\n.has-warning {\n .form-control-validation(@state-warning-text; @state-warning-text; @state-warning-bg);\n}\n.has-error {\n .form-control-validation(@state-danger-text; @state-danger-text; @state-danger-bg);\n}\n\n// Reposition feedback icon if input has visible label above\n.has-feedback label {\n\n & ~ .form-control-feedback {\n top: (@line-height-computed + 5); // Height of the `label` and its margin\n }\n &.sr-only ~ .form-control-feedback {\n top: 0;\n }\n}\n\n\n// Help text\n//\n// Apply to any element you wish to create light text for placement immediately\n// below a form control. Use for general help, formatting, or instructional text.\n\n.help-block {\n display: block; // account for any element using help-block\n margin-top: 5px;\n margin-bottom: 10px;\n color: lighten(@text-color, 25%); // lighten the text some for contrast\n}\n\n\n// Inline forms\n//\n// Make forms appear inline(-block) by adding the `.form-inline` class. Inline\n// forms begin stacked on extra small (mobile) devices and then go inline when\n// viewports reach <768px.\n//\n// Requires wrapping inputs and labels with `.form-group` for proper display of\n// default HTML form controls and our custom form controls (e.g., input groups).\n//\n// Heads up! This is mixin-ed into `.navbar-form` in navbars.less.\n\n.form-inline {\n\n // Kick in the inline\n @media (min-width: @screen-sm-min) {\n // Inline-block all the things for \"inline\"\n .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n\n // In navbar-form, allow folks to *not* use `.form-group`\n .form-control {\n display: inline-block;\n width: auto; // Prevent labels from stacking above inputs in `.form-group`\n vertical-align: middle;\n }\n\n // Make static controls behave like regular ones\n .form-control-static {\n display: inline-block;\n }\n\n .input-group {\n display: inline-table;\n vertical-align: middle;\n\n .input-group-addon,\n .input-group-btn,\n .form-control {\n width: auto;\n }\n }\n\n // Input groups need that 100% width though\n .input-group > .form-control {\n width: 100%;\n }\n\n .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n\n // Remove default margin on radios/checkboxes that were used for stacking, and\n // then undo the floating of radios and checkboxes to match.\n .radio,\n .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n\n label {\n padding-left: 0;\n }\n }\n .radio input[type=\"radio\"],\n .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n\n // Re-override the feedback icon.\n .has-feedback .form-control-feedback {\n top: 0;\n }\n }\n}\n\n\n// Horizontal forms\n//\n// Horizontal forms are built on grid classes and allow you to create forms with\n// labels on the left and inputs on the right.\n\n.form-horizontal {\n\n // Consistent vertical alignment of radios and checkboxes\n //\n // Labels also get some reset styles, but that is scoped to a media query below.\n .radio,\n .checkbox,\n .radio-inline,\n .checkbox-inline {\n margin-top: 0;\n margin-bottom: 0;\n padding-top: (@padding-base-vertical + 1); // Default padding plus a border\n }\n // Account for padding we're adding to ensure the alignment and of help text\n // and other content below items\n .radio,\n .checkbox {\n min-height: (@line-height-computed + (@padding-base-vertical + 1));\n }\n\n // Make form groups behave like rows\n .form-group {\n .make-row();\n }\n\n // Reset spacing and right align labels, but scope to media queries so that\n // labels on narrow viewports stack the same as a default form example.\n @media (min-width: @screen-sm-min) {\n .control-label {\n text-align: right;\n margin-bottom: 0;\n padding-top: (@padding-base-vertical + 1); // Default padding plus a border\n }\n }\n\n // Validation states\n //\n // Reposition the icon because it's now within a grid column and columns have\n // `position: relative;` on them. Also accounts for the grid gutter padding.\n .has-feedback .form-control-feedback {\n right: floor((@grid-gutter-width / 2));\n }\n\n // Form group sizes\n //\n // Quick utility class for applying `.input-lg` and `.input-sm` styles to the\n // inputs and labels within a `.form-group`.\n .form-group-lg {\n @media (min-width: @screen-sm-min) {\n .control-label {\n padding-top: ((@padding-large-vertical * @line-height-large) + 1);\n font-size: @font-size-large;\n }\n }\n }\n .form-group-sm {\n @media (min-width: @screen-sm-min) {\n .control-label {\n padding-top: (@padding-small-vertical + 1);\n font-size: @font-size-small;\n }\n }\n }\n}\n",
+ "// Form validation states\n//\n// Used in forms.less to generate the form validation CSS for warnings, errors,\n// and successes.\n\n.form-control-validation(@text-color: #555; @border-color: #ccc; @background-color: #f5f5f5) {\n // Color the label and help text\n .help-block,\n .control-label,\n .radio,\n .checkbox,\n .radio-inline,\n .checkbox-inline,\n &.radio label,\n &.checkbox label,\n &.radio-inline label,\n &.checkbox-inline label {\n color: @text-color;\n }\n // Set the border and box shadow on specific inputs to match\n .form-control {\n border-color: @border-color;\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work\n &:focus {\n border-color: darken(@border-color, 10%);\n @shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten(@border-color, 20%);\n .box-shadow(@shadow);\n }\n }\n // Set validation states also for addons\n .input-group-addon {\n color: @text-color;\n border-color: @border-color;\n background-color: @background-color;\n }\n // Optional feedback icon\n .form-control-feedback {\n color: @text-color;\n }\n}\n\n\n// Form control focus state\n//\n// Generate a customized focus state and for any input with the specified color,\n// which defaults to the `@input-border-focus` variable.\n//\n// We highly encourage you to not customize the default value, but instead use\n// this to tweak colors on an as-needed basis. This aesthetic change is based on\n// WebKit's default styles, but applicable to a wider range of browsers. Its\n// usability and accessibility should be taken into account with any change.\n//\n// Example usage: change the default blue border and shadow to white for better\n// contrast against a dark gray background.\n.form-control-focus(@color: @input-border-focus) {\n @color-rgba: rgba(red(@color), green(@color), blue(@color), .6);\n &:focus {\n border-color: @color;\n outline: 0;\n .box-shadow(~\"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}\");\n }\n}\n\n// Form control sizing\n//\n// Relative text size, padding, and border-radii changes for form controls. For\n// horizontal sizing, wrap controls in the predefined grid classes. `<select>`\n// element gets special love because it's special, and that's a fact!\n.input-size(@input-height; @padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n height: @input-height;\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n border-radius: @border-radius;\n\n select& {\n height: @input-height;\n line-height: @input-height;\n }\n\n textarea&,\n select[multiple]& {\n height: auto;\n }\n}\n",
+ "//\n// Buttons\n// --------------------------------------------------\n\n\n// Base styles\n// --------------------------------------------------\n\n.btn {\n display: inline-block;\n margin-bottom: 0; // For input.btn\n font-weight: @btn-font-weight;\n text-align: center;\n vertical-align: middle;\n touch-action: manipulation;\n cursor: pointer;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid transparent;\n white-space: nowrap;\n .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @btn-border-radius-base);\n .user-select(none);\n\n &,\n &:active,\n &.active {\n &:focus,\n &.focus {\n .tab-focus();\n }\n }\n\n &:hover,\n &:focus,\n &.focus {\n color: @btn-default-color;\n text-decoration: none;\n }\n\n &:active,\n &.active {\n outline: 0;\n background-image: none;\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n cursor: @cursor-disabled;\n .opacity(.65);\n .box-shadow(none);\n }\n\n a& {\n &.disabled,\n fieldset[disabled] & {\n pointer-events: none; // Future-proof disabling of clicks on `<a>` elements\n }\n }\n}\n\n\n// Alternate buttons\n// --------------------------------------------------\n\n.btn-default {\n .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border);\n}\n.btn-primary {\n .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border);\n}\n// Success appears as green\n.btn-success {\n .button-variant(@btn-success-color; @btn-success-bg; @btn-success-border);\n}\n// Info appears as blue-green\n.btn-info {\n .button-variant(@btn-info-color; @btn-info-bg; @btn-info-border);\n}\n// Warning appears as orange\n.btn-warning {\n .button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border);\n}\n// Danger and error appear as red\n.btn-danger {\n .button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border);\n}\n\n\n// Link buttons\n// -------------------------\n\n// Make a button look and behave like a link\n.btn-link {\n color: @link-color;\n font-weight: normal;\n border-radius: 0;\n\n &,\n &:active,\n &.active,\n &[disabled],\n fieldset[disabled] & {\n background-color: transparent;\n .box-shadow(none);\n }\n &,\n &:hover,\n &:focus,\n &:active {\n border-color: transparent;\n }\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: @link-hover-decoration;\n background-color: transparent;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @btn-link-disabled-color;\n text-decoration: none;\n }\n }\n}\n\n\n// Button Sizes\n// --------------------------------------------------\n\n.btn-lg {\n // line-height: ensure even-numbered height of button next to large input\n .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @btn-border-radius-large);\n}\n.btn-sm {\n // line-height: ensure proper height of button next to small input\n .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small);\n}\n.btn-xs {\n .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small);\n}\n\n\n// Block button\n// --------------------------------------------------\n\n.btn-block {\n display: block;\n width: 100%;\n}\n\n// Vertically space out multiple block buttons\n.btn-block + .btn-block {\n margin-top: 5px;\n}\n\n// Specificity overrides\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n &.btn-block {\n width: 100%;\n }\n}\n",
+ "// Button variants\n//\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n\n.button-variant(@color; @background; @border) {\n color: @color;\n background-color: @background;\n border-color: @border;\n\n &:focus,\n &.focus {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 25%);\n }\n &:hover {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 12%);\n }\n &:active,\n &.active,\n .open > .dropdown-toggle& {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 12%);\n\n &:hover,\n &:focus,\n &.focus {\n color: @color;\n background-color: darken(@background, 17%);\n border-color: darken(@border, 25%);\n }\n }\n &:active,\n &.active,\n .open > .dropdown-toggle& {\n background-image: none;\n }\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &,\n &:hover,\n &:focus,\n &.focus,\n &:active,\n &.active {\n background-color: @background;\n border-color: @border;\n }\n }\n\n .badge {\n color: @background;\n background-color: @color;\n }\n}\n\n// Button sizes\n.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n border-radius: @border-radius;\n}\n",
+ "// Opacity\n\n.opacity(@opacity) {\n opacity: @opacity;\n // IE8 filter\n @opacity-ie: (@opacity * 100);\n filter: ~\"alpha(opacity=@{opacity-ie})\";\n}\n",
+ "//\n// Component animations\n// --------------------------------------------------\n\n// Heads up!\n//\n// We don't use the `.opacity()` mixin here since it causes a bug with text\n// fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552.\n\n.fade {\n opacity: 0;\n .transition(opacity .15s linear);\n &.in {\n opacity: 1;\n }\n}\n\n.collapse {\n display: none;\n\n &.in { display: block; }\n tr&.in { display: table-row; }\n tbody&.in { display: table-row-group; }\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n .transition-property(~\"height, visibility\");\n .transition-duration(.35s);\n .transition-timing-function(ease);\n}\n",
+ "//\n// Dropdown menus\n// --------------------------------------------------\n\n\n// Dropdown arrow/caret\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: @caret-width-base dashed;\n border-top: @caret-width-base solid ~\"\\9\"; // IE8\n border-right: @caret-width-base solid transparent;\n border-left: @caret-width-base solid transparent;\n}\n\n// The dropdown wrapper (div)\n.dropup,\n.dropdown {\n position: relative;\n}\n\n// Prevent the focus on the dropdown toggle when closing dropdowns\n.dropdown-toggle:focus {\n outline: 0;\n}\n\n// The dropdown menu (ul)\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: @zindex-dropdown;\n display: none; // none by default, but block on \"open\" of the menu\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0; // override default ul\n list-style: none;\n font-size: @font-size-base;\n text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)\n background-color: @dropdown-bg;\n border: 1px solid @dropdown-fallback-border; // IE8 fallback\n border: 1px solid @dropdown-border;\n border-radius: @border-radius-base;\n .box-shadow(0 6px 12px rgba(0,0,0,.175));\n background-clip: padding-box;\n\n // Aligns the dropdown menu to right\n //\n // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]`\n &.pull-right {\n right: 0;\n left: auto;\n }\n\n // Dividers (basically an hr) within the dropdown\n .divider {\n .nav-divider(@dropdown-divider-bg);\n }\n\n // Links within the dropdown menu\n > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: @line-height-base;\n color: @dropdown-link-color;\n white-space: nowrap; // prevent links from randomly breaking onto new lines\n }\n}\n\n// Hover/Focus state\n.dropdown-menu > li > a {\n &:hover,\n &:focus {\n text-decoration: none;\n color: @dropdown-link-hover-color;\n background-color: @dropdown-link-hover-bg;\n }\n}\n\n// Active state\n.dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: @dropdown-link-active-color;\n text-decoration: none;\n outline: 0;\n background-color: @dropdown-link-active-bg;\n }\n}\n\n// Disabled state\n//\n// Gray out text and ensure the hover/focus state remains gray\n\n.dropdown-menu > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @dropdown-link-disabled-color;\n }\n\n // Nuke hover/focus effects\n &:hover,\n &:focus {\n text-decoration: none;\n background-color: transparent;\n background-image: none; // Remove CSS gradient\n .reset-filter();\n cursor: @cursor-disabled;\n }\n}\n\n// Open state for the dropdown\n.open {\n // Show the menu\n > .dropdown-menu {\n display: block;\n }\n\n // Remove the outline when :focus is triggered\n > a {\n outline: 0;\n }\n}\n\n// Menu positioning\n//\n// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown\n// menu with the parent.\n.dropdown-menu-right {\n left: auto; // Reset the default from `.dropdown-menu`\n right: 0;\n}\n// With v3, we enabled auto-flipping if you have a dropdown within a right\n// aligned nav component. To enable the undoing of that, we provide an override\n// to restore the default dropdown menu alignment.\n//\n// This is only for left-aligning a dropdown menu within a `.navbar-right` or\n// `.pull-right` nav component.\n.dropdown-menu-left {\n left: 0;\n right: auto;\n}\n\n// Dropdown section headers\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: @font-size-small;\n line-height: @line-height-base;\n color: @dropdown-header-color;\n white-space: nowrap; // as with > li > a\n}\n\n// Backdrop to catch body clicks on mobile, etc.\n.dropdown-backdrop {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n top: 0;\n z-index: (@zindex-dropdown - 10);\n}\n\n// Right aligned dropdowns\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n\n// Allow for dropdowns to go bottom up (aka, dropup-menu)\n//\n// Just add .dropup after the standard .dropdown class and you're set, bro.\n// TODO: abstract this so that the navbar fixed styles are not placed here?\n\n.dropup,\n.navbar-fixed-bottom .dropdown {\n // Reverse the caret\n .caret {\n border-top: 0;\n border-bottom: @caret-width-base dashed;\n border-bottom: @caret-width-base solid ~\"\\9\"; // IE8\n content: \"\";\n }\n // Different positioning for bottom up menu\n .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 2px;\n }\n}\n\n\n// Component alignment\n//\n// Reiterate per navbar.less and the modified component alignment there.\n\n@media (min-width: @grid-float-breakpoint) {\n .navbar-right {\n .dropdown-menu {\n .dropdown-menu-right();\n }\n // Necessary for overrides of the default right aligned menu.\n // Will remove come v4 in all likelihood.\n .dropdown-menu-left {\n .dropdown-menu-left();\n }\n }\n}\n",
+ "// Horizontal dividers\n//\n// Dividers (basically an hr) within dropdowns and nav lists\n\n.nav-divider(@color: #e5e5e5) {\n height: 1px;\n margin: ((@line-height-computed / 2) - 1) 0;\n overflow: hidden;\n background-color: @color;\n}\n",
+ "// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n",
+ "//\n// Button groups\n// --------------------------------------------------\n\n// Make the div behave like a button\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle; // match .btn alignment given font-size hack above\n > .btn {\n position: relative;\n float: left;\n // Bring the \"active\" button to the front\n &:hover,\n &:focus,\n &:active,\n &.active {\n z-index: 2;\n }\n }\n}\n\n// Prevent double borders when buttons are next to each other\n.btn-group {\n .btn + .btn,\n .btn + .btn-group,\n .btn-group + .btn,\n .btn-group + .btn-group {\n margin-left: -1px;\n }\n}\n\n// Optional: Group multiple button groups together for a toolbar\n.btn-toolbar {\n margin-left: -5px; // Offset the first child's margin\n &:extend(.clearfix all);\n\n .btn,\n .btn-group,\n .input-group {\n float: left;\n }\n > .btn,\n > .btn-group,\n > .input-group {\n margin-left: 5px;\n }\n}\n\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n\n// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match\n.btn-group > .btn:first-child {\n margin-left: 0;\n &:not(:last-child):not(.dropdown-toggle) {\n .border-right-radius(0);\n }\n}\n// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n .border-left-radius(0);\n}\n\n// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group)\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) {\n > .btn:last-child,\n > .dropdown-toggle {\n .border-right-radius(0);\n }\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n .border-left-radius(0);\n}\n\n// On active and open, don't show outline\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n\n\n// Sizing\n//\n// Remix the default button sizing classes into new ones for easier manipulation.\n\n.btn-group-xs > .btn { &:extend(.btn-xs); }\n.btn-group-sm > .btn { &:extend(.btn-sm); }\n.btn-group-lg > .btn { &:extend(.btn-lg); }\n\n\n// Split button dropdowns\n// ----------------------\n\n// Give the line between buttons some depth\n.btn-group > .btn + .dropdown-toggle {\n padding-left: 8px;\n padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-left: 12px;\n padding-right: 12px;\n}\n\n// The clickable button for toggling the menu\n// Remove the gradient and set the same inset shadow as the :active state\n.btn-group.open .dropdown-toggle {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n\n // Show no shadow for `.btn-link` since it has no other button styles.\n &.btn-link {\n .box-shadow(none);\n }\n}\n\n\n// Reposition the caret\n.btn .caret {\n margin-left: 0;\n}\n// Carets in other button sizes\n.btn-lg .caret {\n border-width: @caret-width-large @caret-width-large 0;\n border-bottom-width: 0;\n}\n// Upside down carets for .dropup\n.dropup .btn-lg .caret {\n border-width: 0 @caret-width-large @caret-width-large;\n}\n\n\n// Vertical button groups\n// ----------------------\n\n.btn-group-vertical {\n > .btn,\n > .btn-group,\n > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n }\n\n // Clear floats so dropdown menus can be properly placed\n > .btn-group {\n &:extend(.clearfix all);\n > .btn {\n float: none;\n }\n }\n\n > .btn + .btn,\n > .btn + .btn-group,\n > .btn-group + .btn,\n > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n }\n}\n\n.btn-group-vertical > .btn {\n &:not(:first-child):not(:last-child) {\n border-radius: 0;\n }\n &:first-child:not(:last-child) {\n border-top-right-radius: @btn-border-radius-base;\n .border-bottom-radius(0);\n }\n &:last-child:not(:first-child) {\n border-bottom-left-radius: @btn-border-radius-base;\n .border-top-radius(0);\n }\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) {\n > .btn:last-child,\n > .dropdown-toggle {\n .border-bottom-radius(0);\n }\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n .border-top-radius(0);\n}\n\n\n// Justified button groups\n// ----------------------\n\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n > .btn,\n > .btn-group {\n float: none;\n display: table-cell;\n width: 1%;\n }\n > .btn-group .btn {\n width: 100%;\n }\n\n > .btn-group .dropdown-menu {\n left: auto;\n }\n}\n\n\n// Checkbox and radio options\n//\n// In order to support the browser's form validation feedback, powered by the\n// `required` attribute, we have to \"hide\" the inputs via `clip`. We cannot use\n// `display: none;` or `visibility: hidden;` as that also hides the popover.\n// Simply visually hiding the inputs via `opacity` would leave them clickable in\n// certain cases which is prevented by using `clip` and `pointer-events`.\n// This way, we ensure a DOM element is visible to position the popover from.\n//\n// See https://github.com/twbs/bootstrap/pull/12794 and\n// https://github.com/twbs/bootstrap/pull/14559 for more information.\n\n[data-toggle=\"buttons\"] {\n > .btn,\n > .btn-group > .btn {\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0,0,0,0);\n pointer-events: none;\n }\n }\n}\n",
+ "// Single side border-radius\n\n.border-top-radius(@radius) {\n border-top-right-radius: @radius;\n border-top-left-radius: @radius;\n}\n.border-right-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-top-right-radius: @radius;\n}\n.border-bottom-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-bottom-left-radius: @radius;\n}\n.border-left-radius(@radius) {\n border-bottom-left-radius: @radius;\n border-top-left-radius: @radius;\n}\n",
+ "//\n// Input groups\n// --------------------------------------------------\n\n// Base styles\n// -------------------------\n.input-group {\n position: relative; // For dropdowns\n display: table;\n border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table\n\n // Undo padding and float of grid classes\n &[class*=\"col-\"] {\n float: none;\n padding-left: 0;\n padding-right: 0;\n }\n\n .form-control {\n // Ensure that the input is always above the *appended* addon button for\n // proper border colors.\n position: relative;\n z-index: 2;\n\n // IE9 fubars the placeholder attribute in text inputs and the arrows on\n // select elements in input groups. To fix it, we float the input. Details:\n // https://github.com/twbs/bootstrap/issues/11561#issuecomment-28936855\n float: left;\n\n width: 100%;\n margin-bottom: 0;\n }\n}\n\n// Sizing options\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n .input-lg();\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n .input-sm();\n}\n\n\n// Display as table-cell\n// -------------------------\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n\n &:not(:first-child):not(:last-child) {\n border-radius: 0;\n }\n}\n// Addon and addon wrapper for buttons\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle; // Match the inputs\n}\n\n// Text input groups\n// -------------------------\n.input-group-addon {\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n font-weight: normal;\n line-height: 1;\n color: @input-color;\n text-align: center;\n background-color: @input-group-addon-bg;\n border: 1px solid @input-group-addon-border-color;\n border-radius: @border-radius-base;\n\n // Sizing\n &.input-sm {\n padding: @padding-small-vertical @padding-small-horizontal;\n font-size: @font-size-small;\n border-radius: @border-radius-small;\n }\n &.input-lg {\n padding: @padding-large-vertical @padding-large-horizontal;\n font-size: @font-size-large;\n border-radius: @border-radius-large;\n }\n\n // Nuke default margins from checkboxes and radios to vertically center within.\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n margin-top: 0;\n }\n}\n\n// Reset rounded corners\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n .border-right-radius(0);\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n .border-left-radius(0);\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n\n// Button input groups\n// -------------------------\n.input-group-btn {\n position: relative;\n // Jankily prevent input button groups from wrapping with `white-space` and\n // `font-size` in combination with `inline-block` on buttons.\n font-size: 0;\n white-space: nowrap;\n\n // Negative margin for spacing, position for bringing hovered/focused/actived\n // element above the siblings.\n > .btn {\n position: relative;\n + .btn {\n margin-left: -1px;\n }\n // Bring the \"active\" button to the front\n &:hover,\n &:focus,\n &:active {\n z-index: 2;\n }\n }\n\n // Negative margin to only have a 1px border between the two\n &:first-child {\n > .btn,\n > .btn-group {\n margin-right: -1px;\n }\n }\n &:last-child {\n > .btn,\n > .btn-group {\n z-index: 2;\n margin-left: -1px;\n }\n }\n}\n",
+ "//\n// Navs\n// --------------------------------------------------\n\n\n// Base class\n// --------------------------------------------------\n\n.nav {\n margin-bottom: 0;\n padding-left: 0; // Override default ul/ol\n list-style: none;\n &:extend(.clearfix all);\n\n > li {\n position: relative;\n display: block;\n\n > a {\n position: relative;\n display: block;\n padding: @nav-link-padding;\n &:hover,\n &:focus {\n text-decoration: none;\n background-color: @nav-link-hover-bg;\n }\n }\n\n // Disabled state sets text to gray and nukes hover/tab effects\n &.disabled > a {\n color: @nav-disabled-link-color;\n\n &:hover,\n &:focus {\n color: @nav-disabled-link-hover-color;\n text-decoration: none;\n background-color: transparent;\n cursor: @cursor-disabled;\n }\n }\n }\n\n // Open dropdowns\n .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @nav-link-hover-bg;\n border-color: @link-color;\n }\n }\n\n // Nav dividers (deprecated with v3.0.1)\n //\n // This should have been removed in v3 with the dropping of `.nav-list`, but\n // we missed it. We don't currently support this anywhere, but in the interest\n // of maintaining backward compatibility in case you use it, it's deprecated.\n .nav-divider {\n .nav-divider();\n }\n\n // Prevent IE8 from misplacing imgs\n //\n // See https://github.com/h5bp/html5-boilerplate/issues/984#issuecomment-3985989\n > li > a > img {\n max-width: none;\n }\n}\n\n\n// Tabs\n// -------------------------\n\n// Give the tabs something to sit on\n.nav-tabs {\n border-bottom: 1px solid @nav-tabs-border-color;\n > li {\n float: left;\n // Make the list-items overlay the bottom border\n margin-bottom: -1px;\n\n // Actual tabs (as links)\n > a {\n margin-right: 2px;\n line-height: @line-height-base;\n border: 1px solid transparent;\n border-radius: @border-radius-base @border-radius-base 0 0;\n &:hover {\n border-color: @nav-tabs-link-hover-border-color @nav-tabs-link-hover-border-color @nav-tabs-border-color;\n }\n }\n\n // Active state, and its :hover to override normal :hover\n &.active > a {\n &,\n &:hover,\n &:focus {\n color: @nav-tabs-active-link-hover-color;\n background-color: @nav-tabs-active-link-hover-bg;\n border: 1px solid @nav-tabs-active-link-hover-border-color;\n border-bottom-color: transparent;\n cursor: default;\n }\n }\n }\n // pulling this in mainly for less shorthand\n &.nav-justified {\n .nav-justified();\n .nav-tabs-justified();\n }\n}\n\n\n// Pills\n// -------------------------\n.nav-pills {\n > li {\n float: left;\n\n // Links rendered as pills\n > a {\n border-radius: @nav-pills-border-radius;\n }\n + li {\n margin-left: 2px;\n }\n\n // Active state\n &.active > a {\n &,\n &:hover,\n &:focus {\n color: @nav-pills-active-link-hover-color;\n background-color: @nav-pills-active-link-hover-bg;\n }\n }\n }\n}\n\n\n// Stacked pills\n.nav-stacked {\n > li {\n float: none;\n + li {\n margin-top: 2px;\n margin-left: 0; // no need for this gap between nav items\n }\n }\n}\n\n\n// Nav variations\n// --------------------------------------------------\n\n// Justified nav links\n// -------------------------\n\n.nav-justified {\n width: 100%;\n\n > li {\n float: none;\n > a {\n text-align: center;\n margin-bottom: 5px;\n }\n }\n\n > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n }\n\n @media (min-width: @screen-sm-min) {\n > li {\n display: table-cell;\n width: 1%;\n > a {\n margin-bottom: 0;\n }\n }\n }\n}\n\n// Move borders to anchors instead of bottom of list\n//\n// Mixin for adding on top the shared `.nav-justified` styles for our tabs\n.nav-tabs-justified {\n border-bottom: 0;\n\n > li > a {\n // Override margin from .nav-tabs\n margin-right: 0;\n border-radius: @border-radius-base;\n }\n\n > .active > a,\n > .active > a:hover,\n > .active > a:focus {\n border: 1px solid @nav-tabs-justified-link-border-color;\n }\n\n @media (min-width: @screen-sm-min) {\n > li > a {\n border-bottom: 1px solid @nav-tabs-justified-link-border-color;\n border-radius: @border-radius-base @border-radius-base 0 0;\n }\n > .active > a,\n > .active > a:hover,\n > .active > a:focus {\n border-bottom-color: @nav-tabs-justified-active-link-border-color;\n }\n }\n}\n\n\n// Tabbable tabs\n// -------------------------\n\n// Hide tabbable panes to start, show them when `.active`\n.tab-content {\n > .tab-pane {\n display: none;\n }\n > .active {\n display: block;\n }\n}\n\n\n// Dropdowns\n// -------------------------\n\n// Specific dropdowns\n.nav-tabs .dropdown-menu {\n // make dropdown border overlap tab border\n margin-top: -1px;\n // Remove the top rounded corners here since there is a hard edge above the menu\n .border-top-radius(0);\n}\n",
+ "//\n// Navbars\n// --------------------------------------------------\n\n\n// Wrapper and base class\n//\n// Provide a static navbar from which we expand to create full-width, fixed, and\n// other navbar variations.\n\n.navbar {\n position: relative;\n min-height: @navbar-height; // Ensure a navbar always shows (e.g., without a .navbar-brand in collapsed mode)\n margin-bottom: @navbar-margin-bottom;\n border: 1px solid transparent;\n\n // Prevent floats from breaking the navbar\n &:extend(.clearfix all);\n\n @media (min-width: @grid-float-breakpoint) {\n border-radius: @navbar-border-radius;\n }\n}\n\n\n// Navbar heading\n//\n// Groups `.navbar-brand` and `.navbar-toggle` into a single component for easy\n// styling of responsive aspects.\n\n.navbar-header {\n &:extend(.clearfix all);\n\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n }\n}\n\n\n// Navbar collapse (body)\n//\n// Group your navbar content into this for easy collapsing and expanding across\n// various device sizes. By default, this content is collapsed when <768px, but\n// will expand past that for a horizontal display.\n//\n// To start (on mobile devices) the navbar links, forms, and buttons are stacked\n// vertically and include a `max-height` to overflow in case you have too much\n// content for the user's viewport.\n\n.navbar-collapse {\n overflow-x: visible;\n padding-right: @navbar-padding-horizontal;\n padding-left: @navbar-padding-horizontal;\n border-top: 1px solid transparent;\n box-shadow: inset 0 1px 0 rgba(255,255,255,.1);\n &:extend(.clearfix all);\n -webkit-overflow-scrolling: touch;\n\n &.in {\n overflow-y: auto;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n width: auto;\n border-top: 0;\n box-shadow: none;\n\n &.collapse {\n display: block !important;\n height: auto !important;\n padding-bottom: 0; // Override default setting\n overflow: visible !important;\n }\n\n &.in {\n overflow-y: visible;\n }\n\n // Undo the collapse side padding for navbars with containers to ensure\n // alignment of right-aligned contents.\n .navbar-fixed-top &,\n .navbar-static-top &,\n .navbar-fixed-bottom & {\n padding-left: 0;\n padding-right: 0;\n }\n }\n}\n\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n .navbar-collapse {\n max-height: @navbar-collapse-max-height;\n\n @media (max-device-width: @screen-xs-min) and (orientation: landscape) {\n max-height: 200px;\n }\n }\n}\n\n\n// Both navbar header and collapse\n//\n// When a container is present, change the behavior of the header and collapse.\n\n.container,\n.container-fluid {\n > .navbar-header,\n > .navbar-collapse {\n margin-right: -@navbar-padding-horizontal;\n margin-left: -@navbar-padding-horizontal;\n\n @media (min-width: @grid-float-breakpoint) {\n margin-right: 0;\n margin-left: 0;\n }\n }\n}\n\n\n//\n// Navbar alignment options\n//\n// Display the navbar across the entirety of the page or fixed it to the top or\n// bottom of the page.\n\n// Static top (unfixed, but 100% wide) navbar\n.navbar-static-top {\n z-index: @zindex-navbar;\n border-width: 0 0 1px;\n\n @media (min-width: @grid-float-breakpoint) {\n border-radius: 0;\n }\n}\n\n// Fix the top/bottom navbars when screen real estate supports it\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: @zindex-navbar-fixed;\n\n // Undo the rounded corners\n @media (min-width: @grid-float-breakpoint) {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0; // override .navbar defaults\n border-width: 1px 0 0;\n}\n\n\n// Brand/project name\n\n.navbar-brand {\n float: left;\n padding: @navbar-padding-vertical @navbar-padding-horizontal;\n font-size: @font-size-large;\n line-height: @line-height-computed;\n height: @navbar-height;\n\n &:hover,\n &:focus {\n text-decoration: none;\n }\n\n > img {\n display: block;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n .navbar > .container &,\n .navbar > .container-fluid & {\n margin-left: -@navbar-padding-horizontal;\n }\n }\n}\n\n\n// Navbar toggle\n//\n// Custom button for toggling the `.navbar-collapse`, powered by the collapse\n// JavaScript plugin.\n\n.navbar-toggle {\n position: relative;\n float: right;\n margin-right: @navbar-padding-horizontal;\n padding: 9px 10px;\n .navbar-vertical-align(34px);\n background-color: transparent;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid transparent;\n border-radius: @border-radius-base;\n\n // We remove the `outline` here, but later compensate by attaching `:hover`\n // styles to `:focus`.\n &:focus {\n outline: 0;\n }\n\n // Bars\n .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n }\n .icon-bar + .icon-bar {\n margin-top: 4px;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n display: none;\n }\n}\n\n\n// Navbar nav links\n//\n// Builds on top of the `.nav` components with its own modifier class to make\n// the nav the full height of the horizontal nav (above 768px).\n\n.navbar-nav {\n margin: (@navbar-padding-vertical / 2) -@navbar-padding-horizontal;\n\n > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: @line-height-computed;\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display when collapsed\n .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n > li > a,\n .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n > li > a {\n line-height: @line-height-computed;\n &:hover,\n &:focus {\n background-image: none;\n }\n }\n }\n }\n\n // Uncollapse the nav\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n margin: 0;\n\n > li {\n float: left;\n > a {\n padding-top: @navbar-padding-vertical;\n padding-bottom: @navbar-padding-vertical;\n }\n }\n }\n}\n\n\n// Navbar form\n//\n// Extension of the `.form-inline` with some extra flavor for optimum display in\n// our navbars.\n\n.navbar-form {\n margin-left: -@navbar-padding-horizontal;\n margin-right: -@navbar-padding-horizontal;\n padding: 10px @navbar-padding-horizontal;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n @shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n\n // Mixin behavior for optimum display\n .form-inline();\n\n .form-group {\n @media (max-width: @grid-float-breakpoint-max) {\n margin-bottom: 5px;\n\n &:last-child {\n margin-bottom: 0;\n }\n }\n }\n\n // Vertically center in expanded, horizontal navbar\n .navbar-vertical-align(@input-height-base);\n\n // Undo 100% width for pull classes\n @media (min-width: @grid-float-breakpoint) {\n width: auto;\n border: 0;\n margin-left: 0;\n margin-right: 0;\n padding-top: 0;\n padding-bottom: 0;\n .box-shadow(none);\n }\n}\n\n\n// Dropdown menus\n\n// Menu position and menu carets\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n .border-top-radius(0);\n}\n// Menu position and menu caret support for dropups via extra dropup class\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n margin-bottom: 0;\n .border-top-radius(@navbar-border-radius);\n .border-bottom-radius(0);\n}\n\n\n// Buttons in navbars\n//\n// Vertically center a button within a navbar (when *not* in a form).\n\n.navbar-btn {\n .navbar-vertical-align(@input-height-base);\n\n &.btn-sm {\n .navbar-vertical-align(@input-height-small);\n }\n &.btn-xs {\n .navbar-vertical-align(22);\n }\n}\n\n\n// Text in navbars\n//\n// Add a class to make any element properly align itself vertically within the navbars.\n\n.navbar-text {\n .navbar-vertical-align(@line-height-computed);\n\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n margin-left: @navbar-padding-horizontal;\n margin-right: @navbar-padding-horizontal;\n }\n}\n\n\n// Component alignment\n//\n// Repurpose the pull utilities as their own navbar utilities to avoid specificity\n// issues with parents and chaining. Only do this when the navbar is uncollapsed\n// though so that navbar contents properly stack and align in mobile.\n//\n// Declared after the navbar components to ensure more specificity on the margins.\n\n@media (min-width: @grid-float-breakpoint) {\n .navbar-left { .pull-left(); }\n .navbar-right {\n .pull-right();\n margin-right: -@navbar-padding-horizontal;\n\n ~ .navbar-right {\n margin-right: 0;\n }\n }\n}\n\n\n// Alternate navbars\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n background-color: @navbar-default-bg;\n border-color: @navbar-default-border;\n\n .navbar-brand {\n color: @navbar-default-brand-color;\n &:hover,\n &:focus {\n color: @navbar-default-brand-hover-color;\n background-color: @navbar-default-brand-hover-bg;\n }\n }\n\n .navbar-text {\n color: @navbar-default-color;\n }\n\n .navbar-nav {\n > li > a {\n color: @navbar-default-link-color;\n\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n background-color: @navbar-default-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-active-color;\n background-color: @navbar-default-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n background-color: @navbar-default-link-disabled-bg;\n }\n }\n }\n\n .navbar-toggle {\n border-color: @navbar-default-toggle-border-color;\n &:hover,\n &:focus {\n background-color: @navbar-default-toggle-hover-bg;\n }\n .icon-bar {\n background-color: @navbar-default-toggle-icon-bar-bg;\n }\n }\n\n .navbar-collapse,\n .navbar-form {\n border-color: @navbar-default-border;\n }\n\n // Dropdown menu items\n .navbar-nav {\n // Remove background color from open dropdown\n > .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @navbar-default-link-active-bg;\n color: @navbar-default-link-active-color;\n }\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display when collapsed\n .open .dropdown-menu {\n > li > a {\n color: @navbar-default-link-color;\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n background-color: @navbar-default-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-active-color;\n background-color: @navbar-default-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n background-color: @navbar-default-link-disabled-bg;\n }\n }\n }\n }\n }\n\n\n // Links in navbars\n //\n // Add a class to ensure links outside the navbar nav are colored correctly.\n\n .navbar-link {\n color: @navbar-default-link-color;\n &:hover {\n color: @navbar-default-link-hover-color;\n }\n }\n\n .btn-link {\n color: @navbar-default-link-color;\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n }\n }\n }\n}\n\n// Inverse navbar\n\n.navbar-inverse {\n background-color: @navbar-inverse-bg;\n border-color: @navbar-inverse-border;\n\n .navbar-brand {\n color: @navbar-inverse-brand-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-brand-hover-color;\n background-color: @navbar-inverse-brand-hover-bg;\n }\n }\n\n .navbar-text {\n color: @navbar-inverse-color;\n }\n\n .navbar-nav {\n > li > a {\n color: @navbar-inverse-link-color;\n\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n background-color: @navbar-inverse-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-active-color;\n background-color: @navbar-inverse-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n background-color: @navbar-inverse-link-disabled-bg;\n }\n }\n }\n\n // Darken the responsive nav toggle\n .navbar-toggle {\n border-color: @navbar-inverse-toggle-border-color;\n &:hover,\n &:focus {\n background-color: @navbar-inverse-toggle-hover-bg;\n }\n .icon-bar {\n background-color: @navbar-inverse-toggle-icon-bar-bg;\n }\n }\n\n .navbar-collapse,\n .navbar-form {\n border-color: darken(@navbar-inverse-bg, 7%);\n }\n\n // Dropdowns\n .navbar-nav {\n > .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @navbar-inverse-link-active-bg;\n color: @navbar-inverse-link-active-color;\n }\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display\n .open .dropdown-menu {\n > .dropdown-header {\n border-color: @navbar-inverse-border;\n }\n .divider {\n background-color: @navbar-inverse-border;\n }\n > li > a {\n color: @navbar-inverse-link-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n background-color: @navbar-inverse-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-active-color;\n background-color: @navbar-inverse-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n background-color: @navbar-inverse-link-disabled-bg;\n }\n }\n }\n }\n }\n\n .navbar-link {\n color: @navbar-inverse-link-color;\n &:hover {\n color: @navbar-inverse-link-hover-color;\n }\n }\n\n .btn-link {\n color: @navbar-inverse-link-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n }\n }\n }\n}\n",
+ "// Navbar vertical align\n//\n// Vertically center elements in the navbar.\n// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.\n\n.navbar-vertical-align(@element-height) {\n margin-top: ((@navbar-height - @element-height) / 2);\n margin-bottom: ((@navbar-height - @element-height) / 2);\n}\n",
+ "//\n// Utility classes\n// --------------------------------------------------\n\n\n// Floats\n// -------------------------\n\n.clearfix {\n .clearfix();\n}\n.center-block {\n .center-block();\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n\n\n// Toggling content\n// -------------------------\n\n// Note: Deprecated .hide in favor of .hidden or .sr-only (as appropriate) in v3.0.1\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n .text-hide();\n}\n\n\n// Hide from screenreaders and browsers\n//\n// Credit: HTML5 Boilerplate\n\n.hidden {\n display: none !important;\n}\n\n\n// For Affix plugin\n// -------------------------\n\n.affix {\n position: fixed;\n}\n",
+ "//\n// Breadcrumbs\n// --------------------------------------------------\n\n\n.breadcrumb {\n padding: @breadcrumb-padding-vertical @breadcrumb-padding-horizontal;\n margin-bottom: @line-height-computed;\n list-style: none;\n background-color: @breadcrumb-bg;\n border-radius: @border-radius-base;\n\n > li {\n display: inline-block;\n\n + li:before {\n content: \"@{breadcrumb-separator}\\00a0\"; // Unicode space added since inline-block means non-collapsing white-space\n padding: 0 5px;\n color: @breadcrumb-color;\n }\n }\n\n > .active {\n color: @breadcrumb-active-color;\n }\n}\n",
+ "//\n// Pagination (multiple pages)\n// --------------------------------------------------\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: @line-height-computed 0;\n border-radius: @border-radius-base;\n\n > li {\n display: inline; // Remove list-style and block-level defaults\n > a,\n > span {\n position: relative;\n float: left; // Collapse white-space\n padding: @padding-base-vertical @padding-base-horizontal;\n line-height: @line-height-base;\n text-decoration: none;\n color: @pagination-color;\n background-color: @pagination-bg;\n border: 1px solid @pagination-border;\n margin-left: -1px;\n }\n &:first-child {\n > a,\n > span {\n margin-left: 0;\n .border-left-radius(@border-radius-base);\n }\n }\n &:last-child {\n > a,\n > span {\n .border-right-radius(@border-radius-base);\n }\n }\n }\n\n > li > a,\n > li > span {\n &:hover,\n &:focus {\n z-index: 3;\n color: @pagination-hover-color;\n background-color: @pagination-hover-bg;\n border-color: @pagination-hover-border;\n }\n }\n\n > .active > a,\n > .active > span {\n &,\n &:hover,\n &:focus {\n z-index: 2;\n color: @pagination-active-color;\n background-color: @pagination-active-bg;\n border-color: @pagination-active-border;\n cursor: default;\n }\n }\n\n > .disabled {\n > span,\n > span:hover,\n > span:focus,\n > a,\n > a:hover,\n > a:focus {\n color: @pagination-disabled-color;\n background-color: @pagination-disabled-bg;\n border-color: @pagination-disabled-border;\n cursor: @cursor-disabled;\n }\n }\n}\n\n// Sizing\n// --------------------------------------------------\n\n// Large\n.pagination-lg {\n .pagination-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);\n}\n\n// Small\n.pagination-sm {\n .pagination-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n",
+ "// Pagination\n\n.pagination-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n > li {\n > a,\n > span {\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n }\n &:first-child {\n > a,\n > span {\n .border-left-radius(@border-radius);\n }\n }\n &:last-child {\n > a,\n > span {\n .border-right-radius(@border-radius);\n }\n }\n }\n}\n",
+ "//\n// Pager pagination\n// --------------------------------------------------\n\n\n.pager {\n padding-left: 0;\n margin: @line-height-computed 0;\n list-style: none;\n text-align: center;\n &:extend(.clearfix all);\n li {\n display: inline;\n > a,\n > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: @pager-bg;\n border: 1px solid @pager-border;\n border-radius: @pager-border-radius;\n }\n\n > a:hover,\n > a:focus {\n text-decoration: none;\n background-color: @pager-hover-bg;\n }\n }\n\n .next {\n > a,\n > span {\n float: right;\n }\n }\n\n .previous {\n > a,\n > span {\n float: left;\n }\n }\n\n .disabled {\n > a,\n > a:hover,\n > a:focus,\n > span {\n color: @pager-disabled-color;\n background-color: @pager-bg;\n cursor: @cursor-disabled;\n }\n }\n}\n",
+ "//\n// Labels\n// --------------------------------------------------\n\n.label {\n display: inline;\n padding: .2em .6em .3em;\n font-size: 75%;\n font-weight: bold;\n line-height: 1;\n color: @label-color;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: .25em;\n\n // Add hover effects, but only for links\n a& {\n &:hover,\n &:focus {\n color: @label-link-hover-color;\n text-decoration: none;\n cursor: pointer;\n }\n }\n\n // Empty labels collapse automatically (not available in IE8)\n &:empty {\n display: none;\n }\n\n // Quick fix for labels in buttons\n .btn & {\n position: relative;\n top: -1px;\n }\n}\n\n// Colors\n// Contextual variations (linked labels get darker on :hover)\n\n.label-default {\n .label-variant(@label-default-bg);\n}\n\n.label-primary {\n .label-variant(@label-primary-bg);\n}\n\n.label-success {\n .label-variant(@label-success-bg);\n}\n\n.label-info {\n .label-variant(@label-info-bg);\n}\n\n.label-warning {\n .label-variant(@label-warning-bg);\n}\n\n.label-danger {\n .label-variant(@label-danger-bg);\n}\n",
+ "// Labels\n\n.label-variant(@color) {\n background-color: @color;\n\n &[href] {\n &:hover,\n &:focus {\n background-color: darken(@color, 10%);\n }\n }\n}\n",
+ "//\n// Badges\n// --------------------------------------------------\n\n\n// Base class\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: @font-size-small;\n font-weight: @badge-font-weight;\n color: @badge-color;\n line-height: @badge-line-height;\n vertical-align: middle;\n white-space: nowrap;\n text-align: center;\n background-color: @badge-bg;\n border-radius: @badge-border-radius;\n\n // Empty badges collapse automatically (not available in IE8)\n &:empty {\n display: none;\n }\n\n // Quick fix for badges in buttons\n .btn & {\n position: relative;\n top: -1px;\n }\n\n .btn-xs &,\n .btn-group-xs > .btn & {\n top: 0;\n padding: 1px 5px;\n }\n\n // Hover state, but only for links\n a& {\n &:hover,\n &:focus {\n color: @badge-link-hover-color;\n text-decoration: none;\n cursor: pointer;\n }\n }\n\n // Account for badges in navs\n .list-group-item.active > &,\n .nav-pills > .active > a > & {\n color: @badge-active-color;\n background-color: @badge-active-bg;\n }\n\n .list-group-item > & {\n float: right;\n }\n\n .list-group-item > & + & {\n margin-right: 5px;\n }\n\n .nav-pills > li > a > & {\n margin-left: 3px;\n }\n}\n",
+ "//\n// Jumbotron\n// --------------------------------------------------\n\n\n.jumbotron {\n padding-top: @jumbotron-padding;\n padding-bottom: @jumbotron-padding;\n margin-bottom: @jumbotron-padding;\n color: @jumbotron-color;\n background-color: @jumbotron-bg;\n\n h1,\n .h1 {\n color: @jumbotron-heading-color;\n }\n\n p {\n margin-bottom: (@jumbotron-padding / 2);\n font-size: @jumbotron-font-size;\n font-weight: 200;\n }\n\n > hr {\n border-top-color: darken(@jumbotron-bg, 10%);\n }\n\n .container &,\n .container-fluid & {\n border-radius: @border-radius-large; // Only round corners at higher resolutions if contained in a container\n }\n\n .container {\n max-width: 100%;\n }\n\n @media screen and (min-width: @screen-sm-min) {\n padding-top: (@jumbotron-padding * 1.6);\n padding-bottom: (@jumbotron-padding * 1.6);\n\n .container &,\n .container-fluid & {\n padding-left: (@jumbotron-padding * 2);\n padding-right: (@jumbotron-padding * 2);\n }\n\n h1,\n .h1 {\n font-size: @jumbotron-heading-font-size;\n }\n }\n}\n",
+ "//\n// Thumbnails\n// --------------------------------------------------\n\n\n// Mixin and adjust the regular image class\n.thumbnail {\n display: block;\n padding: @thumbnail-padding;\n margin-bottom: @line-height-computed;\n line-height: @line-height-base;\n background-color: @thumbnail-bg;\n border: 1px solid @thumbnail-border;\n border-radius: @thumbnail-border-radius;\n .transition(border .2s ease-in-out);\n\n > img,\n a > img {\n &:extend(.img-responsive);\n margin-left: auto;\n margin-right: auto;\n }\n\n // Add a hover state for linked versions only\n a&:hover,\n a&:focus,\n a&.active {\n border-color: @link-color;\n }\n\n // Image captions\n .caption {\n padding: @thumbnail-caption-padding;\n color: @thumbnail-caption-color;\n }\n}\n",
+ "//\n// Alerts\n// --------------------------------------------------\n\n\n// Base styles\n// -------------------------\n\n.alert {\n padding: @alert-padding;\n margin-bottom: @line-height-computed;\n border: 1px solid transparent;\n border-radius: @alert-border-radius;\n\n // Headings for larger alerts\n h4 {\n margin-top: 0;\n // Specified for the h4 to prevent conflicts of changing @headings-color\n color: inherit;\n }\n\n // Provide class for links that match alerts\n .alert-link {\n font-weight: @alert-link-font-weight;\n }\n\n // Improve alignment and spacing of inner content\n > p,\n > ul {\n margin-bottom: 0;\n }\n\n > p + p {\n margin-top: 5px;\n }\n}\n\n// Dismissible alerts\n//\n// Expand the right padding and account for the close button's positioning.\n\n.alert-dismissable, // The misspelled .alert-dismissable was deprecated in 3.2.0.\n.alert-dismissible {\n padding-right: (@alert-padding + 20);\n\n // Adjust close link position\n .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n }\n}\n\n// Alternate styles\n//\n// Generate contextual modifier classes for colorizing the alert.\n\n.alert-success {\n .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text);\n}\n\n.alert-info {\n .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text);\n}\n\n.alert-warning {\n .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text);\n}\n\n.alert-danger {\n .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text);\n}\n",
+ "// Alerts\n\n.alert-variant(@background; @border; @text-color) {\n background-color: @background;\n border-color: @border;\n color: @text-color;\n\n hr {\n border-top-color: darken(@border, 5%);\n }\n .alert-link {\n color: darken(@text-color, 10%);\n }\n}\n",
+ "//\n// Progress bars\n// --------------------------------------------------\n\n\n// Bar animations\n// -------------------------\n\n// WebKit\n@-webkit-keyframes progress-bar-stripes {\n from { background-position: 40px 0; }\n to { background-position: 0 0; }\n}\n\n// Spec and IE10+\n@keyframes progress-bar-stripes {\n from { background-position: 40px 0; }\n to { background-position: 0 0; }\n}\n\n\n// Bar itself\n// -------------------------\n\n// Outer container\n.progress {\n overflow: hidden;\n height: @line-height-computed;\n margin-bottom: @line-height-computed;\n background-color: @progress-bg;\n border-radius: @progress-border-radius;\n .box-shadow(inset 0 1px 2px rgba(0,0,0,.1));\n}\n\n// Bar of progress\n.progress-bar {\n float: left;\n width: 0%;\n height: 100%;\n font-size: @font-size-small;\n line-height: @line-height-computed;\n color: @progress-bar-color;\n text-align: center;\n background-color: @progress-bar-bg;\n .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15));\n .transition(width .6s ease);\n}\n\n// Striped bars\n//\n// `.progress-striped .progress-bar` is deprecated as of v3.2.0 in favor of the\n// `.progress-bar-striped` class, which you just add to an existing\n// `.progress-bar`.\n.progress-striped .progress-bar,\n.progress-bar-striped {\n #gradient > .striped();\n background-size: 40px 40px;\n}\n\n// Call animation for the active one\n//\n// `.progress.active .progress-bar` is deprecated as of v3.2.0 in favor of the\n// `.progress-bar.active` approach.\n.progress.active .progress-bar,\n.progress-bar.active {\n .animation(progress-bar-stripes 2s linear infinite);\n}\n\n\n// Variations\n// -------------------------\n\n.progress-bar-success {\n .progress-bar-variant(@progress-bar-success-bg);\n}\n\n.progress-bar-info {\n .progress-bar-variant(@progress-bar-info-bg);\n}\n\n.progress-bar-warning {\n .progress-bar-variant(@progress-bar-warning-bg);\n}\n\n.progress-bar-danger {\n .progress-bar-variant(@progress-bar-danger-bg);\n}\n",
+ "// Gradients\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n",
+ "// Progress bars\n\n.progress-bar-variant(@color) {\n background-color: @color;\n\n // Deprecated parent class requirement as of v3.2.0\n .progress-striped & {\n #gradient > .striped();\n }\n}\n",
+ ".media {\n // Proper spacing between instances of .media\n margin-top: 15px;\n\n &:first-child {\n margin-top: 0;\n }\n}\n\n.media,\n.media-body {\n zoom: 1;\n overflow: hidden;\n}\n\n.media-body {\n width: 10000px;\n}\n\n.media-object {\n display: block;\n\n // Fix collapse in webkit from max-width: 100% and display: table-cell.\n &.img-thumbnail {\n max-width: none;\n }\n}\n\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n\n.media-middle {\n vertical-align: middle;\n}\n\n.media-bottom {\n vertical-align: bottom;\n}\n\n// Reset margins on headings for tighter default spacing\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n\n// Media list variation\n//\n// Undo default ul/ol styles\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n",
+ "//\n// List groups\n// --------------------------------------------------\n\n\n// Base class\n//\n// Easily usable on <ul>, <ol>, or <div>.\n\n.list-group {\n // No need to set list-style: none; since .list-group-item is block level\n margin-bottom: 20px;\n padding-left: 0; // reset padding because ul and ol\n}\n\n\n// Individual list items\n//\n// Use on `li`s or `div`s within the `.list-group` parent.\n\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n // Place the border on the list items and negative margin up for better styling\n margin-bottom: -1px;\n background-color: @list-group-bg;\n border: 1px solid @list-group-border;\n\n // Round the first and last items\n &:first-child {\n .border-top-radius(@list-group-border-radius);\n }\n &:last-child {\n margin-bottom: 0;\n .border-bottom-radius(@list-group-border-radius);\n }\n}\n\n\n// Interactive list items\n//\n// Use anchor or button elements instead of `li`s or `div`s to create interactive items.\n// Includes an extra `.active` modifier class for showing selected items.\n\na.list-group-item,\nbutton.list-group-item {\n color: @list-group-link-color;\n\n .list-group-item-heading {\n color: @list-group-link-heading-color;\n }\n\n // Hover state\n &:hover,\n &:focus {\n text-decoration: none;\n color: @list-group-link-hover-color;\n background-color: @list-group-hover-bg;\n }\n}\n\nbutton.list-group-item {\n width: 100%;\n text-align: left;\n}\n\n.list-group-item {\n // Disabled state\n &.disabled,\n &.disabled:hover,\n &.disabled:focus {\n background-color: @list-group-disabled-bg;\n color: @list-group-disabled-color;\n cursor: @cursor-disabled;\n\n // Force color to inherit for custom content\n .list-group-item-heading {\n color: inherit;\n }\n .list-group-item-text {\n color: @list-group-disabled-text-color;\n }\n }\n\n // Active class on item itself, not parent\n &.active,\n &.active:hover,\n &.active:focus {\n z-index: 2; // Place active items above their siblings for proper border styling\n color: @list-group-active-color;\n background-color: @list-group-active-bg;\n border-color: @list-group-active-border;\n\n // Force color to inherit for custom content\n .list-group-item-heading,\n .list-group-item-heading > small,\n .list-group-item-heading > .small {\n color: inherit;\n }\n .list-group-item-text {\n color: @list-group-active-text-color;\n }\n }\n}\n\n\n// Contextual variants\n//\n// Add modifier classes to change text and background color on individual items.\n// Organizationally, this must come after the `:hover` states.\n\n.list-group-item-variant(success; @state-success-bg; @state-success-text);\n.list-group-item-variant(info; @state-info-bg; @state-info-text);\n.list-group-item-variant(warning; @state-warning-bg; @state-warning-text);\n.list-group-item-variant(danger; @state-danger-bg; @state-danger-text);\n\n\n// Custom content options\n//\n// Extra classes for creating well-formatted content within `.list-group-item`s.\n\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n",
+ "// List Groups\n\n.list-group-item-variant(@state; @background; @color) {\n .list-group-item-@{state} {\n color: @color;\n background-color: @background;\n\n a&,\n button& {\n color: @color;\n\n .list-group-item-heading {\n color: inherit;\n }\n\n &:hover,\n &:focus {\n color: @color;\n background-color: darken(@background, 5%);\n }\n &.active,\n &.active:hover,\n &.active:focus {\n color: #fff;\n background-color: @color;\n border-color: @color;\n }\n }\n }\n}\n",
+ "//\n// Panels\n// --------------------------------------------------\n\n\n// Base class\n.panel {\n margin-bottom: @line-height-computed;\n background-color: @panel-bg;\n border: 1px solid transparent;\n border-radius: @panel-border-radius;\n .box-shadow(0 1px 1px rgba(0,0,0,.05));\n}\n\n// Panel contents\n.panel-body {\n padding: @panel-body-padding;\n &:extend(.clearfix all);\n}\n\n// Optional heading\n.panel-heading {\n padding: @panel-heading-padding;\n border-bottom: 1px solid transparent;\n .border-top-radius((@panel-border-radius - 1));\n\n > .dropdown .dropdown-toggle {\n color: inherit;\n }\n}\n\n// Within heading, strip any `h*` tag of its default margins for spacing.\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: ceil((@font-size-base * 1.125));\n color: inherit;\n\n > a,\n > small,\n > .small,\n > small > a,\n > .small > a {\n color: inherit;\n }\n}\n\n// Optional footer (stays gray in every modifier class)\n.panel-footer {\n padding: @panel-footer-padding;\n background-color: @panel-footer-bg;\n border-top: 1px solid @panel-inner-border;\n .border-bottom-radius((@panel-border-radius - 1));\n}\n\n\n// List groups in panels\n//\n// By default, space out list group content from panel headings to account for\n// any kind of custom content between the two.\n\n.panel {\n > .list-group,\n > .panel-collapse > .list-group {\n margin-bottom: 0;\n\n .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n }\n\n // Add border top radius for first one\n &:first-child {\n .list-group-item:first-child {\n border-top: 0;\n .border-top-radius((@panel-border-radius - 1));\n }\n }\n\n // Add border bottom radius for last one\n &:last-child {\n .list-group-item:last-child {\n border-bottom: 0;\n .border-bottom-radius((@panel-border-radius - 1));\n }\n }\n }\n > .panel-heading + .panel-collapse > .list-group {\n .list-group-item:first-child {\n .border-top-radius(0);\n }\n }\n}\n// Collapse space between when there's no additional content.\n.panel-heading + .list-group {\n .list-group-item:first-child {\n border-top-width: 0;\n }\n}\n.list-group + .panel-footer {\n border-top-width: 0;\n}\n\n// Tables in panels\n//\n// Place a non-bordered `.table` within a panel (not within a `.panel-body`) and\n// watch it go full width.\n\n.panel {\n > .table,\n > .table-responsive > .table,\n > .panel-collapse > .table {\n margin-bottom: 0;\n\n caption {\n padding-left: @panel-body-padding;\n padding-right: @panel-body-padding;\n }\n }\n // Add border top radius for first one\n > .table:first-child,\n > .table-responsive:first-child > .table:first-child {\n .border-top-radius((@panel-border-radius - 1));\n\n > thead:first-child,\n > tbody:first-child {\n > tr:first-child {\n border-top-left-radius: (@panel-border-radius - 1);\n border-top-right-radius: (@panel-border-radius - 1);\n\n td:first-child,\n th:first-child {\n border-top-left-radius: (@panel-border-radius - 1);\n }\n td:last-child,\n th:last-child {\n border-top-right-radius: (@panel-border-radius - 1);\n }\n }\n }\n }\n // Add border bottom radius for last one\n > .table:last-child,\n > .table-responsive:last-child > .table:last-child {\n .border-bottom-radius((@panel-border-radius - 1));\n\n > tbody:last-child,\n > tfoot:last-child {\n > tr:last-child {\n border-bottom-left-radius: (@panel-border-radius - 1);\n border-bottom-right-radius: (@panel-border-radius - 1);\n\n td:first-child,\n th:first-child {\n border-bottom-left-radius: (@panel-border-radius - 1);\n }\n td:last-child,\n th:last-child {\n border-bottom-right-radius: (@panel-border-radius - 1);\n }\n }\n }\n }\n > .panel-body + .table,\n > .panel-body + .table-responsive,\n > .table + .panel-body,\n > .table-responsive + .panel-body {\n border-top: 1px solid @table-border-color;\n }\n > .table > tbody:first-child > tr:first-child th,\n > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n }\n > .table-bordered,\n > .table-responsive > .table-bordered {\n border: 0;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n > thead,\n > tbody {\n > tr:first-child {\n > td,\n > th {\n border-bottom: 0;\n }\n }\n }\n > tbody,\n > tfoot {\n > tr:last-child {\n > td,\n > th {\n border-bottom: 0;\n }\n }\n }\n }\n > .table-responsive {\n border: 0;\n margin-bottom: 0;\n }\n}\n\n\n// Collapsable panels (aka, accordion)\n//\n// Wrap a series of panels in `.panel-group` to turn them into an accordion with\n// the help of our collapse JavaScript plugin.\n\n.panel-group {\n margin-bottom: @line-height-computed;\n\n // Tighten up margin so it's only between panels\n .panel {\n margin-bottom: 0;\n border-radius: @panel-border-radius;\n\n + .panel {\n margin-top: 5px;\n }\n }\n\n .panel-heading {\n border-bottom: 0;\n\n + .panel-collapse > .panel-body,\n + .panel-collapse > .list-group {\n border-top: 1px solid @panel-inner-border;\n }\n }\n\n .panel-footer {\n border-top: 0;\n + .panel-collapse .panel-body {\n border-bottom: 1px solid @panel-inner-border;\n }\n }\n}\n\n\n// Contextual variations\n.panel-default {\n .panel-variant(@panel-default-border; @panel-default-text; @panel-default-heading-bg; @panel-default-border);\n}\n.panel-primary {\n .panel-variant(@panel-primary-border; @panel-primary-text; @panel-primary-heading-bg; @panel-primary-border);\n}\n.panel-success {\n .panel-variant(@panel-success-border; @panel-success-text; @panel-success-heading-bg; @panel-success-border);\n}\n.panel-info {\n .panel-variant(@panel-info-border; @panel-info-text; @panel-info-heading-bg; @panel-info-border);\n}\n.panel-warning {\n .panel-variant(@panel-warning-border; @panel-warning-text; @panel-warning-heading-bg; @panel-warning-border);\n}\n.panel-danger {\n .panel-variant(@panel-danger-border; @panel-danger-text; @panel-danger-heading-bg; @panel-danger-border);\n}\n",
+ "// Panels\n\n.panel-variant(@border; @heading-text-color; @heading-bg-color; @heading-border) {\n border-color: @border;\n\n & > .panel-heading {\n color: @heading-text-color;\n background-color: @heading-bg-color;\n border-color: @heading-border;\n\n + .panel-collapse > .panel-body {\n border-top-color: @border;\n }\n .badge {\n color: @heading-bg-color;\n background-color: @heading-text-color;\n }\n }\n & > .panel-footer {\n + .panel-collapse > .panel-body {\n border-bottom-color: @border;\n }\n }\n}\n",
+ "// Embeds responsive\n//\n// Credit: Nicolas Gallagher and SUIT CSS.\n\n.embed-responsive {\n position: relative;\n display: block;\n height: 0;\n padding: 0;\n overflow: hidden;\n\n .embed-responsive-item,\n iframe,\n embed,\n object,\n video {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n height: 100%;\n width: 100%;\n border: 0;\n }\n}\n\n// Modifier class for 16:9 aspect ratio\n.embed-responsive-16by9 {\n padding-bottom: 56.25%;\n}\n\n// Modifier class for 4:3 aspect ratio\n.embed-responsive-4by3 {\n padding-bottom: 75%;\n}\n",
+ "//\n// Wells\n// --------------------------------------------------\n\n\n// Base class\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: @well-bg;\n border: 1px solid @well-border;\n border-radius: @border-radius-base;\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.05));\n blockquote {\n border-color: #ddd;\n border-color: rgba(0,0,0,.15);\n }\n}\n\n// Sizes\n.well-lg {\n padding: 24px;\n border-radius: @border-radius-large;\n}\n.well-sm {\n padding: 9px;\n border-radius: @border-radius-small;\n}\n",
+ "//\n// Close icons\n// --------------------------------------------------\n\n\n.close {\n float: right;\n font-size: (@font-size-base * 1.5);\n font-weight: @close-font-weight;\n line-height: 1;\n color: @close-color;\n text-shadow: @close-text-shadow;\n .opacity(.2);\n\n &:hover,\n &:focus {\n color: @close-color;\n text-decoration: none;\n cursor: pointer;\n .opacity(.5);\n }\n\n // Additional properties for button version\n // iOS requires the button element instead of an anchor tag.\n // If you want the anchor version, it requires `href=\"#\"`.\n // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n button& {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n }\n}\n",
+ "//\n// Modals\n// --------------------------------------------------\n\n// .modal-open - body class for killing the scroll\n// .modal - container to scroll within\n// .modal-dialog - positioning shell for the actual modal\n// .modal-content - actual modal w/ bg and corners and shit\n\n// Kill the scroll on the body\n.modal-open {\n overflow: hidden;\n}\n\n// Container that the modal scrolls within\n.modal {\n display: none;\n overflow: hidden;\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: @zindex-modal;\n -webkit-overflow-scrolling: touch;\n\n // Prevent Chrome on Windows from adding a focus outline. For details, see\n // https://github.com/twbs/bootstrap/pull/10951.\n outline: 0;\n\n // When fading in the modal, animate it to slide down\n &.fade .modal-dialog {\n .translate(0, -25%);\n .transition-transform(~\"0.3s ease-out\");\n }\n &.in .modal-dialog { .translate(0, 0) }\n}\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n// Shell div to position the modal with bottom padding\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n\n// Actual modal\n.modal-content {\n position: relative;\n background-color: @modal-content-bg;\n border: 1px solid @modal-content-fallback-border-color; //old browsers fallback (ie8 etc)\n border: 1px solid @modal-content-border-color;\n border-radius: @border-radius-large;\n .box-shadow(0 3px 9px rgba(0,0,0,.5));\n background-clip: padding-box;\n // Remove focus outline from opened modal\n outline: 0;\n}\n\n// Modal background\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: @zindex-modal-background;\n background-color: @modal-backdrop-bg;\n // Fade for backdrop\n &.fade { .opacity(0); }\n &.in { .opacity(@modal-backdrop-opacity); }\n}\n\n// Modal header\n// Top section of the modal w/ title and dismiss\n.modal-header {\n padding: @modal-title-padding;\n border-bottom: 1px solid @modal-header-border-color;\n min-height: (@modal-title-padding + @modal-title-line-height);\n}\n// Close icon\n.modal-header .close {\n margin-top: -2px;\n}\n\n// Title text within header\n.modal-title {\n margin: 0;\n line-height: @modal-title-line-height;\n}\n\n// Modal body\n// Where all modal content resides (sibling of .modal-header and .modal-footer)\n.modal-body {\n position: relative;\n padding: @modal-inner-padding;\n}\n\n// Footer (for actions)\n.modal-footer {\n padding: @modal-inner-padding;\n text-align: right; // right align buttons\n border-top: 1px solid @modal-footer-border-color;\n &:extend(.clearfix all); // clear it in case folks use .pull-* classes on buttons\n\n // Properly space out buttons\n .btn + .btn {\n margin-left: 5px;\n margin-bottom: 0; // account for input[type=\"submit\"] which gets the bottom margin like all other inputs\n }\n // but override that for button groups\n .btn-group .btn + .btn {\n margin-left: -1px;\n }\n // and override it for block buttons as well\n .btn-block + .btn-block {\n margin-left: 0;\n }\n}\n\n// Measure scrollbar width for padding body during modal show/hide\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n\n// Scale up the modal\n@media (min-width: @screen-sm-min) {\n // Automatically set modal's width for larger viewports\n .modal-dialog {\n width: @modal-md;\n margin: 30px auto;\n }\n .modal-content {\n .box-shadow(0 5px 15px rgba(0,0,0,.5));\n }\n\n // Modal sizes\n .modal-sm { width: @modal-sm; }\n}\n\n@media (min-width: @screen-md-min) {\n .modal-lg { width: @modal-lg; }\n}\n",
+ "//\n// Tooltips\n// --------------------------------------------------\n\n\n// Base class\n.tooltip {\n position: absolute;\n z-index: @zindex-tooltip;\n display: block;\n // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.\n // So reset our font and text properties to avoid inheriting weird values.\n .reset-text();\n font-size: @font-size-small;\n\n .opacity(0);\n\n &.in { .opacity(@tooltip-opacity); }\n &.top { margin-top: -3px; padding: @tooltip-arrow-width 0; }\n &.right { margin-left: 3px; padding: 0 @tooltip-arrow-width; }\n &.bottom { margin-top: 3px; padding: @tooltip-arrow-width 0; }\n &.left { margin-left: -3px; padding: 0 @tooltip-arrow-width; }\n}\n\n// Wrapper for the tooltip content\n.tooltip-inner {\n max-width: @tooltip-max-width;\n padding: 3px 8px;\n color: @tooltip-color;\n text-align: center;\n background-color: @tooltip-bg;\n border-radius: @border-radius-base;\n}\n\n// Arrows\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n// Note: Deprecated .top-left, .top-right, .bottom-left, and .bottom-right as of v3.3.1\n.tooltip {\n &.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.top-left .tooltip-arrow {\n bottom: 0;\n right: @tooltip-arrow-width;\n margin-bottom: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.top-right .tooltip-arrow {\n bottom: 0;\n left: @tooltip-arrow-width;\n margin-bottom: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width @tooltip-arrow-width 0;\n border-right-color: @tooltip-arrow-color;\n }\n &.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-left-color: @tooltip-arrow-color;\n }\n &.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n &.bottom-left .tooltip-arrow {\n top: 0;\n right: @tooltip-arrow-width;\n margin-top: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n &.bottom-right .tooltip-arrow {\n top: 0;\n left: @tooltip-arrow-width;\n margin-top: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n}\n",
+ ".reset-text() {\n font-family: @font-family-base;\n // We deliberately do NOT reset font-size.\n font-style: normal;\n font-weight: normal;\n letter-spacing: normal;\n line-break: auto;\n line-height: @line-height-base;\n text-align: left; // Fallback for where `start` is not supported\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n white-space: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n}\n",
+ "//\n// Popovers\n// --------------------------------------------------\n\n\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: @zindex-popover;\n display: none;\n max-width: @popover-max-width;\n padding: 1px;\n // Our parent element can be arbitrary since popovers are by default inserted as a sibling of their target element.\n // So reset our font and text properties to avoid inheriting weird values.\n .reset-text();\n font-size: @font-size-base;\n\n background-color: @popover-bg;\n background-clip: padding-box;\n border: 1px solid @popover-fallback-border-color;\n border: 1px solid @popover-border-color;\n border-radius: @border-radius-large;\n .box-shadow(0 5px 10px rgba(0,0,0,.2));\n\n // Offset the popover to account for the popover arrow\n &.top { margin-top: -@popover-arrow-width; }\n &.right { margin-left: @popover-arrow-width; }\n &.bottom { margin-top: @popover-arrow-width; }\n &.left { margin-left: -@popover-arrow-width; }\n}\n\n.popover-title {\n margin: 0; // reset heading margin\n padding: 8px 14px;\n font-size: @font-size-base;\n background-color: @popover-title-bg;\n border-bottom: 1px solid darken(@popover-title-bg, 5%);\n border-radius: (@border-radius-large - 1) (@border-radius-large - 1) 0 0;\n}\n\n.popover-content {\n padding: 9px 14px;\n}\n\n// Arrows\n//\n// .arrow is outer, .arrow:after is inner\n\n.popover > .arrow {\n &,\n &:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n }\n}\n.popover > .arrow {\n border-width: @popover-arrow-outer-width;\n}\n.popover > .arrow:after {\n border-width: @popover-arrow-width;\n content: \"\";\n}\n\n.popover {\n &.top > .arrow {\n left: 50%;\n margin-left: -@popover-arrow-outer-width;\n border-bottom-width: 0;\n border-top-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-top-color: @popover-arrow-outer-color;\n bottom: -@popover-arrow-outer-width;\n &:after {\n content: \" \";\n bottom: 1px;\n margin-left: -@popover-arrow-width;\n border-bottom-width: 0;\n border-top-color: @popover-arrow-color;\n }\n }\n &.right > .arrow {\n top: 50%;\n left: -@popover-arrow-outer-width;\n margin-top: -@popover-arrow-outer-width;\n border-left-width: 0;\n border-right-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-right-color: @popover-arrow-outer-color;\n &:after {\n content: \" \";\n left: 1px;\n bottom: -@popover-arrow-width;\n border-left-width: 0;\n border-right-color: @popover-arrow-color;\n }\n }\n &.bottom > .arrow {\n left: 50%;\n margin-left: -@popover-arrow-outer-width;\n border-top-width: 0;\n border-bottom-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-bottom-color: @popover-arrow-outer-color;\n top: -@popover-arrow-outer-width;\n &:after {\n content: \" \";\n top: 1px;\n margin-left: -@popover-arrow-width;\n border-top-width: 0;\n border-bottom-color: @popover-arrow-color;\n }\n }\n\n &.left > .arrow {\n top: 50%;\n right: -@popover-arrow-outer-width;\n margin-top: -@popover-arrow-outer-width;\n border-right-width: 0;\n border-left-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-left-color: @popover-arrow-outer-color;\n &:after {\n content: \" \";\n right: 1px;\n border-right-width: 0;\n border-left-color: @popover-arrow-color;\n bottom: -@popover-arrow-width;\n }\n }\n}\n",
+ "//\n// Carousel\n// --------------------------------------------------\n\n\n// Wrapper for the slide container and indicators\n.carousel {\n position: relative;\n}\n\n.carousel-inner {\n position: relative;\n overflow: hidden;\n width: 100%;\n\n > .item {\n display: none;\n position: relative;\n .transition(.6s ease-in-out left);\n\n // Account for jankitude on images\n > img,\n > a > img {\n &:extend(.img-responsive);\n line-height: 1;\n }\n\n // WebKit CSS3 transforms for supported devices\n @media all and (transform-3d), (-webkit-transform-3d) {\n .transition-transform(~'0.6s ease-in-out');\n .backface-visibility(~'hidden');\n .perspective(1000px);\n\n &.next,\n &.active.right {\n .translate3d(100%, 0, 0);\n left: 0;\n }\n &.prev,\n &.active.left {\n .translate3d(-100%, 0, 0);\n left: 0;\n }\n &.next.left,\n &.prev.right,\n &.active {\n .translate3d(0, 0, 0);\n left: 0;\n }\n }\n }\n\n > .active,\n > .next,\n > .prev {\n display: block;\n }\n\n > .active {\n left: 0;\n }\n\n > .next,\n > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n }\n\n > .next {\n left: 100%;\n }\n > .prev {\n left: -100%;\n }\n > .next.left,\n > .prev.right {\n left: 0;\n }\n\n > .active.left {\n left: -100%;\n }\n > .active.right {\n left: 100%;\n }\n\n}\n\n// Left/right controls for nav\n// ---------------------------\n\n.carousel-control {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n width: @carousel-control-width;\n .opacity(@carousel-control-opacity);\n font-size: @carousel-control-font-size;\n color: @carousel-control-color;\n text-align: center;\n text-shadow: @carousel-text-shadow;\n // We can't have this transition here because WebKit cancels the carousel\n // animation if you trip this while in the middle of another animation.\n\n // Set gradients for backgrounds\n &.left {\n #gradient > .horizontal(@start-color: rgba(0,0,0,.5); @end-color: rgba(0,0,0,.0001));\n }\n &.right {\n left: auto;\n right: 0;\n #gradient > .horizontal(@start-color: rgba(0,0,0,.0001); @end-color: rgba(0,0,0,.5));\n }\n\n // Hover/focus state\n &:hover,\n &:focus {\n outline: 0;\n color: @carousel-control-color;\n text-decoration: none;\n .opacity(.9);\n }\n\n // Toggles\n .icon-prev,\n .icon-next,\n .glyphicon-chevron-left,\n .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n margin-top: -10px;\n z-index: 5;\n display: inline-block;\n }\n .icon-prev,\n .glyphicon-chevron-left {\n left: 50%;\n margin-left: -10px;\n }\n .icon-next,\n .glyphicon-chevron-right {\n right: 50%;\n margin-right: -10px;\n }\n .icon-prev,\n .icon-next {\n width: 20px;\n height: 20px;\n line-height: 1;\n font-family: serif;\n }\n\n\n .icon-prev {\n &:before {\n content: '\\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039)\n }\n }\n .icon-next {\n &:before {\n content: '\\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A)\n }\n }\n}\n\n// Optional indicator pips\n//\n// Add an unordered list with the following class and add a list item for each\n// slide your carousel holds.\n\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n margin-left: -30%;\n padding-left: 0;\n list-style: none;\n text-align: center;\n\n li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n border: 1px solid @carousel-indicator-border-color;\n border-radius: 10px;\n cursor: pointer;\n\n // IE8-9 hack for event handling\n //\n // Internet Explorer 8-9 does not support clicks on elements without a set\n // `background-color`. We cannot use `filter` since that's not viewed as a\n // background color by the browser. Thus, a hack is needed.\n // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Internet_Explorer\n //\n // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we\n // set alpha transparency for the best results possible.\n background-color: #000 \\9; // IE8\n background-color: rgba(0,0,0,0); // IE9\n }\n .active {\n margin: 0;\n width: 12px;\n height: 12px;\n background-color: @carousel-indicator-active-bg;\n }\n}\n\n// Optional captions\n// -----------------------------\n// Hidden by default for smaller viewports\n.carousel-caption {\n position: absolute;\n left: 15%;\n right: 15%;\n bottom: 20px;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: @carousel-caption-color;\n text-align: center;\n text-shadow: @carousel-text-shadow;\n & .btn {\n text-shadow: none; // No shadow for button elements in carousel-caption\n }\n}\n\n\n// Scale up controls for tablets and up\n@media screen and (min-width: @screen-sm-min) {\n\n // Scale up the controls a smidge\n .carousel-control {\n .glyphicon-chevron-left,\n .glyphicon-chevron-right,\n .icon-prev,\n .icon-next {\n width: 30px;\n height: 30px;\n margin-top: -15px;\n font-size: 30px;\n }\n .glyphicon-chevron-left,\n .icon-prev {\n margin-left: -15px;\n }\n .glyphicon-chevron-right,\n .icon-next {\n margin-right: -15px;\n }\n }\n\n // Show and left align the captions\n .carousel-caption {\n left: 20%;\n right: 20%;\n padding-bottom: 30px;\n }\n\n // Move up the indicators\n .carousel-indicators {\n bottom: 20px;\n }\n}\n",
+ "// Clearfix\n//\n// For modern browsers\n// 1. The space content is one way to avoid an Opera bug when the\n// contenteditable attribute is included anywhere else in the document.\n// Otherwise it causes space to appear at the top and bottom of elements\n// that are clearfixed.\n// 2. The use of `table` rather than `block` is only necessary if using\n// `:before` to contain the top-margins of child elements.\n//\n// Source: http://nicolasgallagher.com/micro-clearfix-hack/\n\n.clearfix() {\n &:before,\n &:after {\n content: \" \"; // 1\n display: table; // 2\n }\n &:after {\n clear: both;\n }\n}\n",
+ "// Center-align a block level element\n\n.center-block() {\n display: block;\n margin-left: auto;\n margin-right: auto;\n}\n",
+ "// CSS image replacement\n//\n// Heads up! v3 launched with only `.hide-text()`, but per our pattern for\n// mixins being reused as classes with the same name, this doesn't hold up. As\n// of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`.\n//\n// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757\n\n// Deprecated as of v3.0.1 (will be removed in v4)\n.hide-text() {\n font: ~\"0/0\" a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n\n// New mixin to use as of v3.0.1\n.text-hide() {\n .hide-text();\n}\n",
+ "//\n// Responsive: Utility classes\n// --------------------------------------------------\n\n\n// IE10 in Windows (Phone) 8\n//\n// Support for responsive views via media queries is kind of borked in IE10, for\n// Surface/desktop in split view and for Windows Phone 8. This particular fix\n// must be accompanied by a snippet of JavaScript to sniff the user agent and\n// apply some conditional CSS to *only* the Surface/desktop Windows 8. Look at\n// our Getting Started page for more information on this bug.\n//\n// For more information, see the following:\n//\n// Issue: https://github.com/twbs/bootstrap/issues/10497\n// Docs: http://getbootstrap.com/getting-started/#support-ie10-width\n// Source: http://timkadlec.com/2013/01/windows-phone-8-and-device-width/\n// Source: http://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/\n\n@-ms-viewport {\n width: device-width;\n}\n\n\n// Visibility utilities\n// Note: Deprecated .visible-xs, .visible-sm, .visible-md, and .visible-lg as of v3.2.0\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n .responsive-invisibility();\n}\n\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n display: none !important;\n}\n\n.visible-xs {\n @media (max-width: @screen-xs-max) {\n .responsive-visibility();\n }\n}\n.visible-xs-block {\n @media (max-width: @screen-xs-max) {\n display: block !important;\n }\n}\n.visible-xs-inline {\n @media (max-width: @screen-xs-max) {\n display: inline !important;\n }\n}\n.visible-xs-inline-block {\n @media (max-width: @screen-xs-max) {\n display: inline-block !important;\n }\n}\n\n.visible-sm {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n .responsive-visibility();\n }\n}\n.visible-sm-block {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n display: block !important;\n }\n}\n.visible-sm-inline {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n display: inline !important;\n }\n}\n.visible-sm-inline-block {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n display: inline-block !important;\n }\n}\n\n.visible-md {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n .responsive-visibility();\n }\n}\n.visible-md-block {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n display: block !important;\n }\n}\n.visible-md-inline {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n display: inline !important;\n }\n}\n.visible-md-inline-block {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n display: inline-block !important;\n }\n}\n\n.visible-lg {\n @media (min-width: @screen-lg-min) {\n .responsive-visibility();\n }\n}\n.visible-lg-block {\n @media (min-width: @screen-lg-min) {\n display: block !important;\n }\n}\n.visible-lg-inline {\n @media (min-width: @screen-lg-min) {\n display: inline !important;\n }\n}\n.visible-lg-inline-block {\n @media (min-width: @screen-lg-min) {\n display: inline-block !important;\n }\n}\n\n.hidden-xs {\n @media (max-width: @screen-xs-max) {\n .responsive-invisibility();\n }\n}\n.hidden-sm {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n .responsive-invisibility();\n }\n}\n.hidden-md {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n .responsive-invisibility();\n }\n}\n.hidden-lg {\n @media (min-width: @screen-lg-min) {\n .responsive-invisibility();\n }\n}\n\n\n// Print utilities\n//\n// Media queries are placed on the inside to be mixin-friendly.\n\n// Note: Deprecated .visible-print as of v3.2.0\n.visible-print {\n .responsive-invisibility();\n\n @media print {\n .responsive-visibility();\n }\n}\n.visible-print-block {\n display: none !important;\n\n @media print {\n display: block !important;\n }\n}\n.visible-print-inline {\n display: none !important;\n\n @media print {\n display: inline !important;\n }\n}\n.visible-print-inline-block {\n display: none !important;\n\n @media print {\n display: inline-block !important;\n }\n}\n\n.hidden-print {\n @media print {\n .responsive-invisibility();\n }\n}\n",
+ "// Responsive utilities\n\n//\n// More easily include all the states for responsive-utilities.less.\n.responsive-visibility() {\n display: block !important;\n table& { display: table !important; }\n tr& { display: table-row !important; }\n th&,\n td& { display: table-cell !important; }\n}\n\n.responsive-invisibility() {\n display: none !important;\n}\n"
+ ]
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/js/bootstrap/css/bootstrap.min.css
@@ -0,0 +1,7199 @@
+/*!
+ * Bootstrap v3.3.5 (http://getbootstrap.com)
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
+html {
+ font-family: sans-serif;
+ -webkit-text-size-adjust: 100%;
+ -ms-text-size-adjust: 100%
+}
+
+body {
+ margin: 0
+}
+
+article, aside, details, figcaption, figure, footer, header, hgroup, main, menu, nav, section, summary {
+ display: block
+}
+
+audio, canvas, progress, video {
+ display: inline-block;
+ vertical-align: baseline
+}
+
+audio:not([controls]) {
+ display: none;
+ height: 0
+}
+
+[hidden], template {
+ display: none
+}
+
+a {
+ background-color: transparent
+}
+
+a:active, a:hover {
+ outline: 0
+}
+
+abbr[title] {
+ border-bottom: 1px dotted
+}
+
+b, strong {
+ font-weight: 700
+}
+
+dfn {
+ font-style: italic
+}
+
+h1 {
+ margin: .67em 0;
+ font-size: 2em
+}
+
+mark {
+ color: #000;
+ background: #ff0
+}
+
+small {
+ font-size: 80%
+}
+
+sub, sup {
+ position: relative;
+ font-size: 75%;
+ line-height: 0;
+ vertical-align: baseline
+}
+
+sup {
+ top: -.5em
+}
+
+sub {
+ bottom: -.25em
+}
+
+img {
+ border: 0
+}
+
+svg:not(:root) {
+ overflow: hidden
+}
+
+figure {
+ margin: 1em 40px
+}
+
+hr {
+ height: 0;
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box
+}
+
+pre {
+ overflow: auto
+}
+
+code, kbd, pre, samp {
+ font-family: monospace, monospace;
+ font-size: 1em
+}
+
+button, input, optgroup, select, textarea {
+ margin: 0;
+ font: inherit;
+ color: inherit
+}
+
+button {
+ overflow: visible
+}
+
+button, select {
+ text-transform: none
+}
+
+button, html input[type=button], input[type=reset], input[type=submit] {
+ -webkit-appearance: button;
+ cursor: pointer
+}
+
+button[disabled], html input[disabled] {
+ cursor: default
+}
+
+button::-moz-focus-inner, input::-moz-focus-inner {
+ padding: 0;
+ border: 0
+}
+
+input {
+ line-height: normal
+}
+
+input[type=checkbox], input[type=radio] {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ padding: 0
+}
+
+input[type=number]::-webkit-inner-spin-button, input[type=number]::-webkit-outer-spin-button {
+ height: auto
+}
+
+input[type=search] {
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+ -webkit-appearance: textfield
+}
+
+input[type=search]::-webkit-search-cancel-button, input[type=search]::-webkit-search-decoration {
+ -webkit-appearance: none
+}
+
+fieldset {
+ padding: .35em .625em .75em;
+ margin: 0 2px;
+ border: 1px solid silver
+}
+
+legend {
+ padding: 0;
+ border: 0
+}
+
+textarea {
+ overflow: auto
+}
+
+optgroup {
+ font-weight: 700
+}
+
+table {
+ border-spacing: 0;
+ border-collapse: collapse
+}
+
+td, th {
+ padding: 0
+}
+
+/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */
+@media print {
+ *, :after, :before {
+ color: #000 !important;
+ text-shadow: none !important;
+ background: 0 0 !important;
+ -webkit-box-shadow: none !important;
+ box-shadow: none !important
+ }
+
+ a, a:visited {
+ text-decoration: underline
+ }
+
+ a[href]:after {
+ content: " (" attr(href) ")"
+ }
+
+ abbr[title]:after {
+ content: " (" attr(title) ")"
+ }
+
+ a[href^="javascript:"]:after, a[href^="#"]:after {
+ content: ""
+ }
+
+ blockquote, pre {
+ border: 1px solid #999;
+ page-break-inside: avoid
+ }
+
+ thead {
+ display: table-header-group
+ }
+
+ img, tr {
+ page-break-inside: avoid
+ }
+
+ img {
+ max-width: 100% !important
+ }
+
+ h2, h3, p {
+ orphans: 3;
+ widows: 3
+ }
+
+ h2, h3 {
+ page-break-after: avoid
+ }
+
+ .navbar {
+ display: none
+ }
+
+ .btn > .caret, .dropup > .btn > .caret {
+ border-top-color: #000 !important
+ }
+
+ .label {
+ border: 1px solid #000
+ }
+
+ .table {
+ border-collapse: collapse !important
+ }
+
+ .table td, .table th {
+ background-color: #fff !important
+ }
+
+ .table-bordered td, .table-bordered th {
+ border: 1px solid #ddd !important
+ }
+}
+
+@font-face {
+ font-family: 'Glyphicons Halflings';
+ src: url(../fonts/glyphicons-halflings-regular.eot);
+ src: url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'), url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'), url(../fonts/glyphicons-halflings-regular.woff) format('woff'), url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'), url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')
+}
+
+.glyphicon {
+ position: relative;
+ top: 1px;
+ display: inline-block;
+ font-family: 'Glyphicons Halflings';
+ font-style: normal;
+ font-weight: 400;
+ line-height: 1;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale
+}
+
+.glyphicon-asterisk:before {
+ content: "\2a"
+}
+
+.glyphicon-plus:before {
+ content: "\2b"
+}
+
+.glyphicon-eur:before, .glyphicon-euro:before {
+ content: "\20ac"
+}
+
+.glyphicon-minus:before {
+ content: "\2212"
+}
+
+.glyphicon-cloud:before {
+ content: "\2601"
+}
+
+.glyphicon-envelope:before {
+ content: "\2709"
+}
+
+.glyphicon-pencil:before {
+ content: "\270f"
+}
+
+.glyphicon-glass:before {
+ content: "\e001"
+}
+
+.glyphicon-music:before {
+ content: "\e002"
+}
+
+.glyphicon-search:before {
+ content: "\e003"
+}
+
+.glyphicon-heart:before {
+ content: "\e005"
+}
+
+.glyphicon-star:before {
+ content: "\e006"
+}
+
+.glyphicon-star-empty:before {
+ content: "\e007"
+}
+
+.glyphicon-user:before {
+ content: "\e008"
+}
+
+.glyphicon-film:before {
+ content: "\e009"
+}
+
+.glyphicon-th-large:before {
+ content: "\e010"
+}
+
+.glyphicon-th:before {
+ content: "\e011"
+}
+
+.glyphicon-th-list:before {
+ content: "\e012"
+}
+
+.glyphicon-ok:before {
+ content: "\e013"
+}
+
+.glyphicon-remove:before {
+ content: "\e014"
+}
+
+.glyphicon-zoom-in:before {
+ content: "\e015"
+}
+
+.glyphicon-zoom-out:before {
+ content: "\e016"
+}
+
+.glyphicon-off:before {
+ content: "\e017"
+}
+
+.glyphicon-signal:before {
+ content: "\e018"
+}
+
+.glyphicon-cog:before {
+ content: "\e019"
+}
+
+.glyphicon-trash:before {
+ content: "\e020"
+}
+
+.glyphicon-home:before {
+ content: "\e021"
+}
+
+.glyphicon-file:before {
+ content: "\e022"
+}
+
+.glyphicon-time:before {
+ content: "\e023"
+}
+
+.glyphicon-road:before {
+ content: "\e024"
+}
+
+.glyphicon-download-alt:before {
+ content: "\e025"
+}
+
+.glyphicon-download:before {
+ content: "\e026"
+}
+
+.glyphicon-upload:before {
+ content: "\e027"
+}
+
+.glyphicon-inbox:before {
+ content: "\e028"
+}
+
+.glyphicon-play-circle:before {
+ content: "\e029"
+}
+
+.glyphicon-repeat:before {
+ content: "\e030"
+}
+
+.glyphicon-refresh:before {
+ content: "\e031"
+}
+
+.glyphicon-list-alt:before {
+ content: "\e032"
+}
+
+.glyphicon-lock:before {
+ content: "\e033"
+}
+
+.glyphicon-flag:before {
+ content: "\e034"
+}
+
+.glyphicon-headphones:before {
+ content: "\e035"
+}
+
+.glyphicon-volume-off:before {
+ content: "\e036"
+}
+
+.glyphicon-volume-down:before {
+ content: "\e037"
+}
+
+.glyphicon-volume-up:before {
+ content: "\e038"
+}
+
+.glyphicon-qrcode:before {
+ content: "\e039"
+}
+
+.glyphicon-barcode:before {
+ content: "\e040"
+}
+
+.glyphicon-tag:before {
+ content: "\e041"
+}
+
+.glyphicon-tags:before {
+ content: "\e042"
+}
+
+.glyphicon-book:before {
+ content: "\e043"
+}
+
+.glyphicon-bookmark:before {
+ content: "\e044"
+}
+
+.glyphicon-print:before {
+ content: "\e045"
+}
+
+.glyphicon-camera:before {
+ content: "\e046"
+}
+
+.glyphicon-font:before {
+ content: "\e047"
+}
+
+.glyphicon-bold:before {
+ content: "\e048"
+}
+
+.glyphicon-italic:before {
+ content: "\e049"
+}
+
+.glyphicon-text-height:before {
+ content: "\e050"
+}
+
+.glyphicon-text-width:before {
+ content: "\e051"
+}
+
+.glyphicon-align-left:before {
+ content: "\e052"
+}
+
+.glyphicon-align-center:before {
+ content: "\e053"
+}
+
+.glyphicon-align-right:before {
+ content: "\e054"
+}
+
+.glyphicon-align-justify:before {
+ content: "\e055"
+}
+
+.glyphicon-list:before {
+ content: "\e056"
+}
+
+.glyphicon-indent-left:before {
+ content: "\e057"
+}
+
+.glyphicon-indent-right:before {
+ content: "\e058"
+}
+
+.glyphicon-facetime-video:before {
+ content: "\e059"
+}
+
+.glyphicon-picture:before {
+ content: "\e060"
+}
+
+.glyphicon-map-marker:before {
+ content: "\e062"
+}
+
+.glyphicon-adjust:before {
+ content: "\e063"
+}
+
+.glyphicon-tint:before {
+ content: "\e064"
+}
+
+.glyphicon-edit:before {
+ content: "\e065"
+}
+
+.glyphicon-share:before {
+ content: "\e066"
+}
+
+.glyphicon-check:before {
+ content: "\e067"
+}
+
+.glyphicon-move:before {
+ content: "\e068"
+}
+
+.glyphicon-step-backward:before {
+ content: "\e069"
+}
+
+.glyphicon-fast-backward:before {
+ content: "\e070"
+}
+
+.glyphicon-backward:before {
+ content: "\e071"
+}
+
+.glyphicon-play:before {
+ content: "\e072"
+}
+
+.glyphicon-pause:before {
+ content: "\e073"
+}
+
+.glyphicon-stop:before {
+ content: "\e074"
+}
+
+.glyphicon-forward:before {
+ content: "\e075"
+}
+
+.glyphicon-fast-forward:before {
+ content: "\e076"
+}
+
+.glyphicon-step-forward:before {
+ content: "\e077"
+}
+
+.glyphicon-eject:before {
+ content: "\e078"
+}
+
+.glyphicon-chevron-left:before {
+ content: "\e079"
+}
+
+.glyphicon-chevron-right:before {
+ content: "\e080"
+}
+
+.glyphicon-plus-sign:before {
+ content: "\e081"
+}
+
+.glyphicon-minus-sign:before {
+ content: "\e082"
+}
+
+.glyphicon-remove-sign:before {
+ content: "\e083"
+}
+
+.glyphicon-ok-sign:before {
+ content: "\e084"
+}
+
+.glyphicon-question-sign:before {
+ content: "\e085"
+}
+
+.glyphicon-info-sign:before {
+ content: "\e086"
+}
+
+.glyphicon-screenshot:before {
+ content: "\e087"
+}
+
+.glyphicon-remove-circle:before {
+ content: "\e088"
+}
+
+.glyphicon-ok-circle:before {
+ content: "\e089"
+}
+
+.glyphicon-ban-circle:before {
+ content: "\e090"
+}
+
+.glyphicon-arrow-left:before {
+ content: "\e091"
+}
+
+.glyphicon-arrow-right:before {
+ content: "\e092"
+}
+
+.glyphicon-arrow-up:before {
+ content: "\e093"
+}
+
+.glyphicon-arrow-down:before {
+ content: "\e094"
+}
+
+.glyphicon-share-alt:before {
+ content: "\e095"
+}
+
+.glyphicon-resize-full:before {
+ content: "\e096"
+}
+
+.glyphicon-resize-small:before {
+ content: "\e097"
+}
+
+.glyphicon-exclamation-sign:before {
+ content: "\e101"
+}
+
+.glyphicon-gift:before {
+ content: "\e102"
+}
+
+.glyphicon-leaf:before {
+ content: "\e103"
+}
+
+.glyphicon-fire:before {
+ content: "\e104"
+}
+
+.glyphicon-eye-open:before {
+ content: "\e105"
+}
+
+.glyphicon-eye-close:before {
+ content: "\e106"
+}
+
+.glyphicon-warning-sign:before {
+ content: "\e107"
+}
+
+.glyphicon-plane:before {
+ content: "\e108"
+}
+
+.glyphicon-calendar:before {
+ content: "\e109"
+}
+
+.glyphicon-random:before {
+ content: "\e110"
+}
+
+.glyphicon-comment:before {
+ content: "\e111"
+}
+
+.glyphicon-magnet:before {
+ content: "\e112"
+}
+
+.glyphicon-chevron-up:before {
+ content: "\e113"
+}
+
+.glyphicon-chevron-down:before {
+ content: "\e114"
+}
+
+.glyphicon-retweet:before {
+ content: "\e115"
+}
+
+.glyphicon-shopping-cart:before {
+ content: "\e116"
+}
+
+.glyphicon-folder-close:before {
+ content: "\e117"
+}
+
+.glyphicon-folder-open:before {
+ content: "\e118"
+}
+
+.glyphicon-resize-vertical:before {
+ content: "\e119"
+}
+
+.glyphicon-resize-horizontal:before {
+ content: "\e120"
+}
+
+.glyphicon-hdd:before {
+ content: "\e121"
+}
+
+.glyphicon-bullhorn:before {
+ content: "\e122"
+}
+
+.glyphicon-bell:before {
+ content: "\e123"
+}
+
+.glyphicon-certificate:before {
+ content: "\e124"
+}
+
+.glyphicon-thumbs-up:before {
+ content: "\e125"
+}
+
+.glyphicon-thumbs-down:before {
+ content: "\e126"
+}
+
+.glyphicon-hand-right:before {
+ content: "\e127"
+}
+
+.glyphicon-hand-left:before {
+ content: "\e128"
+}
+
+.glyphicon-hand-up:before {
+ content: "\e129"
+}
+
+.glyphicon-hand-down:before {
+ content: "\e130"
+}
+
+.glyphicon-circle-arrow-right:before {
+ content: "\e131"
+}
+
+.glyphicon-circle-arrow-left:before {
+ content: "\e132"
+}
+
+.glyphicon-circle-arrow-up:before {
+ content: "\e133"
+}
+
+.glyphicon-circle-arrow-down:before {
+ content: "\e134"
+}
+
+.glyphicon-globe:before {
+ content: "\e135"
+}
+
+.glyphicon-wrench:before {
+ content: "\e136"
+}
+
+.glyphicon-tasks:before {
+ content: "\e137"
+}
+
+.glyphicon-filter:before {
+ content: "\e138"
+}
+
+.glyphicon-briefcase:before {
+ content: "\e139"
+}
+
+.glyphicon-fullscreen:before {
+ content: "\e140"
+}
+
+.glyphicon-dashboard:before {
+ content: "\e141"
+}
+
+.glyphicon-paperclip:before {
+ content: "\e142"
+}
+
+.glyphicon-heart-empty:before {
+ content: "\e143"
+}
+
+.glyphicon-link:before {
+ content: "\e144"
+}
+
+.glyphicon-phone:before {
+ content: "\e145"
+}
+
+.glyphicon-pushpin:before {
+ content: "\e146"
+}
+
+.glyphicon-usd:before {
+ content: "\e148"
+}
+
+.glyphicon-gbp:before {
+ content: "\e149"
+}
+
+.glyphicon-sort:before {
+ content: "\e150"
+}
+
+.glyphicon-sort-by-alphabet:before {
+ content: "\e151"
+}
+
+.glyphicon-sort-by-alphabet-alt:before {
+ content: "\e152"
+}
+
+.glyphicon-sort-by-order:before {
+ content: "\e153"
+}
+
+.glyphicon-sort-by-order-alt:before {
+ content: "\e154"
+}
+
+.glyphicon-sort-by-attributes:before {
+ content: "\e155"
+}
+
+.glyphicon-sort-by-attributes-alt:before {
+ content: "\e156"
+}
+
+.glyphicon-unchecked:before {
+ content: "\e157"
+}
+
+.glyphicon-expand:before {
+ content: "\e158"
+}
+
+.glyphicon-collapse-down:before {
+ content: "\e159"
+}
+
+.glyphicon-collapse-up:before {
+ content: "\e160"
+}
+
+.glyphicon-log-in:before {
+ content: "\e161"
+}
+
+.glyphicon-flash:before {
+ content: "\e162"
+}
+
+.glyphicon-log-out:before {
+ content: "\e163"
+}
+
+.glyphicon-new-window:before {
+ content: "\e164"
+}
+
+.glyphicon-record:before {
+ content: "\e165"
+}
+
+.glyphicon-save:before {
+ content: "\e166"
+}
+
+.glyphicon-open:before {
+ content: "\e167"
+}
+
+.glyphicon-saved:before {
+ content: "\e168"
+}
+
+.glyphicon-import:before {
+ content: "\e169"
+}
+
+.glyphicon-export:before {
+ content: "\e170"
+}
+
+.glyphicon-send:before {
+ content: "\e171"
+}
+
+.glyphicon-floppy-disk:before {
+ content: "\e172"
+}
+
+.glyphicon-floppy-saved:before {
+ content: "\e173"
+}
+
+.glyphicon-floppy-remove:before {
+ content: "\e174"
+}
+
+.glyphicon-floppy-save:before {
+ content: "\e175"
+}
+
+.glyphicon-floppy-open:before {
+ content: "\e176"
+}
+
+.glyphicon-credit-card:before {
+ content: "\e177"
+}
+
+.glyphicon-transfer:before {
+ content: "\e178"
+}
+
+.glyphicon-cutlery:before {
+ content: "\e179"
+}
+
+.glyphicon-header:before {
+ content: "\e180"
+}
+
+.glyphicon-compressed:before {
+ content: "\e181"
+}
+
+.glyphicon-earphone:before {
+ content: "\e182"
+}
+
+.glyphicon-phone-alt:before {
+ content: "\e183"
+}
+
+.glyphicon-tower:before {
+ content: "\e184"
+}
+
+.glyphicon-stats:before {
+ content: "\e185"
+}
+
+.glyphicon-sd-video:before {
+ content: "\e186"
+}
+
+.glyphicon-hd-video:before {
+ content: "\e187"
+}
+
+.glyphicon-subtitles:before {
+ content: "\e188"
+}
+
+.glyphicon-sound-stereo:before {
+ content: "\e189"
+}
+
+.glyphicon-sound-dolby:before {
+ content: "\e190"
+}
+
+.glyphicon-sound-5-1:before {
+ content: "\e191"
+}
+
+.glyphicon-sound-6-1:before {
+ content: "\e192"
+}
+
+.glyphicon-sound-7-1:before {
+ content: "\e193"
+}
+
+.glyphicon-copyright-mark:before {
+ content: "\e194"
+}
+
+.glyphicon-registration-mark:before {
+ content: "\e195"
+}
+
+.glyphicon-cloud-download:before {
+ content: "\e197"
+}
+
+.glyphicon-cloud-upload:before {
+ content: "\e198"
+}
+
+.glyphicon-tree-conifer:before {
+ content: "\e199"
+}
+
+.glyphicon-tree-deciduous:before {
+ content: "\e200"
+}
+
+.glyphicon-cd:before {
+ content: "\e201"
+}
+
+.glyphicon-save-file:before {
+ content: "\e202"
+}
+
+.glyphicon-open-file:before {
+ content: "\e203"
+}
+
+.glyphicon-level-up:before {
+ content: "\e204"
+}
+
+.glyphicon-copy:before {
+ content: "\e205"
+}
+
+.glyphicon-paste:before {
+ content: "\e206"
+}
+
+.glyphicon-alert:before {
+ content: "\e209"
+}
+
+.glyphicon-equalizer:before {
+ content: "\e210"
+}
+
+.glyphicon-king:before {
+ content: "\e211"
+}
+
+.glyphicon-queen:before {
+ content: "\e212"
+}
+
+.glyphicon-pawn:before {
+ content: "\e213"
+}
+
+.glyphicon-bishop:before {
+ content: "\e214"
+}
+
+.glyphicon-knight:before {
+ content: "\e215"
+}
+
+.glyphicon-baby-formula:before {
+ content: "\e216"
+}
+
+.glyphicon-tent:before {
+ content: "\26fa"
+}
+
+.glyphicon-blackboard:before {
+ content: "\e218"
+}
+
+.glyphicon-bed:before {
+ content: "\e219"
+}
+
+.glyphicon-apple:before {
+ content: "\f8ff"
+}
+
+.glyphicon-erase:before {
+ content: "\e221"
+}
+
+.glyphicon-hourglass:before {
+ content: "\231b"
+}
+
+.glyphicon-lamp:before {
+ content: "\e223"
+}
+
+.glyphicon-duplicate:before {
+ content: "\e224"
+}
+
+.glyphicon-piggy-bank:before {
+ content: "\e225"
+}
+
+.glyphicon-scissors:before {
+ content: "\e226"
+}
+
+.glyphicon-bitcoin:before {
+ content: "\e227"
+}
+
+.glyphicon-btc:before {
+ content: "\e227"
+}
+
+.glyphicon-xbt:before {
+ content: "\e227"
+}
+
+.glyphicon-yen:before {
+ content: "\00a5"
+}
+
+.glyphicon-jpy:before {
+ content: "\00a5"
+}
+
+.glyphicon-ruble:before {
+ content: "\20bd"
+}
+
+.glyphicon-rub:before {
+ content: "\20bd"
+}
+
+.glyphicon-scale:before {
+ content: "\e230"
+}
+
+.glyphicon-ice-lolly:before {
+ content: "\e231"
+}
+
+.glyphicon-ice-lolly-tasted:before {
+ content: "\e232"
+}
+
+.glyphicon-education:before {
+ content: "\e233"
+}
+
+.glyphicon-option-horizontal:before {
+ content: "\e234"
+}
+
+.glyphicon-option-vertical:before {
+ content: "\e235"
+}
+
+.glyphicon-menu-hamburger:before {
+ content: "\e236"
+}
+
+.glyphicon-modal-window:before {
+ content: "\e237"
+}
+
+.glyphicon-oil:before {
+ content: "\e238"
+}
+
+.glyphicon-grain:before {
+ content: "\e239"
+}
+
+.glyphicon-sunglasses:before {
+ content: "\e240"
+}
+
+.glyphicon-text-size:before {
+ content: "\e241"
+}
+
+.glyphicon-text-color:before {
+ content: "\e242"
+}
+
+.glyphicon-text-background:before {
+ content: "\e243"
+}
+
+.glyphicon-object-align-top:before {
+ content: "\e244"
+}
+
+.glyphicon-object-align-bottom:before {
+ content: "\e245"
+}
+
+.glyphicon-object-align-horizontal:before {
+ content: "\e246"
+}
+
+.glyphicon-object-align-left:before {
+ content: "\e247"
+}
+
+.glyphicon-object-align-vertical:before {
+ content: "\e248"
+}
+
+.glyphicon-object-align-right:before {
+ content: "\e249"
+}
+
+.glyphicon-triangle-right:before {
+ content: "\e250"
+}
+
+.glyphicon-triangle-left:before {
+ content: "\e251"
+}
+
+.glyphicon-triangle-bottom:before {
+ content: "\e252"
+}
+
+.glyphicon-triangle-top:before {
+ content: "\e253"
+}
+
+.glyphicon-console:before {
+ content: "\e254"
+}
+
+.glyphicon-superscript:before {
+ content: "\e255"
+}
+
+.glyphicon-subscript:before {
+ content: "\e256"
+}
+
+.glyphicon-menu-left:before {
+ content: "\e257"
+}
+
+.glyphicon-menu-right:before {
+ content: "\e258"
+}
+
+.glyphicon-menu-down:before {
+ content: "\e259"
+}
+
+.glyphicon-menu-up:before {
+ content: "\e260"
+}
+
+* {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box
+}
+
+:after, :before {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box
+}
+
+html {
+ font-size: 10px;
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0)
+}
+
+body {
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #333;
+ background-color: #fff
+}
+
+button, input, select, textarea {
+ font-family: inherit;
+ font-size: inherit;
+ line-height: inherit
+}
+
+a {
+ color: #337ab7;
+ text-decoration: none
+}
+
+a:focus, a:hover {
+ color: #23527c;
+ text-decoration: underline
+}
+
+a:focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px
+}
+
+figure {
+ margin: 0
+}
+
+img {
+ vertical-align: middle
+}
+
+.carousel-inner > .item > a > img, .carousel-inner > .item > img, .img-responsive, .thumbnail a > img, .thumbnail > img {
+ display: block;
+ max-width: 100%;
+ height: auto
+}
+
+.img-rounded {
+ border-radius: 6px
+}
+
+.img-thumbnail {
+ display: inline-block;
+ max-width: 100%;
+ height: auto;
+ padding: 4px;
+ line-height: 1.42857143;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ -webkit-transition: all .2s ease-in-out;
+ -o-transition: all .2s ease-in-out;
+ transition: all .2s ease-in-out
+}
+
+.img-circle {
+ border-radius: 50%
+}
+
+hr {
+ margin-top: 20px;
+ margin-bottom: 20px;
+ border: 0;
+ border-top: 1px solid #eee
+}
+
+.sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ border: 0
+}
+
+.sr-only-focusable:active, .sr-only-focusable:focus {
+ position: static;
+ width: auto;
+ height: auto;
+ margin: 0;
+ overflow: visible;
+ clip: auto
+}
+
+[role=button] {
+ cursor: pointer
+}
+
+.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 {
+ font-family: inherit;
+ font-weight: 500;
+ line-height: 1.1;
+ color: inherit
+}
+
+.h1 .small, .h1 small, .h2 .small, .h2 small, .h3 .small, .h3 small, .h4 .small, .h4 small, .h5 .small, .h5 small, .h6 .small, .h6 small, h1 .small, h1 small, h2 .small, h2 small, h3 .small, h3 small, h4 .small, h4 small, h5 .small, h5 small, h6 .small, h6 small {
+ font-weight: 400;
+ line-height: 1;
+ color: #777
+}
+
+.h1, .h2, .h3, h1, h2, h3 {
+ margin-top: 20px;
+ margin-bottom: 10px
+}
+
+.h1 .small, .h1 small, .h2 .small, .h2 small, .h3 .small, .h3 small, h1 .small, h1 small, h2 .small, h2 small, h3 .small, h3 small {
+ font-size: 65%
+}
+
+.h4, .h5, .h6, h4, h5, h6 {
+ margin-top: 10px;
+ margin-bottom: 10px
+}
+
+.h4 .small, .h4 small, .h5 .small, .h5 small, .h6 .small, .h6 small, h4 .small, h4 small, h5 .small, h5 small, h6 .small, h6 small {
+ font-size: 75%
+}
+
+.h1, h1 {
+ font-size: 36px
+}
+
+.h2, h2 {
+ font-size: 30px
+}
+
+.h3, h3 {
+ font-size: 24px
+}
+
+.h4, h4 {
+ font-size: 18px
+}
+
+.h5, h5 {
+ font-size: 14px
+}
+
+.h6, h6 {
+ font-size: 12px
+}
+
+p {
+ margin: 0 0 10px
+}
+
+.lead {
+ margin-bottom: 20px;
+ font-size: 16px;
+ font-weight: 300;
+ line-height: 1.4
+}
+
+@media (min-width: 768px) {
+ .lead {
+ font-size: 21px
+ }
+}
+
+.small, small {
+ font-size: 85%
+}
+
+.mark, mark {
+ padding: .2em;
+ background-color: #fcf8e3
+}
+
+.text-left {
+ text-align: left
+}
+
+.text-right {
+ text-align: right
+}
+
+.text-center {
+ text-align: center
+}
+
+.text-justify {
+ text-align: justify
+}
+
+.text-nowrap {
+ white-space: nowrap
+}
+
+.text-lowercase {
+ text-transform: lowercase
+}
+
+.text-uppercase {
+ text-transform: uppercase
+}
+
+.text-capitalize {
+ text-transform: capitalize
+}
+
+.text-muted {
+ color: #777
+}
+
+.text-primary {
+ color: #337ab7
+}
+
+a.text-primary:focus, a.text-primary:hover {
+ color: #286090
+}
+
+.text-success {
+ color: #3c763d
+}
+
+a.text-success:focus, a.text-success:hover {
+ color: #2b542c
+}
+
+.text-info {
+ color: #31708f
+}
+
+a.text-info:focus, a.text-info:hover {
+ color: #245269
+}
+
+.text-warning {
+ color: #8a6d3b
+}
+
+a.text-warning:focus, a.text-warning:hover {
+ color: #66512c
+}
+
+.text-danger {
+ color: #a94442
+}
+
+a.text-danger:focus, a.text-danger:hover {
+ color: #843534
+}
+
+.bg-primary {
+ color: #fff;
+ background-color: #337ab7
+}
+
+a.bg-primary:focus, a.bg-primary:hover {
+ background-color: #286090
+}
+
+.bg-success {
+ background-color: #dff0d8
+}
+
+a.bg-success:focus, a.bg-success:hover {
+ background-color: #c1e2b3
+}
+
+.bg-info {
+ background-color: #d9edf7
+}
+
+a.bg-info:focus, a.bg-info:hover {
+ background-color: #afd9ee
+}
+
+.bg-warning {
+ background-color: #fcf8e3
+}
+
+a.bg-warning:focus, a.bg-warning:hover {
+ background-color: #f7ecb5
+}
+
+.bg-danger {
+ background-color: #f2dede
+}
+
+a.bg-danger:focus, a.bg-danger:hover {
+ background-color: #e4b9b9
+}
+
+.page-header {
+ padding-bottom: 9px;
+ margin: 40px 0 20px;
+ border-bottom: 1px solid #eee
+}
+
+ol, ul {
+ margin-top: 0;
+ margin-bottom: 10px
+}
+
+ol ol, ol ul, ul ol, ul ul {
+ margin-bottom: 0
+}
+
+.list-unstyled {
+ padding-left: 0;
+ list-style: none
+}
+
+.list-inline {
+ padding-left: 0;
+ margin-left: -5px;
+ list-style: none
+}
+
+.list-inline > li {
+ display: inline-block;
+ padding-right: 5px;
+ padding-left: 5px
+}
+
+dl {
+ margin-top: 0;
+ margin-bottom: 20px
+}
+
+dd, dt {
+ line-height: 1.42857143
+}
+
+dt {
+ font-weight: 700
+}
+
+dd {
+ margin-left: 0
+}
+
+@media (min-width: 768px) {
+ .dl-horizontal dt {
+ float: left;
+ width: 160px;
+ overflow: hidden;
+ clear: left;
+ text-align: right;
+ text-overflow: ellipsis;
+ white-space: nowrap
+ }
+
+ .dl-horizontal dd {
+ margin-left: 180px
+ }
+}
+
+abbr[data-original-title], abbr[title] {
+ cursor: help;
+ border-bottom: 1px dotted #777
+}
+
+.initialism {
+ font-size: 90%;
+ text-transform: uppercase
+}
+
+blockquote {
+ padding: 10px 20px;
+ margin: 0 0 20px;
+ font-size: 17.5px;
+ border-left: 5px solid #eee
+}
+
+blockquote ol:last-child, blockquote p:last-child, blockquote ul:last-child {
+ margin-bottom: 0
+}
+
+blockquote .small, blockquote footer, blockquote small {
+ display: block;
+ font-size: 80%;
+ line-height: 1.42857143;
+ color: #777
+}
+
+blockquote .small:before, blockquote footer:before, blockquote small:before {
+ content: '\2014 \00A0'
+}
+
+.blockquote-reverse, blockquote.pull-right {
+ padding-right: 15px;
+ padding-left: 0;
+ text-align: right;
+ border-right: 5px solid #eee;
+ border-left: 0
+}
+
+.blockquote-reverse .small:before, .blockquote-reverse footer:before, .blockquote-reverse small:before, blockquote.pull-right .small:before, blockquote.pull-right footer:before, blockquote.pull-right small:before {
+ content: ''
+}
+
+.blockquote-reverse .small:after, .blockquote-reverse footer:after, .blockquote-reverse small:after, blockquote.pull-right .small:after, blockquote.pull-right footer:after, blockquote.pull-right small:after {
+ content: '\00A0 \2014'
+}
+
+address {
+ margin-bottom: 20px;
+ font-style: normal;
+ line-height: 1.42857143
+}
+
+code, kbd, pre, samp {
+ font-family: Menlo, Monaco, Consolas, "Courier New", monospace
+}
+
+code {
+ padding: 2px 4px;
+ font-size: 90%;
+ color: #c7254e;
+ background-color: #f9f2f4;
+ border-radius: 4px
+}
+
+kbd {
+ padding: 2px 4px;
+ font-size: 90%;
+ color: #fff;
+ background-color: #333;
+ border-radius: 3px;
+ -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);
+ box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25)
+}
+
+kbd kbd {
+ padding: 0;
+ font-size: 100%;
+ font-weight: 700;
+ -webkit-box-shadow: none;
+ box-shadow: none
+}
+
+pre {
+ display: block;
+ padding: 9.5px;
+ margin: 0 0 10px;
+ font-size: 13px;
+ line-height: 1.42857143;
+ color: #333;
+ word-break: break-all;
+ word-wrap: break-word;
+ background-color: #f5f5f5;
+ border: 1px solid #ccc;
+ border-radius: 4px
+}
+
+pre code {
+ padding: 0;
+ font-size: inherit;
+ color: inherit;
+ white-space: pre-wrap;
+ background-color: transparent;
+ border-radius: 0
+}
+
+.pre-scrollable {
+ max-height: 340px;
+ overflow-y: scroll
+}
+
+.container {
+ padding-right: 15px;
+ padding-left: 15px;
+ margin-right: auto;
+ margin-left: auto
+}
+
+@media (min-width: 768px) {
+ .container {
+ width: 750px
+ }
+}
+
+@media (min-width: 992px) {
+ .container {
+ width: 970px
+ }
+}
+
+@media (min-width: 1200px) {
+ .container {
+ width: 1170px
+ }
+}
+
+.container-fluid {
+ padding-right: 15px;
+ padding-left: 15px;
+ margin-right: auto;
+ margin-left: auto
+}
+
+.row {
+ margin-right: -15px;
+ margin-left: -15px
+}
+
+.col-lg-1, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-md-1, .col-md-10, .col-md-11, .col-md-12, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-sm-1, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-xs-1, .col-xs-10, .col-xs-11, .col-xs-12, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9 {
+ position: relative;
+ min-height: 1px;
+ padding-right: 15px;
+ padding-left: 15px
+}
+
+.col-xs-1, .col-xs-10, .col-xs-11, .col-xs-12, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9 {
+ float: left
+}
+
+.col-xs-12 {
+ width: 100%
+}
+
+.col-xs-11 {
+ width: 91.66666667%
+}
+
+.col-xs-10 {
+ width: 83.33333333%
+}
+
+.col-xs-9 {
+ width: 75%
+}
+
+.col-xs-8 {
+ width: 66.66666667%
+}
+
+.col-xs-7 {
+ width: 58.33333333%
+}
+
+.col-xs-6 {
+ width: 50%
+}
+
+.col-xs-5 {
+ width: 41.66666667%
+}
+
+.col-xs-4 {
+ width: 33.33333333%
+}
+
+.col-xs-3 {
+ width: 25%
+}
+
+.col-xs-2 {
+ width: 16.66666667%
+}
+
+.col-xs-1 {
+ width: 8.33333333%
+}
+
+.col-xs-pull-12 {
+ right: 100%
+}
+
+.col-xs-pull-11 {
+ right: 91.66666667%
+}
+
+.col-xs-pull-10 {
+ right: 83.33333333%
+}
+
+.col-xs-pull-9 {
+ right: 75%
+}
+
+.col-xs-pull-8 {
+ right: 66.66666667%
+}
+
+.col-xs-pull-7 {
+ right: 58.33333333%
+}
+
+.col-xs-pull-6 {
+ right: 50%
+}
+
+.col-xs-pull-5 {
+ right: 41.66666667%
+}
+
+.col-xs-pull-4 {
+ right: 33.33333333%
+}
+
+.col-xs-pull-3 {
+ right: 25%
+}
+
+.col-xs-pull-2 {
+ right: 16.66666667%
+}
+
+.col-xs-pull-1 {
+ right: 8.33333333%
+}
+
+.col-xs-pull-0 {
+ right: auto
+}
+
+.col-xs-push-12 {
+ left: 100%
+}
+
+.col-xs-push-11 {
+ left: 91.66666667%
+}
+
+.col-xs-push-10 {
+ left: 83.33333333%
+}
+
+.col-xs-push-9 {
+ left: 75%
+}
+
+.col-xs-push-8 {
+ left: 66.66666667%
+}
+
+.col-xs-push-7 {
+ left: 58.33333333%
+}
+
+.col-xs-push-6 {
+ left: 50%
+}
+
+.col-xs-push-5 {
+ left: 41.66666667%
+}
+
+.col-xs-push-4 {
+ left: 33.33333333%
+}
+
+.col-xs-push-3 {
+ left: 25%
+}
+
+.col-xs-push-2 {
+ left: 16.66666667%
+}
+
+.col-xs-push-1 {
+ left: 8.33333333%
+}
+
+.col-xs-push-0 {
+ left: auto
+}
+
+.col-xs-offset-12 {
+ margin-left: 100%
+}
+
+.col-xs-offset-11 {
+ margin-left: 91.66666667%
+}
+
+.col-xs-offset-10 {
+ margin-left: 83.33333333%
+}
+
+.col-xs-offset-9 {
+ margin-left: 75%
+}
+
+.col-xs-offset-8 {
+ margin-left: 66.66666667%
+}
+
+.col-xs-offset-7 {
+ margin-left: 58.33333333%
+}
+
+.col-xs-offset-6 {
+ margin-left: 50%
+}
+
+.col-xs-offset-5 {
+ margin-left: 41.66666667%
+}
+
+.col-xs-offset-4 {
+ margin-left: 33.33333333%
+}
+
+.col-xs-offset-3 {
+ margin-left: 25%
+}
+
+.col-xs-offset-2 {
+ margin-left: 16.66666667%
+}
+
+.col-xs-offset-1 {
+ margin-left: 8.33333333%
+}
+
+.col-xs-offset-0 {
+ margin-left: 0
+}
+
+@media (min-width: 768px) {
+ .col-sm-1, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9 {
+ float: left
+ }
+
+ .col-sm-12 {
+ width: 100%
+ }
+
+ .col-sm-11 {
+ width: 91.66666667%
+ }
+
+ .col-sm-10 {
+ width: 83.33333333%
+ }
+
+ .col-sm-9 {
+ width: 75%
+ }
+
+ .col-sm-8 {
+ width: 66.66666667%
+ }
+
+ .col-sm-7 {
+ width: 58.33333333%
+ }
+
+ .col-sm-6 {
+ width: 50%
+ }
+
+ .col-sm-5 {
+ width: 41.66666667%
+ }
+
+ .col-sm-4 {
+ width: 33.33333333%
+ }
+
+ .col-sm-3 {
+ width: 25%
+ }
+
+ .col-sm-2 {
+ width: 16.66666667%
+ }
+
+ .col-sm-1 {
+ width: 8.33333333%
+ }
+
+ .col-sm-pull-12 {
+ right: 100%
+ }
+
+ .col-sm-pull-11 {
+ right: 91.66666667%
+ }
+
+ .col-sm-pull-10 {
+ right: 83.33333333%
+ }
+
+ .col-sm-pull-9 {
+ right: 75%
+ }
+
+ .col-sm-pull-8 {
+ right: 66.66666667%
+ }
+
+ .col-sm-pull-7 {
+ right: 58.33333333%
+ }
+
+ .col-sm-pull-6 {
+ right: 50%
+ }
+
+ .col-sm-pull-5 {
+ right: 41.66666667%
+ }
+
+ .col-sm-pull-4 {
+ right: 33.33333333%
+ }
+
+ .col-sm-pull-3 {
+ right: 25%
+ }
+
+ .col-sm-pull-2 {
+ right: 16.66666667%
+ }
+
+ .col-sm-pull-1 {
+ right: 8.33333333%
+ }
+
+ .col-sm-pull-0 {
+ right: auto
+ }
+
+ .col-sm-push-12 {
+ left: 100%
+ }
+
+ .col-sm-push-11 {
+ left: 91.66666667%
+ }
+
+ .col-sm-push-10 {
+ left: 83.33333333%
+ }
+
+ .col-sm-push-9 {
+ left: 75%
+ }
+
+ .col-sm-push-8 {
+ left: 66.66666667%
+ }
+
+ .col-sm-push-7 {
+ left: 58.33333333%
+ }
+
+ .col-sm-push-6 {
+ left: 50%
+ }
+
+ .col-sm-push-5 {
+ left: 41.66666667%
+ }
+
+ .col-sm-push-4 {
+ left: 33.33333333%
+ }
+
+ .col-sm-push-3 {
+ left: 25%
+ }
+
+ .col-sm-push-2 {
+ left: 16.66666667%
+ }
+
+ .col-sm-push-1 {
+ left: 8.33333333%
+ }
+
+ .col-sm-push-0 {
+ left: auto
+ }
+
+ .col-sm-offset-12 {
+ margin-left: 100%
+ }
+
+ .col-sm-offset-11 {
+ margin-left: 91.66666667%
+ }
+
+ .col-sm-offset-10 {
+ margin-left: 83.33333333%
+ }
+
+ .col-sm-offset-9 {
+ margin-left: 75%
+ }
+
+ .col-sm-offset-8 {
+ margin-left: 66.66666667%
+ }
+
+ .col-sm-offset-7 {
+ margin-left: 58.33333333%
+ }
+
+ .col-sm-offset-6 {
+ margin-left: 50%
+ }
+
+ .col-sm-offset-5 {
+ margin-left: 41.66666667%
+ }
+
+ .col-sm-offset-4 {
+ margin-left: 33.33333333%
+ }
+
+ .col-sm-offset-3 {
+ margin-left: 25%
+ }
+
+ .col-sm-offset-2 {
+ margin-left: 16.66666667%
+ }
+
+ .col-sm-offset-1 {
+ margin-left: 8.33333333%
+ }
+
+ .col-sm-offset-0 {
+ margin-left: 0
+ }
+}
+
+@media (min-width: 992px) {
+ .col-md-1, .col-md-10, .col-md-11, .col-md-12, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9 {
+ float: left
+ }
+
+ .col-md-12 {
+ width: 100%
+ }
+
+ .col-md-11 {
+ width: 91.66666667%
+ }
+
+ .col-md-10 {
+ width: 83.33333333%
+ }
+
+ .col-md-9 {
+ width: 75%
+ }
+
+ .col-md-8 {
+ width: 66.66666667%
+ }
+
+ .col-md-7 {
+ width: 58.33333333%
+ }
+
+ .col-md-6 {
+ width: 50%
+ }
+
+ .col-md-5 {
+ width: 41.66666667%
+ }
+
+ .col-md-4 {
+ width: 33.33333333%
+ }
+
+ .col-md-3 {
+ width: 25%
+ }
+
+ .col-md-2 {
+ width: 16.66666667%
+ }
+
+ .col-md-1 {
+ width: 8.33333333%
+ }
+
+ .col-md-pull-12 {
+ right: 100%
+ }
+
+ .col-md-pull-11 {
+ right: 91.66666667%
+ }
+
+ .col-md-pull-10 {
+ right: 83.33333333%
+ }
+
+ .col-md-pull-9 {
+ right: 75%
+ }
+
+ .col-md-pull-8 {
+ right: 66.66666667%
+ }
+
+ .col-md-pull-7 {
+ right: 58.33333333%
+ }
+
+ .col-md-pull-6 {
+ right: 50%
+ }
+
+ .col-md-pull-5 {
+ right: 41.66666667%
+ }
+
+ .col-md-pull-4 {
+ right: 33.33333333%
+ }
+
+ .col-md-pull-3 {
+ right: 25%
+ }
+
+ .col-md-pull-2 {
+ right: 16.66666667%
+ }
+
+ .col-md-pull-1 {
+ right: 8.33333333%
+ }
+
+ .col-md-pull-0 {
+ right: auto
+ }
+
+ .col-md-push-12 {
+ left: 100%
+ }
+
+ .col-md-push-11 {
+ left: 91.66666667%
+ }
+
+ .col-md-push-10 {
+ left: 83.33333333%
+ }
+
+ .col-md-push-9 {
+ left: 75%
+ }
+
+ .col-md-push-8 {
+ left: 66.66666667%
+ }
+
+ .col-md-push-7 {
+ left: 58.33333333%
+ }
+
+ .col-md-push-6 {
+ left: 50%
+ }
+
+ .col-md-push-5 {
+ left: 41.66666667%
+ }
+
+ .col-md-push-4 {
+ left: 33.33333333%
+ }
+
+ .col-md-push-3 {
+ left: 25%
+ }
+
+ .col-md-push-2 {
+ left: 16.66666667%
+ }
+
+ .col-md-push-1 {
+ left: 8.33333333%
+ }
+
+ .col-md-push-0 {
+ left: auto
+ }
+
+ .col-md-offset-12 {
+ margin-left: 100%
+ }
+
+ .col-md-offset-11 {
+ margin-left: 91.66666667%
+ }
+
+ .col-md-offset-10 {
+ margin-left: 83.33333333%
+ }
+
+ .col-md-offset-9 {
+ margin-left: 75%
+ }
+
+ .col-md-offset-8 {
+ margin-left: 66.66666667%
+ }
+
+ .col-md-offset-7 {
+ margin-left: 58.33333333%
+ }
+
+ .col-md-offset-6 {
+ margin-left: 50%
+ }
+
+ .col-md-offset-5 {
+ margin-left: 41.66666667%
+ }
+
+ .col-md-offset-4 {
+ margin-left: 33.33333333%
+ }
+
+ .col-md-offset-3 {
+ margin-left: 25%
+ }
+
+ .col-md-offset-2 {
+ margin-left: 16.66666667%
+ }
+
+ .col-md-offset-1 {
+ margin-left: 8.33333333%
+ }
+
+ .col-md-offset-0 {
+ margin-left: 0
+ }
+}
+
+@media (min-width: 1200px) {
+ .col-lg-1, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9 {
+ float: left
+ }
+
+ .col-lg-12 {
+ width: 100%
+ }
+
+ .col-lg-11 {
+ width: 91.66666667%
+ }
+
+ .col-lg-10 {
+ width: 83.33333333%
+ }
+
+ .col-lg-9 {
+ width: 75%
+ }
+
+ .col-lg-8 {
+ width: 66.66666667%
+ }
+
+ .col-lg-7 {
+ width: 58.33333333%
+ }
+
+ .col-lg-6 {
+ width: 50%
+ }
+
+ .col-lg-5 {
+ width: 41.66666667%
+ }
+
+ .col-lg-4 {
+ width: 33.33333333%
+ }
+
+ .col-lg-3 {
+ width: 25%
+ }
+
+ .col-lg-2 {
+ width: 16.66666667%
+ }
+
+ .col-lg-1 {
+ width: 8.33333333%
+ }
+
+ .col-lg-pull-12 {
+ right: 100%
+ }
+
+ .col-lg-pull-11 {
+ right: 91.66666667%
+ }
+
+ .col-lg-pull-10 {
+ right: 83.33333333%
+ }
+
+ .col-lg-pull-9 {
+ right: 75%
+ }
+
+ .col-lg-pull-8 {
+ right: 66.66666667%
+ }
+
+ .col-lg-pull-7 {
+ right: 58.33333333%
+ }
+
+ .col-lg-pull-6 {
+ right: 50%
+ }
+
+ .col-lg-pull-5 {
+ right: 41.66666667%
+ }
+
+ .col-lg-pull-4 {
+ right: 33.33333333%
+ }
+
+ .col-lg-pull-3 {
+ right: 25%
+ }
+
+ .col-lg-pull-2 {
+ right: 16.66666667%
+ }
+
+ .col-lg-pull-1 {
+ right: 8.33333333%
+ }
+
+ .col-lg-pull-0 {
+ right: auto
+ }
+
+ .col-lg-push-12 {
+ left: 100%
+ }
+
+ .col-lg-push-11 {
+ left: 91.66666667%
+ }
+
+ .col-lg-push-10 {
+ left: 83.33333333%
+ }
+
+ .col-lg-push-9 {
+ left: 75%
+ }
+
+ .col-lg-push-8 {
+ left: 66.66666667%
+ }
+
+ .col-lg-push-7 {
+ left: 58.33333333%
+ }
+
+ .col-lg-push-6 {
+ left: 50%
+ }
+
+ .col-lg-push-5 {
+ left: 41.66666667%
+ }
+
+ .col-lg-push-4 {
+ left: 33.33333333%
+ }
+
+ .col-lg-push-3 {
+ left: 25%
+ }
+
+ .col-lg-push-2 {
+ left: 16.66666667%
+ }
+
+ .col-lg-push-1 {
+ left: 8.33333333%
+ }
+
+ .col-lg-push-0 {
+ left: auto
+ }
+
+ .col-lg-offset-12 {
+ margin-left: 100%
+ }
+
+ .col-lg-offset-11 {
+ margin-left: 91.66666667%
+ }
+
+ .col-lg-offset-10 {
+ margin-left: 83.33333333%
+ }
+
+ .col-lg-offset-9 {
+ margin-left: 75%
+ }
+
+ .col-lg-offset-8 {
+ margin-left: 66.66666667%
+ }
+
+ .col-lg-offset-7 {
+ margin-left: 58.33333333%
+ }
+
+ .col-lg-offset-6 {
+ margin-left: 50%
+ }
+
+ .col-lg-offset-5 {
+ margin-left: 41.66666667%
+ }
+
+ .col-lg-offset-4 {
+ margin-left: 33.33333333%
+ }
+
+ .col-lg-offset-3 {
+ margin-left: 25%
+ }
+
+ .col-lg-offset-2 {
+ margin-left: 16.66666667%
+ }
+
+ .col-lg-offset-1 {
+ margin-left: 8.33333333%
+ }
+
+ .col-lg-offset-0 {
+ margin-left: 0
+ }
+}
+
+table {
+ background-color: transparent
+}
+
+caption {
+ padding-top: 8px;
+ padding-bottom: 8px;
+ color: #777;
+ text-align: left
+}
+
+th {
+ text-align: left
+}
+
+.table {
+ width: 100%;
+ max-width: 100%;
+ margin-bottom: 20px
+}
+
+.table > tbody > tr > td, .table > tbody > tr > th, .table > tfoot > tr > td, .table > tfoot > tr > th, .table > thead > tr > td, .table > thead > tr > th {
+ padding: 8px;
+ line-height: 1.42857143;
+ vertical-align: top;
+ border-top: 1px solid #ddd
+}
+
+.table > thead > tr > th {
+ vertical-align: bottom;
+ border-bottom: 2px solid #ddd
+}
+
+.table > caption + thead > tr:first-child > td, .table > caption + thead > tr:first-child > th, .table > colgroup + thead > tr:first-child > td, .table > colgroup + thead > tr:first-child > th, .table > thead:first-child > tr:first-child > td, .table > thead:first-child > tr:first-child > th {
+ border-top: 0
+}
+
+.table > tbody + tbody {
+ border-top: 2px solid #ddd
+}
+
+.table .table {
+ background-color: #fff
+}
+
+.table-condensed > tbody > tr > td, .table-condensed > tbody > tr > th, .table-condensed > tfoot > tr > td, .table-condensed > tfoot > tr > th, .table-condensed > thead > tr > td, .table-condensed > thead > tr > th {
+ padding: 5px
+}
+
+.table-bordered {
+ border: 1px solid #ddd
+}
+
+.table-bordered > tbody > tr > td, .table-bordered > tbody > tr > th, .table-bordered > tfoot > tr > td, .table-bordered > tfoot > tr > th, .table-bordered > thead > tr > td, .table-bordered > thead > tr > th {
+ border: 1px solid #ddd
+}
+
+.table-bordered > thead > tr > td, .table-bordered > thead > tr > th {
+ border-bottom-width: 2px
+}
+
+.table-striped > tbody > tr:nth-of-type(odd) {
+ background-color: #f9f9f9
+}
+
+.table-hover > tbody > tr:hover {
+ background-color: #f5f5f5
+}
+
+table col[class*=col-] {
+ position: static;
+ display: table-column;
+ float: none
+}
+
+table td[class*=col-], table th[class*=col-] {
+ position: static;
+ display: table-cell;
+ float: none
+}
+
+.table > tbody > tr.active > td, .table > tbody > tr.active > th, .table > tbody > tr > td.active, .table > tbody > tr > th.active, .table > tfoot > tr.active > td, .table > tfoot > tr.active > th, .table > tfoot > tr > td.active, .table > tfoot > tr > th.active, .table > thead > tr.active > td, .table > thead > tr.active > th, .table > thead > tr > td.active, .table > thead > tr > th.active {
+ background-color: #f5f5f5
+}
+
+.table-hover > tbody > tr.active:hover > td, .table-hover > tbody > tr.active:hover > th, .table-hover > tbody > tr:hover > .active, .table-hover > tbody > tr > td.active:hover, .table-hover > tbody > tr > th.active:hover {
+ background-color: #e8e8e8
+}
+
+.table > tbody > tr.success > td, .table > tbody > tr.success > th, .table > tbody > tr > td.success, .table > tbody > tr > th.success, .table > tfoot > tr.success > td, .table > tfoot > tr.success > th, .table > tfoot > tr > td.success, .table > tfoot > tr > th.success, .table > thead > tr.success > td, .table > thead > tr.success > th, .table > thead > tr > td.success, .table > thead > tr > th.success {
+ background-color: #dff0d8
+}
+
+.table-hover > tbody > tr.success:hover > td, .table-hover > tbody > tr.success:hover > th, .table-hover > tbody > tr:hover > .success, .table-hover > tbody > tr > td.success:hover, .table-hover > tbody > tr > th.success:hover {
+ background-color: #d0e9c6
+}
+
+.table > tbody > tr.info > td, .table > tbody > tr.info > th, .table > tbody > tr > td.info, .table > tbody > tr > th.info, .table > tfoot > tr.info > td, .table > tfoot > tr.info > th, .table > tfoot > tr > td.info, .table > tfoot > tr > th.info, .table > thead > tr.info > td, .table > thead > tr.info > th, .table > thead > tr > td.info, .table > thead > tr > th.info {
+ background-color: #d9edf7
+}
+
+.table-hover > tbody > tr.info:hover > td, .table-hover > tbody > tr.info:hover > th, .table-hover > tbody > tr:hover > .info, .table-hover > tbody > tr > td.info:hover, .table-hover > tbody > tr > th.info:hover {
+ background-color: #c4e3f3
+}
+
+.table > tbody > tr.warning > td, .table > tbody > tr.warning > th, .table > tbody > tr > td.warning, .table > tbody > tr > th.warning, .table > tfoot > tr.warning > td, .table > tfoot > tr.warning > th, .table > tfoot > tr > td.warning, .table > tfoot > tr > th.warning, .table > thead > tr.warning > td, .table > thead > tr.warning > th, .table > thead > tr > td.warning, .table > thead > tr > th.warning {
+ background-color: #fcf8e3
+}
+
+.table-hover > tbody > tr.warning:hover > td, .table-hover > tbody > tr.warning:hover > th, .table-hover > tbody > tr:hover > .warning, .table-hover > tbody > tr > td.warning:hover, .table-hover > tbody > tr > th.warning:hover {
+ background-color: #faf2cc
+}
+
+.table > tbody > tr.danger > td, .table > tbody > tr.danger > th, .table > tbody > tr > td.danger, .table > tbody > tr > th.danger, .table > tfoot > tr.danger > td, .table > tfoot > tr.danger > th, .table > tfoot > tr > td.danger, .table > tfoot > tr > th.danger, .table > thead > tr.danger > td, .table > thead > tr.danger > th, .table > thead > tr > td.danger, .table > thead > tr > th.danger {
+ background-color: #f2dede
+}
+
+.table-hover > tbody > tr.danger:hover > td, .table-hover > tbody > tr.danger:hover > th, .table-hover > tbody > tr:hover > .danger, .table-hover > tbody > tr > td.danger:hover, .table-hover > tbody > tr > th.danger:hover {
+ background-color: #ebcccc
+}
+
+.table-responsive {
+ min-height: .01%;
+ overflow-x: auto
+}
+
+@media screen and (max-width: 767px) {
+ .table-responsive {
+ width: 100%;
+ margin-bottom: 15px;
+ overflow-y: hidden;
+ -ms-overflow-style: -ms-autohiding-scrollbar;
+ border: 1px solid #ddd
+ }
+
+ .table-responsive > .table {
+ margin-bottom: 0
+ }
+
+ .table-responsive > .table > tbody > tr > td, .table-responsive > .table > tbody > tr > th, .table-responsive > .table > tfoot > tr > td, .table-responsive > .table > tfoot > tr > th, .table-responsive > .table > thead > tr > td, .table-responsive > .table > thead > tr > th {
+ white-space: nowrap
+ }
+
+ .table-responsive > .table-bordered {
+ border: 0
+ }
+
+ .table-responsive > .table-bordered > tbody > tr > td:first-child, .table-responsive > .table-bordered > tbody > tr > th:first-child, .table-responsive > .table-bordered > tfoot > tr > td:first-child, .table-responsive > .table-bordered > tfoot > tr > th:first-child, .table-responsive > .table-bordered > thead > tr > td:first-child, .table-responsive > .table-bordered > thead > tr > th:first-child {
+ border-left: 0
+ }
+
+ .table-responsive > .table-bordered > tbody > tr > td:last-child, .table-responsive > .table-bordered > tbody > tr > th:last-child, .table-responsive > .table-bordered > tfoot > tr > td:last-child, .table-responsive > .table-bordered > tfoot > tr > th:last-child, .table-responsive > .table-bordered > thead > tr > td:last-child, .table-responsive > .table-bordered > thead > tr > th:last-child {
+ border-right: 0
+ }
+
+ .table-responsive > .table-bordered > tbody > tr:last-child > td, .table-responsive > .table-bordered > tbody > tr:last-child > th, .table-responsive > .table-bordered > tfoot > tr:last-child > td, .table-responsive > .table-bordered > tfoot > tr:last-child > th {
+ border-bottom: 0
+ }
+}
+
+fieldset {
+ min-width: 0;
+ padding: 0;
+ margin: 0;
+ border: 0
+}
+
+legend {
+ display: block;
+ width: 100%;
+ padding: 0;
+ margin-bottom: 20px;
+ font-size: 21px;
+ line-height: inherit;
+ color: #333;
+ border: 0;
+ border-bottom: 1px solid #e5e5e5
+}
+
+label {
+ display: inline-block;
+ max-width: 100%;
+ margin-bottom: 5px;
+ font-weight: 700
+}
+
+input[type=search] {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box
+}
+
+input[type=checkbox], input[type=radio] {
+ margin: 4px 0 0;
+ margin-top: 1px \9;
+ line-height: normal
+}
+
+input[type=file] {
+ display: block
+}
+
+input[type=range] {
+ display: block;
+ width: 100%
+}
+
+select[multiple], select[size] {
+ height: auto
+}
+
+input[type=file]:focus, input[type=checkbox]:focus, input[type=radio]:focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px
+}
+
+output {
+ display: block;
+ padding-top: 7px;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #555
+}
+
+.form-control {
+ display: block;
+ width: 100%;
+ height: 34px;
+ padding: 6px 12px;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #555;
+ background-color: #fff;
+ background-image: none;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
+ -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+ transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s
+}
+
+.form-control:focus {
+ border-color: #66afe9;
+ outline: 0;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6)
+}
+
+.form-control::-moz-placeholder {
+ color: #999;
+ opacity: 1
+}
+
+.form-control:-ms-input-placeholder {
+ color: #999
+}
+
+.form-control::-webkit-input-placeholder {
+ color: #999
+}
+
+.form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control {
+ background-color: #eee;
+ opacity: 1
+}
+
+.form-control[disabled], fieldset[disabled] .form-control {
+ cursor: not-allowed
+}
+
+textarea.form-control {
+ height: auto
+}
+
+input[type=search] {
+ -webkit-appearance: none
+}
+
+@media screen and (-webkit-min-device-pixel-ratio: 0) {
+ input[type=date].form-control, input[type=time].form-control, input[type=datetime-local].form-control, input[type=month].form-control {
+ line-height: 34px
+ }
+
+ .input-group-sm input[type=date], .input-group-sm input[type=time], .input-group-sm input[type=datetime-local], .input-group-sm input[type=month], input[type=date].input-sm, input[type=time].input-sm, input[type=datetime-local].input-sm, input[type=month].input-sm {
+ line-height: 30px
+ }
+
+ .input-group-lg input[type=date], .input-group-lg input[type=time], .input-group-lg input[type=datetime-local], .input-group-lg input[type=month], input[type=date].input-lg, input[type=time].input-lg, input[type=datetime-local].input-lg, input[type=month].input-lg {
+ line-height: 46px
+ }
+}
+
+.form-group {
+ margin-bottom: 15px
+}
+
+.checkbox, .radio {
+ position: relative;
+ display: block;
+ margin-top: 10px;
+ margin-bottom: 10px
+}
+
+.checkbox label, .radio label {
+ min-height: 20px;
+ padding-left: 20px;
+ margin-bottom: 0;
+ font-weight: 400;
+ cursor: pointer
+}
+
+.checkbox input[type=checkbox], .checkbox-inline input[type=checkbox], .radio input[type=radio], .radio-inline input[type=radio] {
+ position: absolute;
+ margin-top: 4px \9;
+ margin-left: -20px
+}
+
+.checkbox + .checkbox, .radio + .radio {
+ margin-top: -5px
+}
+
+.checkbox-inline, .radio-inline {
+ position: relative;
+ display: inline-block;
+ padding-left: 20px;
+ margin-bottom: 0;
+ font-weight: 400;
+ vertical-align: middle;
+ cursor: pointer
+}
+
+.checkbox-inline + .checkbox-inline, .radio-inline + .radio-inline {
+ margin-top: 0;
+ margin-left: 10px
+}
+
+fieldset[disabled] input[type=checkbox], fieldset[disabled] input[type=radio], input[type=checkbox].disabled, input[type=checkbox][disabled], input[type=radio].disabled, input[type=radio][disabled] {
+ cursor: not-allowed
+}
+
+.checkbox-inline.disabled, .radio-inline.disabled, fieldset[disabled] .checkbox-inline, fieldset[disabled] .radio-inline {
+ cursor: not-allowed
+}
+
+.checkbox.disabled label, .radio.disabled label, fieldset[disabled] .checkbox label, fieldset[disabled] .radio label {
+ cursor: not-allowed
+}
+
+.form-control-static {
+ min-height: 34px;
+ padding-top: 7px;
+ padding-bottom: 7px;
+ margin-bottom: 0
+}
+
+.form-control-static.input-lg, .form-control-static.input-sm {
+ padding-right: 0;
+ padding-left: 0
+}
+
+.input-sm {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px
+}
+
+select.input-sm {
+ height: 30px;
+ line-height: 30px
+}
+
+select[multiple].input-sm, textarea.input-sm {
+ height: auto
+}
+
+.form-group-sm .form-control {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px
+}
+
+.form-group-sm select.form-control {
+ height: 30px;
+ line-height: 30px
+}
+
+.form-group-sm select[multiple].form-control, .form-group-sm textarea.form-control {
+ height: auto
+}
+
+.form-group-sm .form-control-static {
+ height: 30px;
+ min-height: 32px;
+ padding: 6px 10px;
+ font-size: 12px;
+ line-height: 1.5
+}
+
+.input-lg {
+ height: 46px;
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 6px
+}
+
+select.input-lg {
+ height: 46px;
+ line-height: 46px
+}
+
+select[multiple].input-lg, textarea.input-lg {
+ height: auto
+}
+
+.form-group-lg .form-control {
+ height: 46px;
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 6px
+}
+
+.form-group-lg select.form-control {
+ height: 46px;
+ line-height: 46px
+}
+
+.form-group-lg select[multiple].form-control, .form-group-lg textarea.form-control {
+ height: auto
+}
+
+.form-group-lg .form-control-static {
+ height: 46px;
+ min-height: 38px;
+ padding: 11px 16px;
+ font-size: 18px;
+ line-height: 1.3333333
+}
+
+.has-feedback {
+ position: relative
+}
+
+.has-feedback .form-control {
+ padding-right: 42.5px
+}
+
+.form-control-feedback {
+ position: absolute;
+ top: 0;
+ right: 0;
+ z-index: 2;
+ display: block;
+ width: 34px;
+ height: 34px;
+ line-height: 34px;
+ text-align: center;
+ pointer-events: none
+}
+
+.form-group-lg .form-control + .form-control-feedback, .input-group-lg + .form-control-feedback, .input-lg + .form-control-feedback {
+ width: 46px;
+ height: 46px;
+ line-height: 46px
+}
+
+.form-group-sm .form-control + .form-control-feedback, .input-group-sm + .form-control-feedback, .input-sm + .form-control-feedback {
+ width: 30px;
+ height: 30px;
+ line-height: 30px
+}
+
+.has-success .checkbox, .has-success .checkbox-inline, .has-success .control-label, .has-success .help-block, .has-success .radio, .has-success .radio-inline, .has-success.checkbox label, .has-success.checkbox-inline label, .has-success.radio label, .has-success.radio-inline label {
+ color: #3c763d
+}
+
+.has-success .form-control {
+ border-color: #3c763d;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075)
+}
+
+.has-success .form-control:focus {
+ border-color: #2b542c;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168
+}
+
+.has-success .input-group-addon {
+ color: #3c763d;
+ background-color: #dff0d8;
+ border-color: #3c763d
+}
+
+.has-success .form-control-feedback {
+ color: #3c763d
+}
+
+.has-warning .checkbox, .has-warning .checkbox-inline, .has-warning .control-label, .has-warning .help-block, .has-warning .radio, .has-warning .radio-inline, .has-warning.checkbox label, .has-warning.checkbox-inline label, .has-warning.radio label, .has-warning.radio-inline label {
+ color: #8a6d3b
+}
+
+.has-warning .form-control {
+ border-color: #8a6d3b;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075)
+}
+
+.has-warning .form-control:focus {
+ border-color: #66512c;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b
+}
+
+.has-warning .input-group-addon {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+ border-color: #8a6d3b
+}
+
+.has-warning .form-control-feedback {
+ color: #8a6d3b
+}
+
+.has-error .checkbox, .has-error .checkbox-inline, .has-error .control-label, .has-error .help-block, .has-error .radio, .has-error .radio-inline, .has-error.checkbox label, .has-error.checkbox-inline label, .has-error.radio label, .has-error.radio-inline label {
+ color: #a94442
+}
+
+.has-error .form-control {
+ border-color: #a94442;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075)
+}
+
+.has-error .form-control:focus {
+ border-color: #843534;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483
+}
+
+.has-error .input-group-addon {
+ color: #a94442;
+ background-color: #f2dede;
+ border-color: #a94442
+}
+
+.has-error .form-control-feedback {
+ color: #a94442
+}
+
+.has-feedback label ~ .form-control-feedback {
+ top: 25px
+}
+
+.has-feedback label.sr-only ~ .form-control-feedback {
+ top: 0
+}
+
+.help-block {
+ display: block;
+ margin-top: 5px;
+ margin-bottom: 10px;
+ color: #737373
+}
+
+@media (min-width: 768px) {
+ .form-inline .form-group {
+ display: inline-block;
+ margin-bottom: 0;
+ vertical-align: middle
+ }
+
+ .form-inline .form-control {
+ display: inline-block;
+ width: auto;
+ vertical-align: middle
+ }
+
+ .form-inline .form-control-static {
+ display: inline-block
+ }
+
+ .form-inline .input-group {
+ display: inline-table;
+ vertical-align: middle
+ }
+
+ .form-inline .input-group .form-control, .form-inline .input-group .input-group-addon, .form-inline .input-group .input-group-btn {
+ width: auto
+ }
+
+ .form-inline .input-group > .form-control {
+ width: 100%
+ }
+
+ .form-inline .control-label {
+ margin-bottom: 0;
+ vertical-align: middle
+ }
+
+ .form-inline .checkbox, .form-inline .radio {
+ display: inline-block;
+ margin-top: 0;
+ margin-bottom: 0;
+ vertical-align: middle
+ }
+
+ .form-inline .checkbox label, .form-inline .radio label {
+ padding-left: 0
+ }
+
+ .form-inline .checkbox input[type=checkbox], .form-inline .radio input[type=radio] {
+ position: relative;
+ margin-left: 0
+ }
+
+ .form-inline .has-feedback .form-control-feedback {
+ top: 0
+ }
+}
+
+.form-horizontal .checkbox, .form-horizontal .checkbox-inline, .form-horizontal .radio, .form-horizontal .radio-inline {
+ padding-top: 7px;
+ margin-top: 0;
+ margin-bottom: 0
+}
+
+.form-horizontal .checkbox, .form-horizontal .radio {
+ min-height: 27px
+}
+
+.form-horizontal .form-group {
+ margin-right: -15px;
+ margin-left: -15px
+}
+
+@media (min-width: 768px) {
+ .form-horizontal .control-label {
+ padding-top: 7px;
+ margin-bottom: 0;
+ text-align: right
+ }
+}
+
+.form-horizontal .has-feedback .form-control-feedback {
+ right: 15px
+}
+
+@media (min-width: 768px) {
+ .form-horizontal .form-group-lg .control-label {
+ padding-top: 14.33px;
+ font-size: 18px
+ }
+}
+
+@media (min-width: 768px) {
+ .form-horizontal .form-group-sm .control-label {
+ padding-top: 6px;
+ font-size: 12px
+ }
+}
+
+.btn {
+ display: inline-block;
+ padding: 6px 12px;
+ margin-bottom: 0;
+ font-size: 14px;
+ font-weight: 400;
+ line-height: 1.42857143;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: middle;
+ -ms-touch-action: manipulation;
+ touch-action: manipulation;
+ cursor: pointer;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ background-image: none;
+ border: 1px solid transparent;
+ border-radius: 4px
+}
+
+.btn.active.focus, .btn.active:focus, .btn.focus, .btn:active.focus, .btn:active:focus, .btn:focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px
+}
+
+.btn.focus, .btn:focus, .btn:hover {
+ color: #333;
+ text-decoration: none
+}
+
+.btn.active, .btn:active {
+ background-image: none;
+ outline: 0;
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125)
+}
+
+.btn.disabled, .btn[disabled], fieldset[disabled] .btn {
+ cursor: not-allowed;
+ filter: alpha(opacity=65);
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ opacity: .65
+}
+
+a.btn.disabled, fieldset[disabled] a.btn {
+ pointer-events: none
+}
+
+.btn-default {
+ color: #333;
+ background-color: #fff;
+ border-color: #ccc
+}
+
+.btn-default.focus, .btn-default:focus {
+ color: #333;
+ background-color: #e6e6e6;
+ border-color: #8c8c8c
+}
+
+.btn-default:hover {
+ color: #333;
+ background-color: #e6e6e6;
+ border-color: #adadad
+}
+
+.btn-default.active, .btn-default:active, .open > .dropdown-toggle.btn-default {
+ color: #333;
+ background-color: #e6e6e6;
+ border-color: #adadad
+}
+
+.btn-default.active.focus, .btn-default.active:focus, .btn-default.active:hover, .btn-default:active.focus, .btn-default:active:focus, .btn-default:active:hover, .open > .dropdown-toggle.btn-default.focus, .open > .dropdown-toggle.btn-default:focus, .open > .dropdown-toggle.btn-default:hover {
+ color: #333;
+ background-color: #d4d4d4;
+ border-color: #8c8c8c
+}
+
+.btn-default.active, .btn-default:active, .open > .dropdown-toggle.btn-default {
+ background-image: none
+}
+
+.btn-default.disabled, .btn-default.disabled.active, .btn-default.disabled.focus, .btn-default.disabled:active, .btn-default.disabled:focus, .btn-default.disabled:hover, .btn-default[disabled], .btn-default[disabled].active, .btn-default[disabled].focus, .btn-default[disabled]:active, .btn-default[disabled]:focus, .btn-default[disabled]:hover, fieldset[disabled] .btn-default, fieldset[disabled] .btn-default.active, fieldset[disabled] .btn-default.focus, fieldset[disabled] .btn-default:active, fieldset[disabled] .btn-default:focus, fieldset[disabled] .btn-default:hover {
+ background-color: #fff;
+ border-color: #ccc
+}
+
+.btn-default .badge {
+ color: #fff;
+ background-color: #333
+}
+
+.btn-primary {
+ color: #fff;
+ background-color: #337ab7;
+ border-color: #2e6da4
+}
+
+.btn-primary.focus, .btn-primary:focus {
+ color: #fff;
+ background-color: #286090;
+ border-color: #122b40
+}
+
+.btn-primary:hover {
+ color: #fff;
+ background-color: #286090;
+ border-color: #204d74
+}
+
+.btn-primary.active, .btn-primary:active, .open > .dropdown-toggle.btn-primary {
+ color: #fff;
+ background-color: #286090;
+ border-color: #204d74
+}
+
+.btn-primary.active.focus, .btn-primary.active:focus, .btn-primary.active:hover, .btn-primary:active.focus, .btn-primary:active:focus, .btn-primary:active:hover, .open > .dropdown-toggle.btn-primary.focus, .open > .dropdown-toggle.btn-primary:focus, .open > .dropdown-toggle.btn-primary:hover {
+ color: #fff;
+ background-color: #204d74;
+ border-color: #122b40
+}
+
+.btn-primary.active, .btn-primary:active, .open > .dropdown-toggle.btn-primary {
+ background-image: none
+}
+
+.btn-primary.disabled, .btn-primary.disabled.active, .btn-primary.disabled.focus, .btn-primary.disabled:active, .btn-primary.disabled:focus, .btn-primary.disabled:hover, .btn-primary[disabled], .btn-primary[disabled].active, .btn-primary[disabled].focus, .btn-primary[disabled]:active, .btn-primary[disabled]:focus, .btn-primary[disabled]:hover, fieldset[disabled] .btn-primary, fieldset[disabled] .btn-primary.active, fieldset[disabled] .btn-primary.focus, fieldset[disabled] .btn-primary:active, fieldset[disabled] .btn-primary:focus, fieldset[disabled] .btn-primary:hover {
+ background-color: #337ab7;
+ border-color: #2e6da4
+}
+
+.btn-primary .badge {
+ color: #337ab7;
+ background-color: #fff
+}
+
+.btn-success {
+ color: #fff;
+ background-color: #5cb85c;
+ border-color: #4cae4c
+}
+
+.btn-success.focus, .btn-success:focus {
+ color: #fff;
+ background-color: #449d44;
+ border-color: #255625
+}
+
+.btn-success:hover {
+ color: #fff;
+ background-color: #449d44;
+ border-color: #398439
+}
+
+.btn-success.active, .btn-success:active, .open > .dropdown-toggle.btn-success {
+ color: #fff;
+ background-color: #449d44;
+ border-color: #398439
+}
+
+.btn-success.active.focus, .btn-success.active:focus, .btn-success.active:hover, .btn-success:active.focus, .btn-success:active:focus, .btn-success:active:hover, .open > .dropdown-toggle.btn-success.focus, .open > .dropdown-toggle.btn-success:focus, .open > .dropdown-toggle.btn-success:hover {
+ color: #fff;
+ background-color: #398439;
+ border-color: #255625
+}
+
+.btn-success.active, .btn-success:active, .open > .dropdown-toggle.btn-success {
+ background-image: none
+}
+
+.btn-success.disabled, .btn-success.disabled.active, .btn-success.disabled.focus, .btn-success.disabled:active, .btn-success.disabled:focus, .btn-success.disabled:hover, .btn-success[disabled], .btn-success[disabled].active, .btn-success[disabled].focus, .btn-success[disabled]:active, .btn-success[disabled]:focus, .btn-success[disabled]:hover, fieldset[disabled] .btn-success, fieldset[disabled] .btn-success.active, fieldset[disabled] .btn-success.focus, fieldset[disabled] .btn-success:active, fieldset[disabled] .btn-success:focus, fieldset[disabled] .btn-success:hover {
+ background-color: #5cb85c;
+ border-color: #4cae4c
+}
+
+.btn-success .badge {
+ color: #5cb85c;
+ background-color: #fff
+}
+
+.btn-info {
+ color: #fff;
+ background-color: #5bc0de;
+ border-color: #46b8da
+}
+
+.btn-info.focus, .btn-info:focus {
+ color: #fff;
+ background-color: #31b0d5;
+ border-color: #1b6d85
+}
+
+.btn-info:hover {
+ color: #fff;
+ background-color: #31b0d5;
+ border-color: #269abc
+}
+
+.btn-info.active, .btn-info:active, .open > .dropdown-toggle.btn-info {
+ color: #fff;
+ background-color: #31b0d5;
+ border-color: #269abc
+}
+
+.btn-info.active.focus, .btn-info.active:focus, .btn-info.active:hover, .btn-info:active.focus, .btn-info:active:focus, .btn-info:active:hover, .open > .dropdown-toggle.btn-info.focus, .open > .dropdown-toggle.btn-info:focus, .open > .dropdown-toggle.btn-info:hover {
+ color: #fff;
+ background-color: #269abc;
+ border-color: #1b6d85
+}
+
+.btn-info.active, .btn-info:active, .open > .dropdown-toggle.btn-info {
+ background-image: none
+}
+
+.btn-info.disabled, .btn-info.disabled.active, .btn-info.disabled.focus, .btn-info.disabled:active, .btn-info.disabled:focus, .btn-info.disabled:hover, .btn-info[disabled], .btn-info[disabled].active, .btn-info[disabled].focus, .btn-info[disabled]:active, .btn-info[disabled]:focus, .btn-info[disabled]:hover, fieldset[disabled] .btn-info, fieldset[disabled] .btn-info.active, fieldset[disabled] .btn-info.focus, fieldset[disabled] .btn-info:active, fieldset[disabled] .btn-info:focus, fieldset[disabled] .btn-info:hover {
+ background-color: #5bc0de;
+ border-color: #46b8da
+}
+
+.btn-info .badge {
+ color: #5bc0de;
+ background-color: #fff
+}
+
+.btn-warning {
+ color: #fff;
+ background-color: #f0ad4e;
+ border-color: #eea236
+}
+
+.btn-warning.focus, .btn-warning:focus {
+ color: #fff;
+ background-color: #ec971f;
+ border-color: #985f0d
+}
+
+.btn-warning:hover {
+ color: #fff;
+ background-color: #ec971f;
+ border-color: #d58512
+}
+
+.btn-warning.active, .btn-warning:active, .open > .dropdown-toggle.btn-warning {
+ color: #fff;
+ background-color: #ec971f;
+ border-color: #d58512
+}
+
+.btn-warning.active.focus, .btn-warning.active:focus, .btn-warning.active:hover, .btn-warning:active.focus, .btn-warning:active:focus, .btn-warning:active:hover, .open > .dropdown-toggle.btn-warning.focus, .open > .dropdown-toggle.btn-warning:focus, .open > .dropdown-toggle.btn-warning:hover {
+ color: #fff;
+ background-color: #d58512;
+ border-color: #985f0d
+}
+
+.btn-warning.active, .btn-warning:active, .open > .dropdown-toggle.btn-warning {
+ background-image: none
+}
+
+.btn-warning.disabled, .btn-warning.disabled.active, .btn-warning.disabled.focus, .btn-warning.disabled:active, .btn-warning.disabled:focus, .btn-warning.disabled:hover, .btn-warning[disabled], .btn-warning[disabled].active, .btn-warning[disabled].focus, .btn-warning[disabled]:active, .btn-warning[disabled]:focus, .btn-warning[disabled]:hover, fieldset[disabled] .btn-warning, fieldset[disabled] .btn-warning.active, fieldset[disabled] .btn-warning.focus, fieldset[disabled] .btn-warning:active, fieldset[disabled] .btn-warning:focus, fieldset[disabled] .btn-warning:hover {
+ background-color: #f0ad4e;
+ border-color: #eea236
+}
+
+.btn-warning .badge {
+ color: #f0ad4e;
+ background-color: #fff
+}
+
+.btn-danger {
+ color: #fff;
+ background-color: #d9534f;
+ border-color: #d43f3a
+}
+
+.btn-danger.focus, .btn-danger:focus {
+ color: #fff;
+ background-color: #c9302c;
+ border-color: #761c19
+}
+
+.btn-danger:hover {
+ color: #fff;
+ background-color: #c9302c;
+ border-color: #ac2925
+}
+
+.btn-danger.active, .btn-danger:active, .open > .dropdown-toggle.btn-danger {
+ color: #fff;
+ background-color: #c9302c;
+ border-color: #ac2925
+}
+
+.btn-danger.active.focus, .btn-danger.active:focus, .btn-danger.active:hover, .btn-danger:active.focus, .btn-danger:active:focus, .btn-danger:active:hover, .open > .dropdown-toggle.btn-danger.focus, .open > .dropdown-toggle.btn-danger:focus, .open > .dropdown-toggle.btn-danger:hover {
+ color: #fff;
+ background-color: #ac2925;
+ border-color: #761c19
+}
+
+.btn-danger.active, .btn-danger:active, .open > .dropdown-toggle.btn-danger {
+ background-image: none
+}
+
+.btn-danger.disabled, .btn-danger.disabled.active, .btn-danger.disabled.focus, .btn-danger.disabled:active, .btn-danger.disabled:focus, .btn-danger.disabled:hover, .btn-danger[disabled], .btn-danger[disabled].active, .btn-danger[disabled].focus, .btn-danger[disabled]:active, .btn-danger[disabled]:focus, .btn-danger[disabled]:hover, fieldset[disabled] .btn-danger, fieldset[disabled] .btn-danger.active, fieldset[disabled] .btn-danger.focus, fieldset[disabled] .btn-danger:active, fieldset[disabled] .btn-danger:focus, fieldset[disabled] .btn-danger:hover {
+ background-color: #d9534f;
+ border-color: #d43f3a
+}
+
+.btn-danger .badge {
+ color: #d9534f;
+ background-color: #fff
+}
+
+.btn-link {
+ font-weight: 400;
+ color: #337ab7;
+ border-radius: 0
+}
+
+.btn-link, .btn-link.active, .btn-link:active, .btn-link[disabled], fieldset[disabled] .btn-link {
+ background-color: transparent;
+ -webkit-box-shadow: none;
+ box-shadow: none
+}
+
+.btn-link, .btn-link:active, .btn-link:focus, .btn-link:hover {
+ border-color: transparent
+}
+
+.btn-link:focus, .btn-link:hover {
+ color: #23527c;
+ text-decoration: underline;
+ background-color: transparent
+}
+
+.btn-link[disabled]:focus, .btn-link[disabled]:hover, fieldset[disabled] .btn-link:focus, fieldset[disabled] .btn-link:hover {
+ color: #777;
+ text-decoration: none
+}
+
+.btn-group-lg > .btn, .btn-lg {
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 6px
+}
+
+.btn-group-sm > .btn, .btn-sm {
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px
+}
+
+.btn-group-xs > .btn, .btn-xs {
+ padding: 1px 5px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px
+}
+
+.btn-block {
+ display: block;
+ width: 100%
+}
+
+.btn-block + .btn-block {
+ margin-top: 5px
+}
+
+input[type=button].btn-block, input[type=reset].btn-block, input[type=submit].btn-block {
+ width: 100%
+}
+
+.fade {
+ opacity: 0;
+ -webkit-transition: opacity .15s linear;
+ -o-transition: opacity .15s linear;
+ transition: opacity .15s linear
+}
+
+.fade.in {
+ opacity: 1
+}
+
+.collapse {
+ display: none
+}
+
+.collapse.in {
+ display: block
+}
+
+tr.collapse.in {
+ display: table-row
+}
+
+tbody.collapse.in {
+ display: table-row-group
+}
+
+.collapsing {
+ position: relative;
+ height: 0;
+ overflow: hidden;
+ -webkit-transition-timing-function: ease;
+ -o-transition-timing-function: ease;
+ transition-timing-function: ease;
+ -webkit-transition-duration: .35s;
+ -o-transition-duration: .35s;
+ transition-duration: .35s;
+ -webkit-transition-property: height, visibility;
+ -o-transition-property: height, visibility;
+ transition-property: height, visibility
+}
+
+.caret {
+ display: inline-block;
+ width: 0;
+ height: 0;
+ margin-left: 2px;
+ vertical-align: middle;
+ border-top: 4px dashed;
+ border-top: 4px solid \9;
+ border-right: 4px solid transparent;
+ border-left: 4px solid transparent
+}
+
+.dropdown, .dropup {
+ position: relative
+}
+
+.dropdown-toggle:focus {
+ outline: 0
+}
+
+.dropdown-menu {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ z-index: 1000;
+ display: none;
+ float: left;
+ min-width: 160px;
+ padding: 5px 0;
+ margin: 2px 0 0;
+ font-size: 14px;
+ text-align: left;
+ list-style: none;
+ background-color: #fff;
+ -webkit-background-clip: padding-box;
+ background-clip: padding-box;
+ border: 1px solid #ccc;
+ border: 1px solid rgba(0, 0, 0, .15);
+ border-radius: 4px;
+ -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
+ box-shadow: 0 6px 12px rgba(0, 0, 0, .175)
+}
+
+.dropdown-menu.pull-right {
+ right: 0;
+ left: auto
+}
+
+.dropdown-menu .divider {
+ height: 1px;
+ margin: 9px 0;
+ overflow: hidden;
+ background-color: #e5e5e5
+}
+
+.dropdown-menu > li > a {
+ display: block;
+ padding: 3px 20px;
+ clear: both;
+ font-weight: 400;
+ line-height: 1.42857143;
+ color: #333;
+ white-space: nowrap
+}
+
+.dropdown-menu > li > a:focus, .dropdown-menu > li > a:hover {
+ color: #262626;
+ text-decoration: none;
+ background-color: #f5f5f5
+}
+
+.dropdown-menu > .active > a, .dropdown-menu > .active > a:focus, .dropdown-menu > .active > a:hover {
+ color: #fff;
+ text-decoration: none;
+ background-color: #337ab7;
+ outline: 0
+}
+
+.dropdown-menu > .disabled > a, .dropdown-menu > .disabled > a:focus, .dropdown-menu > .disabled > a:hover {
+ color: #777
+}
+
+.dropdown-menu > .disabled > a:focus, .dropdown-menu > .disabled > a:hover {
+ text-decoration: none;
+ cursor: not-allowed;
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false)
+}
+
+.open > .dropdown-menu {
+ display: block
+}
+
+.open > a {
+ outline: 0
+}
+
+.dropdown-menu-right {
+ right: 0;
+ left: auto
+}
+
+.dropdown-menu-left {
+ right: auto;
+ left: 0
+}
+
+.dropdown-header {
+ display: block;
+ padding: 3px 20px;
+ font-size: 12px;
+ line-height: 1.42857143;
+ color: #777;
+ white-space: nowrap
+}
+
+.dropdown-backdrop {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 990
+}
+
+.pull-right > .dropdown-menu {
+ right: 0;
+ left: auto
+}
+
+.dropup .caret, .navbar-fixed-bottom .dropdown .caret {
+ content: "";
+ border-top: 0;
+ border-bottom: 4px dashed;
+ border-bottom: 4px solid \9
+}
+
+.dropup .dropdown-menu, .navbar-fixed-bottom .dropdown .dropdown-menu {
+ top: auto;
+ bottom: 100%;
+ margin-bottom: 2px
+}
+
+@media (min-width: 768px) {
+ .navbar-right .dropdown-menu {
+ right: 0;
+ left: auto
+ }
+
+ .navbar-right .dropdown-menu-left {
+ right: auto;
+ left: 0
+ }
+}
+
+.btn-group, .btn-group-vertical {
+ position: relative;
+ display: inline-block;
+ vertical-align: middle
+}
+
+.btn-group-vertical > .btn, .btn-group > .btn {
+ position: relative;
+ float: left
+}
+
+.btn-group-vertical > .btn.active, .btn-group-vertical > .btn:active, .btn-group-vertical > .btn:focus, .btn-group-vertical > .btn:hover, .btn-group > .btn.active, .btn-group > .btn:active, .btn-group > .btn:focus, .btn-group > .btn:hover {
+ z-index: 2
+}
+
+.btn-group .btn + .btn, .btn-group .btn + .btn-group, .btn-group .btn-group + .btn, .btn-group .btn-group + .btn-group {
+ margin-left: -1px
+}
+
+.btn-toolbar {
+ margin-left: -5px
+}
+
+.btn-toolbar .btn, .btn-toolbar .btn-group, .btn-toolbar .input-group {
+ float: left
+}
+
+.btn-toolbar > .btn, .btn-toolbar > .btn-group, .btn-toolbar > .input-group {
+ margin-left: 5px
+}
+
+.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
+ border-radius: 0
+}
+
+.btn-group > .btn:first-child {
+ margin-left: 0
+}
+
+.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0
+}
+
+.btn-group > .btn:last-child:not(:first-child), .btn-group > .dropdown-toggle:not(:first-child) {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0
+}
+
+.btn-group > .btn-group {
+ float: left
+}
+
+.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
+ border-radius: 0
+}
+
+.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child, .btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0
+}
+
+.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0
+}
+
+.btn-group .dropdown-toggle:active, .btn-group.open .dropdown-toggle {
+ outline: 0
+}
+
+.btn-group > .btn + .dropdown-toggle {
+ padding-right: 8px;
+ padding-left: 8px
+}
+
+.btn-group > .btn-lg + .dropdown-toggle {
+ padding-right: 12px;
+ padding-left: 12px
+}
+
+.btn-group.open .dropdown-toggle {
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125)
+}
+
+.btn-group.open .dropdown-toggle.btn-link {
+ -webkit-box-shadow: none;
+ box-shadow: none
+}
+
+.btn .caret {
+ margin-left: 0
+}
+
+.btn-lg .caret {
+ border-width: 5px 5px 0;
+ border-bottom-width: 0
+}
+
+.dropup .btn-lg .caret {
+ border-width: 0 5px 5px
+}
+
+.btn-group-vertical > .btn, .btn-group-vertical > .btn-group, .btn-group-vertical > .btn-group > .btn {
+ display: block;
+ float: none;
+ width: 100%;
+ max-width: 100%
+}
+
+.btn-group-vertical > .btn-group > .btn {
+ float: none
+}
+
+.btn-group-vertical > .btn + .btn, .btn-group-vertical > .btn + .btn-group, .btn-group-vertical > .btn-group + .btn, .btn-group-vertical > .btn-group + .btn-group {
+ margin-top: -1px;
+ margin-left: 0
+}
+
+.btn-group-vertical > .btn:not(:first-child):not(:last-child) {
+ border-radius: 0
+}
+
+.btn-group-vertical > .btn:first-child:not(:last-child) {
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0
+}
+
+.btn-group-vertical > .btn:last-child:not(:first-child) {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ border-bottom-left-radius: 4px
+}
+
+.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
+ border-radius: 0
+}
+
+.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, .btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0
+}
+
+.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0
+}
+
+.btn-group-justified {
+ display: table;
+ width: 100%;
+ table-layout: fixed;
+ border-collapse: separate
+}
+
+.btn-group-justified > .btn, .btn-group-justified > .btn-group {
+ display: table-cell;
+ float: none;
+ width: 1%
+}
+
+.btn-group-justified > .btn-group .btn {
+ width: 100%
+}
+
+.btn-group-justified > .btn-group .dropdown-menu {
+ left: auto
+}
+
+[data-toggle=buttons] > .btn input[type=checkbox], [data-toggle=buttons] > .btn input[type=radio], [data-toggle=buttons] > .btn-group > .btn input[type=checkbox], [data-toggle=buttons] > .btn-group > .btn input[type=radio] {
+ position: absolute;
+ clip: rect(0, 0, 0, 0);
+ pointer-events: none
+}
+
+.input-group {
+ position: relative;
+ display: table;
+ border-collapse: separate
+}
+
+.input-group[class*=col-] {
+ float: none;
+ padding-right: 0;
+ padding-left: 0
+}
+
+.input-group .form-control {
+ position: relative;
+ z-index: 2;
+ float: left;
+ width: 100%;
+ margin-bottom: 0
+}
+
+.input-group-lg > .form-control, .input-group-lg > .input-group-addon, .input-group-lg > .input-group-btn > .btn {
+ height: 46px;
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 6px
+}
+
+select.input-group-lg > .form-control, select.input-group-lg > .input-group-addon, select.input-group-lg > .input-group-btn > .btn {
+ height: 46px;
+ line-height: 46px
+}
+
+select[multiple].input-group-lg > .form-control, select[multiple].input-group-lg > .input-group-addon, select[multiple].input-group-lg > .input-group-btn > .btn, textarea.input-group-lg > .form-control, textarea.input-group-lg > .input-group-addon, textarea.input-group-lg > .input-group-btn > .btn {
+ height: auto
+}
+
+.input-group-sm > .form-control, .input-group-sm > .input-group-addon, .input-group-sm > .input-group-btn > .btn {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px
+}
+
+select.input-group-sm > .form-control, select.input-group-sm > .input-group-addon, select.input-group-sm > .input-group-btn > .btn {
+ height: 30px;
+ line-height: 30px
+}
+
+select[multiple].input-group-sm > .form-control, select[multiple].input-group-sm > .input-group-addon, select[multiple].input-group-sm > .input-group-btn > .btn, textarea.input-group-sm > .form-control, textarea.input-group-sm > .input-group-addon, textarea.input-group-sm > .input-group-btn > .btn {
+ height: auto
+}
+
+.input-group .form-control, .input-group-addon, .input-group-btn {
+ display: table-cell
+}
+
+.input-group .form-control:not(:first-child):not(:last-child), .input-group-addon:not(:first-child):not(:last-child), .input-group-btn:not(:first-child):not(:last-child) {
+ border-radius: 0
+}
+
+.input-group-addon, .input-group-btn {
+ width: 1%;
+ white-space: nowrap;
+ vertical-align: middle
+}
+
+.input-group-addon {
+ padding: 6px 12px;
+ font-size: 14px;
+ font-weight: 400;
+ line-height: 1;
+ color: #555;
+ text-align: center;
+ background-color: #eee;
+ border: 1px solid #ccc;
+ border-radius: 4px
+}
+
+.input-group-addon.input-sm {
+ padding: 5px 10px;
+ font-size: 12px;
+ border-radius: 3px
+}
+
+.input-group-addon.input-lg {
+ padding: 10px 16px;
+ font-size: 18px;
+ border-radius: 6px
+}
+
+.input-group-addon input[type=checkbox], .input-group-addon input[type=radio] {
+ margin-top: 0
+}
+
+.input-group .form-control:first-child, .input-group-addon:first-child, .input-group-btn:first-child > .btn, .input-group-btn:first-child > .btn-group > .btn, .input-group-btn:first-child > .dropdown-toggle, .input-group-btn:last-child > .btn-group:not(:last-child) > .btn, .input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle) {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0
+}
+
+.input-group-addon:first-child {
+ border-right: 0
+}
+
+.input-group .form-control:last-child, .input-group-addon:last-child, .input-group-btn:first-child > .btn-group:not(:first-child) > .btn, .input-group-btn:first-child > .btn:not(:first-child), .input-group-btn:last-child > .btn, .input-group-btn:last-child > .btn-group > .btn, .input-group-btn:last-child > .dropdown-toggle {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0
+}
+
+.input-group-addon:last-child {
+ border-left: 0
+}
+
+.input-group-btn {
+ position: relative;
+ font-size: 0;
+ white-space: nowrap
+}
+
+.input-group-btn > .btn {
+ position: relative
+}
+
+.input-group-btn > .btn + .btn {
+ margin-left: -1px
+}
+
+.input-group-btn > .btn:active, .input-group-btn > .btn:focus, .input-group-btn > .btn:hover {
+ z-index: 2
+}
+
+.input-group-btn:first-child > .btn, .input-group-btn:first-child > .btn-group {
+ margin-right: -1px
+}
+
+.input-group-btn:last-child > .btn, .input-group-btn:last-child > .btn-group {
+ z-index: 2;
+ margin-left: -1px
+}
+
+.nav {
+ padding-left: 0;
+ margin-bottom: 0;
+ list-style: none
+}
+
+.nav > li {
+ position: relative;
+ display: block
+}
+
+.nav > li > a {
+ position: relative;
+ display: block;
+ padding: 10px 15px
+}
+
+.nav > li > a:focus, .nav > li > a:hover {
+ text-decoration: none;
+ background-color: #eee
+}
+
+.nav > li.disabled > a {
+ color: #777
+}
+
+.nav > li.disabled > a:focus, .nav > li.disabled > a:hover {
+ color: #777;
+ text-decoration: none;
+ cursor: not-allowed;
+ background-color: transparent
+}
+
+.nav .open > a, .nav .open > a:focus, .nav .open > a:hover {
+ background-color: #eee;
+ border-color: #337ab7
+}
+
+.nav .nav-divider {
+ height: 1px;
+ margin: 9px 0;
+ overflow: hidden;
+ background-color: #e5e5e5
+}
+
+.nav > li > a > img {
+ max-width: none
+}
+
+.nav-tabs {
+ border-bottom: 1px solid #ddd
+}
+
+.nav-tabs > li {
+ float: left;
+ margin-bottom: -1px
+}
+
+.nav-tabs > li > a {
+ margin-right: 2px;
+ line-height: 1.42857143;
+ border: 1px solid transparent;
+ border-radius: 4px 4px 0 0
+}
+
+.nav-tabs > li > a:hover {
+ border-color: #eee #eee #ddd
+}
+
+.nav-tabs > li.active > a, .nav-tabs > li.active > a:focus, .nav-tabs > li.active > a:hover {
+ color: #555;
+ cursor: default;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-bottom-color: transparent
+}
+
+.nav-tabs.nav-justified {
+ width: 100%;
+ border-bottom: 0
+}
+
+.nav-tabs.nav-justified > li {
+ float: none
+}
+
+.nav-tabs.nav-justified > li > a {
+ margin-bottom: 5px;
+ text-align: center
+}
+
+.nav-tabs.nav-justified > .dropdown .dropdown-menu {
+ top: auto;
+ left: auto
+}
+
+@media (min-width: 768px) {
+ .nav-tabs.nav-justified > li {
+ display: table-cell;
+ width: 1%
+ }
+
+ .nav-tabs.nav-justified > li > a {
+ margin-bottom: 0
+ }
+}
+
+.nav-tabs.nav-justified > li > a {
+ margin-right: 0;
+ border-radius: 4px
+}
+
+.nav-tabs.nav-justified > .active > a, .nav-tabs.nav-justified > .active > a:focus, .nav-tabs.nav-justified > .active > a:hover {
+ border: 1px solid #ddd
+}
+
+@media (min-width: 768px) {
+ .nav-tabs.nav-justified > li > a {
+ border-bottom: 1px solid #ddd;
+ border-radius: 4px 4px 0 0
+ }
+
+ .nav-tabs.nav-justified > .active > a, .nav-tabs.nav-justified > .active > a:focus, .nav-tabs.nav-justified > .active > a:hover {
+ border-bottom-color: #fff
+ }
+}
+
+.nav-pills > li {
+ float: left
+}
+
+.nav-pills > li > a {
+ border-radius: 4px
+}
+
+.nav-pills > li + li {
+ margin-left: 2px
+}
+
+.nav-pills > li.active > a, .nav-pills > li.active > a:focus, .nav-pills > li.active > a:hover {
+ color: #fff;
+ background-color: #337ab7
+}
+
+.nav-stacked > li {
+ float: none
+}
+
+.nav-stacked > li + li {
+ margin-top: 2px;
+ margin-left: 0
+}
+
+.nav-justified {
+ width: 100%
+}
+
+.nav-justified > li {
+ float: none
+}
+
+.nav-justified > li > a {
+ margin-bottom: 5px;
+ text-align: center
+}
+
+.nav-justified > .dropdown .dropdown-menu {
+ top: auto;
+ left: auto
+}
+
+@media (min-width: 768px) {
+ .nav-justified > li {
+ display: table-cell;
+ width: 1%
+ }
+
+ .nav-justified > li > a {
+ margin-bottom: 0
+ }
+}
+
+.nav-tabs-justified {
+ border-bottom: 0
+}
+
+.nav-tabs-justified > li > a {
+ margin-right: 0;
+ border-radius: 4px
+}
+
+.nav-tabs-justified > .active > a, .nav-tabs-justified > .active > a:focus, .nav-tabs-justified > .active > a:hover {
+ border: 1px solid #ddd
+}
+
+@media (min-width: 768px) {
+ .nav-tabs-justified > li > a {
+ border-bottom: 1px solid #ddd;
+ border-radius: 4px 4px 0 0
+ }
+
+ .nav-tabs-justified > .active > a, .nav-tabs-justified > .active > a:focus, .nav-tabs-justified > .active > a:hover {
+ border-bottom-color: #fff
+ }
+}
+
+.tab-content > .tab-pane {
+ display: none
+}
+
+.tab-content > .active {
+ display: block
+}
+
+.nav-tabs .dropdown-menu {
+ margin-top: -1px;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0
+}
+
+.navbar {
+ position: relative;
+ min-height: 50px;
+ margin-bottom: 20px;
+ border: 1px solid transparent
+}
+
+@media (min-width: 768px) {
+ .navbar {
+ border-radius: 4px
+ }
+}
+
+@media (min-width: 768px) {
+ .navbar-header {
+ float: left
+ }
+}
+
+.navbar-collapse {
+ padding-right: 15px;
+ padding-left: 15px;
+ overflow-x: visible;
+ -webkit-overflow-scrolling: touch;
+ border-top: 1px solid transparent;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1)
+}
+
+.navbar-collapse.in {
+ overflow-y: auto
+}
+
+@media (min-width: 768px) {
+ .navbar-collapse {
+ width: auto;
+ border-top: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none
+ }
+
+ .navbar-collapse.collapse {
+ display: block !important;
+ height: auto !important;
+ padding-bottom: 0;
+ overflow: visible !important
+ }
+
+ .navbar-collapse.in {
+ overflow-y: visible
+ }
+
+ .navbar-fixed-bottom .navbar-collapse, .navbar-fixed-top .navbar-collapse, .navbar-static-top .navbar-collapse {
+ padding-right: 0;
+ padding-left: 0
+ }
+}
+
+.navbar-fixed-bottom .navbar-collapse, .navbar-fixed-top .navbar-collapse {
+ max-height: 340px
+}
+
+@media (max-device-width: 480px) and (orientation: landscape) {
+ .navbar-fixed-bottom .navbar-collapse, .navbar-fixed-top .navbar-collapse {
+ max-height: 200px
+ }
+}
+
+.container-fluid > .navbar-collapse, .container-fluid > .navbar-header, .container > .navbar-collapse, .container > .navbar-header {
+ margin-right: -15px;
+ margin-left: -15px
+}
+
+@media (min-width: 768px) {
+ .container-fluid > .navbar-collapse, .container-fluid > .navbar-header, .container > .navbar-collapse, .container > .navbar-header {
+ margin-right: 0;
+ margin-left: 0
+ }
+}
+
+.navbar-static-top {
+ z-index: 1000;
+ border-width: 0 0 1px
+}
+
+@media (min-width: 768px) {
+ .navbar-static-top {
+ border-radius: 0
+ }
+}
+
+.navbar-fixed-bottom, .navbar-fixed-top {
+ position: fixed;
+ right: 0;
+ left: 0;
+ z-index: 1030
+}
+
+@media (min-width: 768px) {
+ .navbar-fixed-bottom, .navbar-fixed-top {
+ border-radius: 0
+ }
+}
+
+.navbar-fixed-top {
+ top: 0;
+ border-width: 0 0 1px
+}
+
+.navbar-fixed-bottom {
+ bottom: 0;
+ margin-bottom: 0;
+ border-width: 1px 0 0
+}
+
+.navbar-brand {
+ float: left;
+ height: 50px;
+ padding: 15px 15px;
+ font-size: 18px;
+ line-height: 20px
+}
+
+.navbar-brand:focus, .navbar-brand:hover {
+ text-decoration: none
+}
+
+.navbar-brand > img {
+ display: block
+}
+
+@media (min-width: 768px) {
+ .navbar > .container .navbar-brand, .navbar > .container-fluid .navbar-brand {
+ margin-left: -15px
+ }
+}
+
+.navbar-toggle {
+ position: relative;
+ float: right;
+ padding: 9px 10px;
+ margin-top: 8px;
+ margin-right: 15px;
+ margin-bottom: 8px;
+ background-color: transparent;
+ background-image: none;
+ border: 1px solid transparent;
+ border-radius: 4px
+}
+
+.navbar-toggle:focus {
+ outline: 0
+}
+
+.navbar-toggle .icon-bar {
+ display: block;
+ width: 22px;
+ height: 2px;
+ border-radius: 1px
+}
+
+.navbar-toggle .icon-bar + .icon-bar {
+ margin-top: 4px
+}
+
+@media (min-width: 768px) {
+ .navbar-toggle {
+ display: none
+ }
+}
+
+.navbar-nav {
+ margin: 7.5px -15px
+}
+
+.navbar-nav > li > a {
+ padding-top: 10px;
+ padding-bottom: 10px;
+ line-height: 20px
+}
+
+@media (max-width: 767px) {
+ .navbar-nav .open .dropdown-menu {
+ position: static;
+ float: none;
+ width: auto;
+ margin-top: 0;
+ background-color: transparent;
+ border: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none
+ }
+
+ .navbar-nav .open .dropdown-menu .dropdown-header, .navbar-nav .open .dropdown-menu > li > a {
+ padding: 5px 15px 5px 25px
+ }
+
+ .navbar-nav .open .dropdown-menu > li > a {
+ line-height: 20px
+ }
+
+ .navbar-nav .open .dropdown-menu > li > a:focus, .navbar-nav .open .dropdown-menu > li > a:hover {
+ background-image: none
+ }
+}
+
+@media (min-width: 768px) {
+ .navbar-nav {
+ float: left;
+ margin: 0
+ }
+
+ .navbar-nav > li {
+ float: left
+ }
+
+ .navbar-nav > li > a {
+ padding-top: 15px;
+ padding-bottom: 15px
+ }
+}
+
+.navbar-form {
+ padding: 10px 15px;
+ margin-top: 8px;
+ margin-right: -15px;
+ margin-bottom: 8px;
+ margin-left: -15px;
+ border-top: 1px solid transparent;
+ border-bottom: 1px solid transparent;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1)
+}
+
+@media (min-width: 768px) {
+ .navbar-form .form-group {
+ display: inline-block;
+ margin-bottom: 0;
+ vertical-align: middle
+ }
+
+ .navbar-form .form-control {
+ display: inline-block;
+ width: auto;
+ vertical-align: middle
+ }
+
+ .navbar-form .form-control-static {
+ display: inline-block
+ }
+
+ .navbar-form .input-group {
+ display: inline-table;
+ vertical-align: middle
+ }
+
+ .navbar-form .input-group .form-control, .navbar-form .input-group .input-group-addon, .navbar-form .input-group .input-group-btn {
+ width: auto
+ }
+
+ .navbar-form .input-group > .form-control {
+ width: 100%
+ }
+
+ .navbar-form .control-label {
+ margin-bottom: 0;
+ vertical-align: middle
+ }
+
+ .navbar-form .checkbox, .navbar-form .radio {
+ display: inline-block;
+ margin-top: 0;
+ margin-bottom: 0;
+ vertical-align: middle
+ }
+
+ .navbar-form .checkbox label, .navbar-form .radio label {
+ padding-left: 0
+ }
+
+ .navbar-form .checkbox input[type=checkbox], .navbar-form .radio input[type=radio] {
+ position: relative;
+ margin-left: 0
+ }
+
+ .navbar-form .has-feedback .form-control-feedback {
+ top: 0
+ }
+}
+
+@media (max-width: 767px) {
+ .navbar-form .form-group {
+ margin-bottom: 5px
+ }
+
+ .navbar-form .form-group:last-child {
+ margin-bottom: 0
+ }
+}
+
+@media (min-width: 768px) {
+ .navbar-form {
+ width: auto;
+ padding-top: 0;
+ padding-bottom: 0;
+ margin-right: 0;
+ margin-left: 0;
+ border: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none
+ }
+}
+
+.navbar-nav > li > .dropdown-menu {
+ margin-top: 0;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0
+}
+
+.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {
+ margin-bottom: 0;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0
+}
+
+.navbar-btn {
+ margin-top: 8px;
+ margin-bottom: 8px
+}
+
+.navbar-btn.btn-sm {
+ margin-top: 10px;
+ margin-bottom: 10px
+}
+
+.navbar-btn.btn-xs {
+ margin-top: 14px;
+ margin-bottom: 14px
+}
+
+.navbar-text {
+ margin-top: 15px;
+ margin-bottom: 15px
+}
+
+@media (min-width: 768px) {
+ .navbar-text {
+ float: left;
+ margin-right: 15px;
+ margin-left: 15px
+ }
+}
+
+@media (min-width: 768px) {
+ .navbar-left {
+ float: left !important
+ }
+
+ .navbar-right {
+ float: right !important;
+ margin-right: -15px
+ }
+
+ .navbar-right ~ .navbar-right {
+ margin-right: 0
+ }
+}
+
+.navbar-default {
+ background-color: #f8f8f8;
+ border-color: #e7e7e7
+}
+
+.navbar-default .navbar-brand {
+ color: #777
+}
+
+.navbar-default .navbar-brand:focus, .navbar-default .navbar-brand:hover {
+ color: #5e5e5e;
+ background-color: transparent
+}
+
+.navbar-default .navbar-text {
+ color: #777
+}
+
+.navbar-default .navbar-nav > li > a {
+ color: #777
+}
+
+.navbar-default .navbar-nav > li > a:focus, .navbar-default .navbar-nav > li > a:hover {
+ color: #333;
+ background-color: transparent
+}
+
+.navbar-default .navbar-nav > .active > a, .navbar-default .navbar-nav > .active > a:focus, .navbar-default .navbar-nav > .active > a:hover {
+ color: #555;
+ background-color: #e7e7e7
+}
+
+.navbar-default .navbar-nav > .disabled > a, .navbar-default .navbar-nav > .disabled > a:focus, .navbar-default .navbar-nav > .disabled > a:hover {
+ color: #ccc;
+ background-color: transparent
+}
+
+.navbar-default .navbar-toggle {
+ border-color: #ddd
+}
+
+.navbar-default .navbar-toggle:focus, .navbar-default .navbar-toggle:hover {
+ background-color: #ddd
+}
+
+.navbar-default .navbar-toggle .icon-bar {
+ background-color: #888
+}
+
+.navbar-default .navbar-collapse, .navbar-default .navbar-form {
+ border-color: #e7e7e7
+}
+
+.navbar-default .navbar-nav > .open > a, .navbar-default .navbar-nav > .open > a:focus, .navbar-default .navbar-nav > .open > a:hover {
+ color: #555;
+ background-color: #e7e7e7
+}
+
+@media (max-width: 767px) {
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a {
+ color: #777
+ }
+
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus, .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover {
+ color: #333;
+ background-color: transparent
+ }
+
+ .navbar-default .navbar-nav .open .dropdown-menu > .active > a, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover {
+ color: #555;
+ background-color: #e7e7e7
+ }
+
+ .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus, .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover {
+ color: #ccc;
+ background-color: transparent
+ }
+}
+
+.navbar-default .navbar-link {
+ color: #777
+}
+
+.navbar-default .navbar-link:hover {
+ color: #333
+}
+
+.navbar-default .btn-link {
+ color: #777
+}
+
+.navbar-default .btn-link:focus, .navbar-default .btn-link:hover {
+ color: #333
+}
+
+.navbar-default .btn-link[disabled]:focus, .navbar-default .btn-link[disabled]:hover, fieldset[disabled] .navbar-default .btn-link:focus, fieldset[disabled] .navbar-default .btn-link:hover {
+ color: #ccc
+}
+
+.navbar-inverse {
+ background-color: #222;
+ border-color: #080808
+}
+
+.navbar-inverse .navbar-brand {
+ color: #9d9d9d
+}
+
+.navbar-inverse .navbar-brand:focus, .navbar-inverse .navbar-brand:hover {
+ color: #fff;
+ background-color: transparent
+}
+
+.navbar-inverse .navbar-text {
+ color: #9d9d9d
+}
+
+.navbar-inverse .navbar-nav > li > a {
+ color: #9d9d9d
+}
+
+.navbar-inverse .navbar-nav > li > a:focus, .navbar-inverse .navbar-nav > li > a:hover {
+ color: #fff;
+ background-color: transparent
+}
+
+.navbar-inverse .navbar-nav > .active > a, .navbar-inverse .navbar-nav > .active > a:focus, .navbar-inverse .navbar-nav > .active > a:hover {
+ color: #fff;
+ background-color: #080808
+}
+
+.navbar-inverse .navbar-nav > .disabled > a, .navbar-inverse .navbar-nav > .disabled > a:focus, .navbar-inverse .navbar-nav > .disabled > a:hover {
+ color: #444;
+ background-color: transparent
+}
+
+.navbar-inverse .navbar-toggle {
+ border-color: #333
+}
+
+.navbar-inverse .navbar-toggle:focus, .navbar-inverse .navbar-toggle:hover {
+ background-color: #333
+}
+
+.navbar-inverse .navbar-toggle .icon-bar {
+ background-color: #fff
+}
+
+.navbar-inverse .navbar-collapse, .navbar-inverse .navbar-form {
+ border-color: #101010
+}
+
+.navbar-inverse .navbar-nav > .open > a, .navbar-inverse .navbar-nav > .open > a:focus, .navbar-inverse .navbar-nav > .open > a:hover {
+ color: #fff;
+ background-color: #080808
+}
+
+@media (max-width: 767px) {
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {
+ border-color: #080808
+ }
+
+ .navbar-inverse .navbar-nav .open .dropdown-menu .divider {
+ background-color: #080808
+ }
+
+ .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {
+ color: #9d9d9d
+ }
+
+ .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus, .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover {
+ color: #fff;
+ background-color: transparent
+ }
+
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus, .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover {
+ color: #fff;
+ background-color: #080808
+ }
+
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus, .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover {
+ color: #444;
+ background-color: transparent
+ }
+}
+
+.navbar-inverse .navbar-link {
+ color: #9d9d9d
+}
+
+.navbar-inverse .navbar-link:hover {
+ color: #fff
+}
+
+.navbar-inverse .btn-link {
+ color: #9d9d9d
+}
+
+.navbar-inverse .btn-link:focus, .navbar-inverse .btn-link:hover {
+ color: #fff
+}
+
+.navbar-inverse .btn-link[disabled]:focus, .navbar-inverse .btn-link[disabled]:hover, fieldset[disabled] .navbar-inverse .btn-link:focus, fieldset[disabled] .navbar-inverse .btn-link:hover {
+ color: #444
+}
+
+.breadcrumb {
+ padding: 8px 15px;
+ margin-bottom: 20px;
+ list-style: none;
+ background-color: #f5f5f5;
+ border-radius: 4px
+}
+
+.breadcrumb > li {
+ display: inline-block
+}
+
+.breadcrumb > li + li:before {
+ padding: 0 5px;
+ color: #ccc;
+ content: "/\00a0"
+}
+
+.breadcrumb > .active {
+ color: #777
+}
+
+.pagination {
+ display: inline-block;
+ padding-left: 0;
+ margin: 20px 0;
+ border-radius: 4px
+}
+
+.pagination > li {
+ display: inline
+}
+
+.pagination > li > a, .pagination > li > span {
+ position: relative;
+ float: left;
+ padding: 6px 12px;
+ margin-left: -1px;
+ line-height: 1.42857143;
+ color: #337ab7;
+ text-decoration: none;
+ background-color: #fff;
+ border: 1px solid #ddd
+}
+
+.pagination > li:first-child > a, .pagination > li:first-child > span {
+ margin-left: 0;
+ border-top-left-radius: 4px;
+ border-bottom-left-radius: 4px
+}
+
+.pagination > li:last-child > a, .pagination > li:last-child > span {
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 4px
+}
+
+.pagination > li > a:focus, .pagination > li > a:hover, .pagination > li > span:focus, .pagination > li > span:hover {
+ z-index: 3;
+ color: #23527c;
+ background-color: #eee;
+ border-color: #ddd
+}
+
+.pagination > .active > a, .pagination > .active > a:focus, .pagination > .active > a:hover, .pagination > .active > span, .pagination > .active > span:focus, .pagination > .active > span:hover {
+ z-index: 2;
+ color: #fff;
+ cursor: default;
+ background-color: #337ab7;
+ border-color: #337ab7
+}
+
+.pagination > .disabled > a, .pagination > .disabled > a:focus, .pagination > .disabled > a:hover, .pagination > .disabled > span, .pagination > .disabled > span:focus, .pagination > .disabled > span:hover {
+ color: #777;
+ cursor: not-allowed;
+ background-color: #fff;
+ border-color: #ddd
+}
+
+.pagination-lg > li > a, .pagination-lg > li > span {
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333
+}
+
+.pagination-lg > li:first-child > a, .pagination-lg > li:first-child > span {
+ border-top-left-radius: 6px;
+ border-bottom-left-radius: 6px
+}
+
+.pagination-lg > li:last-child > a, .pagination-lg > li:last-child > span {
+ border-top-right-radius: 6px;
+ border-bottom-right-radius: 6px
+}
+
+.pagination-sm > li > a, .pagination-sm > li > span {
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5
+}
+
+.pagination-sm > li:first-child > a, .pagination-sm > li:first-child > span {
+ border-top-left-radius: 3px;
+ border-bottom-left-radius: 3px
+}
+
+.pagination-sm > li:last-child > a, .pagination-sm > li:last-child > span {
+ border-top-right-radius: 3px;
+ border-bottom-right-radius: 3px
+}
+
+.pager {
+ padding-left: 0;
+ margin: 20px 0;
+ text-align: center;
+ list-style: none
+}
+
+.pager li {
+ display: inline
+}
+
+.pager li > a, .pager li > span {
+ display: inline-block;
+ padding: 5px 14px;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-radius: 15px
+}
+
+.pager li > a:focus, .pager li > a:hover {
+ text-decoration: none;
+ background-color: #eee
+}
+
+.pager .next > a, .pager .next > span {
+ float: right
+}
+
+.pager .previous > a, .pager .previous > span {
+ float: left
+}
+
+.pager .disabled > a, .pager .disabled > a:focus, .pager .disabled > a:hover, .pager .disabled > span {
+ color: #777;
+ cursor: not-allowed;
+ background-color: #fff
+}
+
+.label {
+ display: inline;
+ padding: .2em .6em .3em;
+ font-size: 75%;
+ font-weight: 700;
+ line-height: 1;
+ color: #fff;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: baseline;
+ border-radius: .25em
+}
+
+a.label:focus, a.label:hover {
+ color: #fff;
+ text-decoration: none;
+ cursor: pointer
+}
+
+.label:empty {
+ display: none
+}
+
+.btn .label {
+ position: relative;
+ top: -1px
+}
+
+.label-default {
+ background-color: #777
+}
+
+.label-default[href]:focus, .label-default[href]:hover {
+ background-color: #5e5e5e
+}
+
+.label-primary {
+ background-color: #337ab7
+}
+
+.label-primary[href]:focus, .label-primary[href]:hover {
+ background-color: #286090
+}
+
+.label-success {
+ background-color: #5cb85c
+}
+
+.label-success[href]:focus, .label-success[href]:hover {
+ background-color: #449d44
+}
+
+.label-info {
+ background-color: #5bc0de
+}
+
+.label-info[href]:focus, .label-info[href]:hover {
+ background-color: #31b0d5
+}
+
+.label-warning {
+ background-color: #f0ad4e
+}
+
+.label-warning[href]:focus, .label-warning[href]:hover {
+ background-color: #ec971f
+}
+
+.label-danger {
+ background-color: #d9534f
+}
+
+.label-danger[href]:focus, .label-danger[href]:hover {
+ background-color: #c9302c
+}
+
+.badge {
+ display: inline-block;
+ min-width: 10px;
+ padding: 3px 7px;
+ font-size: 12px;
+ font-weight: 700;
+ line-height: 1;
+ color: #fff;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: middle;
+ background-color: #777;
+ border-radius: 10px
+}
+
+.badge:empty {
+ display: none
+}
+
+.btn .badge {
+ position: relative;
+ top: -1px
+}
+
+.btn-group-xs > .btn .badge, .btn-xs .badge {
+ top: 0;
+ padding: 1px 5px
+}
+
+a.badge:focus, a.badge:hover {
+ color: #fff;
+ text-decoration: none;
+ cursor: pointer
+}
+
+.list-group-item.active > .badge, .nav-pills > .active > a > .badge {
+ color: #337ab7;
+ background-color: #fff
+}
+
+.list-group-item > .badge {
+ float: right
+}
+
+.list-group-item > .badge + .badge {
+ margin-right: 5px
+}
+
+.nav-pills > li > a > .badge {
+ margin-left: 3px
+}
+
+.jumbotron {
+ padding-top: 30px;
+ padding-bottom: 30px;
+ margin-bottom: 30px;
+ color: inherit;
+ background-color: #eee
+}
+
+.jumbotron .h1, .jumbotron h1 {
+ color: inherit
+}
+
+.jumbotron p {
+ margin-bottom: 15px;
+ font-size: 21px;
+ font-weight: 200
+}
+
+.jumbotron > hr {
+ border-top-color: #d5d5d5
+}
+
+.container .jumbotron, .container-fluid .jumbotron {
+ border-radius: 6px
+}
+
+.jumbotron .container {
+ max-width: 100%
+}
+
+@media screen and (min-width: 768px) {
+ .jumbotron {
+ padding-top: 48px;
+ padding-bottom: 48px
+ }
+
+ .container .jumbotron, .container-fluid .jumbotron {
+ padding-right: 60px;
+ padding-left: 60px
+ }
+
+ .jumbotron .h1, .jumbotron h1 {
+ font-size: 63px
+ }
+}
+
+.thumbnail {
+ display: block;
+ padding: 4px;
+ margin-bottom: 20px;
+ line-height: 1.42857143;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ -webkit-transition: border .2s ease-in-out;
+ -o-transition: border .2s ease-in-out;
+ transition: border .2s ease-in-out
+}
+
+.thumbnail a > img, .thumbnail > img {
+ margin-right: auto;
+ margin-left: auto
+}
+
+a.thumbnail.active, a.thumbnail:focus, a.thumbnail:hover {
+ border-color: #337ab7
+}
+
+.thumbnail .caption {
+ padding: 9px;
+ color: #333
+}
+
+.alert {
+ padding: 15px;
+ margin-bottom: 20px;
+ border: 1px solid transparent;
+ border-radius: 4px
+}
+
+.alert h4 {
+ margin-top: 0;
+ color: inherit
+}
+
+.alert .alert-link {
+ font-weight: 700
+}
+
+.alert > p, .alert > ul {
+ margin-bottom: 0
+}
+
+.alert > p + p {
+ margin-top: 5px
+}
+
+.alert-dismissable, .alert-dismissible {
+ padding-right: 35px
+}
+
+.alert-dismissable .close, .alert-dismissible .close {
+ position: relative;
+ top: -2px;
+ right: -21px;
+ color: inherit
+}
+
+.alert-success {
+ color: #3c763d;
+ background-color: #dff0d8;
+ border-color: #d6e9c6
+}
+
+.alert-success hr {
+ border-top-color: #c9e2b3
+}
+
+.alert-success .alert-link {
+ color: #2b542c
+}
+
+.alert-info {
+ color: #31708f;
+ background-color: #d9edf7;
+ border-color: #bce8f1
+}
+
+.alert-info hr {
+ border-top-color: #a6e1ec
+}
+
+.alert-info .alert-link {
+ color: #245269
+}
+
+.alert-warning {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+ border-color: #faebcc
+}
+
+.alert-warning hr {
+ border-top-color: #f7e1b5
+}
+
+.alert-warning .alert-link {
+ color: #66512c
+}
+
+.alert-danger {
+ color: #a94442;
+ background-color: #f2dede;
+ border-color: #ebccd1
+}
+
+.alert-danger hr {
+ border-top-color: #e4b9c0
+}
+
+.alert-danger .alert-link {
+ color: #843534
+}
+
+@-webkit-keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0
+ }
+ to {
+ background-position: 0 0
+ }
+}
+
+@-o-keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0
+ }
+ to {
+ background-position: 0 0
+ }
+}
+
+@keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0
+ }
+ to {
+ background-position: 0 0
+ }
+}
+
+.progress {
+ height: 20px;
+ margin-bottom: 20px;
+ overflow: hidden;
+ background-color: #f5f5f5;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1)
+}
+
+.progress-bar {
+ float: left;
+ width: 0;
+ height: 100%;
+ font-size: 12px;
+ line-height: 20px;
+ color: #fff;
+ text-align: center;
+ background-color: #337ab7;
+ -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);
+ box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);
+ -webkit-transition: width .6s ease;
+ -o-transition: width .6s ease;
+ transition: width .6s ease
+}
+
+.progress-bar-striped, .progress-striped .progress-bar {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ -webkit-background-size: 40px 40px;
+ background-size: 40px 40px
+}
+
+.progress-bar.active, .progress.active .progress-bar {
+ -webkit-animation: progress-bar-stripes 2s linear infinite;
+ -o-animation: progress-bar-stripes 2s linear infinite;
+ animation: progress-bar-stripes 2s linear infinite
+}
+
+.progress-bar-success {
+ background-color: #5cb85c
+}
+
+.progress-striped .progress-bar-success {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent)
+}
+
+.progress-bar-info {
+ background-color: #5bc0de
+}
+
+.progress-striped .progress-bar-info {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent)
+}
+
+.progress-bar-warning {
+ background-color: #f0ad4e
+}
+
+.progress-striped .progress-bar-warning {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent)
+}
+
+.progress-bar-danger {
+ background-color: #d9534f
+}
+
+.progress-striped .progress-bar-danger {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent)
+}
+
+.media {
+ margin-top: 15px
+}
+
+.media:first-child {
+ margin-top: 0
+}
+
+.media, .media-body {
+ overflow: hidden;
+ zoom: 1
+}
+
+.media-body {
+ width: 10000px
+}
+
+.media-object {
+ display: block
+}
+
+.media-object.img-thumbnail {
+ max-width: none
+}
+
+.media-right, .media > .pull-right {
+ padding-left: 10px
+}
+
+.media-left, .media > .pull-left {
+ padding-right: 10px
+}
+
+.media-body, .media-left, .media-right {
+ display: table-cell;
+ vertical-align: top
+}
+
+.media-middle {
+ vertical-align: middle
+}
+
+.media-bottom {
+ vertical-align: bottom
+}
+
+.media-heading {
+ margin-top: 0;
+ margin-bottom: 5px
+}
+
+.media-list {
+ padding-left: 0;
+ list-style: none
+}
+
+.list-group {
+ padding-left: 0;
+ margin-bottom: 20px
+}
+
+.list-group-item {
+ position: relative;
+ display: block;
+ padding: 10px 15px;
+ margin-bottom: -1px;
+ background-color: #fff;
+ border: 1px solid #ddd
+}
+
+.list-group-item:first-child {
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px
+}
+
+.list-group-item:last-child {
+ margin-bottom: 0;
+ border-bottom-right-radius: 4px;
+ border-bottom-left-radius: 4px
+}
+
+a.list-group-item, button.list-group-item {
+ color: #555
+}
+
+a.list-group-item .list-group-item-heading, button.list-group-item .list-group-item-heading {
+ color: #333
+}
+
+a.list-group-item:focus, a.list-group-item:hover, button.list-group-item:focus, button.list-group-item:hover {
+ color: #555;
+ text-decoration: none;
+ background-color: #f5f5f5
+}
+
+button.list-group-item {
+ width: 100%;
+ text-align: left
+}
+
+.list-group-item.disabled, .list-group-item.disabled:focus, .list-group-item.disabled:hover {
+ color: #777;
+ cursor: not-allowed;
+ background-color: #eee
+}
+
+.list-group-item.disabled .list-group-item-heading, .list-group-item.disabled:focus .list-group-item-heading, .list-group-item.disabled:hover .list-group-item-heading {
+ color: inherit
+}
+
+.list-group-item.disabled .list-group-item-text, .list-group-item.disabled:focus .list-group-item-text, .list-group-item.disabled:hover .list-group-item-text {
+ color: #777
+}
+
+.list-group-item.active, .list-group-item.active:focus, .list-group-item.active:hover {
+ z-index: 2;
+ color: #fff;
+ background-color: #337ab7;
+ border-color: #337ab7
+}
+
+.list-group-item.active .list-group-item-heading, .list-group-item.active .list-group-item-heading > .small, .list-group-item.active .list-group-item-heading > small, .list-group-item.active:focus .list-group-item-heading, .list-group-item.active:focus .list-group-item-heading > .small, .list-group-item.active:focus .list-group-item-heading > small, .list-group-item.active:hover .list-group-item-heading, .list-group-item.active:hover .list-group-item-heading > .small, .list-group-item.active:hover .list-group-item-heading > small {
+ color: inherit
+}
+
+.list-group-item.active .list-group-item-text, .list-group-item.active:focus .list-group-item-text, .list-group-item.active:hover .list-group-item-text {
+ color: #c7ddef
+}
+
+.list-group-item-success {
+ color: #3c763d;
+ background-color: #dff0d8
+}
+
+a.list-group-item-success, button.list-group-item-success {
+ color: #3c763d
+}
+
+a.list-group-item-success .list-group-item-heading, button.list-group-item-success .list-group-item-heading {
+ color: inherit
+}
+
+a.list-group-item-success:focus, a.list-group-item-success:hover, button.list-group-item-success:focus, button.list-group-item-success:hover {
+ color: #3c763d;
+ background-color: #d0e9c6
+}
+
+a.list-group-item-success.active, a.list-group-item-success.active:focus, a.list-group-item-success.active:hover, button.list-group-item-success.active, button.list-group-item-success.active:focus, button.list-group-item-success.active:hover {
+ color: #fff;
+ background-color: #3c763d;
+ border-color: #3c763d
+}
+
+.list-group-item-info {
+ color: #31708f;
+ background-color: #d9edf7
+}
+
+a.list-group-item-info, button.list-group-item-info {
+ color: #31708f
+}
+
+a.list-group-item-info .list-group-item-heading, button.list-group-item-info .list-group-item-heading {
+ color: inherit
+}
+
+a.list-group-item-info:focus, a.list-group-item-info:hover, button.list-group-item-info:focus, button.list-group-item-info:hover {
+ color: #31708f;
+ background-color: #c4e3f3
+}
+
+a.list-group-item-info.active, a.list-group-item-info.active:focus, a.list-group-item-info.active:hover, button.list-group-item-info.active, button.list-group-item-info.active:focus, button.list-group-item-info.active:hover {
+ color: #fff;
+ background-color: #31708f;
+ border-color: #31708f
+}
+
+.list-group-item-warning {
+ color: #8a6d3b;
+ background-color: #fcf8e3
+}
+
+a.list-group-item-warning, button.list-group-item-warning {
+ color: #8a6d3b
+}
+
+a.list-group-item-warning .list-group-item-heading, button.list-group-item-warning .list-group-item-heading {
+ color: inherit
+}
+
+a.list-group-item-warning:focus, a.list-group-item-warning:hover, button.list-group-item-warning:focus, button.list-group-item-warning:hover {
+ color: #8a6d3b;
+ background-color: #faf2cc
+}
+
+a.list-group-item-warning.active, a.list-group-item-warning.active:focus, a.list-group-item-warning.active:hover, button.list-group-item-warning.active, button.list-group-item-warning.active:focus, button.list-group-item-warning.active:hover {
+ color: #fff;
+ background-color: #8a6d3b;
+ border-color: #8a6d3b
+}
+
+.list-group-item-danger {
+ color: #a94442;
+ background-color: #f2dede
+}
+
+a.list-group-item-danger, button.list-group-item-danger {
+ color: #a94442
+}
+
+a.list-group-item-danger .list-group-item-heading, button.list-group-item-danger .list-group-item-heading {
+ color: inherit
+}
+
+a.list-group-item-danger:focus, a.list-group-item-danger:hover, button.list-group-item-danger:focus, button.list-group-item-danger:hover {
+ color: #a94442;
+ background-color: #ebcccc
+}
+
+a.list-group-item-danger.active, a.list-group-item-danger.active:focus, a.list-group-item-danger.active:hover, button.list-group-item-danger.active, button.list-group-item-danger.active:focus, button.list-group-item-danger.active:hover {
+ color: #fff;
+ background-color: #a94442;
+ border-color: #a94442
+}
+
+.list-group-item-heading {
+ margin-top: 0;
+ margin-bottom: 5px
+}
+
+.list-group-item-text {
+ margin-bottom: 0;
+ line-height: 1.3
+}
+
+.panel {
+ margin-bottom: 20px;
+ background-color: #fff;
+ border: 1px solid transparent;
+ border-radius: 4px;
+ -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
+ box-shadow: 0 1px 1px rgba(0, 0, 0, .05)
+}
+
+.panel-body {
+ padding: 15px
+}
+
+.panel-heading {
+ padding: 10px 15px;
+ border-bottom: 1px solid transparent;
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px
+}
+
+.panel-heading > .dropdown .dropdown-toggle {
+ color: inherit
+}
+
+.panel-title {
+ margin-top: 0;
+ margin-bottom: 0;
+ font-size: 16px;
+ color: inherit
+}
+
+.panel-title > .small, .panel-title > .small > a, .panel-title > a, .panel-title > small, .panel-title > small > a {
+ color: inherit
+}
+
+.panel-footer {
+ padding: 10px 15px;
+ background-color: #f5f5f5;
+ border-top: 1px solid #ddd;
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px
+}
+
+.panel > .list-group, .panel > .panel-collapse > .list-group {
+ margin-bottom: 0
+}
+
+.panel > .list-group .list-group-item, .panel > .panel-collapse > .list-group .list-group-item {
+ border-width: 1px 0;
+ border-radius: 0
+}
+
+.panel > .list-group:first-child .list-group-item:first-child, .panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {
+ border-top: 0;
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px
+}
+
+.panel > .list-group:last-child .list-group-item:last-child, .panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {
+ border-bottom: 0;
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px
+}
+
+.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0
+}
+
+.panel-heading + .list-group .list-group-item:first-child {
+ border-top-width: 0
+}
+
+.list-group + .panel-footer {
+ border-top-width: 0
+}
+
+.panel > .panel-collapse > .table, .panel > .table, .panel > .table-responsive > .table {
+ margin-bottom: 0
+}
+
+.panel > .panel-collapse > .table caption, .panel > .table caption, .panel > .table-responsive > .table caption {
+ padding-right: 15px;
+ padding-left: 15px
+}
+
+.panel > .table-responsive:first-child > .table:first-child, .panel > .table:first-child {
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px
+}
+
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child, .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child, .panel > .table:first-child > tbody:first-child > tr:first-child, .panel > .table:first-child > thead:first-child > tr:first-child {
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px
+}
+
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child, .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child, .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child, .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child, .panel > .table:first-child > tbody:first-child > tr:first-child td:first-child, .panel > .table:first-child > tbody:first-child > tr:first-child th:first-child, .panel > .table:first-child > thead:first-child > tr:first-child td:first-child, .panel > .table:first-child > thead:first-child > tr:first-child th:first-child {
+ border-top-left-radius: 3px
+}
+
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child, .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child, .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child, .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child, .panel > .table:first-child > tbody:first-child > tr:first-child td:last-child, .panel > .table:first-child > tbody:first-child > tr:first-child th:last-child, .panel > .table:first-child > thead:first-child > tr:first-child td:last-child, .panel > .table:first-child > thead:first-child > tr:first-child th:last-child {
+ border-top-right-radius: 3px
+}
+
+.panel > .table-responsive:last-child > .table:last-child, .panel > .table:last-child {
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px
+}
+
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child, .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child, .panel > .table:last-child > tbody:last-child > tr:last-child, .panel > .table:last-child > tfoot:last-child > tr:last-child {
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px
+}
+
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child, .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child, .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child, .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child, .panel > .table:last-child > tbody:last-child > tr:last-child td:first-child, .panel > .table:last-child > tbody:last-child > tr:last-child th:first-child, .panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child, .panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child {
+ border-bottom-left-radius: 3px
+}
+
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child, .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child, .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child, .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child, .panel > .table:last-child > tbody:last-child > tr:last-child td:last-child, .panel > .table:last-child > tbody:last-child > tr:last-child th:last-child, .panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child, .panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child {
+ border-bottom-right-radius: 3px
+}
+
+.panel > .panel-body + .table, .panel > .panel-body + .table-responsive, .panel > .table + .panel-body, .panel > .table-responsive + .panel-body {
+ border-top: 1px solid #ddd
+}
+
+.panel > .table > tbody:first-child > tr:first-child td, .panel > .table > tbody:first-child > tr:first-child th {
+ border-top: 0
+}
+
+.panel > .table-bordered, .panel > .table-responsive > .table-bordered {
+ border: 0
+}
+
+.panel > .table-bordered > tbody > tr > td:first-child, .panel > .table-bordered > tbody > tr > th:first-child, .panel > .table-bordered > tfoot > tr > td:first-child, .panel > .table-bordered > tfoot > tr > th:first-child, .panel > .table-bordered > thead > tr > td:first-child, .panel > .table-bordered > thead > tr > th:first-child, .panel > .table-responsive > .table-bordered > tbody > tr > td:first-child, .panel > .table-responsive > .table-bordered > tbody > tr > th:first-child, .panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child, .panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child, .panel > .table-responsive > .table-bordered > thead > tr > td:first-child, .panel > .table-responsive > .table-bordered > thead > tr > th:first-child {
+ border-left: 0
+}
+
+.panel > .table-bordered > tbody > tr > td:last-child, .panel > .table-bordered > tbody > tr > th:last-child, .panel > .table-bordered > tfoot > tr > td:last-child, .panel > .table-bordered > tfoot > tr > th:last-child, .panel > .table-bordered > thead > tr > td:last-child, .panel > .table-bordered > thead > tr > th:last-child, .panel > .table-responsive > .table-bordered > tbody > tr > td:last-child, .panel > .table-responsive > .table-bordered > tbody > tr > th:last-child, .panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child, .panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child, .panel > .table-responsive > .table-bordered > thead > tr > td:last-child, .panel > .table-responsive > .table-bordered > thead > tr > th:last-child {
+ border-right: 0
+}
+
+.panel > .table-bordered > tbody > tr:first-child > td, .panel > .table-bordered > tbody > tr:first-child > th, .panel > .table-bordered > thead > tr:first-child > td, .panel > .table-bordered > thead > tr:first-child > th, .panel > .table-responsive > .table-bordered > tbody > tr:first-child > td, .panel > .table-responsive > .table-bordered > tbody > tr:first-child > th, .panel > .table-responsive > .table-bordered > thead > tr:first-child > td, .panel > .table-responsive > .table-bordered > thead > tr:first-child > th {
+ border-bottom: 0
+}
+
+.panel > .table-bordered > tbody > tr:last-child > td, .panel > .table-bordered > tbody > tr:last-child > th, .panel > .table-bordered > tfoot > tr:last-child > td, .panel > .table-bordered > tfoot > tr:last-child > th, .panel > .table-responsive > .table-bordered > tbody > tr:last-child > td, .panel > .table-responsive > .table-bordered > tbody > tr:last-child > th, .panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td, .panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {
+ border-bottom: 0
+}
+
+.panel > .table-responsive {
+ margin-bottom: 0;
+ border: 0
+}
+
+.panel-group {
+ margin-bottom: 20px
+}
+
+.panel-group .panel {
+ margin-bottom: 0;
+ border-radius: 4px
+}
+
+.panel-group .panel + .panel {
+ margin-top: 5px
+}
+
+.panel-group .panel-heading {
+ border-bottom: 0
+}
+
+.panel-group .panel-heading + .panel-collapse > .list-group, .panel-group .panel-heading + .panel-collapse > .panel-body {
+ border-top: 1px solid #ddd
+}
+
+.panel-group .panel-footer {
+ border-top: 0
+}
+
+.panel-group .panel-footer + .panel-collapse .panel-body {
+ border-bottom: 1px solid #ddd
+}
+
+.panel-default {
+ border-color: #ddd
+}
+
+.panel-default > .panel-heading {
+ color: #333;
+ background-color: #f5f5f5;
+ border-color: #ddd
+}
+
+.panel-default > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #ddd
+}
+
+.panel-default > .panel-heading .badge {
+ color: #f5f5f5;
+ background-color: #333
+}
+
+.panel-default > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #ddd
+}
+
+.panel-primary {
+ border-color: #337ab7
+}
+
+.panel-primary > .panel-heading {
+ color: #fff;
+ background-color: #337ab7;
+ border-color: #337ab7
+}
+
+.panel-primary > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #337ab7
+}
+
+.panel-primary > .panel-heading .badge {
+ color: #337ab7;
+ background-color: #fff
+}
+
+.panel-primary > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #337ab7
+}
+
+.panel-success {
+ border-color: #d6e9c6
+}
+
+.panel-success > .panel-heading {
+ color: #3c763d;
+ background-color: #dff0d8;
+ border-color: #d6e9c6
+}
+
+.panel-success > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #d6e9c6
+}
+
+.panel-success > .panel-heading .badge {
+ color: #dff0d8;
+ background-color: #3c763d
+}
+
+.panel-success > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #d6e9c6
+}
+
+.panel-info {
+ border-color: #bce8f1
+}
+
+.panel-info > .panel-heading {
+ color: #31708f;
+ background-color: #d9edf7;
+ border-color: #bce8f1
+}
+
+.panel-info > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #bce8f1
+}
+
+.panel-info > .panel-heading .badge {
+ color: #d9edf7;
+ background-color: #31708f
+}
+
+.panel-info > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #bce8f1
+}
+
+.panel-warning {
+ border-color: #faebcc
+}
+
+.panel-warning > .panel-heading {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+ border-color: #faebcc
+}
+
+.panel-warning > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #faebcc
+}
+
+.panel-warning > .panel-heading .badge {
+ color: #fcf8e3;
+ background-color: #8a6d3b
+}
+
+.panel-warning > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #faebcc
+}
+
+.panel-danger {
+ border-color: #ebccd1
+}
+
+.panel-danger > .panel-heading {
+ color: #a94442;
+ background-color: #f2dede;
+ border-color: #ebccd1
+}
+
+.panel-danger > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #ebccd1
+}
+
+.panel-danger > .panel-heading .badge {
+ color: #f2dede;
+ background-color: #a94442
+}
+
+.panel-danger > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #ebccd1
+}
+
+.embed-responsive {
+ position: relative;
+ display: block;
+ height: 0;
+ padding: 0;
+ overflow: hidden
+}
+
+.embed-responsive .embed-responsive-item, .embed-responsive embed, .embed-responsive iframe, .embed-responsive object, .embed-responsive video {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ border: 0
+}
+
+.embed-responsive-16by9 {
+ padding-bottom: 56.25%
+}
+
+.embed-responsive-4by3 {
+ padding-bottom: 75%
+}
+
+.well {
+ min-height: 20px;
+ padding: 19px;
+ margin-bottom: 20px;
+ background-color: #f5f5f5;
+ border: 1px solid #e3e3e3;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05)
+}
+
+.well blockquote {
+ border-color: #ddd;
+ border-color: rgba(0, 0, 0, .15)
+}
+
+.well-lg {
+ padding: 24px;
+ border-radius: 6px
+}
+
+.well-sm {
+ padding: 9px;
+ border-radius: 3px
+}
+
+.close {
+ float: right;
+ font-size: 21px;
+ font-weight: 700;
+ line-height: 1;
+ color: #000;
+ text-shadow: 0 1px 0 #fff;
+ filter: alpha(opacity=20);
+ opacity: .2
+}
+
+.close:focus, .close:hover {
+ color: #000;
+ text-decoration: none;
+ cursor: pointer;
+ filter: alpha(opacity=50);
+ opacity: .5
+}
+
+button.close {
+ -webkit-appearance: none;
+ padding: 0;
+ cursor: pointer;
+ background: 0 0;
+ border: 0
+}
+
+.modal-open {
+ overflow: hidden
+}
+
+.modal {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1050;
+ display: none;
+ overflow: hidden;
+ -webkit-overflow-scrolling: touch;
+ outline: 0
+}
+
+.modal.fade .modal-dialog {
+ -webkit-transition: -webkit-transform .3s ease-out;
+ -o-transition: -o-transform .3s ease-out;
+ transition: transform .3s ease-out;
+ -webkit-transform: translate(0, -25%);
+ -ms-transform: translate(0, -25%);
+ -o-transform: translate(0, -25%);
+ transform: translate(0, -25%)
+}
+
+.modal.in .modal-dialog {
+ -webkit-transform: translate(0, 0);
+ -ms-transform: translate(0, 0);
+ -o-transform: translate(0, 0);
+ transform: translate(0, 0)
+}
+
+.modal-open .modal {
+ overflow-x: hidden;
+ overflow-y: auto
+}
+
+.modal-dialog {
+ position: relative;
+ width: auto;
+ margin: 10px
+}
+
+.modal-content {
+ position: relative;
+ background-color: #fff;
+ -webkit-background-clip: padding-box;
+ background-clip: padding-box;
+ border: 1px solid #999;
+ border: 1px solid rgba(0, 0, 0, .2);
+ border-radius: 6px;
+ outline: 0;
+ -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5);
+ box-shadow: 0 3px 9px rgba(0, 0, 0, .5)
+}
+
+.modal-backdrop {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1040;
+ background-color: #000
+}
+
+.modal-backdrop.fade {
+ filter: alpha(opacity=0);
+ opacity: 0
+}
+
+.modal-backdrop.in {
+ filter: alpha(opacity=50);
+ opacity: .5
+}
+
+.modal-header {
+ min-height: 16.43px;
+ padding: 15px;
+ border-bottom: 1px solid #e5e5e5
+}
+
+.modal-header .close {
+ margin-top: -2px
+}
+
+.modal-title {
+ margin: 0;
+ line-height: 1.42857143
+}
+
+.modal-body {
+ position: relative;
+ padding: 15px
+}
+
+.modal-footer {
+ padding: 15px;
+ text-align: right;
+ border-top: 1px solid #e5e5e5
+}
+
+.modal-footer .btn + .btn {
+ margin-bottom: 0;
+ margin-left: 5px
+}
+
+.modal-footer .btn-group .btn + .btn {
+ margin-left: -1px
+}
+
+.modal-footer .btn-block + .btn-block {
+ margin-left: 0
+}
+
+.modal-scrollbar-measure {
+ position: absolute;
+ top: -9999px;
+ width: 50px;
+ height: 50px;
+ overflow: scroll
+}
+
+@media (min-width: 768px) {
+ .modal-dialog {
+ width: 600px;
+ margin: 30px auto
+ }
+
+ .modal-content {
+ -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
+ box-shadow: 0 5px 15px rgba(0, 0, 0, .5)
+ }
+
+ .modal-sm {
+ width: 300px
+ }
+}
+
+@media (min-width: 992px) {
+ .modal-lg {
+ width: 900px
+ }
+}
+
+.tooltip {
+ position: absolute;
+ z-index: 1070;
+ display: block;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 12px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 1.42857143;
+ text-align: left;
+ text-align: start;
+ text-decoration: none;
+ text-shadow: none;
+ text-transform: none;
+ letter-spacing: normal;
+ word-break: normal;
+ word-spacing: normal;
+ word-wrap: normal;
+ white-space: normal;
+ filter: alpha(opacity=0);
+ opacity: 0;
+ line-break: auto
+}
+
+.tooltip.in {
+ filter: alpha(opacity=90);
+ opacity: .9
+}
+
+.tooltip.top {
+ padding: 5px 0;
+ margin-top: -3px
+}
+
+.tooltip.right {
+ padding: 0 5px;
+ margin-left: 3px
+}
+
+.tooltip.bottom {
+ padding: 5px 0;
+ margin-top: 3px
+}
+
+.tooltip.left {
+ padding: 0 5px;
+ margin-left: -3px
+}
+
+.tooltip-inner {
+ max-width: 200px;
+ padding: 3px 8px;
+ color: #fff;
+ text-align: center;
+ background-color: #000;
+ border-radius: 4px
+}
+
+.tooltip-arrow {
+ position: absolute;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid
+}
+
+.tooltip.top .tooltip-arrow {
+ bottom: 0;
+ left: 50%;
+ margin-left: -5px;
+ border-width: 5px 5px 0;
+ border-top-color: #000
+}
+
+.tooltip.top-left .tooltip-arrow {
+ right: 5px;
+ bottom: 0;
+ margin-bottom: -5px;
+ border-width: 5px 5px 0;
+ border-top-color: #000
+}
+
+.tooltip.top-right .tooltip-arrow {
+ bottom: 0;
+ left: 5px;
+ margin-bottom: -5px;
+ border-width: 5px 5px 0;
+ border-top-color: #000
+}
+
+.tooltip.right .tooltip-arrow {
+ top: 50%;
+ left: 0;
+ margin-top: -5px;
+ border-width: 5px 5px 5px 0;
+ border-right-color: #000
+}
+
+.tooltip.left .tooltip-arrow {
+ top: 50%;
+ right: 0;
+ margin-top: -5px;
+ border-width: 5px 0 5px 5px;
+ border-left-color: #000
+}
+
+.tooltip.bottom .tooltip-arrow {
+ top: 0;
+ left: 50%;
+ margin-left: -5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000
+}
+
+.tooltip.bottom-left .tooltip-arrow {
+ top: 0;
+ right: 5px;
+ margin-top: -5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000
+}
+
+.tooltip.bottom-right .tooltip-arrow {
+ top: 0;
+ left: 5px;
+ margin-top: -5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000
+}
+
+.popover {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 1060;
+ display: none;
+ max-width: 276px;
+ padding: 1px;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 14px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 1.42857143;
+ text-align: left;
+ text-align: start;
+ text-decoration: none;
+ text-shadow: none;
+ text-transform: none;
+ letter-spacing: normal;
+ word-break: normal;
+ word-spacing: normal;
+ word-wrap: normal;
+ white-space: normal;
+ background-color: #fff;
+ -webkit-background-clip: padding-box;
+ background-clip: padding-box;
+ border: 1px solid #ccc;
+ border: 1px solid rgba(0, 0, 0, .2);
+ border-radius: 6px;
+ -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
+ box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
+ line-break: auto
+}
+
+.popover.top {
+ margin-top: -10px
+}
+
+.popover.right {
+ margin-left: 10px
+}
+
+.popover.bottom {
+ margin-top: 10px
+}
+
+.popover.left {
+ margin-left: -10px
+}
+
+.popover-title {
+ padding: 8px 14px;
+ margin: 0;
+ font-size: 14px;
+ background-color: #f7f7f7;
+ border-bottom: 1px solid #ebebeb;
+ border-radius: 5px 5px 0 0
+}
+
+.popover-content {
+ padding: 9px 14px
+}
+
+.popover > .arrow, .popover > .arrow:after {
+ position: absolute;
+ display: block;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid
+}
+
+.popover > .arrow {
+ border-width: 11px
+}
+
+.popover > .arrow:after {
+ content: "";
+ border-width: 10px
+}
+
+.popover.top > .arrow {
+ bottom: -11px;
+ left: 50%;
+ margin-left: -11px;
+ border-top-color: #999;
+ border-top-color: rgba(0, 0, 0, .25);
+ border-bottom-width: 0
+}
+
+.popover.top > .arrow:after {
+ bottom: 1px;
+ margin-left: -10px;
+ content: " ";
+ border-top-color: #fff;
+ border-bottom-width: 0
+}
+
+.popover.right > .arrow {
+ top: 50%;
+ left: -11px;
+ margin-top: -11px;
+ border-right-color: #999;
+ border-right-color: rgba(0, 0, 0, .25);
+ border-left-width: 0
+}
+
+.popover.right > .arrow:after {
+ bottom: -10px;
+ left: 1px;
+ content: " ";
+ border-right-color: #fff;
+ border-left-width: 0
+}
+
+.popover.bottom > .arrow {
+ top: -11px;
+ left: 50%;
+ margin-left: -11px;
+ border-top-width: 0;
+ border-bottom-color: #999;
+ border-bottom-color: rgba(0, 0, 0, .25)
+}
+
+.popover.bottom > .arrow:after {
+ top: 1px;
+ margin-left: -10px;
+ content: " ";
+ border-top-width: 0;
+ border-bottom-color: #fff
+}
+
+.popover.left > .arrow {
+ top: 50%;
+ right: -11px;
+ margin-top: -11px;
+ border-right-width: 0;
+ border-left-color: #999;
+ border-left-color: rgba(0, 0, 0, .25)
+}
+
+.popover.left > .arrow:after {
+ right: 1px;
+ bottom: -10px;
+ content: " ";
+ border-right-width: 0;
+ border-left-color: #fff
+}
+
+.carousel {
+ position: relative
+}
+
+.carousel-inner {
+ position: relative;
+ width: 100%;
+ overflow: hidden
+}
+
+.carousel-inner > .item {
+ position: relative;
+ display: none;
+ -webkit-transition: .6s ease-in-out left;
+ -o-transition: .6s ease-in-out left;
+ transition: .6s ease-in-out left
+}
+
+.carousel-inner > .item > a > img, .carousel-inner > .item > img {
+ line-height: 1
+}
+
+@media all and (transform-3d),(-webkit-transform-3d) {
+ .carousel-inner > .item {
+ -webkit-transition: -webkit-transform .6s ease-in-out;
+ -o-transition: -o-transform .6s ease-in-out;
+ transition: transform .6s ease-in-out;
+ -webkit-backface-visibility: hidden;
+ backface-visibility: hidden;
+ -webkit-perspective: 1000px;
+ perspective: 1000px
+ }
+
+ .carousel-inner > .item.active.right, .carousel-inner > .item.next {
+ left: 0;
+ -webkit-transform: translate3d(100%, 0, 0);
+ transform: translate3d(100%, 0, 0)
+ }
+
+ .carousel-inner > .item.active.left, .carousel-inner > .item.prev {
+ left: 0;
+ -webkit-transform: translate3d(-100%, 0, 0);
+ transform: translate3d(-100%, 0, 0)
+ }
+
+ .carousel-inner > .item.active, .carousel-inner > .item.next.left, .carousel-inner > .item.prev.right {
+ left: 0;
+ -webkit-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0)
+ }
+}
+
+.carousel-inner > .active, .carousel-inner > .next, .carousel-inner > .prev {
+ display: block
+}
+
+.carousel-inner > .active {
+ left: 0
+}
+
+.carousel-inner > .next, .carousel-inner > .prev {
+ position: absolute;
+ top: 0;
+ width: 100%
+}
+
+.carousel-inner > .next {
+ left: 100%
+}
+
+.carousel-inner > .prev {
+ left: -100%
+}
+
+.carousel-inner > .next.left, .carousel-inner > .prev.right {
+ left: 0
+}
+
+.carousel-inner > .active.left {
+ left: -100%
+}
+
+.carousel-inner > .active.right {
+ left: 100%
+}
+
+.carousel-control {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ width: 15%;
+ font-size: 20px;
+ color: #fff;
+ text-align: center;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
+ filter: alpha(opacity=50);
+ opacity: .5
+}
+
+.carousel-control.left {
+ background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0, rgba(0, 0, 0, .0001) 100%);
+ background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5) 0, rgba(0, 0, 0, .0001) 100%);
+ background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001)));
+ background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0, rgba(0, 0, 0, .0001) 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);
+ background-repeat: repeat-x
+}
+
+.carousel-control.right {
+ right: 0;
+ left: auto;
+ background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0, rgba(0, 0, 0, .5) 100%);
+ background-image: -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0, rgba(0, 0, 0, .5) 100%);
+ background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5)));
+ background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0, rgba(0, 0, 0, .5) 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);
+ background-repeat: repeat-x
+}
+
+.carousel-control:focus, .carousel-control:hover {
+ color: #fff;
+ text-decoration: none;
+ filter: alpha(opacity=90);
+ outline: 0;
+ opacity: .9
+}
+
+.carousel-control .glyphicon-chevron-left, .carousel-control .glyphicon-chevron-right, .carousel-control .icon-next, .carousel-control .icon-prev {
+ position: absolute;
+ top: 50%;
+ z-index: 5;
+ display: inline-block;
+ margin-top: -10px
+}
+
+.carousel-control .glyphicon-chevron-left, .carousel-control .icon-prev {
+ left: 50%;
+ margin-left: -10px
+}
+
+.carousel-control .glyphicon-chevron-right, .carousel-control .icon-next {
+ right: 50%;
+ margin-right: -10px
+}
+
+.carousel-control .icon-next, .carousel-control .icon-prev {
+ width: 20px;
+ height: 20px;
+ font-family: serif;
+ line-height: 1
+}
+
+.carousel-control .icon-prev:before {
+ content: '\2039'
+}
+
+.carousel-control .icon-next:before {
+ content: '\203a'
+}
+
+.carousel-indicators {
+ position: absolute;
+ bottom: 10px;
+ left: 50%;
+ z-index: 15;
+ width: 60%;
+ padding-left: 0;
+ margin-left: -30%;
+ text-align: center;
+ list-style: none
+}
+
+.carousel-indicators li {
+ display: inline-block;
+ width: 10px;
+ height: 10px;
+ margin: 1px;
+ text-indent: -999px;
+ cursor: pointer;
+ background-color: #000 \9;
+ background-color: rgba(0, 0, 0, 0);
+ border: 1px solid #fff;
+ border-radius: 10px
+}
+
+.carousel-indicators .active {
+ width: 12px;
+ height: 12px;
+ margin: 0;
+ background-color: #fff
+}
+
+.carousel-caption {
+ position: absolute;
+ right: 15%;
+ bottom: 20px;
+ left: 15%;
+ z-index: 10;
+ padding-top: 20px;
+ padding-bottom: 20px;
+ color: #fff;
+ text-align: center;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, .6)
+}
+
+.carousel-caption .btn {
+ text-shadow: none
+}
+
+@media screen and (min-width: 768px) {
+ .carousel-control .glyphicon-chevron-left, .carousel-control .glyphicon-chevron-right, .carousel-control .icon-next, .carousel-control .icon-prev {
+ width: 30px;
+ height: 30px;
+ margin-top: -15px;
+ font-size: 30px
+ }
+
+ .carousel-control .glyphicon-chevron-left, .carousel-control .icon-prev {
+ margin-left: -15px
+ }
+
+ .carousel-control .glyphicon-chevron-right, .carousel-control .icon-next {
+ margin-right: -15px
+ }
+
+ .carousel-caption {
+ right: 20%;
+ left: 20%;
+ padding-bottom: 30px
+ }
+
+ .carousel-indicators {
+ bottom: 20px
+ }
+}
+
+.btn-group-vertical > .btn-group:after, .btn-group-vertical > .btn-group:before, .btn-toolbar:after, .btn-toolbar:before, .clearfix:after, .clearfix:before, .container-fluid:after, .container-fluid:before, .container:after, .container:before, .dl-horizontal dd:after, .dl-horizontal dd:before, .form-horizontal .form-group:after, .form-horizontal .form-group:before, .modal-footer:after, .modal-footer:before, .nav:after, .nav:before, .navbar-collapse:after, .navbar-collapse:before, .navbar-header:after, .navbar-header:before, .navbar:after, .navbar:before, .pager:after, .pager:before, .panel-body:after, .panel-body:before, .row:after, .row:before {
+ display: table;
+ content: " "
+}
+
+.btn-group-vertical > .btn-group:after, .btn-toolbar:after, .clearfix:after, .container-fluid:after, .container:after, .dl-horizontal dd:after, .form-horizontal .form-group:after, .modal-footer:after, .nav:after, .navbar-collapse:after, .navbar-header:after, .navbar:after, .pager:after, .panel-body:after, .row:after {
+ clear: both
+}
+
+.center-block {
+ display: block;
+ margin-right: auto;
+ margin-left: auto
+}
+
+.pull-right {
+ float: right !important
+}
+
+.pull-left {
+ float: left !important
+}
+
+.hide {
+ display: none !important
+}
+
+.show {
+ display: block !important
+}
+
+.invisible {
+ visibility: hidden
+}
+
+.text-hide {
+ font: 0/0 a;
+ color: transparent;
+ text-shadow: none;
+ background-color: transparent;
+ border: 0
+}
+
+.hidden {
+ display: none !important
+}
+
+.affix {
+ position: fixed
+}
+
+@-ms-viewport {
+ width: device-width
+}
+
+.visible-lg, .visible-md, .visible-sm, .visible-xs {
+ display: none !important
+}
+
+.visible-lg-block, .visible-lg-inline, .visible-lg-inline-block, .visible-md-block, .visible-md-inline, .visible-md-inline-block, .visible-sm-block, .visible-sm-inline, .visible-sm-inline-block, .visible-xs-block, .visible-xs-inline, .visible-xs-inline-block {
+ display: none !important
+}
+
+@media (max-width: 767px) {
+ .visible-xs {
+ display: block !important
+ }
+
+ table.visible-xs {
+ display: table !important
+ }
+
+ tr.visible-xs {
+ display: table-row !important
+ }
+
+ td.visible-xs, th.visible-xs {
+ display: table-cell !important
+ }
+}
+
+@media (max-width: 767px) {
+ .visible-xs-block {
+ display: block !important
+ }
+}
+
+@media (max-width: 767px) {
+ .visible-xs-inline {
+ display: inline !important
+ }
+}
+
+@media (max-width: 767px) {
+ .visible-xs-inline-block {
+ display: inline-block !important
+ }
+}
+
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm {
+ display: block !important
+ }
+
+ table.visible-sm {
+ display: table !important
+ }
+
+ tr.visible-sm {
+ display: table-row !important
+ }
+
+ td.visible-sm, th.visible-sm {
+ display: table-cell !important
+ }
+}
+
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-block {
+ display: block !important
+ }
+}
+
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-inline {
+ display: inline !important
+ }
+}
+
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-inline-block {
+ display: inline-block !important
+ }
+}
+
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md {
+ display: block !important
+ }
+
+ table.visible-md {
+ display: table !important
+ }
+
+ tr.visible-md {
+ display: table-row !important
+ }
+
+ td.visible-md, th.visible-md {
+ display: table-cell !important
+ }
+}
+
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-block {
+ display: block !important
+ }
+}
+
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-inline {
+ display: inline !important
+ }
+}
+
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-inline-block {
+ display: inline-block !important
+ }
+}
+
+@media (min-width: 1200px) {
+ .visible-lg {
+ display: block !important
+ }
+
+ table.visible-lg {
+ display: table !important
+ }
+
+ tr.visible-lg {
+ display: table-row !important
+ }
+
+ td.visible-lg, th.visible-lg {
+ display: table-cell !important
+ }
+}
+
+@media (min-width: 1200px) {
+ .visible-lg-block {
+ display: block !important
+ }
+}
+
+@media (min-width: 1200px) {
+ .visible-lg-inline {
+ display: inline !important
+ }
+}
+
+@media (min-width: 1200px) {
+ .visible-lg-inline-block {
+ display: inline-block !important
+ }
+}
+
+@media (max-width: 767px) {
+ .hidden-xs {
+ display: none !important
+ }
+}
+
+@media (min-width: 768px) and (max-width: 991px) {
+ .hidden-sm {
+ display: none !important
+ }
+}
+
+@media (min-width: 992px) and (max-width: 1199px) {
+ .hidden-md {
+ display: none !important
+ }
+}
+
+@media (min-width: 1200px) {
+ .hidden-lg {
+ display: none !important
+ }
+}
+
+.visible-print {
+ display: none !important
+}
+
+@media print {
+ .visible-print {
+ display: block !important
+ }
+
+ table.visible-print {
+ display: table !important
+ }
+
+ tr.visible-print {
+ display: table-row !important
+ }
+
+ td.visible-print, th.visible-print {
+ display: table-cell !important
+ }
+}
+
+.visible-print-block {
+ display: none !important
+}
+
+@media print {
+ .visible-print-block {
+ display: block !important
+ }
+}
+
+.visible-print-inline {
+ display: none !important
+}
+
+@media print {
+ .visible-print-inline {
+ display: inline !important
+ }
+}
+
+.visible-print-inline-block {
+ display: none !important
+}
+
+@media print {
+ .visible-print-inline-block {
+ display: inline-block !important
+ }
+}
+
+@media print {
+ .hidden-print {
+ display: none !important
+ }
+}
\ No newline at end of file
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..b93a4953fff68df523aa7656497ee339d6026d64
GIT binary patch
literal 20127
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
Xa1ugufhlr@A=L`vC<+781Zjd`SV@Ta
new file mode 100644
--- /dev/null
+++ b/js/bootstrap/fonts/glyphicons-halflings-regular.svg
@@ -0,0 +1,288 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata></metadata>
+<defs>
+<font id="glyphicons_halflingsregular" horiz-adv-x="1200" >
+<font-face units-per-em="1200" ascent="960" descent="-240" />
+<missing-glyph horiz-adv-x="500" />
+<glyph horiz-adv-x="0" />
+<glyph horiz-adv-x="400" />
+<glyph unicode=" " />
+<glyph unicode="*" d="M600 1100q15 0 34 -1.5t30 -3.5l11 -1q10 -2 17.5 -10.5t7.5 -18.5v-224l158 158q7 7 18 8t19 -6l106 -106q7 -8 6 -19t-8 -18l-158 -158h224q10 0 18.5 -7.5t10.5 -17.5q6 -41 6 -75q0 -15 -1.5 -34t-3.5 -30l-1 -11q-2 -10 -10.5 -17.5t-18.5 -7.5h-224l158 -158 q7 -7 8 -18t-6 -19l-106 -106q-8 -7 -19 -6t-18 8l-158 158v-224q0 -10 -7.5 -18.5t-17.5 -10.5q-41 -6 -75 -6q-15 0 -34 1.5t-30 3.5l-11 1q-10 2 -17.5 10.5t-7.5 18.5v224l-158 -158q-7 -7 -18 -8t-19 6l-106 106q-7 8 -6 19t8 18l158 158h-224q-10 0 -18.5 7.5 t-10.5 17.5q-6 41 -6 75q0 15 1.5 34t3.5 30l1 11q2 10 10.5 17.5t18.5 7.5h224l-158 158q-7 7 -8 18t6 19l106 106q8 7 19 6t18 -8l158 -158v224q0 10 7.5 18.5t17.5 10.5q41 6 75 6z" />
+<glyph unicode="+" d="M450 1100h200q21 0 35.5 -14.5t14.5 -35.5v-350h350q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-350v-350q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v350h-350q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5 h350v350q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode=" " />
+<glyph unicode="¥" d="M825 1100h250q10 0 12.5 -5t-5.5 -13l-364 -364q-6 -6 -11 -18h268q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-125v-100h275q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-125v-174q0 -11 -7.5 -18.5t-18.5 -7.5h-148q-11 0 -18.5 7.5t-7.5 18.5v174 h-275q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h125v100h-275q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h118q-5 12 -11 18l-364 364q-8 8 -5.5 13t12.5 5h250q25 0 43 -18l164 -164q8 -8 18 -8t18 8l164 164q18 18 43 18z" />
+<glyph unicode=" " horiz-adv-x="650" />
+<glyph unicode=" " horiz-adv-x="1300" />
+<glyph unicode=" " horiz-adv-x="650" />
+<glyph unicode=" " horiz-adv-x="1300" />
+<glyph unicode=" " horiz-adv-x="433" />
+<glyph unicode=" " horiz-adv-x="325" />
+<glyph unicode=" " horiz-adv-x="216" />
+<glyph unicode=" " horiz-adv-x="216" />
+<glyph unicode=" " horiz-adv-x="162" />
+<glyph unicode=" " horiz-adv-x="260" />
+<glyph unicode=" " horiz-adv-x="72" />
+<glyph unicode=" " horiz-adv-x="260" />
+<glyph unicode=" " horiz-adv-x="325" />
+<glyph unicode="€" d="M744 1198q242 0 354 -189q60 -104 66 -209h-181q0 45 -17.5 82.5t-43.5 61.5t-58 40.5t-60.5 24t-51.5 7.5q-19 0 -40.5 -5.5t-49.5 -20.5t-53 -38t-49 -62.5t-39 -89.5h379l-100 -100h-300q-6 -50 -6 -100h406l-100 -100h-300q9 -74 33 -132t52.5 -91t61.5 -54.5t59 -29 t47 -7.5q22 0 50.5 7.5t60.5 24.5t58 41t43.5 61t17.5 80h174q-30 -171 -128 -278q-107 -117 -274 -117q-206 0 -324 158q-36 48 -69 133t-45 204h-217l100 100h112q1 47 6 100h-218l100 100h134q20 87 51 153.5t62 103.5q117 141 297 141z" />
+<glyph unicode="₽" d="M428 1200h350q67 0 120 -13t86 -31t57 -49.5t35 -56.5t17 -64.5t6.5 -60.5t0.5 -57v-16.5v-16.5q0 -36 -0.5 -57t-6.5 -61t-17 -65t-35 -57t-57 -50.5t-86 -31.5t-120 -13h-178l-2 -100h288q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-138v-175q0 -11 -5.5 -18 t-15.5 -7h-149q-10 0 -17.5 7.5t-7.5 17.5v175h-267q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h117v100h-267q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h117v475q0 10 7.5 17.5t17.5 7.5zM600 1000v-300h203q64 0 86.5 33t22.5 119q0 84 -22.5 116t-86.5 32h-203z" />
+<glyph unicode="−" d="M250 700h800q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="⌛" d="M1000 1200v-150q0 -21 -14.5 -35.5t-35.5 -14.5h-50v-100q0 -91 -49.5 -165.5t-130.5 -109.5q81 -35 130.5 -109.5t49.5 -165.5v-150h50q21 0 35.5 -14.5t14.5 -35.5v-150h-800v150q0 21 14.5 35.5t35.5 14.5h50v150q0 91 49.5 165.5t130.5 109.5q-81 35 -130.5 109.5 t-49.5 165.5v100h-50q-21 0 -35.5 14.5t-14.5 35.5v150h800zM400 1000v-100q0 -60 32.5 -109.5t87.5 -73.5q28 -12 44 -37t16 -55t-16 -55t-44 -37q-55 -24 -87.5 -73.5t-32.5 -109.5v-150h400v150q0 60 -32.5 109.5t-87.5 73.5q-28 12 -44 37t-16 55t16 55t44 37 q55 24 87.5 73.5t32.5 109.5v100h-400z" />
+<glyph unicode="◼" horiz-adv-x="500" d="M0 0z" />
+<glyph unicode="☁" d="M503 1089q110 0 200.5 -59.5t134.5 -156.5q44 14 90 14q120 0 205 -86.5t85 -206.5q0 -121 -85 -207.5t-205 -86.5h-750q-79 0 -135.5 57t-56.5 137q0 69 42.5 122.5t108.5 67.5q-2 12 -2 37q0 153 108 260.5t260 107.5z" />
+<glyph unicode="⛺" d="M774 1193.5q16 -9.5 20.5 -27t-5.5 -33.5l-136 -187l467 -746h30q20 0 35 -18.5t15 -39.5v-42h-1200v42q0 21 15 39.5t35 18.5h30l468 746l-135 183q-10 16 -5.5 34t20.5 28t34 5.5t28 -20.5l111 -148l112 150q9 16 27 20.5t34 -5zM600 200h377l-182 112l-195 534v-646z " />
+<glyph unicode="✉" d="M25 1100h1150q10 0 12.5 -5t-5.5 -13l-564 -567q-8 -8 -18 -8t-18 8l-564 567q-8 8 -5.5 13t12.5 5zM18 882l264 -264q8 -8 8 -18t-8 -18l-264 -264q-8 -8 -13 -5.5t-5 12.5v550q0 10 5 12.5t13 -5.5zM918 618l264 264q8 8 13 5.5t5 -12.5v-550q0 -10 -5 -12.5t-13 5.5 l-264 264q-8 8 -8 18t8 18zM818 482l364 -364q8 -8 5.5 -13t-12.5 -5h-1150q-10 0 -12.5 5t5.5 13l364 364q8 8 18 8t18 -8l164 -164q8 -8 18 -8t18 8l164 164q8 8 18 8t18 -8z" />
+<glyph unicode="✏" d="M1011 1210q19 0 33 -13l153 -153q13 -14 13 -33t-13 -33l-99 -92l-214 214l95 96q13 14 32 14zM1013 800l-615 -614l-214 214l614 614zM317 96l-333 -112l110 335z" />
+<glyph unicode="" d="M700 650v-550h250q21 0 35.5 -14.5t14.5 -35.5v-50h-800v50q0 21 14.5 35.5t35.5 14.5h250v550l-500 550h1200z" />
+<glyph unicode="" d="M368 1017l645 163q39 15 63 0t24 -49v-831q0 -55 -41.5 -95.5t-111.5 -63.5q-79 -25 -147 -4.5t-86 75t25.5 111.5t122.5 82q72 24 138 8v521l-600 -155v-606q0 -42 -44 -90t-109 -69q-79 -26 -147 -5.5t-86 75.5t25.5 111.5t122.5 82.5q72 24 138 7v639q0 38 14.5 59 t53.5 34z" />
+<glyph unicode="" d="M500 1191q100 0 191 -39t156.5 -104.5t104.5 -156.5t39 -191l-1 -2l1 -5q0 -141 -78 -262l275 -274q23 -26 22.5 -44.5t-22.5 -42.5l-59 -58q-26 -20 -46.5 -20t-39.5 20l-275 274q-119 -77 -261 -77l-5 1l-2 -1q-100 0 -191 39t-156.5 104.5t-104.5 156.5t-39 191 t39 191t104.5 156.5t156.5 104.5t191 39zM500 1022q-88 0 -162 -43t-117 -117t-43 -162t43 -162t117 -117t162 -43t162 43t117 117t43 162t-43 162t-117 117t-162 43z" />
+<glyph unicode="" d="M649 949q48 68 109.5 104t121.5 38.5t118.5 -20t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-150 152.5t-126.5 127.5t-93.5 124.5t-33.5 117.5q0 64 28 123t73 100.5t104 64t119 20 t120.5 -38.5t104.5 -104z" />
+<glyph unicode="" d="M407 800l131 353q7 19 17.5 19t17.5 -19l129 -353h421q21 0 24 -8.5t-14 -20.5l-342 -249l130 -401q7 -20 -0.5 -25.5t-24.5 6.5l-343 246l-342 -247q-17 -12 -24.5 -6.5t-0.5 25.5l130 400l-347 251q-17 12 -14 20.5t23 8.5h429z" />
+<glyph unicode="" d="M407 800l131 353q7 19 17.5 19t17.5 -19l129 -353h421q21 0 24 -8.5t-14 -20.5l-342 -249l130 -401q7 -20 -0.5 -25.5t-24.5 6.5l-343 246l-342 -247q-17 -12 -24.5 -6.5t-0.5 25.5l130 400l-347 251q-17 12 -14 20.5t23 8.5h429zM477 700h-240l197 -142l-74 -226 l193 139l195 -140l-74 229l192 140h-234l-78 211z" />
+<glyph unicode="" d="M600 1200q124 0 212 -88t88 -212v-250q0 -46 -31 -98t-69 -52v-75q0 -10 6 -21.5t15 -17.5l358 -230q9 -5 15 -16.5t6 -21.5v-93q0 -10 -7.5 -17.5t-17.5 -7.5h-1150q-10 0 -17.5 7.5t-7.5 17.5v93q0 10 6 21.5t15 16.5l358 230q9 6 15 17.5t6 21.5v75q-38 0 -69 52 t-31 98v250q0 124 88 212t212 88z" />
+<glyph unicode="" d="M25 1100h1150q10 0 17.5 -7.5t7.5 -17.5v-1050q0 -10 -7.5 -17.5t-17.5 -7.5h-1150q-10 0 -17.5 7.5t-7.5 17.5v1050q0 10 7.5 17.5t17.5 7.5zM100 1000v-100h100v100h-100zM875 1000h-550q-10 0 -17.5 -7.5t-7.5 -17.5v-350q0 -10 7.5 -17.5t17.5 -7.5h550 q10 0 17.5 7.5t7.5 17.5v350q0 10 -7.5 17.5t-17.5 7.5zM1000 1000v-100h100v100h-100zM100 800v-100h100v100h-100zM1000 800v-100h100v100h-100zM100 600v-100h100v100h-100zM1000 600v-100h100v100h-100zM875 500h-550q-10 0 -17.5 -7.5t-7.5 -17.5v-350q0 -10 7.5 -17.5 t17.5 -7.5h550q10 0 17.5 7.5t7.5 17.5v350q0 10 -7.5 17.5t-17.5 7.5zM100 400v-100h100v100h-100zM1000 400v-100h100v100h-100zM100 200v-100h100v100h-100zM1000 200v-100h100v100h-100z" />
+<glyph unicode="" d="M50 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM650 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400 q0 21 14.5 35.5t35.5 14.5zM50 500h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM650 500h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M50 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200 q0 21 14.5 35.5t35.5 14.5zM850 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200 q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM850 700h200q21 0 35.5 -14.5t14.5 -35.5v-200 q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 300h200 q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM850 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5 t35.5 14.5z" />
+<glyph unicode="" d="M50 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 1100h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v200 q0 21 14.5 35.5t35.5 14.5zM50 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 700h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700 q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 300h700q21 0 35.5 -14.5t14.5 -35.5v-200 q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M465 477l571 571q8 8 18 8t17 -8l177 -177q8 -7 8 -17t-8 -18l-783 -784q-7 -8 -17.5 -8t-17.5 8l-384 384q-8 8 -8 18t8 17l177 177q7 8 17 8t18 -8l171 -171q7 -7 18 -7t18 7z" />
+<glyph unicode="" d="M904 1083l178 -179q8 -8 8 -18.5t-8 -17.5l-267 -268l267 -268q8 -7 8 -17.5t-8 -18.5l-178 -178q-8 -8 -18.5 -8t-17.5 8l-268 267l-268 -267q-7 -8 -17.5 -8t-18.5 8l-178 178q-8 8 -8 18.5t8 17.5l267 268l-267 268q-8 7 -8 17.5t8 18.5l178 178q8 8 18.5 8t17.5 -8 l268 -267l268 268q7 7 17.5 7t18.5 -7z" />
+<glyph unicode="" d="M507 1177q98 0 187.5 -38.5t154.5 -103.5t103.5 -154.5t38.5 -187.5q0 -141 -78 -262l300 -299q8 -8 8 -18.5t-8 -18.5l-109 -108q-7 -8 -17.5 -8t-18.5 8l-300 299q-119 -77 -261 -77q-98 0 -188 38.5t-154.5 103t-103 154.5t-38.5 188t38.5 187.5t103 154.5 t154.5 103.5t188 38.5zM506.5 1023q-89.5 0 -165.5 -44t-120 -120.5t-44 -166t44 -165.5t120 -120t165.5 -44t166 44t120.5 120t44 165.5t-44 166t-120.5 120.5t-166 44zM425 900h150q10 0 17.5 -7.5t7.5 -17.5v-75h75q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5 t-17.5 -7.5h-75v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-75q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h75v75q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="" d="M507 1177q98 0 187.5 -38.5t154.5 -103.5t103.5 -154.5t38.5 -187.5q0 -141 -78 -262l300 -299q8 -8 8 -18.5t-8 -18.5l-109 -108q-7 -8 -17.5 -8t-18.5 8l-300 299q-119 -77 -261 -77q-98 0 -188 38.5t-154.5 103t-103 154.5t-38.5 188t38.5 187.5t103 154.5 t154.5 103.5t188 38.5zM506.5 1023q-89.5 0 -165.5 -44t-120 -120.5t-44 -166t44 -165.5t120 -120t165.5 -44t166 44t120.5 120t44 165.5t-44 166t-120.5 120.5t-166 44zM325 800h350q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-350q-10 0 -17.5 7.5 t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="" d="M550 1200h100q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM800 975v166q167 -62 272 -209.5t105 -331.5q0 -117 -45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5 t-184.5 123t-123 184.5t-45.5 224q0 184 105 331.5t272 209.5v-166q-103 -55 -165 -155t-62 -220q0 -116 57 -214.5t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5q0 120 -62 220t-165 155z" />
+<glyph unicode="" d="M1025 1200h150q10 0 17.5 -7.5t7.5 -17.5v-1150q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v1150q0 10 7.5 17.5t17.5 7.5zM725 800h150q10 0 17.5 -7.5t7.5 -17.5v-750q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v750 q0 10 7.5 17.5t17.5 7.5zM425 500h150q10 0 17.5 -7.5t7.5 -17.5v-450q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v450q0 10 7.5 17.5t17.5 7.5zM125 300h150q10 0 17.5 -7.5t7.5 -17.5v-250q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5 v250q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="" d="M600 1174q33 0 74 -5l38 -152l5 -1q49 -14 94 -39l5 -2l134 80q61 -48 104 -105l-80 -134l3 -5q25 -44 39 -93l1 -6l152 -38q5 -43 5 -73q0 -34 -5 -74l-152 -38l-1 -6q-15 -49 -39 -93l-3 -5l80 -134q-48 -61 -104 -105l-134 81l-5 -3q-44 -25 -94 -39l-5 -2l-38 -151 q-43 -5 -74 -5q-33 0 -74 5l-38 151l-5 2q-49 14 -94 39l-5 3l-134 -81q-60 48 -104 105l80 134l-3 5q-25 45 -38 93l-2 6l-151 38q-6 42 -6 74q0 33 6 73l151 38l2 6q13 48 38 93l3 5l-80 134q47 61 105 105l133 -80l5 2q45 25 94 39l5 1l38 152q43 5 74 5zM600 815 q-89 0 -152 -63t-63 -151.5t63 -151.5t152 -63t152 63t63 151.5t-63 151.5t-152 63z" />
+<glyph unicode="" d="M500 1300h300q41 0 70.5 -29.5t29.5 -70.5v-100h275q10 0 17.5 -7.5t7.5 -17.5v-75h-1100v75q0 10 7.5 17.5t17.5 7.5h275v100q0 41 29.5 70.5t70.5 29.5zM500 1200v-100h300v100h-300zM1100 900v-800q0 -41 -29.5 -70.5t-70.5 -29.5h-700q-41 0 -70.5 29.5t-29.5 70.5 v800h900zM300 800v-700h100v700h-100zM500 800v-700h100v700h-100zM700 800v-700h100v700h-100zM900 800v-700h100v700h-100z" />
+<glyph unicode="" d="M18 618l620 608q8 7 18.5 7t17.5 -7l608 -608q8 -8 5.5 -13t-12.5 -5h-175v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v375h-300v-375q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v575h-175q-10 0 -12.5 5t5.5 13z" />
+<glyph unicode="" d="M600 1200v-400q0 -41 29.5 -70.5t70.5 -29.5h300v-650q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v1100q0 21 14.5 35.5t35.5 14.5h450zM1000 800h-250q-21 0 -35.5 14.5t-14.5 35.5v250z" />
+<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM525 900h50q10 0 17.5 -7.5t7.5 -17.5v-275h175q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="" d="M1300 0h-538l-41 400h-242l-41 -400h-538l431 1200h209l-21 -300h162l-20 300h208zM515 800l-27 -300h224l-27 300h-170z" />
+<glyph unicode="" d="M550 1200h200q21 0 35.5 -14.5t14.5 -35.5v-450h191q20 0 25.5 -11.5t-7.5 -27.5l-327 -400q-13 -16 -32 -16t-32 16l-327 400q-13 16 -7.5 27.5t25.5 11.5h191v450q0 21 14.5 35.5t35.5 14.5zM1125 400h50q10 0 17.5 -7.5t7.5 -17.5v-350q0 -10 -7.5 -17.5t-17.5 -7.5 h-1050q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h50q10 0 17.5 -7.5t7.5 -17.5v-175h900v175q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM525 900h150q10 0 17.5 -7.5t7.5 -17.5v-275h137q21 0 26 -11.5t-8 -27.5l-223 -275q-13 -16 -32 -16t-32 16l-223 275q-13 16 -8 27.5t26 11.5h137v275q0 10 7.5 17.5t17.5 7.5z " />
+<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM632 914l223 -275q13 -16 8 -27.5t-26 -11.5h-137v-275q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v275h-137q-21 0 -26 11.5t8 27.5l223 275q13 16 32 16 t32 -16z" />
+<glyph unicode="" d="M225 1200h750q10 0 19.5 -7t12.5 -17l186 -652q7 -24 7 -49v-425q0 -12 -4 -27t-9 -17q-12 -6 -37 -6h-1100q-12 0 -27 4t-17 8q-6 13 -6 38l1 425q0 25 7 49l185 652q3 10 12.5 17t19.5 7zM878 1000h-556q-10 0 -19 -7t-11 -18l-87 -450q-2 -11 4 -18t16 -7h150 q10 0 19.5 -7t11.5 -17l38 -152q2 -10 11.5 -17t19.5 -7h250q10 0 19.5 7t11.5 17l38 152q2 10 11.5 17t19.5 7h150q10 0 16 7t4 18l-87 450q-2 11 -11 18t-19 7z" />
+<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM540 820l253 -190q17 -12 17 -30t-17 -30l-253 -190q-16 -12 -28 -6.5t-12 26.5v400q0 21 12 26.5t28 -6.5z" />
+<glyph unicode="" d="M947 1060l135 135q7 7 12.5 5t5.5 -13v-362q0 -10 -7.5 -17.5t-17.5 -7.5h-362q-11 0 -13 5.5t5 12.5l133 133q-109 76 -238 76q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5h150q0 -117 -45.5 -224 t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5q192 0 347 -117z" />
+<glyph unicode="" d="M947 1060l135 135q7 7 12.5 5t5.5 -13v-361q0 -11 -7.5 -18.5t-18.5 -7.5h-361q-11 0 -13 5.5t5 12.5l134 134q-110 75 -239 75q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5h-150q0 117 45.5 224t123 184.5t184.5 123t224 45.5q192 0 347 -117zM1027 600h150 q0 -117 -45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5q-192 0 -348 118l-134 -134q-7 -8 -12.5 -5.5t-5.5 12.5v360q0 11 7.5 18.5t18.5 7.5h360q10 0 12.5 -5.5t-5.5 -12.5l-133 -133q110 -76 240 -76q116 0 214.5 57t155.5 155.5t57 214.5z" />
+<glyph unicode="" d="M125 1200h1050q10 0 17.5 -7.5t7.5 -17.5v-1150q0 -10 -7.5 -17.5t-17.5 -7.5h-1050q-10 0 -17.5 7.5t-7.5 17.5v1150q0 10 7.5 17.5t17.5 7.5zM1075 1000h-850q-10 0 -17.5 -7.5t-7.5 -17.5v-850q0 -10 7.5 -17.5t17.5 -7.5h850q10 0 17.5 7.5t7.5 17.5v850 q0 10 -7.5 17.5t-17.5 7.5zM325 900h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 900h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 700h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 700h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 500h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 500h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 300h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 300h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="" d="M900 800v200q0 83 -58.5 141.5t-141.5 58.5h-300q-82 0 -141 -59t-59 -141v-200h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-600q0 -41 29.5 -70.5t70.5 -29.5h900q41 0 70.5 29.5t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5h-100zM400 800v150q0 21 15 35.5t35 14.5h200 q20 0 35 -14.5t15 -35.5v-150h-300z" />
+<glyph unicode="" d="M125 1100h50q10 0 17.5 -7.5t7.5 -17.5v-1075h-100v1075q0 10 7.5 17.5t17.5 7.5zM1075 1052q4 0 9 -2q16 -6 16 -23v-421q0 -6 -3 -12q-33 -59 -66.5 -99t-65.5 -58t-56.5 -24.5t-52.5 -6.5q-26 0 -57.5 6.5t-52.5 13.5t-60 21q-41 15 -63 22.5t-57.5 15t-65.5 7.5 q-85 0 -160 -57q-7 -5 -15 -5q-6 0 -11 3q-14 7 -14 22v438q22 55 82 98.5t119 46.5q23 2 43 0.5t43 -7t32.5 -8.5t38 -13t32.5 -11q41 -14 63.5 -21t57 -14t63.5 -7q103 0 183 87q7 8 18 8z" />
+<glyph unicode="" d="M600 1175q116 0 227 -49.5t192.5 -131t131 -192.5t49.5 -227v-300q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v300q0 127 -70.5 231.5t-184.5 161.5t-245 57t-245 -57t-184.5 -161.5t-70.5 -231.5v-300q0 -10 -7.5 -17.5t-17.5 -7.5h-50 q-10 0 -17.5 7.5t-7.5 17.5v300q0 116 49.5 227t131 192.5t192.5 131t227 49.5zM220 500h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14v460q0 8 6 14t14 6zM820 500h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14v460 q0 8 6 14t14 6z" />
+<glyph unicode="" d="M321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM900 668l120 120q7 7 17 7t17 -7l34 -34q7 -7 7 -17t-7 -17l-120 -120l120 -120q7 -7 7 -17 t-7 -17l-34 -34q-7 -7 -17 -7t-17 7l-120 119l-120 -119q-7 -7 -17 -7t-17 7l-34 34q-7 7 -7 17t7 17l119 120l-119 120q-7 7 -7 17t7 17l34 34q7 8 17 8t17 -8z" />
+<glyph unicode="" d="M321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM766 900h4q10 -1 16 -10q96 -129 96 -290q0 -154 -90 -281q-6 -9 -17 -10l-3 -1q-9 0 -16 6 l-29 23q-7 7 -8.5 16.5t4.5 17.5q72 103 72 229q0 132 -78 238q-6 8 -4.5 18t9.5 17l29 22q7 5 15 5z" />
+<glyph unicode="" d="M967 1004h3q11 -1 17 -10q135 -179 135 -396q0 -105 -34 -206.5t-98 -185.5q-7 -9 -17 -10h-3q-9 0 -16 6l-42 34q-8 6 -9 16t5 18q111 150 111 328q0 90 -29.5 176t-84.5 157q-6 9 -5 19t10 16l42 33q7 5 15 5zM321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5 t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM766 900h4q10 -1 16 -10q96 -129 96 -290q0 -154 -90 -281q-6 -9 -17 -10l-3 -1q-9 0 -16 6l-29 23q-7 7 -8.5 16.5t4.5 17.5q72 103 72 229q0 132 -78 238 q-6 8 -4.5 18.5t9.5 16.5l29 22q7 5 15 5z" />
+<glyph unicode="" d="M500 900h100v-100h-100v-100h-400v-100h-100v600h500v-300zM1200 700h-200v-100h200v-200h-300v300h-200v300h-100v200h600v-500zM100 1100v-300h300v300h-300zM800 1100v-300h300v300h-300zM300 900h-100v100h100v-100zM1000 900h-100v100h100v-100zM300 500h200v-500 h-500v500h200v100h100v-100zM800 300h200v-100h-100v-100h-200v100h-100v100h100v200h-200v100h300v-300zM100 400v-300h300v300h-300zM300 200h-100v100h100v-100zM1200 200h-100v100h100v-100zM700 0h-100v100h100v-100zM1200 0h-300v100h300v-100z" />
+<glyph unicode="" d="M100 200h-100v1000h100v-1000zM300 200h-100v1000h100v-1000zM700 200h-200v1000h200v-1000zM900 200h-100v1000h100v-1000zM1200 200h-200v1000h200v-1000zM400 0h-300v100h300v-100zM600 0h-100v91h100v-91zM800 0h-100v91h100v-91zM1100 0h-200v91h200v-91z" />
+<glyph unicode="" d="M500 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-682 682l1 475q0 10 7.5 17.5t17.5 7.5h474zM319.5 1024.5q-29.5 29.5 -71 29.5t-71 -29.5t-29.5 -71.5t29.5 -71.5t71 -29.5t71 29.5t29.5 71.5t-29.5 71.5z" />
+<glyph unicode="" d="M500 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-682 682l1 475q0 10 7.5 17.5t17.5 7.5h474zM800 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-56 56l424 426l-700 700h150zM319.5 1024.5q-29.5 29.5 -71 29.5t-71 -29.5 t-29.5 -71.5t29.5 -71.5t71 -29.5t71 29.5t29.5 71.5t-29.5 71.5z" />
+<glyph unicode="" d="M300 1200h825q75 0 75 -75v-900q0 -25 -18 -43l-64 -64q-8 -8 -13 -5.5t-5 12.5v950q0 10 -7.5 17.5t-17.5 7.5h-700q-25 0 -43 -18l-64 -64q-8 -8 -5.5 -13t12.5 -5h700q10 0 17.5 -7.5t7.5 -17.5v-950q0 -10 -7.5 -17.5t-17.5 -7.5h-850q-10 0 -17.5 7.5t-7.5 17.5v975 q0 25 18 43l139 139q18 18 43 18z" />
+<glyph unicode="" d="M250 1200h800q21 0 35.5 -14.5t14.5 -35.5v-1150l-450 444l-450 -445v1151q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M822 1200h-444q-11 0 -19 -7.5t-9 -17.5l-78 -301q-7 -24 7 -45l57 -108q6 -9 17.5 -15t21.5 -6h450q10 0 21.5 6t17.5 15l62 108q14 21 7 45l-83 301q-1 10 -9 17.5t-19 7.5zM1175 800h-150q-10 0 -21 -6.5t-15 -15.5l-78 -156q-4 -9 -15 -15.5t-21 -6.5h-550 q-10 0 -21 6.5t-15 15.5l-78 156q-4 9 -15 15.5t-21 6.5h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-650q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h750q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5 t7.5 17.5v650q0 10 -7.5 17.5t-17.5 7.5zM850 200h-500q-10 0 -19.5 -7t-11.5 -17l-38 -152q-2 -10 3.5 -17t15.5 -7h600q10 0 15.5 7t3.5 17l-38 152q-2 10 -11.5 17t-19.5 7z" />
+<glyph unicode="" d="M500 1100h200q56 0 102.5 -20.5t72.5 -50t44 -59t25 -50.5l6 -20h150q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v600q0 41 29.5 70.5t70.5 29.5h150q2 8 6.5 21.5t24 48t45 61t72 48t102.5 21.5zM900 800v-100 h100v100h-100zM600 730q-95 0 -162.5 -67.5t-67.5 -162.5t67.5 -162.5t162.5 -67.5t162.5 67.5t67.5 162.5t-67.5 162.5t-162.5 67.5zM600 603q43 0 73 -30t30 -73t-30 -73t-73 -30t-73 30t-30 73t30 73t73 30z" />
+<glyph unicode="" d="M681 1199l385 -998q20 -50 60 -92q18 -19 36.5 -29.5t27.5 -11.5l10 -2v-66h-417v66q53 0 75 43.5t5 88.5l-82 222h-391q-58 -145 -92 -234q-11 -34 -6.5 -57t25.5 -37t46 -20t55 -6v-66h-365v66q56 24 84 52q12 12 25 30.5t20 31.5l7 13l399 1006h93zM416 521h340 l-162 457z" />
+<glyph unicode="" d="M753 641q5 -1 14.5 -4.5t36 -15.5t50.5 -26.5t53.5 -40t50.5 -54.5t35.5 -70t14.5 -87q0 -67 -27.5 -125.5t-71.5 -97.5t-98.5 -66.5t-108.5 -40.5t-102 -13h-500v89q41 7 70.5 32.5t29.5 65.5v827q0 24 -0.5 34t-3.5 24t-8.5 19.5t-17 13.5t-28 12.5t-42.5 11.5v71 l471 -1q57 0 115.5 -20.5t108 -57t80.5 -94t31 -124.5q0 -51 -15.5 -96.5t-38 -74.5t-45 -50.5t-38.5 -30.5zM400 700h139q78 0 130.5 48.5t52.5 122.5q0 41 -8.5 70.5t-29.5 55.5t-62.5 39.5t-103.5 13.5h-118v-350zM400 200h216q80 0 121 50.5t41 130.5q0 90 -62.5 154.5 t-156.5 64.5h-159v-400z" />
+<glyph unicode="" d="M877 1200l2 -57q-83 -19 -116 -45.5t-40 -66.5l-132 -839q-9 -49 13 -69t96 -26v-97h-500v97q186 16 200 98l173 832q3 17 3 30t-1.5 22.5t-9 17.5t-13.5 12.5t-21.5 10t-26 8.5t-33.5 10q-13 3 -19 5v57h425z" />
+<glyph unicode="" d="M1300 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-850q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v850h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM175 1000h-75v-800h75l-125 -167l-125 167h75v800h-75l125 167z" />
+<glyph unicode="" d="M1100 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-650q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v650h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM1167 50l-167 -125v75h-800v-75l-167 125l167 125v-75h800v75z" />
+<glyph unicode="" d="M50 1100h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 500h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M250 1100h700q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM250 500h700q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M500 950v100q0 21 14.5 35.5t35.5 14.5h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5zM100 650v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000 q-21 0 -35.5 14.5t-14.5 35.5zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5zM0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100 q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5z" />
+<glyph unicode="" d="M50 1100h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 500h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 1100h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 800h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 500h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 500h800q21 0 35.5 -14.5t14.5 -35.5v-100 q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 200h800 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M400 0h-100v1100h100v-1100zM550 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM550 800h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM267 550l-167 -125v75h-200v100h200v75zM550 500h300q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM550 200h600 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM900 0h-100v1100h100v-1100zM50 800h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM1100 600h200v-100h-200v-75l-167 125l167 125v-75zM50 500h300q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h600 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M75 1000h750q31 0 53 -22t22 -53v-650q0 -31 -22 -53t-53 -22h-750q-31 0 -53 22t-22 53v650q0 31 22 53t53 22zM1200 300l-300 300l300 300v-600z" />
+<glyph unicode="" d="M44 1100h1112q18 0 31 -13t13 -31v-1012q0 -18 -13 -31t-31 -13h-1112q-18 0 -31 13t-13 31v1012q0 18 13 31t31 13zM100 1000v-737l247 182l298 -131l-74 156l293 318l236 -288v500h-1000zM342 884q56 0 95 -39t39 -94.5t-39 -95t-95 -39.5t-95 39.5t-39 95t39 94.5 t95 39z" />
+<glyph unicode="" d="M648 1169q117 0 216 -60t156.5 -161t57.5 -218q0 -115 -70 -258q-69 -109 -158 -225.5t-143 -179.5l-54 -62q-9 8 -25.5 24.5t-63.5 67.5t-91 103t-98.5 128t-95.5 148q-60 132 -60 249q0 88 34 169.5t91.5 142t137 96.5t166.5 36zM652.5 974q-91.5 0 -156.5 -65 t-65 -157t65 -156.5t156.5 -64.5t156.5 64.5t65 156.5t-65 157t-156.5 65z" />
+<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 173v854q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57z" />
+<glyph unicode="" d="M554 1295q21 -72 57.5 -143.5t76 -130t83 -118t82.5 -117t70 -116t49.5 -126t18.5 -136.5q0 -71 -25.5 -135t-68.5 -111t-99 -82t-118.5 -54t-125.5 -23q-84 5 -161.5 34t-139.5 78.5t-99 125t-37 164.5q0 69 18 136.5t49.5 126.5t69.5 116.5t81.5 117.5t83.5 119 t76.5 131t58.5 143zM344 710q-23 -33 -43.5 -70.5t-40.5 -102.5t-17 -123q1 -37 14.5 -69.5t30 -52t41 -37t38.5 -24.5t33 -15q21 -7 32 -1t13 22l6 34q2 10 -2.5 22t-13.5 19q-5 4 -14 12t-29.5 40.5t-32.5 73.5q-26 89 6 271q2 11 -6 11q-8 1 -15 -10z" />
+<glyph unicode="" d="M1000 1013l108 115q2 1 5 2t13 2t20.5 -1t25 -9.5t28.5 -21.5q22 -22 27 -43t0 -32l-6 -10l-108 -115zM350 1100h400q50 0 105 -13l-187 -187h-368q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v182l200 200v-332 q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5zM1009 803l-362 -362l-161 -50l55 170l355 355z" />
+<glyph unicode="" d="M350 1100h361q-164 -146 -216 -200h-195q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5l200 153v-103q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5z M824 1073l339 -301q8 -7 8 -17.5t-8 -17.5l-340 -306q-7 -6 -12.5 -4t-6.5 11v203q-26 1 -54.5 0t-78.5 -7.5t-92 -17.5t-86 -35t-70 -57q10 59 33 108t51.5 81.5t65 58.5t68.5 40.5t67 24.5t56 13.5t40 4.5v210q1 10 6.5 12.5t13.5 -4.5z" />
+<glyph unicode="" d="M350 1100h350q60 0 127 -23l-178 -177h-349q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v69l200 200v-219q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5z M643 639l395 395q7 7 17.5 7t17.5 -7l101 -101q7 -7 7 -17.5t-7 -17.5l-531 -532q-7 -7 -17.5 -7t-17.5 7l-248 248q-7 7 -7 17.5t7 17.5l101 101q7 7 17.5 7t17.5 -7l111 -111q8 -7 18 -7t18 7z" />
+<glyph unicode="" d="M318 918l264 264q8 8 18 8t18 -8l260 -264q7 -8 4.5 -13t-12.5 -5h-170v-200h200v173q0 10 5 12t13 -5l264 -260q8 -7 8 -17.5t-8 -17.5l-264 -265q-8 -7 -13 -5t-5 12v173h-200v-200h170q10 0 12.5 -5t-4.5 -13l-260 -264q-8 -8 -18 -8t-18 8l-264 264q-8 8 -5.5 13 t12.5 5h175v200h-200v-173q0 -10 -5 -12t-13 5l-264 265q-8 7 -8 17.5t8 17.5l264 260q8 7 13 5t5 -12v-173h200v200h-175q-10 0 -12.5 5t5.5 13z" />
+<glyph unicode="" d="M250 1100h100q21 0 35.5 -14.5t14.5 -35.5v-438l464 453q15 14 25.5 10t10.5 -25v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v1000q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-438l464 453q15 14 25.5 10t10.5 -25v-438l464 453q15 14 25.5 10t10.5 -25v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5 t-14.5 35.5v1000q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M1200 1050v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -10.5 -25t-25.5 10l-492 480q-15 14 -15 35t15 35l492 480q15 14 25.5 10t10.5 -25v-438l464 453q15 14 25.5 10t10.5 -25z" />
+<glyph unicode="" d="M243 1074l814 -498q18 -11 18 -26t-18 -26l-814 -498q-18 -11 -30.5 -4t-12.5 28v1000q0 21 12.5 28t30.5 -4z" />
+<glyph unicode="" d="M250 1000h200q21 0 35.5 -14.5t14.5 -35.5v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5zM650 1000h200q21 0 35.5 -14.5t14.5 -35.5v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v800 q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M1100 950v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5z" />
+<glyph unicode="" d="M500 612v438q0 21 10.5 25t25.5 -10l492 -480q15 -14 15 -35t-15 -35l-492 -480q-15 -14 -25.5 -10t-10.5 25v438l-464 -453q-15 -14 -25.5 -10t-10.5 25v1000q0 21 10.5 25t25.5 -10z" />
+<glyph unicode="" d="M1048 1102l100 1q20 0 35 -14.5t15 -35.5l5 -1000q0 -21 -14.5 -35.5t-35.5 -14.5l-100 -1q-21 0 -35.5 14.5t-14.5 35.5l-2 437l-463 -454q-14 -15 -24.5 -10.5t-10.5 25.5l-2 437l-462 -455q-15 -14 -25.5 -9.5t-10.5 24.5l-5 1000q0 21 10.5 25.5t25.5 -10.5l466 -450 l-2 438q0 20 10.5 24.5t25.5 -9.5l466 -451l-2 438q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M850 1100h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438l-464 -453q-15 -14 -25.5 -10t-10.5 25v1000q0 21 10.5 25t25.5 -10l464 -453v438q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M686 1081l501 -540q15 -15 10.5 -26t-26.5 -11h-1042q-22 0 -26.5 11t10.5 26l501 540q15 15 36 15t36 -15zM150 400h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M885 900l-352 -353l352 -353l-197 -198l-552 552l552 550z" />
+<glyph unicode="" d="M1064 547l-551 -551l-198 198l353 353l-353 353l198 198z" />
+<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM650 900h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-150h-150 q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5t35.5 -14.5h150v-150q0 -21 14.5 -35.5t35.5 -14.5h100q21 0 35.5 14.5t14.5 35.5v150h150q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5h-150v150q0 21 -14.5 35.5t-35.5 14.5z" />
+<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM850 700h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5 t35.5 -14.5h500q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5z" />
+<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM741.5 913q-12.5 0 -21.5 -9l-120 -120l-120 120q-9 9 -21.5 9 t-21.5 -9l-141 -141q-9 -9 -9 -21.5t9 -21.5l120 -120l-120 -120q-9 -9 -9 -21.5t9 -21.5l141 -141q9 -9 21.5 -9t21.5 9l120 120l120 -120q9 -9 21.5 -9t21.5 9l141 141q9 9 9 21.5t-9 21.5l-120 120l120 120q9 9 9 21.5t-9 21.5l-141 141q-9 9 -21.5 9z" />
+<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM546 623l-84 85q-7 7 -17.5 7t-18.5 -7l-139 -139q-7 -8 -7 -18t7 -18 l242 -241q7 -8 17.5 -8t17.5 8l375 375q7 7 7 17.5t-7 18.5l-139 139q-7 7 -17.5 7t-17.5 -7z" />
+<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM588 941q-29 0 -59 -5.5t-63 -20.5t-58 -38.5t-41.5 -63t-16.5 -89.5 q0 -25 20 -25h131q30 -5 35 11q6 20 20.5 28t45.5 8q20 0 31.5 -10.5t11.5 -28.5q0 -23 -7 -34t-26 -18q-1 0 -13.5 -4t-19.5 -7.5t-20 -10.5t-22 -17t-18.5 -24t-15.5 -35t-8 -46q-1 -8 5.5 -16.5t20.5 -8.5h173q7 0 22 8t35 28t37.5 48t29.5 74t12 100q0 47 -17 83 t-42.5 57t-59.5 34.5t-64 18t-59 4.5zM675 400h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5z" />
+<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM675 1000h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5 t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5zM675 700h-250q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h75v-200h-75q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h350q10 0 17.5 7.5t7.5 17.5v50q0 10 -7.5 17.5 t-17.5 7.5h-75v275q0 10 -7.5 17.5t-17.5 7.5z" />
+<glyph unicode="" d="M525 1200h150q10 0 17.5 -7.5t7.5 -17.5v-194q103 -27 178.5 -102.5t102.5 -178.5h194q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-194q-27 -103 -102.5 -178.5t-178.5 -102.5v-194q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v194 q-103 27 -178.5 102.5t-102.5 178.5h-194q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h194q27 103 102.5 178.5t178.5 102.5v194q0 10 7.5 17.5t17.5 7.5zM700 893v-168q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v168q-68 -23 -119 -74 t-74 -119h168q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-168q23 -68 74 -119t119 -74v168q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-168q68 23 119 74t74 119h-168q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h168 q-23 68 -74 119t-119 74z" />
+<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM759 823l64 -64q7 -7 7 -17.5t-7 -17.5l-124 -124l124 -124q7 -7 7 -17.5t-7 -17.5l-64 -64q-7 -7 -17.5 -7t-17.5 7l-124 124l-124 -124q-7 -7 -17.5 -7t-17.5 7l-64 64 q-7 7 -7 17.5t7 17.5l124 124l-124 124q-7 7 -7 17.5t7 17.5l64 64q7 7 17.5 7t17.5 -7l124 -124l124 124q7 7 17.5 7t17.5 -7z" />
+<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM782 788l106 -106q7 -7 7 -17.5t-7 -17.5l-320 -321q-8 -7 -18 -7t-18 7l-202 203q-8 7 -8 17.5t8 17.5l106 106q7 8 17.5 8t17.5 -8l79 -79l197 197q7 7 17.5 7t17.5 -7z" />
+<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5q0 -120 65 -225 l587 587q-105 65 -225 65zM965 819l-584 -584q104 -62 219 -62q116 0 214.5 57t155.5 155.5t57 214.5q0 115 -62 219z" />
+<glyph unicode="" d="M39 582l522 427q16 13 27.5 8t11.5 -26v-291h550q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-550v-291q0 -21 -11.5 -26t-27.5 8l-522 427q-16 13 -16 32t16 32z" />
+<glyph unicode="" d="M639 1009l522 -427q16 -13 16 -32t-16 -32l-522 -427q-16 -13 -27.5 -8t-11.5 26v291h-550q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h550v291q0 21 11.5 26t27.5 -8z" />
+<glyph unicode="" d="M682 1161l427 -522q13 -16 8 -27.5t-26 -11.5h-291v-550q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v550h-291q-21 0 -26 11.5t8 27.5l427 522q13 16 32 16t32 -16z" />
+<glyph unicode="" d="M550 1200h200q21 0 35.5 -14.5t14.5 -35.5v-550h291q21 0 26 -11.5t-8 -27.5l-427 -522q-13 -16 -32 -16t-32 16l-427 522q-13 16 -8 27.5t26 11.5h291v550q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M639 1109l522 -427q16 -13 16 -32t-16 -32l-522 -427q-16 -13 -27.5 -8t-11.5 26v291q-94 -2 -182 -20t-170.5 -52t-147 -92.5t-100.5 -135.5q5 105 27 193.5t67.5 167t113 135t167 91.5t225.5 42v262q0 21 11.5 26t27.5 -8z" />
+<glyph unicode="" d="M850 1200h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94l-249 -249q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l249 249l-94 94q-14 14 -10 24.5t25 10.5zM350 0h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l249 249 q8 7 18 7t18 -7l106 -106q7 -8 7 -18t-7 -18l-249 -249l94 -94q14 -14 10 -24.5t-25 -10.5z" />
+<glyph unicode="" d="M1014 1120l106 -106q7 -8 7 -18t-7 -18l-249 -249l94 -94q14 -14 10 -24.5t-25 -10.5h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l249 249q8 7 18 7t18 -7zM250 600h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94 l-249 -249q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l249 249l-94 94q-14 14 -10 24.5t25 10.5z" />
+<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM704 900h-208q-20 0 -32 -14.5t-8 -34.5l58 -302q4 -20 21.5 -34.5 t37.5 -14.5h54q20 0 37.5 14.5t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5zM675 400h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5z" />
+<glyph unicode="" d="M260 1200q9 0 19 -2t15 -4l5 -2q22 -10 44 -23l196 -118q21 -13 36 -24q29 -21 37 -12q11 13 49 35l196 118q22 13 45 23q17 7 38 7q23 0 47 -16.5t37 -33.5l13 -16q14 -21 18 -45l25 -123l8 -44q1 -9 8.5 -14.5t17.5 -5.5h61q10 0 17.5 -7.5t7.5 -17.5v-50 q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 -7.5t-7.5 -17.5v-175h-400v300h-200v-300h-400v175q0 10 -7.5 17.5t-17.5 7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5h61q11 0 18 3t7 8q0 4 9 52l25 128q5 25 19 45q2 3 5 7t13.5 15t21.5 19.5t26.5 15.5 t29.5 7zM915 1079l-166 -162q-7 -7 -5 -12t12 -5h219q10 0 15 7t2 17l-51 149q-3 10 -11 12t-15 -6zM463 917l-177 157q-8 7 -16 5t-11 -12l-51 -143q-3 -10 2 -17t15 -7h231q11 0 12.5 5t-5.5 12zM500 0h-375q-10 0 -17.5 7.5t-7.5 17.5v375h400v-400zM1100 400v-375 q0 -10 -7.5 -17.5t-17.5 -7.5h-375v400h400z" />
+<glyph unicode="" d="M1165 1190q8 3 21 -6.5t13 -17.5q-2 -178 -24.5 -323.5t-55.5 -245.5t-87 -174.5t-102.5 -118.5t-118 -68.5t-118.5 -33t-120 -4.5t-105 9.5t-90 16.5q-61 12 -78 11q-4 1 -12.5 0t-34 -14.5t-52.5 -40.5l-153 -153q-26 -24 -37 -14.5t-11 43.5q0 64 42 102q8 8 50.5 45 t66.5 58q19 17 35 47t13 61q-9 55 -10 102.5t7 111t37 130t78 129.5q39 51 80 88t89.5 63.5t94.5 45t113.5 36t129 31t157.5 37t182 47.5zM1116 1098q-8 9 -22.5 -3t-45.5 -50q-38 -47 -119 -103.5t-142 -89.5l-62 -33q-56 -30 -102 -57t-104 -68t-102.5 -80.5t-85.5 -91 t-64 -104.5q-24 -56 -31 -86t2 -32t31.5 17.5t55.5 59.5q25 30 94 75.5t125.5 77.5t147.5 81q70 37 118.5 69t102 79.5t99 111t86.5 148.5q22 50 24 60t-6 19z" />
+<glyph unicode="" d="M653 1231q-39 -67 -54.5 -131t-10.5 -114.5t24.5 -96.5t47.5 -80t63.5 -62.5t68.5 -46.5t65 -30q-4 7 -17.5 35t-18.5 39.5t-17 39.5t-17 43t-13 42t-9.5 44.5t-2 42t4 43t13.5 39t23 38.5q96 -42 165 -107.5t105 -138t52 -156t13 -159t-19 -149.5q-13 -55 -44 -106.5 t-68 -87t-78.5 -64.5t-72.5 -45t-53 -22q-72 -22 -127 -11q-31 6 -13 19q6 3 17 7q13 5 32.5 21t41 44t38.5 63.5t21.5 81.5t-6.5 94.5t-50 107t-104 115.5q10 -104 -0.5 -189t-37 -140.5t-65 -93t-84 -52t-93.5 -11t-95 24.5q-80 36 -131.5 114t-53.5 171q-2 23 0 49.5 t4.5 52.5t13.5 56t27.5 60t46 64.5t69.5 68.5q-8 -53 -5 -102.5t17.5 -90t34 -68.5t44.5 -39t49 -2q31 13 38.5 36t-4.5 55t-29 64.5t-36 75t-26 75.5q-15 85 2 161.5t53.5 128.5t85.5 92.5t93.5 61t81.5 25.5z" />
+<glyph unicode="" d="M600 1094q82 0 160.5 -22.5t140 -59t116.5 -82.5t94.5 -95t68 -95t42.5 -82.5t14 -57.5t-14 -57.5t-43 -82.5t-68.5 -95t-94.5 -95t-116.5 -82.5t-140 -59t-159.5 -22.5t-159.5 22.5t-140 59t-116.5 82.5t-94.5 95t-68.5 95t-43 82.5t-14 57.5t14 57.5t42.5 82.5t68 95 t94.5 95t116.5 82.5t140 59t160.5 22.5zM888 829q-15 15 -18 12t5 -22q25 -57 25 -119q0 -124 -88 -212t-212 -88t-212 88t-88 212q0 59 23 114q8 19 4.5 22t-17.5 -12q-70 -69 -160 -184q-13 -16 -15 -40.5t9 -42.5q22 -36 47 -71t70 -82t92.5 -81t113 -58.5t133.5 -24.5 t133.5 24t113 58.5t92.5 81.5t70 81.5t47 70.5q11 18 9 42.5t-14 41.5q-90 117 -163 189zM448 727l-35 -36q-15 -15 -19.5 -38.5t4.5 -41.5q37 -68 93 -116q16 -13 38.5 -11t36.5 17l35 34q14 15 12.5 33.5t-16.5 33.5q-44 44 -89 117q-11 18 -28 20t-32 -12z" />
+<glyph unicode="" d="M592 0h-148l31 120q-91 20 -175.5 68.5t-143.5 106.5t-103.5 119t-66.5 110t-22 76q0 21 14 57.5t42.5 82.5t68 95t94.5 95t116.5 82.5t140 59t160.5 22.5q61 0 126 -15l32 121h148zM944 770l47 181q108 -85 176.5 -192t68.5 -159q0 -26 -19.5 -71t-59.5 -102t-93 -112 t-129 -104.5t-158 -75.5l46 173q77 49 136 117t97 131q11 18 9 42.5t-14 41.5q-54 70 -107 130zM310 824q-70 -69 -160 -184q-13 -16 -15 -40.5t9 -42.5q18 -30 39 -60t57 -70.5t74 -73t90 -61t105 -41.5l41 154q-107 18 -178.5 101.5t-71.5 193.5q0 59 23 114q8 19 4.5 22 t-17.5 -12zM448 727l-35 -36q-15 -15 -19.5 -38.5t4.5 -41.5q37 -68 93 -116q16 -13 38.5 -11t36.5 17l12 11l22 86l-3 4q-44 44 -89 117q-11 18 -28 20t-32 -12z" />
+<glyph unicode="" d="M-90 100l642 1066q20 31 48 28.5t48 -35.5l642 -1056q21 -32 7.5 -67.5t-50.5 -35.5h-1294q-37 0 -50.5 34t7.5 66zM155 200h345v75q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-75h345l-445 723zM496 700h208q20 0 32 -14.5t8 -34.5l-58 -252 q-4 -20 -21.5 -34.5t-37.5 -14.5h-54q-20 0 -37.5 14.5t-21.5 34.5l-58 252q-4 20 8 34.5t32 14.5z" />
+<glyph unicode="" d="M650 1200q62 0 106 -44t44 -106v-339l363 -325q15 -14 26 -38.5t11 -44.5v-41q0 -20 -12 -26.5t-29 5.5l-359 249v-263q100 -93 100 -113v-64q0 -21 -13 -29t-32 1l-205 128l-205 -128q-19 -9 -32 -1t-13 29v64q0 20 100 113v263l-359 -249q-17 -12 -29 -5.5t-12 26.5v41 q0 20 11 44.5t26 38.5l363 325v339q0 62 44 106t106 44z" />
+<glyph unicode="" d="M850 1200h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-150h-1100v150q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-50h500v50q0 21 14.5 35.5t35.5 14.5zM1100 800v-750q0 -21 -14.5 -35.5 t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v750h1100zM100 600v-100h100v100h-100zM300 600v-100h100v100h-100zM500 600v-100h100v100h-100zM700 600v-100h100v100h-100zM900 600v-100h100v100h-100zM100 400v-100h100v100h-100zM300 400v-100h100v100h-100zM500 400 v-100h100v100h-100zM700 400v-100h100v100h-100zM900 400v-100h100v100h-100zM100 200v-100h100v100h-100zM300 200v-100h100v100h-100zM500 200v-100h100v100h-100zM700 200v-100h100v100h-100zM900 200v-100h100v100h-100z" />
+<glyph unicode="" d="M1135 1165l249 -230q15 -14 15 -35t-15 -35l-249 -230q-14 -14 -24.5 -10t-10.5 25v150h-159l-600 -600h-291q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h209l600 600h241v150q0 21 10.5 25t24.5 -10zM522 819l-141 -141l-122 122h-209q-21 0 -35.5 14.5 t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h291zM1135 565l249 -230q15 -14 15 -35t-15 -35l-249 -230q-14 -14 -24.5 -10t-10.5 25v150h-241l-181 181l141 141l122 -122h159v150q0 21 10.5 25t24.5 -10z" />
+<glyph unicode="" d="M100 1100h1000q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-596l-304 -300v300h-100q-41 0 -70.5 29.5t-29.5 70.5v600q0 41 29.5 70.5t70.5 29.5z" />
+<glyph unicode="" d="M150 1200h200q21 0 35.5 -14.5t14.5 -35.5v-250h-300v250q0 21 14.5 35.5t35.5 14.5zM850 1200h200q21 0 35.5 -14.5t14.5 -35.5v-250h-300v250q0 21 14.5 35.5t35.5 14.5zM1100 800v-300q0 -41 -3 -77.5t-15 -89.5t-32 -96t-58 -89t-89 -77t-129 -51t-174 -20t-174 20 t-129 51t-89 77t-58 89t-32 96t-15 89.5t-3 77.5v300h300v-250v-27v-42.5t1.5 -41t5 -38t10 -35t16.5 -30t25.5 -24.5t35 -19t46.5 -12t60 -4t60 4.5t46.5 12.5t35 19.5t25 25.5t17 30.5t10 35t5 38t2 40.5t-0.5 42v25v250h300z" />
+<glyph unicode="" d="M1100 411l-198 -199l-353 353l-353 -353l-197 199l551 551z" />
+<glyph unicode="" d="M1101 789l-550 -551l-551 551l198 199l353 -353l353 353z" />
+<glyph unicode="" d="M404 1000h746q21 0 35.5 -14.5t14.5 -35.5v-551h150q21 0 25 -10.5t-10 -24.5l-230 -249q-14 -15 -35 -15t-35 15l-230 249q-14 14 -10 24.5t25 10.5h150v401h-381zM135 984l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-400h385l215 -200h-750q-21 0 -35.5 14.5 t-14.5 35.5v550h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
+<glyph unicode="" d="M56 1200h94q17 0 31 -11t18 -27l38 -162h896q24 0 39 -18.5t10 -42.5l-100 -475q-5 -21 -27 -42.5t-55 -21.5h-633l48 -200h535q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-50q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v50h-300v-50 q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v50h-31q-18 0 -32.5 10t-20.5 19l-5 10l-201 961h-54q-20 0 -35 14.5t-15 35.5t15 35.5t35 14.5z" />
+<glyph unicode="" d="M1200 1000v-100h-1200v100h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500zM0 800h1200v-800h-1200v800z" />
+<glyph unicode="" d="M200 800l-200 -400v600h200q0 41 29.5 70.5t70.5 29.5h300q42 0 71 -29.5t29 -70.5h500v-200h-1000zM1500 700l-300 -700h-1200l300 700h1200z" />
+<glyph unicode="" d="M635 1184l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-601h150q21 0 25 -10.5t-10 -24.5l-230 -249q-14 -15 -35 -15t-35 15l-230 249q-14 14 -10 24.5t25 10.5h150v601h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
+<glyph unicode="" d="M936 864l249 -229q14 -15 14 -35.5t-14 -35.5l-249 -229q-15 -15 -25.5 -10.5t-10.5 24.5v151h-600v-151q0 -20 -10.5 -24.5t-25.5 10.5l-249 229q-14 15 -14 35.5t14 35.5l249 229q15 15 25.5 10.5t10.5 -25.5v-149h600v149q0 21 10.5 25.5t25.5 -10.5z" />
+<glyph unicode="" d="M1169 400l-172 732q-5 23 -23 45.5t-38 22.5h-672q-20 0 -38 -20t-23 -41l-172 -739h1138zM1100 300h-1000q-41 0 -70.5 -29.5t-29.5 -70.5v-100q0 -41 29.5 -70.5t70.5 -29.5h1000q41 0 70.5 29.5t29.5 70.5v100q0 41 -29.5 70.5t-70.5 29.5zM800 100v100h100v-100h-100 zM1000 100v100h100v-100h-100z" />
+<glyph unicode="" d="M1150 1100q21 0 35.5 -14.5t14.5 -35.5v-850q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v850q0 21 14.5 35.5t35.5 14.5zM1000 200l-675 200h-38l47 -276q3 -16 -5.5 -20t-29.5 -4h-7h-84q-20 0 -34.5 14t-18.5 35q-55 337 -55 351v250v6q0 16 1 23.5t6.5 14 t17.5 6.5h200l675 250v-850zM0 750v-250q-4 0 -11 0.5t-24 6t-30 15t-24 30t-11 48.5v50q0 26 10.5 46t25 30t29 16t25.5 7z" />
+<glyph unicode="" d="M553 1200h94q20 0 29 -10.5t3 -29.5l-18 -37q83 -19 144 -82.5t76 -140.5l63 -327l118 -173h17q19 0 33 -14.5t14 -35t-13 -40.5t-31 -27q-8 -4 -23 -9.5t-65 -19.5t-103 -25t-132.5 -20t-158.5 -9q-57 0 -115 5t-104 12t-88.5 15.5t-73.5 17.5t-54.5 16t-35.5 12l-11 4 q-18 8 -31 28t-13 40.5t14 35t33 14.5h17l118 173l63 327q15 77 76 140t144 83l-18 32q-6 19 3.5 32t28.5 13zM498 110q50 -6 102 -6q53 0 102 6q-12 -49 -39.5 -79.5t-62.5 -30.5t-63 30.5t-39 79.5z" />
+<glyph unicode="" d="M800 946l224 78l-78 -224l234 -45l-180 -155l180 -155l-234 -45l78 -224l-224 78l-45 -234l-155 180l-155 -180l-45 234l-224 -78l78 224l-234 45l180 155l-180 155l234 45l-78 224l224 -78l45 234l155 -180l155 180z" />
+<glyph unicode="" d="M650 1200h50q40 0 70 -40.5t30 -84.5v-150l-28 -125h328q40 0 70 -40.5t30 -84.5v-100q0 -45 -29 -74l-238 -344q-16 -24 -38 -40.5t-45 -16.5h-250q-7 0 -42 25t-66 50l-31 25h-61q-45 0 -72.5 18t-27.5 57v400q0 36 20 63l145 196l96 198q13 28 37.5 48t51.5 20z M650 1100l-100 -212l-150 -213v-375h100l136 -100h214l250 375v125h-450l50 225v175h-50zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M600 1100h250q23 0 45 -16.5t38 -40.5l238 -344q29 -29 29 -74v-100q0 -44 -30 -84.5t-70 -40.5h-328q28 -118 28 -125v-150q0 -44 -30 -84.5t-70 -40.5h-50q-27 0 -51.5 20t-37.5 48l-96 198l-145 196q-20 27 -20 63v400q0 39 27.5 57t72.5 18h61q124 100 139 100z M50 1000h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5zM636 1000l-136 -100h-100v-375l150 -213l100 -212h50v175l-50 225h450v125l-250 375h-214z" />
+<glyph unicode="" d="M356 873l363 230q31 16 53 -6l110 -112q13 -13 13.5 -32t-11.5 -34l-84 -121h302q84 0 138 -38t54 -110t-55 -111t-139 -39h-106l-131 -339q-6 -21 -19.5 -41t-28.5 -20h-342q-7 0 -90 81t-83 94v525q0 17 14 35.5t28 28.5zM400 792v-503l100 -89h293l131 339 q6 21 19.5 41t28.5 20h203q21 0 30.5 25t0.5 50t-31 25h-456h-7h-6h-5.5t-6 0.5t-5 1.5t-5 2t-4 2.5t-4 4t-2.5 4.5q-12 25 5 47l146 183l-86 83zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500 q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M475 1103l366 -230q2 -1 6 -3.5t14 -10.5t18 -16.5t14.5 -20t6.5 -22.5v-525q0 -13 -86 -94t-93 -81h-342q-15 0 -28.5 20t-19.5 41l-131 339h-106q-85 0 -139.5 39t-54.5 111t54 110t138 38h302l-85 121q-11 15 -10.5 34t13.5 32l110 112q22 22 53 6zM370 945l146 -183 q17 -22 5 -47q-2 -2 -3.5 -4.5t-4 -4t-4 -2.5t-5 -2t-5 -1.5t-6 -0.5h-6h-6.5h-6h-475v-100h221q15 0 29 -20t20 -41l130 -339h294l106 89v503l-342 236zM1050 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5 v500q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M550 1294q72 0 111 -55t39 -139v-106l339 -131q21 -6 41 -19.5t20 -28.5v-342q0 -7 -81 -90t-94 -83h-525q-17 0 -35.5 14t-28.5 28l-9 14l-230 363q-16 31 6 53l112 110q13 13 32 13.5t34 -11.5l121 -84v302q0 84 38 138t110 54zM600 972v203q0 21 -25 30.5t-50 0.5 t-25 -31v-456v-7v-6v-5.5t-0.5 -6t-1.5 -5t-2 -5t-2.5 -4t-4 -4t-4.5 -2.5q-25 -12 -47 5l-183 146l-83 -86l236 -339h503l89 100v293l-339 131q-21 6 -41 19.5t-20 28.5zM450 200h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M350 1100h500q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5t35.5 -14.5zM600 306v-106q0 -84 -39 -139t-111 -55t-110 54t-38 138v302l-121 -84q-15 -12 -34 -11.5t-32 13.5l-112 110 q-22 22 -6 53l230 363q1 2 3.5 6t10.5 13.5t16.5 17t20 13.5t22.5 6h525q13 0 94 -83t81 -90v-342q0 -15 -20 -28.5t-41 -19.5zM308 900l-236 -339l83 -86l183 146q22 17 47 5q2 -1 4.5 -2.5t4 -4t2.5 -4t2 -5t1.5 -5t0.5 -6v-5.5v-6v-7v-456q0 -22 25 -31t50 0.5t25 30.5 v203q0 15 20 28.5t41 19.5l339 131v293l-89 100h-503z" />
+<glyph unicode="" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM914 632l-275 223q-16 13 -27.5 8t-11.5 -26v-137h-275 q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h275v-137q0 -21 11.5 -26t27.5 8l275 223q16 13 16 32t-16 32z" />
+<glyph unicode="" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM561 855l-275 -223q-16 -13 -16 -32t16 -32l275 -223q16 -13 27.5 -8 t11.5 26v137h275q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5h-275v137q0 21 -11.5 26t-27.5 -8z" />
+<glyph unicode="" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM855 639l-223 275q-13 16 -32 16t-32 -16l-223 -275q-13 -16 -8 -27.5 t26 -11.5h137v-275q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v275h137q21 0 26 11.5t-8 27.5z" />
+<glyph unicode="" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM675 900h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-275h-137q-21 0 -26 -11.5 t8 -27.5l223 -275q13 -16 32 -16t32 16l223 275q13 16 8 27.5t-26 11.5h-137v275q0 10 -7.5 17.5t-17.5 7.5z" />
+<glyph unicode="" d="M600 1176q116 0 222.5 -46t184 -123.5t123.5 -184t46 -222.5t-46 -222.5t-123.5 -184t-184 -123.5t-222.5 -46t-222.5 46t-184 123.5t-123.5 184t-46 222.5t46 222.5t123.5 184t184 123.5t222.5 46zM627 1101q-15 -12 -36.5 -20.5t-35.5 -12t-43 -8t-39 -6.5 q-15 -3 -45.5 0t-45.5 -2q-20 -7 -51.5 -26.5t-34.5 -34.5q-3 -11 6.5 -22.5t8.5 -18.5q-3 -34 -27.5 -91t-29.5 -79q-9 -34 5 -93t8 -87q0 -9 17 -44.5t16 -59.5q12 0 23 -5t23.5 -15t19.5 -14q16 -8 33 -15t40.5 -15t34.5 -12q21 -9 52.5 -32t60 -38t57.5 -11 q7 -15 -3 -34t-22.5 -40t-9.5 -38q13 -21 23 -34.5t27.5 -27.5t36.5 -18q0 -7 -3.5 -16t-3.5 -14t5 -17q104 -2 221 112q30 29 46.5 47t34.5 49t21 63q-13 8 -37 8.5t-36 7.5q-15 7 -49.5 15t-51.5 19q-18 0 -41 -0.5t-43 -1.5t-42 -6.5t-38 -16.5q-51 -35 -66 -12 q-4 1 -3.5 25.5t0.5 25.5q-6 13 -26.5 17.5t-24.5 6.5q1 15 -0.5 30.5t-7 28t-18.5 11.5t-31 -21q-23 -25 -42 4q-19 28 -8 58q6 16 22 22q6 -1 26 -1.5t33.5 -4t19.5 -13.5q7 -12 18 -24t21.5 -20.5t20 -15t15.5 -10.5l5 -3q2 12 7.5 30.5t8 34.5t-0.5 32q-3 18 3.5 29 t18 22.5t15.5 24.5q6 14 10.5 35t8 31t15.5 22.5t34 22.5q-6 18 10 36q8 0 24 -1.5t24.5 -1.5t20 4.5t20.5 15.5q-10 23 -31 42.5t-37.5 29.5t-49 27t-43.5 23q0 1 2 8t3 11.5t1.5 10.5t-1 9.5t-4.5 4.5q31 -13 58.5 -14.5t38.5 2.5l12 5q5 28 -9.5 46t-36.5 24t-50 15 t-41 20q-18 -4 -37 0zM613 994q0 -17 8 -42t17 -45t9 -23q-8 1 -39.5 5.5t-52.5 10t-37 16.5q3 11 16 29.5t16 25.5q10 -10 19 -10t14 6t13.5 14.5t16.5 12.5z" />
+<glyph unicode="" d="M756 1157q164 92 306 -9l-259 -138l145 -232l251 126q6 -89 -34 -156.5t-117 -110.5q-60 -34 -127 -39.5t-126 16.5l-596 -596q-15 -16 -36.5 -16t-36.5 16l-111 110q-15 15 -15 36.5t15 37.5l600 599q-34 101 5.5 201.5t135.5 154.5z" />
+<glyph unicode="" horiz-adv-x="1220" d="M100 1196h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 1096h-200v-100h200v100zM100 796h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 696h-500v-100h500v100zM100 396h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 296h-300v-100h300v100z " />
+<glyph unicode="" d="M150 1200h900q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM700 500v-300l-200 -200v500l-350 500h900z" />
+<glyph unicode="" d="M500 1200h200q41 0 70.5 -29.5t29.5 -70.5v-100h300q41 0 70.5 -29.5t29.5 -70.5v-400h-500v100h-200v-100h-500v400q0 41 29.5 70.5t70.5 29.5h300v100q0 41 29.5 70.5t70.5 29.5zM500 1100v-100h200v100h-200zM1200 400v-200q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5v200h1200z" />
+<glyph unicode="" d="M50 1200h300q21 0 25 -10.5t-10 -24.5l-94 -94l199 -199q7 -8 7 -18t-7 -18l-106 -106q-8 -7 -18 -7t-18 7l-199 199l-94 -94q-14 -14 -24.5 -10t-10.5 25v300q0 21 14.5 35.5t35.5 14.5zM850 1200h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94 l-199 -199q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l199 199l-94 94q-14 14 -10 24.5t25 10.5zM364 470l106 -106q7 -8 7 -18t-7 -18l-199 -199l94 -94q14 -14 10 -24.5t-25 -10.5h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l199 199 q8 7 18 7t18 -7zM1071 271l94 94q14 14 24.5 10t10.5 -25v-300q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -25 10.5t10 24.5l94 94l-199 199q-7 8 -7 18t7 18l106 106q8 7 18 7t18 -7z" />
+<glyph unicode="" d="M596 1192q121 0 231.5 -47.5t190 -127t127 -190t47.5 -231.5t-47.5 -231.5t-127 -190.5t-190 -127t-231.5 -47t-231.5 47t-190.5 127t-127 190.5t-47 231.5t47 231.5t127 190t190.5 127t231.5 47.5zM596 1010q-112 0 -207.5 -55.5t-151 -151t-55.5 -207.5t55.5 -207.5 t151 -151t207.5 -55.5t207.5 55.5t151 151t55.5 207.5t-55.5 207.5t-151 151t-207.5 55.5zM454.5 905q22.5 0 38.5 -16t16 -38.5t-16 -39t-38.5 -16.5t-38.5 16.5t-16 39t16 38.5t38.5 16zM754.5 905q22.5 0 38.5 -16t16 -38.5t-16 -39t-38 -16.5q-14 0 -29 10l-55 -145 q17 -23 17 -51q0 -36 -25.5 -61.5t-61.5 -25.5t-61.5 25.5t-25.5 61.5q0 32 20.5 56.5t51.5 29.5l122 126l1 1q-9 14 -9 28q0 23 16 39t38.5 16zM345.5 709q22.5 0 38.5 -16t16 -38.5t-16 -38.5t-38.5 -16t-38.5 16t-16 38.5t16 38.5t38.5 16zM854.5 709q22.5 0 38.5 -16 t16 -38.5t-16 -38.5t-38.5 -16t-38.5 16t-16 38.5t16 38.5t38.5 16z" />
+<glyph unicode="" d="M546 173l469 470q91 91 99 192q7 98 -52 175.5t-154 94.5q-22 4 -47 4q-34 0 -66.5 -10t-56.5 -23t-55.5 -38t-48 -41.5t-48.5 -47.5q-376 -375 -391 -390q-30 -27 -45 -41.5t-37.5 -41t-32 -46.5t-16 -47.5t-1.5 -56.5q9 -62 53.5 -95t99.5 -33q74 0 125 51l548 548 q36 36 20 75q-7 16 -21.5 26t-32.5 10q-26 0 -50 -23q-13 -12 -39 -38l-341 -338q-15 -15 -35.5 -15.5t-34.5 13.5t-14 34.5t14 34.5q327 333 361 367q35 35 67.5 51.5t78.5 16.5q14 0 29 -1q44 -8 74.5 -35.5t43.5 -68.5q14 -47 2 -96.5t-47 -84.5q-12 -11 -32 -32 t-79.5 -81t-114.5 -115t-124.5 -123.5t-123 -119.5t-96.5 -89t-57 -45q-56 -27 -120 -27q-70 0 -129 32t-93 89q-48 78 -35 173t81 163l511 511q71 72 111 96q91 55 198 55q80 0 152 -33q78 -36 129.5 -103t66.5 -154q17 -93 -11 -183.5t-94 -156.5l-482 -476 q-15 -15 -36 -16t-37 14t-17.5 34t14.5 35z" />
+<glyph unicode="" d="M649 949q48 68 109.5 104t121.5 38.5t118.5 -20t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-150 152.5t-126.5 127.5t-93.5 124.5t-33.5 117.5q0 64 28 123t73 100.5t104 64t119 20 t120.5 -38.5t104.5 -104zM896 972q-33 0 -64.5 -19t-56.5 -46t-47.5 -53.5t-43.5 -45.5t-37.5 -19t-36 19t-40 45.5t-43 53.5t-54 46t-65.5 19q-67 0 -122.5 -55.5t-55.5 -132.5q0 -23 13.5 -51t46 -65t57.5 -63t76 -75l22 -22q15 -14 44 -44t50.5 -51t46 -44t41 -35t23 -12 t23.5 12t42.5 36t46 44t52.5 52t44 43q4 4 12 13q43 41 63.5 62t52 55t46 55t26 46t11.5 44q0 79 -53 133.5t-120 54.5z" />
+<glyph unicode="" d="M776.5 1214q93.5 0 159.5 -66l141 -141q66 -66 66 -160q0 -42 -28 -95.5t-62 -87.5l-29 -29q-31 53 -77 99l-18 18l95 95l-247 248l-389 -389l212 -212l-105 -106l-19 18l-141 141q-66 66 -66 159t66 159l283 283q65 66 158.5 66zM600 706l105 105q10 -8 19 -17l141 -141 q66 -66 66 -159t-66 -159l-283 -283q-66 -66 -159 -66t-159 66l-141 141q-66 66 -66 159.5t66 159.5l55 55q29 -55 75 -102l18 -17l-95 -95l247 -248l389 389z" />
+<glyph unicode="" d="M603 1200q85 0 162 -15t127 -38t79 -48t29 -46v-953q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-41 0 -70.5 29.5t-29.5 70.5v953q0 21 30 46.5t81 48t129 37.5t163 15zM300 1000v-700h600v700h-600zM600 254q-43 0 -73.5 -30.5t-30.5 -73.5t30.5 -73.5t73.5 -30.5t73.5 30.5 t30.5 73.5t-30.5 73.5t-73.5 30.5z" />
+<glyph unicode="" d="M902 1185l283 -282q15 -15 15 -36t-14.5 -35.5t-35.5 -14.5t-35 15l-36 35l-279 -267v-300l-212 210l-308 -307l-280 -203l203 280l307 308l-210 212h300l267 279l-35 36q-15 14 -15 35t14.5 35.5t35.5 14.5t35 -15z" />
+<glyph unicode="" d="M700 1248v-78q38 -5 72.5 -14.5t75.5 -31.5t71 -53.5t52 -84t24 -118.5h-159q-4 36 -10.5 59t-21 45t-40 35.5t-64.5 20.5v-307l64 -13q34 -7 64 -16.5t70 -32t67.5 -52.5t47.5 -80t20 -112q0 -139 -89 -224t-244 -97v-77h-100v79q-150 16 -237 103q-40 40 -52.5 93.5 t-15.5 139.5h139q5 -77 48.5 -126t117.5 -65v335l-27 8q-46 14 -79 26.5t-72 36t-63 52t-40 72.5t-16 98q0 70 25 126t67.5 92t94.5 57t110 27v77h100zM600 754v274q-29 -4 -50 -11t-42 -21.5t-31.5 -41.5t-10.5 -65q0 -29 7 -50.5t16.5 -34t28.5 -22.5t31.5 -14t37.5 -10 q9 -3 13 -4zM700 547v-310q22 2 42.5 6.5t45 15.5t41.5 27t29 42t12 59.5t-12.5 59.5t-38 44.5t-53 31t-66.5 24.5z" />
+<glyph unicode="" d="M561 1197q84 0 160.5 -40t123.5 -109.5t47 -147.5h-153q0 40 -19.5 71.5t-49.5 48.5t-59.5 26t-55.5 9q-37 0 -79 -14.5t-62 -35.5q-41 -44 -41 -101q0 -26 13.5 -63t26.5 -61t37 -66q6 -9 9 -14h241v-100h-197q8 -50 -2.5 -115t-31.5 -95q-45 -62 -99 -112 q34 10 83 17.5t71 7.5q32 1 102 -16t104 -17q83 0 136 30l50 -147q-31 -19 -58 -30.5t-55 -15.5t-42 -4.5t-46 -0.5q-23 0 -76 17t-111 32.5t-96 11.5q-39 -3 -82 -16t-67 -25l-23 -11l-55 145q4 3 16 11t15.5 10.5t13 9t15.5 12t14.5 14t17.5 18.5q48 55 54 126.5 t-30 142.5h-221v100h166q-23 47 -44 104q-7 20 -12 41.5t-6 55.5t6 66.5t29.5 70.5t58.5 71q97 88 263 88z" />
+<glyph unicode="" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM935 1184l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-900h-200v900h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
+<glyph unicode="" d="M1000 700h-100v100h-100v-100h-100v500h300v-500zM400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM801 1100v-200h100v200h-100zM1000 350l-200 -250h200v-100h-300v150l200 250h-200v100h300v-150z " />
+<glyph unicode="" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1000 1050l-200 -250h200v-100h-300v150l200 250h-200v100h300v-150zM1000 0h-100v100h-100v-100h-100v500h300v-500zM801 400v-200h100v200h-100z " />
+<glyph unicode="" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1000 700h-100v400h-100v100h200v-500zM1100 0h-100v100h-200v400h300v-500zM901 400v-200h100v200h-100z" />
+<glyph unicode="" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1100 700h-100v100h-200v400h300v-500zM901 1100v-200h100v200h-100zM1000 0h-100v400h-100v100h200v-500z" />
+<glyph unicode="" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM900 1000h-200v200h200v-200zM1000 700h-300v200h300v-200zM1100 400h-400v200h400v-200zM1200 100h-500v200h500v-200z" />
+<glyph unicode="" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1200 1000h-500v200h500v-200zM1100 700h-400v200h400v-200zM1000 400h-300v200h300v-200zM900 100h-200v200h200v-200z" />
+<glyph unicode="" d="M350 1100h400q162 0 256 -93.5t94 -256.5v-400q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5z" />
+<glyph unicode="" d="M350 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-163 0 -256.5 92.5t-93.5 257.5v400q0 163 94 256.5t256 93.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM440 770l253 -190q17 -12 17 -30t-17 -30l-253 -190q-16 -12 -28 -6.5t-12 26.5v400q0 21 12 26.5t28 -6.5z" />
+<glyph unicode="" d="M350 1100h400q163 0 256.5 -94t93.5 -256v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 163 92.5 256.5t257.5 93.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM350 700h400q21 0 26.5 -12t-6.5 -28l-190 -253q-12 -17 -30 -17t-30 17l-190 253q-12 16 -6.5 28t26.5 12z" />
+<glyph unicode="" d="M350 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -163 -92.5 -256.5t-257.5 -93.5h-400q-163 0 -256.5 94t-93.5 256v400q0 165 92.5 257.5t257.5 92.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM580 693l190 -253q12 -16 6.5 -28t-26.5 -12h-400q-21 0 -26.5 12t6.5 28l190 253q12 17 30 17t30 -17z" />
+<glyph unicode="" d="M550 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h450q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-450q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM338 867l324 -284q16 -14 16 -33t-16 -33l-324 -284q-16 -14 -27 -9t-11 26v150h-250q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h250v150q0 21 11 26t27 -9z" />
+<glyph unicode="" d="M793 1182l9 -9q8 -10 5 -27q-3 -11 -79 -225.5t-78 -221.5l300 1q24 0 32.5 -17.5t-5.5 -35.5q-1 0 -133.5 -155t-267 -312.5t-138.5 -162.5q-12 -15 -26 -15h-9l-9 8q-9 11 -4 32q2 9 42 123.5t79 224.5l39 110h-302q-23 0 -31 19q-10 21 6 41q75 86 209.5 237.5 t228 257t98.5 111.5q9 16 25 16h9z" />
+<glyph unicode="" d="M350 1100h400q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-450q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h450q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400 q0 165 92.5 257.5t257.5 92.5zM938 867l324 -284q16 -14 16 -33t-16 -33l-324 -284q-16 -14 -27 -9t-11 26v150h-250q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h250v150q0 21 11 26t27 -9z" />
+<glyph unicode="" d="M750 1200h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -10.5 -25t-24.5 10l-109 109l-312 -312q-15 -15 -35.5 -15t-35.5 15l-141 141q-15 15 -15 35.5t15 35.5l312 312l-109 109q-14 14 -10 24.5t25 10.5zM456 900h-156q-41 0 -70.5 -29.5t-29.5 -70.5v-500 q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v148l200 200v-298q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5h300z" />
+<glyph unicode="" d="M600 1186q119 0 227.5 -46.5t187 -125t125 -187t46.5 -227.5t-46.5 -227.5t-125 -187t-187 -125t-227.5 -46.5t-227.5 46.5t-187 125t-125 187t-46.5 227.5t46.5 227.5t125 187t187 125t227.5 46.5zM600 1022q-115 0 -212 -56.5t-153.5 -153.5t-56.5 -212t56.5 -212 t153.5 -153.5t212 -56.5t212 56.5t153.5 153.5t56.5 212t-56.5 212t-153.5 153.5t-212 56.5zM600 794q80 0 137 -57t57 -137t-57 -137t-137 -57t-137 57t-57 137t57 137t137 57z" />
+<glyph unicode="" d="M450 1200h200q21 0 35.5 -14.5t14.5 -35.5v-350h245q20 0 25 -11t-9 -26l-383 -426q-14 -15 -33.5 -15t-32.5 15l-379 426q-13 15 -8.5 26t25.5 11h250v350q0 21 14.5 35.5t35.5 14.5zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5z M900 200v-50h100v50h-100z" />
+<glyph unicode="" d="M583 1182l378 -435q14 -15 9 -31t-26 -16h-244v-250q0 -20 -17 -35t-39 -15h-200q-20 0 -32 14.5t-12 35.5v250h-250q-20 0 -25.5 16.5t8.5 31.5l383 431q14 16 33.5 17t33.5 -14zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5z M900 200v-50h100v50h-100z" />
+<glyph unicode="" d="M396 723l369 369q7 7 17.5 7t17.5 -7l139 -139q7 -8 7 -18.5t-7 -17.5l-525 -525q-7 -8 -17.5 -8t-17.5 8l-292 291q-7 8 -7 18t7 18l139 139q8 7 18.5 7t17.5 -7zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50 h-100z" />
+<glyph unicode="" d="M135 1023l142 142q14 14 35 14t35 -14l77 -77l-212 -212l-77 76q-14 15 -14 36t14 35zM655 855l210 210q14 14 24.5 10t10.5 -25l-2 -599q-1 -20 -15.5 -35t-35.5 -15l-597 -1q-21 0 -25 10.5t10 24.5l208 208l-154 155l212 212zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5 v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50h-100z" />
+<glyph unicode="" d="M350 1200l599 -2q20 -1 35 -15.5t15 -35.5l1 -597q0 -21 -10.5 -25t-24.5 10l-208 208l-155 -154l-212 212l155 154l-210 210q-14 14 -10 24.5t25 10.5zM524 512l-76 -77q-15 -14 -36 -14t-35 14l-142 142q-14 14 -14 35t14 35l77 77zM50 300h1000q21 0 35.5 -14.5 t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50h-100z" />
+<glyph unicode="" d="M1200 103l-483 276l-314 -399v423h-399l1196 796v-1096zM483 424v-230l683 953z" />
+<glyph unicode="" d="M1100 1000v-850q0 -21 -14.5 -35.5t-35.5 -14.5h-150v400h-700v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200z" />
+<glyph unicode="" d="M1100 1000l-2 -149l-299 -299l-95 95q-9 9 -21.5 9t-21.5 -9l-149 -147h-312v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM1132 638l106 -106q7 -7 7 -17.5t-7 -17.5l-420 -421q-8 -7 -18 -7 t-18 7l-202 203q-8 7 -8 17.5t8 17.5l106 106q7 8 17.5 8t17.5 -8l79 -79l297 297q7 7 17.5 7t17.5 -7z" />
+<glyph unicode="" d="M1100 1000v-269l-103 -103l-134 134q-15 15 -33.5 16.5t-34.5 -12.5l-266 -266h-329v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM1202 572l70 -70q15 -15 15 -35.5t-15 -35.5l-131 -131 l131 -131q15 -15 15 -35.5t-15 -35.5l-70 -70q-15 -15 -35.5 -15t-35.5 15l-131 131l-131 -131q-15 -15 -35.5 -15t-35.5 15l-70 70q-15 15 -15 35.5t15 35.5l131 131l-131 131q-15 15 -15 35.5t15 35.5l70 70q15 15 35.5 15t35.5 -15l131 -131l131 131q15 15 35.5 15 t35.5 -15z" />
+<glyph unicode="" d="M1100 1000v-300h-350q-21 0 -35.5 -14.5t-14.5 -35.5v-150h-500v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM850 600h100q21 0 35.5 -14.5t14.5 -35.5v-250h150q21 0 25 -10.5t-10 -24.5 l-230 -230q-14 -14 -35 -14t-35 14l-230 230q-14 14 -10 24.5t25 10.5h150v250q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M1100 1000v-400l-165 165q-14 15 -35 15t-35 -15l-263 -265h-402v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM935 565l230 -229q14 -15 10 -25.5t-25 -10.5h-150v-250q0 -20 -14.5 -35 t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35v250h-150q-21 0 -25 10.5t10 25.5l230 229q14 15 35 15t35 -15z" />
+<glyph unicode="" d="M50 1100h1100q21 0 35.5 -14.5t14.5 -35.5v-150h-1200v150q0 21 14.5 35.5t35.5 14.5zM1200 800v-550q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v550h1200zM100 500v-200h400v200h-400z" />
+<glyph unicode="" d="M935 1165l248 -230q14 -14 14 -35t-14 -35l-248 -230q-14 -14 -24.5 -10t-10.5 25v150h-400v200h400v150q0 21 10.5 25t24.5 -10zM200 800h-50q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v-200zM400 800h-100v200h100v-200zM18 435l247 230 q14 14 24.5 10t10.5 -25v-150h400v-200h-400v-150q0 -21 -10.5 -25t-24.5 10l-247 230q-15 14 -15 35t15 35zM900 300h-100v200h100v-200zM1000 500h51q20 0 34.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-34.5 -14.5h-51v200z" />
+<glyph unicode="" d="M862 1073l276 116q25 18 43.5 8t18.5 -41v-1106q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v397q-4 1 -11 5t-24 17.5t-30 29t-24 42t-11 56.5v359q0 31 18.5 65t43.5 52zM550 1200q22 0 34.5 -12.5t14.5 -24.5l1 -13v-450q0 -28 -10.5 -59.5 t-25 -56t-29 -45t-25.5 -31.5l-10 -11v-447q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v447q-4 4 -11 11.5t-24 30.5t-30 46t-24 55t-11 60v450q0 2 0.5 5.5t4 12t8.5 15t14.5 12t22.5 5.5q20 0 32.5 -12.5t14.5 -24.5l3 -13v-350h100v350v5.5t2.5 12 t7 15t15 12t25.5 5.5q23 0 35.5 -12.5t13.5 -24.5l1 -13v-350h100v350q0 2 0.5 5.5t3 12t7 15t15 12t24.5 5.5z" />
+<glyph unicode="" d="M1200 1100v-56q-4 0 -11 -0.5t-24 -3t-30 -7.5t-24 -15t-11 -24v-888q0 -22 25 -34.5t50 -13.5l25 -2v-56h-400v56q75 0 87.5 6.5t12.5 43.5v394h-500v-394q0 -37 12.5 -43.5t87.5 -6.5v-56h-400v56q4 0 11 0.5t24 3t30 7.5t24 15t11 24v888q0 22 -25 34.5t-50 13.5 l-25 2v56h400v-56q-75 0 -87.5 -6.5t-12.5 -43.5v-394h500v394q0 37 -12.5 43.5t-87.5 6.5v56h400z" />
+<glyph unicode="" d="M675 1000h375q21 0 35.5 -14.5t14.5 -35.5v-150h-105l-295 -98v98l-200 200h-400l100 100h375zM100 900h300q41 0 70.5 -29.5t29.5 -70.5v-500q0 -41 -29.5 -70.5t-70.5 -29.5h-300q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5zM100 800v-200h300v200 h-300zM1100 535l-400 -133v163l400 133v-163zM100 500v-200h300v200h-300zM1100 398v-248q0 -21 -14.5 -35.5t-35.5 -14.5h-375l-100 -100h-375l-100 100h400l200 200h105z" />
+<glyph unicode="" d="M17 1007l162 162q17 17 40 14t37 -22l139 -194q14 -20 11 -44.5t-20 -41.5l-119 -118q102 -142 228 -268t267 -227l119 118q17 17 42.5 19t44.5 -12l192 -136q19 -14 22.5 -37.5t-13.5 -40.5l-163 -162q-3 -1 -9.5 -1t-29.5 2t-47.5 6t-62.5 14.5t-77.5 26.5t-90 42.5 t-101.5 60t-111 83t-119 108.5q-74 74 -133.5 150.5t-94.5 138.5t-60 119.5t-34.5 100t-15 74.5t-4.5 48z" />
+<glyph unicode="" d="M600 1100q92 0 175 -10.5t141.5 -27t108.5 -36.5t81.5 -40t53.5 -37t31 -27l9 -10v-200q0 -21 -14.5 -33t-34.5 -9l-202 34q-20 3 -34.5 20t-14.5 38v146q-141 24 -300 24t-300 -24v-146q0 -21 -14.5 -38t-34.5 -20l-202 -34q-20 -3 -34.5 9t-14.5 33v200q3 4 9.5 10.5 t31 26t54 37.5t80.5 39.5t109 37.5t141 26.5t175 10.5zM600 795q56 0 97 -9.5t60 -23.5t30 -28t12 -24l1 -10v-50l365 -303q14 -15 24.5 -40t10.5 -45v-212q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v212q0 20 10.5 45t24.5 40l365 303v50 q0 4 1 10.5t12 23t30 29t60 22.5t97 10z" />
+<glyph unicode="" d="M1100 700l-200 -200h-600l-200 200v500h200v-200h200v200h200v-200h200v200h200v-500zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-12l137 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5 t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M700 1100h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-1000h300v1000q0 41 -29.5 70.5t-70.5 29.5zM1100 800h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-700h300v700q0 41 -29.5 70.5t-70.5 29.5zM400 0h-300v400q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-400z " />
+<glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-100h200v-300h-300v100h200v100h-200v300h300v-100zM900 700v-300l-100 -100h-200v500h200z M700 700v-300h100v300h-100z" />
+<glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 300h-100v200h-100v-200h-100v500h100v-200h100v200h100v-500zM900 700v-300l-100 -100h-200v500h200z M700 700v-300h100v300h-100z" />
+<glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-300h200v-100h-300v500h300v-100zM900 700h-200v-300h200v-100h-300v500h300v-100z" />
+<glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 400l-300 150l300 150v-300zM900 550l-300 -150v300z" />
+<glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM900 300h-700v500h700v-500zM800 700h-130q-38 0 -66.5 -43t-28.5 -108t27 -107t68 -42h130v300zM300 700v-300 h130q41 0 68 42t27 107t-28.5 108t-66.5 43h-130z" />
+<glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-100h200v-300h-300v100h200v100h-200v300h300v-100zM900 300h-100v400h-100v100h200v-500z M700 300h-100v100h100v-100z" />
+<glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM300 700h200v-400h-300v500h100v-100zM900 300h-100v400h-100v100h200v-500zM300 600v-200h100v200h-100z M700 300h-100v100h100v-100z" />
+<glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 500l-199 -200h-100v50l199 200v150h-200v100h300v-300zM900 300h-100v400h-100v100h200v-500zM701 300h-100 v100h100v-100z" />
+<glyph unicode="" d="M600 1191q120 0 229.5 -47t188.5 -126t126 -188.5t47 -229.5t-47 -229.5t-126 -188.5t-188.5 -126t-229.5 -47t-229.5 47t-188.5 126t-126 188.5t-47 229.5t47 229.5t126 188.5t188.5 126t229.5 47zM600 1021q-114 0 -211 -56.5t-153.5 -153.5t-56.5 -211t56.5 -211 t153.5 -153.5t211 -56.5t211 56.5t153.5 153.5t56.5 211t-56.5 211t-153.5 153.5t-211 56.5zM800 700h-300v-200h300v-100h-300l-100 100v200l100 100h300v-100z" />
+<glyph unicode="" d="M600 1191q120 0 229.5 -47t188.5 -126t126 -188.5t47 -229.5t-47 -229.5t-126 -188.5t-188.5 -126t-229.5 -47t-229.5 47t-188.5 126t-126 188.5t-47 229.5t47 229.5t126 188.5t188.5 126t229.5 47zM600 1021q-114 0 -211 -56.5t-153.5 -153.5t-56.5 -211t56.5 -211 t153.5 -153.5t211 -56.5t211 56.5t153.5 153.5t56.5 211t-56.5 211t-153.5 153.5t-211 56.5zM800 700v-100l-50 -50l100 -100v-50h-100l-100 100h-150v-100h-100v400h300zM500 700v-100h200v100h-200z" />
+<glyph unicode="" d="M503 1089q110 0 200.5 -59.5t134.5 -156.5q44 14 90 14q120 0 205 -86.5t85 -207t-85 -207t-205 -86.5h-128v250q0 21 -14.5 35.5t-35.5 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-250h-222q-80 0 -136 57.5t-56 136.5q0 69 43 122.5t108 67.5q-2 19 -2 37q0 100 49 185 t134 134t185 49zM525 500h150q10 0 17.5 -7.5t7.5 -17.5v-275h137q21 0 26 -11.5t-8 -27.5l-223 -244q-13 -16 -32 -16t-32 16l-223 244q-13 16 -8 27.5t26 11.5h137v275q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="" d="M502 1089q110 0 201 -59.5t135 -156.5q43 15 89 15q121 0 206 -86.5t86 -206.5q0 -99 -60 -181t-150 -110l-378 360q-13 16 -31.5 16t-31.5 -16l-381 -365h-9q-79 0 -135.5 57.5t-56.5 136.5q0 69 43 122.5t108 67.5q-2 19 -2 38q0 100 49 184.5t133.5 134t184.5 49.5z M632 467l223 -228q13 -16 8 -27.5t-26 -11.5h-137v-275q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v275h-137q-21 0 -26 11.5t8 27.5q199 204 223 228q19 19 31.5 19t32.5 -19z" />
+<glyph unicode="" d="M700 100v100h400l-270 300h170l-270 300h170l-300 333l-300 -333h170l-270 -300h170l-270 -300h400v-100h-50q-21 0 -35.5 -14.5t-14.5 -35.5v-50h400v50q0 21 -14.5 35.5t-35.5 14.5h-50z" />
+<glyph unicode="" d="M600 1179q94 0 167.5 -56.5t99.5 -145.5q89 -6 150.5 -71.5t61.5 -155.5q0 -61 -29.5 -112.5t-79.5 -82.5q9 -29 9 -55q0 -74 -52.5 -126.5t-126.5 -52.5q-55 0 -100 30v-251q21 0 35.5 -14.5t14.5 -35.5v-50h-300v50q0 21 14.5 35.5t35.5 14.5v251q-45 -30 -100 -30 q-74 0 -126.5 52.5t-52.5 126.5q0 18 4 38q-47 21 -75.5 65t-28.5 97q0 74 52.5 126.5t126.5 52.5q5 0 23 -2q0 2 -1 10t-1 13q0 116 81.5 197.5t197.5 81.5z" />
+<glyph unicode="" d="M1010 1010q111 -111 150.5 -260.5t0 -299t-150.5 -260.5q-83 -83 -191.5 -126.5t-218.5 -43.5t-218.5 43.5t-191.5 126.5q-111 111 -150.5 260.5t0 299t150.5 260.5q83 83 191.5 126.5t218.5 43.5t218.5 -43.5t191.5 -126.5zM476 1065q-4 0 -8 -1q-121 -34 -209.5 -122.5 t-122.5 -209.5q-4 -12 2.5 -23t18.5 -14l36 -9q3 -1 7 -1q23 0 29 22q27 96 98 166q70 71 166 98q11 3 17.5 13.5t3.5 22.5l-9 35q-3 13 -14 19q-7 4 -15 4zM512 920q-4 0 -9 -2q-80 -24 -138.5 -82.5t-82.5 -138.5q-4 -13 2 -24t19 -14l34 -9q4 -1 8 -1q22 0 28 21 q18 58 58.5 98.5t97.5 58.5q12 3 18 13.5t3 21.5l-9 35q-3 12 -14 19q-7 4 -15 4zM719.5 719.5q-49.5 49.5 -119.5 49.5t-119.5 -49.5t-49.5 -119.5t49.5 -119.5t119.5 -49.5t119.5 49.5t49.5 119.5t-49.5 119.5zM855 551q-22 0 -28 -21q-18 -58 -58.5 -98.5t-98.5 -57.5 q-11 -4 -17 -14.5t-3 -21.5l9 -35q3 -12 14 -19q7 -4 15 -4q4 0 9 2q80 24 138.5 82.5t82.5 138.5q4 13 -2.5 24t-18.5 14l-34 9q-4 1 -8 1zM1000 515q-23 0 -29 -22q-27 -96 -98 -166q-70 -71 -166 -98q-11 -3 -17.5 -13.5t-3.5 -22.5l9 -35q3 -13 14 -19q7 -4 15 -4 q4 0 8 1q121 34 209.5 122.5t122.5 209.5q4 12 -2.5 23t-18.5 14l-36 9q-3 1 -7 1z" />
+<glyph unicode="" d="M700 800h300v-380h-180v200h-340v-200h-380v755q0 10 7.5 17.5t17.5 7.5h575v-400zM1000 900h-200v200zM700 300h162l-212 -212l-212 212h162v200h100v-200zM520 0h-395q-10 0 -17.5 7.5t-7.5 17.5v395zM1000 220v-195q0 -10 -7.5 -17.5t-17.5 -7.5h-195z" />
+<glyph unicode="" d="M700 800h300v-520l-350 350l-550 -550v1095q0 10 7.5 17.5t17.5 7.5h575v-400zM1000 900h-200v200zM862 200h-162v-200h-100v200h-162l212 212zM480 0h-355q-10 0 -17.5 7.5t-7.5 17.5v55h380v-80zM1000 80v-55q0 -10 -7.5 -17.5t-17.5 -7.5h-155v80h180z" />
+<glyph unicode="" d="M1162 800h-162v-200h100l100 -100h-300v300h-162l212 212zM200 800h200q27 0 40 -2t29.5 -10.5t23.5 -30t7 -57.5h300v-100h-600l-200 -350v450h100q0 36 7 57.5t23.5 30t29.5 10.5t40 2zM800 400h240l-240 -400h-800l300 500h500v-100z" />
+<glyph unicode="" d="M650 1100h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5zM1000 850v150q41 0 70.5 -29.5t29.5 -70.5v-800 q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-1 0 -20 4l246 246l-326 326v324q0 41 29.5 70.5t70.5 29.5v-150q0 -62 44 -106t106 -44h300q62 0 106 44t44 106zM412 250l-212 -212v162h-200v100h200v162z" />
+<glyph unicode="" d="M450 1100h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5zM800 850v150q41 0 70.5 -29.5t29.5 -70.5v-500 h-200v-300h200q0 -36 -7 -57.5t-23.5 -30t-29.5 -10.5t-40 -2h-600q-41 0 -70.5 29.5t-29.5 70.5v800q0 41 29.5 70.5t70.5 29.5v-150q0 -62 44 -106t106 -44h300q62 0 106 44t44 106zM1212 250l-212 -212v162h-200v100h200v162z" />
+<glyph unicode="" d="M658 1197l637 -1104q23 -38 7 -65.5t-60 -27.5h-1276q-44 0 -60 27.5t7 65.5l637 1104q22 39 54 39t54 -39zM704 800h-208q-20 0 -32 -14.5t-8 -34.5l58 -302q4 -20 21.5 -34.5t37.5 -14.5h54q20 0 37.5 14.5t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5zM500 300v-100h200 v100h-200z" />
+<glyph unicode="" d="M425 1100h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM425 800h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5 t17.5 7.5zM825 800h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM25 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150 q0 10 7.5 17.5t17.5 7.5zM425 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM825 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5 v150q0 10 7.5 17.5t17.5 7.5zM25 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM425 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5 t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM825 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="" d="M700 1200h100v-200h-100v-100h350q62 0 86.5 -39.5t-3.5 -94.5l-66 -132q-41 -83 -81 -134h-772q-40 51 -81 134l-66 132q-28 55 -3.5 94.5t86.5 39.5h350v100h-100v200h100v100h200v-100zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-12l137 -100 h-950l138 100h-13q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M600 1300q40 0 68.5 -29.5t28.5 -70.5h-194q0 41 28.5 70.5t68.5 29.5zM443 1100h314q18 -37 18 -75q0 -8 -3 -25h328q41 0 44.5 -16.5t-30.5 -38.5l-175 -145h-678l-178 145q-34 22 -29 38.5t46 16.5h328q-3 17 -3 25q0 38 18 75zM250 700h700q21 0 35.5 -14.5 t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-150v-200l275 -200h-950l275 200v200h-150q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M600 1181q75 0 128 -53t53 -128t-53 -128t-128 -53t-128 53t-53 128t53 128t128 53zM602 798h46q34 0 55.5 -28.5t21.5 -86.5q0 -76 39 -183h-324q39 107 39 183q0 58 21.5 86.5t56.5 28.5h45zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13 l138 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M600 1300q47 0 92.5 -53.5t71 -123t25.5 -123.5q0 -78 -55.5 -133.5t-133.5 -55.5t-133.5 55.5t-55.5 133.5q0 62 34 143l144 -143l111 111l-163 163q34 26 63 26zM602 798h46q34 0 55.5 -28.5t21.5 -86.5q0 -76 39 -183h-324q39 107 39 183q0 58 21.5 86.5t56.5 28.5h45 zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13l138 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M600 1200l300 -161v-139h-300q0 -57 18.5 -108t50 -91.5t63 -72t70 -67.5t57.5 -61h-530q-60 83 -90.5 177.5t-30.5 178.5t33 164.5t87.5 139.5t126 96.5t145.5 41.5v-98zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13l138 -100h-950l137 100 h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M600 1300q41 0 70.5 -29.5t29.5 -70.5v-78q46 -26 73 -72t27 -100v-50h-400v50q0 54 27 100t73 72v78q0 41 29.5 70.5t70.5 29.5zM400 800h400q54 0 100 -27t72 -73h-172v-100h200v-100h-200v-100h200v-100h-200v-100h200q0 -83 -58.5 -141.5t-141.5 -58.5h-400 q-83 0 -141.5 58.5t-58.5 141.5v400q0 83 58.5 141.5t141.5 58.5z" />
+<glyph unicode="" d="M150 1100h900q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5zM125 400h950q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-283l224 -224q13 -13 13 -31.5t-13 -32 t-31.5 -13.5t-31.5 13l-88 88h-524l-87 -88q-13 -13 -32 -13t-32 13.5t-13 32t13 31.5l224 224h-289q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM541 300l-100 -100h324l-100 100h-124z" />
+<glyph unicode="" d="M200 1100h800q83 0 141.5 -58.5t58.5 -141.5v-200h-100q0 41 -29.5 70.5t-70.5 29.5h-250q-41 0 -70.5 -29.5t-29.5 -70.5h-100q0 41 -29.5 70.5t-70.5 29.5h-250q-41 0 -70.5 -29.5t-29.5 -70.5h-100v200q0 83 58.5 141.5t141.5 58.5zM100 600h1000q41 0 70.5 -29.5 t29.5 -70.5v-300h-1200v300q0 41 29.5 70.5t70.5 29.5zM300 100v-50q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v50h200zM1100 100v-50q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v50h200z" />
+<glyph unicode="" d="M480 1165l682 -683q31 -31 31 -75.5t-31 -75.5l-131 -131h-481l-517 518q-32 31 -32 75.5t32 75.5l295 296q31 31 75.5 31t76.5 -31zM108 794l342 -342l303 304l-341 341zM250 100h800q21 0 35.5 -14.5t14.5 -35.5v-50h-900v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M1057 647l-189 506q-8 19 -27.5 33t-40.5 14h-400q-21 0 -40.5 -14t-27.5 -33l-189 -506q-8 -19 1.5 -33t30.5 -14h625v-150q0 -21 14.5 -35.5t35.5 -14.5t35.5 14.5t14.5 35.5v150h125q21 0 30.5 14t1.5 33zM897 0h-595v50q0 21 14.5 35.5t35.5 14.5h50v50 q0 21 14.5 35.5t35.5 14.5h48v300h200v-300h47q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-50z" />
+<glyph unicode="" d="M900 800h300v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-375v591l-300 300v84q0 10 7.5 17.5t17.5 7.5h375v-400zM1200 900h-200v200zM400 600h300v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-650q-10 0 -17.5 7.5t-7.5 17.5v950q0 10 7.5 17.5t17.5 7.5h375v-400zM700 700h-200v200z " />
+<glyph unicode="" d="M484 1095h195q75 0 146 -32.5t124 -86t89.5 -122.5t48.5 -142q18 -14 35 -20q31 -10 64.5 6.5t43.5 48.5q10 34 -15 71q-19 27 -9 43q5 8 12.5 11t19 -1t23.5 -16q41 -44 39 -105q-3 -63 -46 -106.5t-104 -43.5h-62q-7 -55 -35 -117t-56 -100l-39 -234q-3 -20 -20 -34.5 t-38 -14.5h-100q-21 0 -33 14.5t-9 34.5l12 70q-49 -14 -91 -14h-195q-24 0 -65 8l-11 -64q-3 -20 -20 -34.5t-38 -14.5h-100q-21 0 -33 14.5t-9 34.5l26 157q-84 74 -128 175l-159 53q-19 7 -33 26t-14 40v50q0 21 14.5 35.5t35.5 14.5h124q11 87 56 166l-111 95 q-16 14 -12.5 23.5t24.5 9.5h203q116 101 250 101zM675 1000h-250q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h250q10 0 17.5 7.5t7.5 17.5v50q0 10 -7.5 17.5t-17.5 7.5z" />
+<glyph unicode="" d="M641 900l423 247q19 8 42 2.5t37 -21.5l32 -38q14 -15 12.5 -36t-17.5 -34l-139 -120h-390zM50 1100h106q67 0 103 -17t66 -71l102 -212h823q21 0 35.5 -14.5t14.5 -35.5v-50q0 -21 -14 -40t-33 -26l-737 -132q-23 -4 -40 6t-26 25q-42 67 -100 67h-300q-62 0 -106 44 t-44 106v200q0 62 44 106t106 44zM173 928h-80q-19 0 -28 -14t-9 -35v-56q0 -51 42 -51h134q16 0 21.5 8t5.5 24q0 11 -16 45t-27 51q-18 28 -43 28zM550 727q-32 0 -54.5 -22.5t-22.5 -54.5t22.5 -54.5t54.5 -22.5t54.5 22.5t22.5 54.5t-22.5 54.5t-54.5 22.5zM130 389 l152 130q18 19 34 24t31 -3.5t24.5 -17.5t25.5 -28q28 -35 50.5 -51t48.5 -13l63 5l48 -179q13 -61 -3.5 -97.5t-67.5 -79.5l-80 -69q-47 -40 -109 -35.5t-103 51.5l-130 151q-40 47 -35.5 109.5t51.5 102.5zM380 377l-102 -88q-31 -27 2 -65l37 -43q13 -15 27.5 -19.5 t31.5 6.5l61 53q19 16 14 49q-2 20 -12 56t-17 45q-11 12 -19 14t-23 -8z" />
+<glyph unicode="" d="M625 1200h150q10 0 17.5 -7.5t7.5 -17.5v-109q79 -33 131 -87.5t53 -128.5q1 -46 -15 -84.5t-39 -61t-46 -38t-39 -21.5l-17 -6q6 0 15 -1.5t35 -9t50 -17.5t53 -30t50 -45t35.5 -64t14.5 -84q0 -59 -11.5 -105.5t-28.5 -76.5t-44 -51t-49.5 -31.5t-54.5 -16t-49.5 -6.5 t-43.5 -1v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-100v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-175q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h75v600h-75q-10 0 -17.5 7.5t-7.5 17.5v150 q0 10 7.5 17.5t17.5 7.5h175v75q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-75h100v75q0 10 7.5 17.5t17.5 7.5zM400 900v-200h263q28 0 48.5 10.5t30 25t15 29t5.5 25.5l1 10q0 4 -0.5 11t-6 24t-15 30t-30 24t-48.5 11h-263zM400 500v-200h363q28 0 48.5 10.5 t30 25t15 29t5.5 25.5l1 10q0 4 -0.5 11t-6 24t-15 30t-30 24t-48.5 11h-363z" />
+<glyph unicode="" d="M212 1198h780q86 0 147 -61t61 -147v-416q0 -51 -18 -142.5t-36 -157.5l-18 -66q-29 -87 -93.5 -146.5t-146.5 -59.5h-572q-82 0 -147 59t-93 147q-8 28 -20 73t-32 143.5t-20 149.5v416q0 86 61 147t147 61zM600 1045q-70 0 -132.5 -11.5t-105.5 -30.5t-78.5 -41.5 t-57 -45t-36 -41t-20.5 -30.5l-6 -12l156 -243h560l156 243q-2 5 -6 12.5t-20 29.5t-36.5 42t-57 44.5t-79 42t-105 29.5t-132.5 12zM762 703h-157l195 261z" />
+<glyph unicode="" d="M475 1300h150q103 0 189 -86t86 -189v-500q0 -41 -42 -83t-83 -42h-450q-41 0 -83 42t-42 83v500q0 103 86 189t189 86zM700 300v-225q0 -21 -27 -48t-48 -27h-150q-21 0 -48 27t-27 48v225h300z" />
+<glyph unicode="" d="M475 1300h96q0 -150 89.5 -239.5t239.5 -89.5v-446q0 -41 -42 -83t-83 -42h-450q-41 0 -83 42t-42 83v500q0 103 86 189t189 86zM700 300v-225q0 -21 -27 -48t-48 -27h-150q-21 0 -48 27t-27 48v225h300z" />
+<glyph unicode="" d="M1294 767l-638 -283l-378 170l-78 -60v-224l100 -150v-199l-150 148l-150 -149v200l100 150v250q0 4 -0.5 10.5t0 9.5t1 8t3 8t6.5 6l47 40l-147 65l642 283zM1000 380l-350 -166l-350 166v147l350 -165l350 165v-147z" />
+<glyph unicode="" d="M250 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM650 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM1050 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44z" />
+<glyph unicode="" d="M550 1100q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM550 700q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM550 300q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44z" />
+<glyph unicode="" d="M125 1100h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM125 700h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5 t17.5 7.5zM125 300h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="" d="M350 1200h500q162 0 256 -93.5t94 -256.5v-500q0 -165 -93.5 -257.5t-256.5 -92.5h-500q-165 0 -257.5 92.5t-92.5 257.5v500q0 165 92.5 257.5t257.5 92.5zM900 1000h-600q-41 0 -70.5 -29.5t-29.5 -70.5v-600q0 -41 29.5 -70.5t70.5 -29.5h600q41 0 70.5 29.5 t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5zM350 900h500q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -14.5 -35.5t-35.5 -14.5h-500q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 14.5 35.5t35.5 14.5zM400 800v-200h400v200h-400z" />
+<glyph unicode="" d="M150 1100h1000q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5 t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M650 1187q87 -67 118.5 -156t0 -178t-118.5 -155q-87 66 -118.5 155t0 178t118.5 156zM300 800q124 0 212 -88t88 -212q-124 0 -212 88t-88 212zM1000 800q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM300 500q124 0 212 -88t88 -212q-124 0 -212 88t-88 212z M1000 500q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM700 199v-144q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v142q40 -4 43 -4q17 0 57 6z" />
+<glyph unicode="" d="M745 878l69 19q25 6 45 -12l298 -295q11 -11 15 -26.5t-2 -30.5q-5 -14 -18 -23.5t-28 -9.5h-8q1 0 1 -13q0 -29 -2 -56t-8.5 -62t-20 -63t-33 -53t-51 -39t-72.5 -14h-146q-184 0 -184 288q0 24 10 47q-20 4 -62 4t-63 -4q11 -24 11 -47q0 -288 -184 -288h-142 q-48 0 -84.5 21t-56 51t-32 71.5t-16 75t-3.5 68.5q0 13 2 13h-7q-15 0 -27.5 9.5t-18.5 23.5q-6 15 -2 30.5t15 25.5l298 296q20 18 46 11l76 -19q20 -5 30.5 -22.5t5.5 -37.5t-22.5 -31t-37.5 -5l-51 12l-182 -193h891l-182 193l-44 -12q-20 -5 -37.5 6t-22.5 31t6 37.5 t31 22.5z" />
+<glyph unicode="" d="M1200 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-850q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v850h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM500 450h-25q0 15 -4 24.5t-9 14.5t-17 7.5t-20 3t-25 0.5h-100v-425q0 -11 12.5 -17.5t25.5 -7.5h12v-50h-200v50q50 0 50 25v425h-100q-17 0 -25 -0.5t-20 -3t-17 -7.5t-9 -14.5t-4 -24.5h-25v150h500v-150z" />
+<glyph unicode="" d="M1000 300v50q-25 0 -55 32q-14 14 -25 31t-16 27l-4 11l-289 747h-69l-300 -754q-18 -35 -39 -56q-9 -9 -24.5 -18.5t-26.5 -14.5l-11 -5v-50h273v50q-49 0 -78.5 21.5t-11.5 67.5l69 176h293l61 -166q13 -34 -3.5 -66.5t-55.5 -32.5v-50h312zM412 691l134 342l121 -342 h-255zM1100 150v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5z" />
+<glyph unicode="" d="M50 1200h1100q21 0 35.5 -14.5t14.5 -35.5v-1100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v1100q0 21 14.5 35.5t35.5 14.5zM611 1118h-70q-13 0 -18 -12l-299 -753q-17 -32 -35 -51q-18 -18 -56 -34q-12 -5 -12 -18v-50q0 -8 5.5 -14t14.5 -6 h273q8 0 14 6t6 14v50q0 8 -6 14t-14 6q-55 0 -71 23q-10 14 0 39l63 163h266l57 -153q11 -31 -6 -55q-12 -17 -36 -17q-8 0 -14 -6t-6 -14v-50q0 -8 6 -14t14 -6h313q8 0 14 6t6 14v50q0 7 -5.5 13t-13.5 7q-17 0 -42 25q-25 27 -40 63h-1l-288 748q-5 12 -19 12zM639 611 h-197l103 264z" />
+<glyph unicode="" d="M1200 1100h-1200v100h1200v-100zM50 1000h400q21 0 35.5 -14.5t14.5 -35.5v-900q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v900q0 21 14.5 35.5t35.5 14.5zM650 1000h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM700 900v-300h300v300h-300z" />
+<glyph unicode="" d="M50 1200h400q21 0 35.5 -14.5t14.5 -35.5v-900q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v900q0 21 14.5 35.5t35.5 14.5zM650 700h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400 q0 21 14.5 35.5t35.5 14.5zM700 600v-300h300v300h-300zM1200 0h-1200v100h1200v-100z" />
+<glyph unicode="" d="M50 1000h400q21 0 35.5 -14.5t14.5 -35.5v-350h100v150q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-150h100v-100h-100v-150q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v150h-100v-350q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5zM700 700v-300h300v300h-300z" />
+<glyph unicode="" d="M100 0h-100v1200h100v-1200zM250 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM300 1000v-300h300v300h-300zM250 500h900q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M600 1100h150q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-150v-100h450q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5h350v100h-150q-21 0 -35.5 14.5 t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5h150v100h100v-100zM400 1000v-300h300v300h-300z" />
+<glyph unicode="" d="M1200 0h-100v1200h100v-1200zM550 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM600 1000v-300h300v300h-300zM50 500h900q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="" d="M865 565l-494 -494q-23 -23 -41 -23q-14 0 -22 13.5t-8 38.5v1000q0 25 8 38.5t22 13.5q18 0 41 -23l494 -494q14 -14 14 -35t-14 -35z" />
+<glyph unicode="" d="M335 635l494 494q29 29 50 20.5t21 -49.5v-1000q0 -41 -21 -49.5t-50 20.5l-494 494q-14 14 -14 35t14 35z" />
+<glyph unicode="" d="M100 900h1000q41 0 49.5 -21t-20.5 -50l-494 -494q-14 -14 -35 -14t-35 14l-494 494q-29 29 -20.5 50t49.5 21z" />
+<glyph unicode="" d="M635 865l494 -494q29 -29 20.5 -50t-49.5 -21h-1000q-41 0 -49.5 21t20.5 50l494 494q14 14 35 14t35 -14z" />
+<glyph unicode="" d="M700 741v-182l-692 -323v221l413 193l-413 193v221zM1200 0h-800v200h800v-200z" />
+<glyph unicode="" d="M1200 900h-200v-100h200v-100h-300v300h200v100h-200v100h300v-300zM0 700h50q0 21 4 37t9.5 26.5t18 17.5t22 11t28.5 5.5t31 2t37 0.5h100v-550q0 -22 -25 -34.5t-50 -13.5l-25 -2v-100h400v100q-4 0 -11 0.5t-24 3t-30 7t-24 15t-11 24.5v550h100q25 0 37 -0.5t31 -2 t28.5 -5.5t22 -11t18 -17.5t9.5 -26.5t4 -37h50v300h-800v-300z" />
+<glyph unicode="" d="M800 700h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-100v-550q0 -22 25 -34.5t50 -14.5l25 -1v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v550h-100q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h800v-300zM1100 200h-200v-100h200v-100h-300v300h200v100h-200v100h300v-300z" />
+<glyph unicode="" d="M701 1098h160q16 0 21 -11t-7 -23l-464 -464l464 -464q12 -12 7 -23t-21 -11h-160q-13 0 -23 9l-471 471q-7 8 -7 18t7 18l471 471q10 9 23 9z" />
+<glyph unicode="" d="M339 1098h160q13 0 23 -9l471 -471q7 -8 7 -18t-7 -18l-471 -471q-10 -9 -23 -9h-160q-16 0 -21 11t7 23l464 464l-464 464q-12 12 -7 23t21 11z" />
+<glyph unicode="" d="M1087 882q11 -5 11 -21v-160q0 -13 -9 -23l-471 -471q-8 -7 -18 -7t-18 7l-471 471q-9 10 -9 23v160q0 16 11 21t23 -7l464 -464l464 464q12 12 23 7z" />
+<glyph unicode="" d="M618 993l471 -471q9 -10 9 -23v-160q0 -16 -11 -21t-23 7l-464 464l-464 -464q-12 -12 -23 -7t-11 21v160q0 13 9 23l471 471q8 7 18 7t18 -7z" />
+<glyph unicode="" d="M1000 1200q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM450 1000h100q21 0 40 -14t26 -33l79 -194q5 1 16 3q34 6 54 9.5t60 7t65.5 1t61 -10t56.5 -23t42.5 -42t29 -64t5 -92t-19.5 -121.5q-1 -7 -3 -19.5t-11 -50t-20.5 -73t-32.5 -81.5t-46.5 -83t-64 -70 t-82.5 -50q-13 -5 -42 -5t-65.5 2.5t-47.5 2.5q-14 0 -49.5 -3.5t-63 -3.5t-43.5 7q-57 25 -104.5 78.5t-75 111.5t-46.5 112t-26 90l-7 35q-15 63 -18 115t4.5 88.5t26 64t39.5 43.5t52 25.5t58.5 13t62.5 2t59.5 -4.5t55.5 -8l-147 192q-12 18 -5.5 30t27.5 12z" />
+<glyph unicode="🔑" d="M250 1200h600q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-150v-500l-255 -178q-19 -9 -32 -1t-13 29v650h-150q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM400 1100v-100h300v100h-300z" />
+<glyph unicode="🚪" d="M250 1200h750q39 0 69.5 -40.5t30.5 -84.5v-933l-700 -117v950l600 125h-700v-1000h-100v1025q0 23 15.5 49t34.5 26zM500 525v-100l100 20v100z" />
+</font>
+</defs></svg>
\ No newline at end of file
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..1413fc609ab6f21774de0cb7e01360095584f65b
GIT binary patch
literal 45404
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
XStY_=A$0InS6e%+*G_v`?YI6DA%94*
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9e612858f802245ddcbf59788a0db942224bab35
GIT binary patch
literal 23424
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
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..64539b54c3751a6d9adb44c8e3a45ba5a73b77f0
GIT binary patch
literal 18028
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
new file mode 100644
--- /dev/null
+++ b/js/jquery-1.11.3.min.js
@@ -0,0 +1,2574 @@
+/*! jQuery v1.11.3 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */
+!function (a, b) {
+ "object" == typeof module && "object" == typeof module.exports ? module.exports = a.document ? b(a, !0) : function (a) {
+ if (!a.document)throw new Error("jQuery requires a window with a document");
+ return b(a)
+ } : b(a)
+}("undefined" != typeof window ? window : this, function (a, b) {
+ var c = [], d = c.slice, e = c.concat, f = c.push, g = c.indexOf, h = {}, i = h.toString, j = h.hasOwnProperty, k = {}, l = "1.11.3", m = function (a, b) {
+ return new m.fn.init(a, b)
+ }, n = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, o = /^-ms-/, p = /-([\da-z])/gi, q = function (a, b) {
+ return b.toUpperCase()
+ };
+ m.fn = m.prototype = {
+ jquery: l, constructor: m, selector: "", length: 0, toArray: function () {
+ return d.call(this)
+ }, get: function (a) {
+ return null != a ? 0 > a ? this[a + this.length] : this[a] : d.call(this)
+ }, pushStack: function (a) {
+ var b = m.merge(this.constructor(), a);
+ return b.prevObject = this, b.context = this.context, b
+ }, each: function (a, b) {
+ return m.each(this, a, b)
+ }, map: function (a) {
+ return this.pushStack(m.map(this, function (b, c) {
+ return a.call(b, c, b)
+ }))
+ }, slice: function () {
+ return this.pushStack(d.apply(this, arguments))
+ }, first: function () {
+ return this.eq(0)
+ }, last: function () {
+ return this.eq(-1)
+ }, eq: function (a) {
+ var b = this.length, c = +a + (0 > a ? b : 0);
+ return this.pushStack(c >= 0 && b > c ? [this[c]] : [])
+ }, end: function () {
+ return this.prevObject || this.constructor(null)
+ }, push: f, sort: c.sort, splice: c.splice
+ }, m.extend = m.fn.extend = function () {
+ var a, b, c, d, e, f, g = arguments[0] || {}, h = 1, i = arguments.length, j = !1;
+ for ("boolean" == typeof g && (j = g, g = arguments[h] || {}, h++), "object" == typeof g || m.isFunction(g) || (g = {}), h === i && (g = this, h--); i > h; h++)if (null != (e = arguments[h]))for (d in e)a = g[d], c = e[d], g !== c && (j && c && (m.isPlainObject(c) || (b = m.isArray(c))) ? (b ? (b = !1, f = a && m.isArray(a) ? a : []) : f = a && m.isPlainObject(a) ? a : {}, g[d] = m.extend(j, f, c)) : void 0 !== c && (g[d] = c));
+ return g
+ }, m.extend({
+ expando: "jQuery" + (l + Math.random()).replace(/\D/g, ""), isReady: !0, error: function (a) {
+ throw new Error(a)
+ }, noop: function () {
+ }, isFunction: function (a) {
+ return "function" === m.type(a)
+ }, isArray: Array.isArray || function (a) {
+ return "array" === m.type(a)
+ }, isWindow: function (a) {
+ return null != a && a == a.window
+ }, isNumeric: function (a) {
+ return !m.isArray(a) && a - parseFloat(a) + 1 >= 0
+ }, isEmptyObject: function (a) {
+ var b;
+ for (b in a)return !1;
+ return !0
+ }, isPlainObject: function (a) {
+ var b;
+ if (!a || "object" !== m.type(a) || a.nodeType || m.isWindow(a))return !1;
+ try {
+ if (a.constructor && !j.call(a, "constructor") && !j.call(a.constructor.prototype, "isPrototypeOf"))return !1
+ } catch (c) {
+ return !1
+ }
+ if (k.ownLast)for (b in a)return j.call(a, b);
+ for (b in a);
+ return void 0 === b || j.call(a, b)
+ }, type: function (a) {
+ return null == a ? a + "" : "object" == typeof a || "function" == typeof a ? h[i.call(a)] || "object" : typeof a
+ }, globalEval: function (b) {
+ b && m.trim(b) && (a.execScript || function (b) {
+ a.eval.call(a, b)
+ })(b)
+ }, camelCase: function (a) {
+ return a.replace(o, "ms-").replace(p, q)
+ }, nodeName: function (a, b) {
+ return a.nodeName && a.nodeName.toLowerCase() === b.toLowerCase()
+ }, each: function (a, b, c) {
+ var d, e = 0, f = a.length, g = r(a);
+ if (c) {
+ if (g) {
+ for (; f > e; e++)if (d = b.apply(a[e], c), d === !1)break
+ } else for (e in a)if (d = b.apply(a[e], c), d === !1)break
+ } else if (g) {
+ for (; f > e; e++)if (d = b.call(a[e], e, a[e]), d === !1)break
+ } else for (e in a)if (d = b.call(a[e], e, a[e]), d === !1)break;
+ return a
+ }, trim: function (a) {
+ return null == a ? "" : (a + "").replace(n, "")
+ }, makeArray: function (a, b) {
+ var c = b || [];
+ return null != a && (r(Object(a)) ? m.merge(c, "string" == typeof a ? [a] : a) : f.call(c, a)), c
+ }, inArray: function (a, b, c) {
+ var d;
+ if (b) {
+ if (g)return g.call(b, a, c);
+ for (d = b.length, c = c ? 0 > c ? Math.max(0, d + c) : c : 0; d > c; c++)if (c in b && b[c] === a)return c
+ }
+ return -1
+ }, merge: function (a, b) {
+ var c = +b.length, d = 0, e = a.length;
+ while (c > d)a[e++] = b[d++];
+ if (c !== c)while (void 0 !== b[d])a[e++] = b[d++];
+ return a.length = e, a
+ }, grep: function (a, b, c) {
+ for (var d, e = [], f = 0, g = a.length, h = !c; g > f; f++)d = !b(a[f], f), d !== h && e.push(a[f]);
+ return e
+ }, map: function (a, b, c) {
+ var d, f = 0, g = a.length, h = r(a), i = [];
+ if (h)for (; g > f; f++)d = b(a[f], f, c), null != d && i.push(d); else for (f in a)d = b(a[f], f, c), null != d && i.push(d);
+ return e.apply([], i)
+ }, guid: 1, proxy: function (a, b) {
+ var c, e, f;
+ return "string" == typeof b && (f = a[b], b = a, a = f), m.isFunction(a) ? (c = d.call(arguments, 2), e = function () {
+ return a.apply(b || this, c.concat(d.call(arguments)))
+ }, e.guid = a.guid = a.guid || m.guid++, e) : void 0
+ }, now: function () {
+ return +new Date
+ }, support: k
+ }), m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function (a, b) {
+ h["[object " + b + "]"] = b.toLowerCase()
+ });
+ function r(a) {
+ var b = "length" in a && a.length, c = m.type(a);
+ return "function" === c || m.isWindow(a) ? !1 : 1 === a.nodeType && b ? !0 : "array" === c || 0 === b || "number" == typeof b && b > 0 && b - 1 in a
+ }
+
+ var s = function (a) {
+ var b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u = "sizzle" + 1 * new Date, v = a.document, w = 0, x = 0, y = ha(), z = ha(), A = ha(), B = function (a, b) {
+ return a === b && (l = !0), 0
+ }, C = 1 << 31, D = {}.hasOwnProperty, E = [], F = E.pop, G = E.push, H = E.push, I = E.slice, J = function (a, b) {
+ for (var c = 0, d = a.length; d > c; c++)if (a[c] === b)return c;
+ return -1
+ }, K = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", L = "[\\x20\\t\\r\\n\\f]", M = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", N = M.replace("w", "w#"), O = "\\[" + L + "*(" + M + ")(?:" + L + "*([*^$|!~]?=)" + L + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + N + "))|)" + L + "*\\]", P = ":(" + M + ")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|" + O + ")*)|.*)\\)|)", Q = new RegExp(L + "+", "g"), R = new RegExp("^" + L + "+|((?:^|[^\\\\])(?:\\\\.)*)" + L + "+$", "g"), S = new RegExp("^" + L + "*," + L + "*"), T = new RegExp("^" + L + "*([>+~]|" + L + ")" + L + "*"), U = new RegExp("=" + L + "*([^\\]'\"]*?)" + L + "*\\]", "g"), V = new RegExp(P), W = new RegExp("^" + N + "$"), X = {
+ ID: new RegExp("^#(" + M + ")"),
+ CLASS: new RegExp("^\\.(" + M + ")"),
+ TAG: new RegExp("^(" + M.replace("w", "w*") + ")"),
+ ATTR: new RegExp("^" + O),
+ PSEUDO: new RegExp("^" + P),
+ CHILD: new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + L + "*(even|odd|(([+-]|)(\\d*)n|)" + L + "*(?:([+-]|)" + L + "*(\\d+)|))" + L + "*\\)|)", "i"),
+ bool: new RegExp("^(?:" + K + ")$", "i"),
+ needsContext: new RegExp("^" + L + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + L + "*((?:-\\d)?\\d*)" + L + "*\\)|)(?=[^-]|$)", "i")
+ }, Y = /^(?:input|select|textarea|button)$/i, Z = /^h\d$/i, $ = /^[^{]+\{\s*\[native \w/, _ = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, aa = /[+~]/, ba = /'|\\/g, ca = new RegExp("\\\\([\\da-f]{1,6}" + L + "?|(" + L + ")|.)", "ig"), da = function (a, b, c) {
+ var d = "0x" + b - 65536;
+ return d !== d || c ? b : 0 > d ? String.fromCharCode(d + 65536) : String.fromCharCode(d >> 10 | 55296, 1023 & d | 56320)
+ }, ea = function () {
+ m()
+ };
+ try {
+ H.apply(E = I.call(v.childNodes), v.childNodes), E[v.childNodes.length].nodeType
+ } catch (fa) {
+ H = {
+ apply: E.length ? function (a, b) {
+ G.apply(a, I.call(b))
+ } : function (a, b) {
+ var c = a.length, d = 0;
+ while (a[c++] = b[d++]);
+ a.length = c - 1
+ }
+ }
+ }
+ function ga(a, b, d, e) {
+ var f, h, j, k, l, o, r, s, w, x;
+ if ((b ? b.ownerDocument || b : v) !== n && m(b), b = b || n, d = d || [], k = b.nodeType, "string" != typeof a || !a || 1 !== k && 9 !== k && 11 !== k)return d;
+ if (!e && p) {
+ if (11 !== k && (f = _.exec(a)))if (j = f[1]) {
+ if (9 === k) {
+ if (h = b.getElementById(j), !h || !h.parentNode)return d;
+ if (h.id === j)return d.push(h), d
+ } else if (b.ownerDocument && (h = b.ownerDocument.getElementById(j)) && t(b, h) && h.id === j)return d.push(h), d
+ } else {
+ if (f[2])return H.apply(d, b.getElementsByTagName(a)), d;
+ if ((j = f[3]) && c.getElementsByClassName)return H.apply(d, b.getElementsByClassName(j)), d
+ }
+ if (c.qsa && (!q || !q.test(a))) {
+ if (s = r = u, w = b, x = 1 !== k && a, 1 === k && "object" !== b.nodeName.toLowerCase()) {
+ o = g(a), (r = b.getAttribute("id")) ? s = r.replace(ba, "\\$&") : b.setAttribute("id", s), s = "[id='" + s + "'] ", l = o.length;
+ while (l--)o[l] = s + ra(o[l]);
+ w = aa.test(a) && pa(b.parentNode) || b, x = o.join(",")
+ }
+ if (x)try {
+ return H.apply(d, w.querySelectorAll(x)), d
+ } catch (y) {
+ } finally {
+ r || b.removeAttribute("id")
+ }
+ }
+ }
+ return i(a.replace(R, "$1"), b, d, e)
+ }
+
+ function ha() {
+ var a = [];
+
+ function b(c, e) {
+ return a.push(c + " ") > d.cacheLength && delete b[a.shift()], b[c + " "] = e
+ }
+
+ return b
+ }
+
+ function ia(a) {
+ return a[u] = !0, a
+ }
+
+ function ja(a) {
+ var b = n.createElement("div");
+ try {
+ return !!a(b)
+ } catch (c) {
+ return !1
+ } finally {
+ b.parentNode && b.parentNode.removeChild(b), b = null
+ }
+ }
+
+ function ka(a, b) {
+ var c = a.split("|"), e = a.length;
+ while (e--)d.attrHandle[c[e]] = b
+ }
+
+ function la(a, b) {
+ var c = b && a, d = c && 1 === a.nodeType && 1 === b.nodeType && (~b.sourceIndex || C) - (~a.sourceIndex || C);
+ if (d)return d;
+ if (c)while (c = c.nextSibling)if (c === b)return -1;
+ return a ? 1 : -1
+ }
+
+ function ma(a) {
+ return function (b) {
+ var c = b.nodeName.toLowerCase();
+ return "input" === c && b.type === a
+ }
+ }
+
+ function na(a) {
+ return function (b) {
+ var c = b.nodeName.toLowerCase();
+ return ("input" === c || "button" === c) && b.type === a
+ }
+ }
+
+ function oa(a) {
+ return ia(function (b) {
+ return b = +b, ia(function (c, d) {
+ var e, f = a([], c.length, b), g = f.length;
+ while (g--)c[e = f[g]] && (c[e] = !(d[e] = c[e]))
+ })
+ })
+ }
+
+ function pa(a) {
+ return a && "undefined" != typeof a.getElementsByTagName && a
+ }
+
+ c = ga.support = {}, f = ga.isXML = function (a) {
+ var b = a && (a.ownerDocument || a).documentElement;
+ return b ? "HTML" !== b.nodeName : !1
+ }, m = ga.setDocument = function (a) {
+ var b, e, g = a ? a.ownerDocument || a : v;
+ return g !== n && 9 === g.nodeType && g.documentElement ? (n = g, o = g.documentElement, e = g.defaultView, e && e !== e.top && (e.addEventListener ? e.addEventListener("unload", ea, !1) : e.attachEvent && e.attachEvent("onunload", ea)), p = !f(g), c.attributes = ja(function (a) {
+ return a.className = "i", !a.getAttribute("className")
+ }), c.getElementsByTagName = ja(function (a) {
+ return a.appendChild(g.createComment("")), !a.getElementsByTagName("*").length
+ }), c.getElementsByClassName = $.test(g.getElementsByClassName), c.getById = ja(function (a) {
+ return o.appendChild(a).id = u, !g.getElementsByName || !g.getElementsByName(u).length
+ }), c.getById ? (d.find.ID = function (a, b) {
+ if ("undefined" != typeof b.getElementById && p) {
+ var c = b.getElementById(a);
+ return c && c.parentNode ? [c] : []
+ }
+ }, d.filter.ID = function (a) {
+ var b = a.replace(ca, da);
+ return function (a) {
+ return a.getAttribute("id") === b
+ }
+ }) : (delete d.find.ID, d.filter.ID = function (a) {
+ var b = a.replace(ca, da);
+ return function (a) {
+ var c = "undefined" != typeof a.getAttributeNode && a.getAttributeNode("id");
+ return c && c.value === b
+ }
+ }), d.find.TAG = c.getElementsByTagName ? function (a, b) {
+ return "undefined" != typeof b.getElementsByTagName ? b.getElementsByTagName(a) : c.qsa ? b.querySelectorAll(a) : void 0
+ } : function (a, b) {
+ var c, d = [], e = 0, f = b.getElementsByTagName(a);
+ if ("*" === a) {
+ while (c = f[e++])1 === c.nodeType && d.push(c);
+ return d
+ }
+ return f
+ }, d.find.CLASS = c.getElementsByClassName && function (a, b) {
+ return p ? b.getElementsByClassName(a) : void 0
+ }, r = [], q = [], (c.qsa = $.test(g.querySelectorAll)) && (ja(function (a) {
+ o.appendChild(a).innerHTML = "<a id='" + u + "'></a><select id='" + u + "-\f]' msallowcapture=''><option selected=''></option></select>", a.querySelectorAll("[msallowcapture^='']").length && q.push("[*^$]=" + L + "*(?:''|\"\")"), a.querySelectorAll("[selected]").length || q.push("\\[" + L + "*(?:value|" + K + ")"), a.querySelectorAll("[id~=" + u + "-]").length || q.push("~="), a.querySelectorAll(":checked").length || q.push(":checked"), a.querySelectorAll("a#" + u + "+*").length || q.push(".#.+[+~]")
+ }), ja(function (a) {
+ var b = g.createElement("input");
+ b.setAttribute("type", "hidden"), a.appendChild(b).setAttribute("name", "D"), a.querySelectorAll("[name=d]").length && q.push("name" + L + "*[*^$|!~]?="), a.querySelectorAll(":enabled").length || q.push(":enabled", ":disabled"), a.querySelectorAll("*,:x"), q.push(",.*:")
+ })), (c.matchesSelector = $.test(s = o.matches || o.webkitMatchesSelector || o.mozMatchesSelector || o.oMatchesSelector || o.msMatchesSelector)) && ja(function (a) {
+ c.disconnectedMatch = s.call(a, "div"), s.call(a, "[s!='']:x"), r.push("!=", P)
+ }), q = q.length && new RegExp(q.join("|")), r = r.length && new RegExp(r.join("|")), b = $.test(o.compareDocumentPosition), t = b || $.test(o.contains) ? function (a, b) {
+ var c = 9 === a.nodeType ? a.documentElement : a, d = b && b.parentNode;
+ return a === d || !(!d || 1 !== d.nodeType || !(c.contains ? c.contains(d) : a.compareDocumentPosition && 16 & a.compareDocumentPosition(d)))
+ } : function (a, b) {
+ if (b)while (b = b.parentNode)if (b === a)return !0;
+ return !1
+ }, B = b ? function (a, b) {
+ if (a === b)return l = !0, 0;
+ var d = !a.compareDocumentPosition - !b.compareDocumentPosition;
+ return d ? d : (d = (a.ownerDocument || a) === (b.ownerDocument || b) ? a.compareDocumentPosition(b) : 1, 1 & d || !c.sortDetached && b.compareDocumentPosition(a) === d ? a === g || a.ownerDocument === v && t(v, a) ? -1 : b === g || b.ownerDocument === v && t(v, b) ? 1 : k ? J(k, a) - J(k, b) : 0 : 4 & d ? -1 : 1)
+ } : function (a, b) {
+ if (a === b)return l = !0, 0;
+ var c, d = 0, e = a.parentNode, f = b.parentNode, h = [a], i = [b];
+ if (!e || !f)return a === g ? -1 : b === g ? 1 : e ? -1 : f ? 1 : k ? J(k, a) - J(k, b) : 0;
+ if (e === f)return la(a, b);
+ c = a;
+ while (c = c.parentNode)h.unshift(c);
+ c = b;
+ while (c = c.parentNode)i.unshift(c);
+ while (h[d] === i[d])d++;
+ return d ? la(h[d], i[d]) : h[d] === v ? -1 : i[d] === v ? 1 : 0
+ }, g) : n
+ }, ga.matches = function (a, b) {
+ return ga(a, null, null, b)
+ }, ga.matchesSelector = function (a, b) {
+ if ((a.ownerDocument || a) !== n && m(a), b = b.replace(U, "='$1']"), !(!c.matchesSelector || !p || r && r.test(b) || q && q.test(b)))try {
+ var d = s.call(a, b);
+ if (d || c.disconnectedMatch || a.document && 11 !== a.document.nodeType)return d
+ } catch (e) {
+ }
+ return ga(b, n, null, [a]).length > 0
+ }, ga.contains = function (a, b) {
+ return (a.ownerDocument || a) !== n && m(a), t(a, b)
+ }, ga.attr = function (a, b) {
+ (a.ownerDocument || a) !== n && m(a);
+ var e = d.attrHandle[b.toLowerCase()], f = e && D.call(d.attrHandle, b.toLowerCase()) ? e(a, b, !p) : void 0;
+ return void 0 !== f ? f : c.attributes || !p ? a.getAttribute(b) : (f = a.getAttributeNode(b)) && f.specified ? f.value : null
+ }, ga.error = function (a) {
+ throw new Error("Syntax error, unrecognized expression: " + a)
+ }, ga.uniqueSort = function (a) {
+ var b, d = [], e = 0, f = 0;
+ if (l = !c.detectDuplicates, k = !c.sortStable && a.slice(0), a.sort(B), l) {
+ while (b = a[f++])b === a[f] && (e = d.push(f));
+ while (e--)a.splice(d[e], 1)
+ }
+ return k = null, a
+ }, e = ga.getText = function (a) {
+ var b, c = "", d = 0, f = a.nodeType;
+ if (f) {
+ if (1 === f || 9 === f || 11 === f) {
+ if ("string" == typeof a.textContent)return a.textContent;
+ for (a = a.firstChild; a; a = a.nextSibling)c += e(a)
+ } else if (3 === f || 4 === f)return a.nodeValue
+ } else while (b = a[d++])c += e(b);
+ return c
+ }, d = ga.selectors = {
+ cacheLength: 50,
+ createPseudo: ia,
+ match: X,
+ attrHandle: {},
+ find: {},
+ relative: {">": {dir: "parentNode", first: !0}, " ": {dir: "parentNode"}, "+": {dir: "previousSibling", first: !0}, "~": {dir: "previousSibling"}},
+ preFilter: {
+ ATTR: function (a) {
+ return a[1] = a[1].replace(ca, da), a[3] = (a[3] || a[4] || a[5] || "").replace(ca, da), "~=" === a[2] && (a[3] = " " + a[3] + " "), a.slice(0, 4)
+ }, CHILD: function (a) {
+ return a[1] = a[1].toLowerCase(), "nth" === a[1].slice(0, 3) ? (a[3] || ga.error(a[0]), a[4] = +(a[4] ? a[5] + (a[6] || 1) : 2 * ("even" === a[3] || "odd" === a[3])), a[5] = +(a[7] + a[8] || "odd" === a[3])) : a[3] && ga.error(a[0]), a
+ }, PSEUDO: function (a) {
+ var b, c = !a[6] && a[2];
+ return X.CHILD.test(a[0]) ? null : (a[3] ? a[2] = a[4] || a[5] || "" : c && V.test(c) && (b = g(c, !0)) && (b = c.indexOf(")", c.length - b) - c.length) && (a[0] = a[0].slice(0, b), a[2] = c.slice(0, b)), a.slice(0, 3))
+ }
+ },
+ filter: {
+ TAG: function (a) {
+ var b = a.replace(ca, da).toLowerCase();
+ return "*" === a ? function () {
+ return !0
+ } : function (a) {
+ return a.nodeName && a.nodeName.toLowerCase() === b
+ }
+ }, CLASS: function (a) {
+ var b = y[a + " "];
+ return b || (b = new RegExp("(^|" + L + ")" + a + "(" + L + "|$)")) && y(a, function (a) {
+ return b.test("string" == typeof a.className && a.className || "undefined" != typeof a.getAttribute && a.getAttribute("class") || "")
+ })
+ }, ATTR: function (a, b, c) {
+ return function (d) {
+ var e = ga.attr(d, a);
+ return null == e ? "!=" === b : b ? (e += "", "=" === b ? e === c : "!=" === b ? e !== c : "^=" === b ? c && 0 === e.indexOf(c) : "*=" === b ? c && e.indexOf(c) > -1 : "$=" === b ? c && e.slice(-c.length) === c : "~=" === b ? (" " + e.replace(Q, " ") + " ").indexOf(c) > -1 : "|=" === b ? e === c || e.slice(0, c.length + 1) === c + "-" : !1) : !0
+ }
+ }, CHILD: function (a, b, c, d, e) {
+ var f = "nth" !== a.slice(0, 3), g = "last" !== a.slice(-4), h = "of-type" === b;
+ return 1 === d && 0 === e ? function (a) {
+ return !!a.parentNode
+ } : function (b, c, i) {
+ var j, k, l, m, n, o, p = f !== g ? "nextSibling" : "previousSibling", q = b.parentNode, r = h && b.nodeName.toLowerCase(), s = !i && !h;
+ if (q) {
+ if (f) {
+ while (p) {
+ l = b;
+ while (l = l[p])if (h ? l.nodeName.toLowerCase() === r : 1 === l.nodeType)return !1;
+ o = p = "only" === a && !o && "nextSibling"
+ }
+ return !0
+ }
+ if (o = [g ? q.firstChild : q.lastChild], g && s) {
+ k = q[u] || (q[u] = {}), j = k[a] || [], n = j[0] === w && j[1], m = j[0] === w && j[2], l = n && q.childNodes[n];
+ while (l = ++n && l && l[p] || (m = n = 0) || o.pop())if (1 === l.nodeType && ++m && l === b) {
+ k[a] = [w, n, m];
+ break
+ }
+ } else if (s && (j = (b[u] || (b[u] = {}))[a]) && j[0] === w)m = j[1]; else while (l = ++n && l && l[p] || (m = n = 0) || o.pop())if ((h ? l.nodeName.toLowerCase() === r : 1 === l.nodeType) && ++m && (s && ((l[u] || (l[u] = {}))[a] = [w, m]), l === b))break;
+ return m -= e, m === d || m % d === 0 && m / d >= 0
+ }
+ }
+ }, PSEUDO: function (a, b) {
+ var c, e = d.pseudos[a] || d.setFilters[a.toLowerCase()] || ga.error("unsupported pseudo: " + a);
+ return e[u] ? e(b) : e.length > 1 ? (c = [a, a, "", b], d.setFilters.hasOwnProperty(a.toLowerCase()) ? ia(function (a, c) {
+ var d, f = e(a, b), g = f.length;
+ while (g--)d = J(a, f[g]), a[d] = !(c[d] = f[g])
+ }) : function (a) {
+ return e(a, 0, c)
+ }) : e
+ }
+ },
+ pseudos: {
+ not: ia(function (a) {
+ var b = [], c = [], d = h(a.replace(R, "$1"));
+ return d[u] ? ia(function (a, b, c, e) {
+ var f, g = d(a, null, e, []), h = a.length;
+ while (h--)(f = g[h]) && (a[h] = !(b[h] = f))
+ }) : function (a, e, f) {
+ return b[0] = a, d(b, null, f, c), b[0] = null, !c.pop()
+ }
+ }), has: ia(function (a) {
+ return function (b) {
+ return ga(a, b).length > 0
+ }
+ }), contains: ia(function (a) {
+ return a = a.replace(ca, da), function (b) {
+ return (b.textContent || b.innerText || e(b)).indexOf(a) > -1
+ }
+ }), lang: ia(function (a) {
+ return W.test(a || "") || ga.error("unsupported lang: " + a), a = a.replace(ca, da).toLowerCase(), function (b) {
+ var c;
+ do if (c = p ? b.lang : b.getAttribute("xml:lang") || b.getAttribute("lang"))return c = c.toLowerCase(), c === a || 0 === c.indexOf(a + "-"); while ((b = b.parentNode) && 1 === b.nodeType);
+ return !1
+ }
+ }), target: function (b) {
+ var c = a.location && a.location.hash;
+ return c && c.slice(1) === b.id
+ }, root: function (a) {
+ return a === o
+ }, focus: function (a) {
+ return a === n.activeElement && (!n.hasFocus || n.hasFocus()) && !!(a.type || a.href || ~a.tabIndex)
+ }, enabled: function (a) {
+ return a.disabled === !1
+ }, disabled: function (a) {
+ return a.disabled === !0
+ }, checked: function (a) {
+ var b = a.nodeName.toLowerCase();
+ return "input" === b && !!a.checked || "option" === b && !!a.selected
+ }, selected: function (a) {
+ return a.parentNode && a.parentNode.selectedIndex, a.selected === !0
+ }, empty: function (a) {
+ for (a = a.firstChild; a; a = a.nextSibling)if (a.nodeType < 6)return !1;
+ return !0
+ }, parent: function (a) {
+ return !d.pseudos.empty(a)
+ }, header: function (a) {
+ return Z.test(a.nodeName)
+ }, input: function (a) {
+ return Y.test(a.nodeName)
+ }, button: function (a) {
+ var b = a.nodeName.toLowerCase();
+ return "input" === b && "button" === a.type || "button" === b
+ }, text: function (a) {
+ var b;
+ return "input" === a.nodeName.toLowerCase() && "text" === a.type && (null == (b = a.getAttribute("type")) || "text" === b.toLowerCase())
+ }, first: oa(function () {
+ return [0]
+ }), last: oa(function (a, b) {
+ return [b - 1]
+ }), eq: oa(function (a, b, c) {
+ return [0 > c ? c + b : c]
+ }), even: oa(function (a, b) {
+ for (var c = 0; b > c; c += 2)a.push(c);
+ return a
+ }), odd: oa(function (a, b) {
+ for (var c = 1; b > c; c += 2)a.push(c);
+ return a
+ }), lt: oa(function (a, b, c) {
+ for (var d = 0 > c ? c + b : c; --d >= 0;)a.push(d);
+ return a
+ }), gt: oa(function (a, b, c) {
+ for (var d = 0 > c ? c + b : c; ++d < b;)a.push(d);
+ return a
+ })
+ }
+ }, d.pseudos.nth = d.pseudos.eq;
+ for (b in{radio: !0, checkbox: !0, file: !0, password: !0, image: !0})d.pseudos[b] = ma(b);
+ for (b in{submit: !0, reset: !0})d.pseudos[b] = na(b);
+ function qa() {
+ }
+
+ qa.prototype = d.filters = d.pseudos, d.setFilters = new qa, g = ga.tokenize = function (a, b) {
+ var c, e, f, g, h, i, j, k = z[a + " "];
+ if (k)return b ? 0 : k.slice(0);
+ h = a, i = [], j = d.preFilter;
+ while (h) {
+ (!c || (e = S.exec(h))) && (e && (h = h.slice(e[0].length) || h), i.push(f = [])), c = !1, (e = T.exec(h)) && (c = e.shift(), f.push({
+ value: c,
+ type: e[0].replace(R, " ")
+ }), h = h.slice(c.length));
+ for (g in d.filter)!(e = X[g].exec(h)) || j[g] && !(e = j[g](e)) || (c = e.shift(), f.push({value: c, type: g, matches: e}), h = h.slice(c.length));
+ if (!c)break
+ }
+ return b ? h.length : h ? ga.error(a) : z(a, i).slice(0)
+ };
+ function ra(a) {
+ for (var b = 0, c = a.length, d = ""; c > b; b++)d += a[b].value;
+ return d
+ }
+
+ function sa(a, b, c) {
+ var d = b.dir, e = c && "parentNode" === d, f = x++;
+ return b.first ? function (b, c, f) {
+ while (b = b[d])if (1 === b.nodeType || e)return a(b, c, f)
+ } : function (b, c, g) {
+ var h, i, j = [w, f];
+ if (g) {
+ while (b = b[d])if ((1 === b.nodeType || e) && a(b, c, g))return !0
+ } else while (b = b[d])if (1 === b.nodeType || e) {
+ if (i = b[u] || (b[u] = {}), (h = i[d]) && h[0] === w && h[1] === f)return j[2] = h[2];
+ if (i[d] = j, j[2] = a(b, c, g))return !0
+ }
+ }
+ }
+
+ function ta(a) {
+ return a.length > 1 ? function (b, c, d) {
+ var e = a.length;
+ while (e--)if (!a[e](b, c, d))return !1;
+ return !0
+ } : a[0]
+ }
+
+ function ua(a, b, c) {
+ for (var d = 0, e = b.length; e > d; d++)ga(a, b[d], c);
+ return c
+ }
+
+ function va(a, b, c, d, e) {
+ for (var f, g = [], h = 0, i = a.length, j = null != b; i > h; h++)(f = a[h]) && (!c || c(f, d, e)) && (g.push(f), j && b.push(h));
+ return g
+ }
+
+ function wa(a, b, c, d, e, f) {
+ return d && !d[u] && (d = wa(d)), e && !e[u] && (e = wa(e, f)), ia(function (f, g, h, i) {
+ var j, k, l, m = [], n = [], o = g.length, p = f || ua(b || "*", h.nodeType ? [h] : h, []), q = !a || !f && b ? p : va(p, m, a, h, i), r = c ? e || (f ? a : o || d) ? [] : g : q;
+ if (c && c(q, r, h, i), d) {
+ j = va(r, n), d(j, [], h, i), k = j.length;
+ while (k--)(l = j[k]) && (r[n[k]] = !(q[n[k]] = l))
+ }
+ if (f) {
+ if (e || a) {
+ if (e) {
+ j = [], k = r.length;
+ while (k--)(l = r[k]) && j.push(q[k] = l);
+ e(null, r = [], j, i)
+ }
+ k = r.length;
+ while (k--)(l = r[k]) && (j = e ? J(f, l) : m[k]) > -1 && (f[j] = !(g[j] = l))
+ }
+ } else r = va(r === g ? r.splice(o, r.length) : r), e ? e(null, g, r, i) : H.apply(g, r)
+ })
+ }
+
+ function xa(a) {
+ for (var b, c, e, f = a.length, g = d.relative[a[0].type], h = g || d.relative[" "], i = g ? 1 : 0, k = sa(function (a) {
+ return a === b
+ }, h, !0), l = sa(function (a) {
+ return J(b, a) > -1
+ }, h, !0), m = [function (a, c, d) {
+ var e = !g && (d || c !== j) || ((b = c).nodeType ? k(a, c, d) : l(a, c, d));
+ return b = null, e
+ }]; f > i; i++)if (c = d.relative[a[i].type])m = [sa(ta(m), c)]; else {
+ if (c = d.filter[a[i].type].apply(null, a[i].matches), c[u]) {
+ for (e = ++i; f > e; e++)if (d.relative[a[e].type])break;
+ return wa(i > 1 && ta(m), i > 1 && ra(a.slice(0, i - 1).concat({value: " " === a[i - 2].type ? "*" : ""})).replace(R, "$1"), c, e > i && xa(a.slice(i, e)), f > e && xa(a = a.slice(e)), f > e && ra(a))
+ }
+ m.push(c)
+ }
+ return ta(m)
+ }
+
+ function ya(a, b) {
+ var c = b.length > 0, e = a.length > 0, f = function (f, g, h, i, k) {
+ var l, m, o, p = 0, q = "0", r = f && [], s = [], t = j, u = f || e && d.find.TAG("*", k), v = w += null == t ? 1 : Math.random() || .1, x = u.length;
+ for (k && (j = g !== n && g); q !== x && null != (l = u[q]); q++) {
+ if (e && l) {
+ m = 0;
+ while (o = a[m++])if (o(l, g, h)) {
+ i.push(l);
+ break
+ }
+ k && (w = v)
+ }
+ c && ((l = !o && l) && p--, f && r.push(l))
+ }
+ if (p += q, c && q !== p) {
+ m = 0;
+ while (o = b[m++])o(r, s, g, h);
+ if (f) {
+ if (p > 0)while (q--)r[q] || s[q] || (s[q] = F.call(i));
+ s = va(s)
+ }
+ H.apply(i, s), k && !f && s.length > 0 && p + b.length > 1 && ga.uniqueSort(i)
+ }
+ return k && (w = v, j = t), r
+ };
+ return c ? ia(f) : f
+ }
+
+ return h = ga.compile = function (a, b) {
+ var c, d = [], e = [], f = A[a + " "];
+ if (!f) {
+ b || (b = g(a)), c = b.length;
+ while (c--)f = xa(b[c]), f[u] ? d.push(f) : e.push(f);
+ f = A(a, ya(e, d)), f.selector = a
+ }
+ return f
+ }, i = ga.select = function (a, b, e, f) {
+ var i, j, k, l, m, n = "function" == typeof a && a, o = !f && g(a = n.selector || a);
+ if (e = e || [], 1 === o.length) {
+ if (j = o[0] = o[0].slice(0), j.length > 2 && "ID" === (k = j[0]).type && c.getById && 9 === b.nodeType && p && d.relative[j[1].type]) {
+ if (b = (d.find.ID(k.matches[0].replace(ca, da), b) || [])[0], !b)return e;
+ n && (b = b.parentNode), a = a.slice(j.shift().value.length)
+ }
+ i = X.needsContext.test(a) ? 0 : j.length;
+ while (i--) {
+ if (k = j[i], d.relative[l = k.type])break;
+ if ((m = d.find[l]) && (f = m(k.matches[0].replace(ca, da), aa.test(j[0].type) && pa(b.parentNode) || b))) {
+ if (j.splice(i, 1), a = f.length && ra(j), !a)return H.apply(e, f), e;
+ break
+ }
+ }
+ }
+ return (n || h(a, o))(f, b, !p, e, aa.test(a) && pa(b.parentNode) || b), e
+ }, c.sortStable = u.split("").sort(B).join("") === u, c.detectDuplicates = !!l, m(), c.sortDetached = ja(function (a) {
+ return 1 & a.compareDocumentPosition(n.createElement("div"))
+ }), ja(function (a) {
+ return a.innerHTML = "<a href='#'></a>", "#" === a.firstChild.getAttribute("href")
+ }) || ka("type|href|height|width", function (a, b, c) {
+ return c ? void 0 : a.getAttribute(b, "type" === b.toLowerCase() ? 1 : 2)
+ }), c.attributes && ja(function (a) {
+ return a.innerHTML = "<input/>", a.firstChild.setAttribute("value", ""), "" === a.firstChild.getAttribute("value")
+ }) || ka("value", function (a, b, c) {
+ return c || "input" !== a.nodeName.toLowerCase() ? void 0 : a.defaultValue
+ }), ja(function (a) {
+ return null == a.getAttribute("disabled")
+ }) || ka(K, function (a, b, c) {
+ var d;
+ return c ? void 0 : a[b] === !0 ? b.toLowerCase() : (d = a.getAttributeNode(b)) && d.specified ? d.value : null
+ }), ga
+ }(a);
+ m.find = s, m.expr = s.selectors, m.expr[":"] = m.expr.pseudos, m.unique = s.uniqueSort, m.text = s.getText, m.isXMLDoc = s.isXML, m.contains = s.contains;
+ var t = m.expr.match.needsContext, u = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, v = /^.[^:#\[\.,]*$/;
+
+ function w(a, b, c) {
+ if (m.isFunction(b))return m.grep(a, function (a, d) {
+ return !!b.call(a, d, a) !== c
+ });
+ if (b.nodeType)return m.grep(a, function (a) {
+ return a === b !== c
+ });
+ if ("string" == typeof b) {
+ if (v.test(b))return m.filter(b, a, c);
+ b = m.filter(b, a)
+ }
+ return m.grep(a, function (a) {
+ return m.inArray(a, b) >= 0 !== c
+ })
+ }
+
+ m.filter = function (a, b, c) {
+ var d = b[0];
+ return c && (a = ":not(" + a + ")"), 1 === b.length && 1 === d.nodeType ? m.find.matchesSelector(d, a) ? [d] : [] : m.find.matches(a, m.grep(b, function (a) {
+ return 1 === a.nodeType
+ }))
+ }, m.fn.extend({
+ find: function (a) {
+ var b, c = [], d = this, e = d.length;
+ if ("string" != typeof a)return this.pushStack(m(a).filter(function () {
+ for (b = 0; e > b; b++)if (m.contains(d[b], this))return !0
+ }));
+ for (b = 0; e > b; b++)m.find(a, d[b], c);
+ return c = this.pushStack(e > 1 ? m.unique(c) : c), c.selector = this.selector ? this.selector + " " + a : a, c
+ }, filter: function (a) {
+ return this.pushStack(w(this, a || [], !1))
+ }, not: function (a) {
+ return this.pushStack(w(this, a || [], !0))
+ }, is: function (a) {
+ return !!w(this, "string" == typeof a && t.test(a) ? m(a) : a || [], !1).length
+ }
+ });
+ var x, y = a.document, z = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, A = m.fn.init = function (a, b) {
+ var c, d;
+ if (!a)return this;
+ if ("string" == typeof a) {
+ if (c = "<" === a.charAt(0) && ">" === a.charAt(a.length - 1) && a.length >= 3 ? [null, a, null] : z.exec(a), !c || !c[1] && b)return !b || b.jquery ? (b || x).find(a) : this.constructor(b).find(a);
+ if (c[1]) {
+ if (b = b instanceof m ? b[0] : b, m.merge(this, m.parseHTML(c[1], b && b.nodeType ? b.ownerDocument || b : y, !0)), u.test(c[1]) && m.isPlainObject(b))for (c in b)m.isFunction(this[c]) ? this[c](b[c]) : this.attr(c, b[c]);
+ return this
+ }
+ if (d = y.getElementById(c[2]), d && d.parentNode) {
+ if (d.id !== c[2])return x.find(a);
+ this.length = 1, this[0] = d
+ }
+ return this.context = y, this.selector = a, this
+ }
+ return a.nodeType ? (this.context = this[0] = a, this.length = 1, this) : m.isFunction(a) ? "undefined" != typeof x.ready ? x.ready(a) : a(m) : (void 0 !== a.selector && (this.selector = a.selector, this.context = a.context), m.makeArray(a, this))
+ };
+ A.prototype = m.fn, x = m(y);
+ var B = /^(?:parents|prev(?:Until|All))/, C = {children: !0, contents: !0, next: !0, prev: !0};
+ m.extend({
+ dir: function (a, b, c) {
+ var d = [], e = a[b];
+ while (e && 9 !== e.nodeType && (void 0 === c || 1 !== e.nodeType || !m(e).is(c)))1 === e.nodeType && d.push(e), e = e[b];
+ return d
+ }, sibling: function (a, b) {
+ for (var c = []; a; a = a.nextSibling)1 === a.nodeType && a !== b && c.push(a);
+ return c
+ }
+ }), m.fn.extend({
+ has: function (a) {
+ var b, c = m(a, this), d = c.length;
+ return this.filter(function () {
+ for (b = 0; d > b; b++)if (m.contains(this, c[b]))return !0
+ })
+ }, closest: function (a, b) {
+ for (var c, d = 0, e = this.length, f = [], g = t.test(a) || "string" != typeof a ? m(a, b || this.context) : 0; e > d; d++)for (c = this[d]; c && c !== b; c = c.parentNode)if (c.nodeType < 11 && (g ? g.index(c) > -1 : 1 === c.nodeType && m.find.matchesSelector(c, a))) {
+ f.push(c);
+ break
+ }
+ return this.pushStack(f.length > 1 ? m.unique(f) : f)
+ }, index: function (a) {
+ return a ? "string" == typeof a ? m.inArray(this[0], m(a)) : m.inArray(a.jquery ? a[0] : a, this) : this[0] && this[0].parentNode ? this.first().prevAll().length : -1
+ }, add: function (a, b) {
+ return this.pushStack(m.unique(m.merge(this.get(), m(a, b))))
+ }, addBack: function (a) {
+ return this.add(null == a ? this.prevObject : this.prevObject.filter(a))
+ }
+ });
+ function D(a, b) {
+ do a = a[b]; while (a && 1 !== a.nodeType);
+ return a
+ }
+
+ m.each({
+ parent: function (a) {
+ var b = a.parentNode;
+ return b && 11 !== b.nodeType ? b : null
+ }, parents: function (a) {
+ return m.dir(a, "parentNode")
+ }, parentsUntil: function (a, b, c) {
+ return m.dir(a, "parentNode", c)
+ }, next: function (a) {
+ return D(a, "nextSibling")
+ }, prev: function (a) {
+ return D(a, "previousSibling")
+ }, nextAll: function (a) {
+ return m.dir(a, "nextSibling")
+ }, prevAll: function (a) {
+ return m.dir(a, "previousSibling")
+ }, nextUntil: function (a, b, c) {
+ return m.dir(a, "nextSibling", c)
+ }, prevUntil: function (a, b, c) {
+ return m.dir(a, "previousSibling", c)
+ }, siblings: function (a) {
+ return m.sibling((a.parentNode || {}).firstChild, a)
+ }, children: function (a) {
+ return m.sibling(a.firstChild)
+ }, contents: function (a) {
+ return m.nodeName(a, "iframe") ? a.contentDocument || a.contentWindow.document : m.merge([], a.childNodes)
+ }
+ }, function (a, b) {
+ m.fn[a] = function (c, d) {
+ var e = m.map(this, b, c);
+ return "Until" !== a.slice(-5) && (d = c), d && "string" == typeof d && (e = m.filter(d, e)), this.length > 1 && (C[a] || (e = m.unique(e)), B.test(a) && (e = e.reverse())), this.pushStack(e)
+ }
+ });
+ var E = /\S+/g, F = {};
+
+ function G(a) {
+ var b = F[a] = {};
+ return m.each(a.match(E) || [], function (a, c) {
+ b[c] = !0
+ }), b
+ }
+
+ m.Callbacks = function (a) {
+ a = "string" == typeof a ? F[a] || G(a) : m.extend({}, a);
+ var b, c, d, e, f, g, h = [], i = !a.once && [], j = function (l) {
+ for (c = a.memory && l, d = !0, f = g || 0, g = 0, e = h.length, b = !0; h && e > f; f++)if (h[f].apply(l[0], l[1]) === !1 && a.stopOnFalse) {
+ c = !1;
+ break
+ }
+ b = !1, h && (i ? i.length && j(i.shift()) : c ? h = [] : k.disable())
+ }, k = {
+ add: function () {
+ if (h) {
+ var d = h.length;
+ !function f(b) {
+ m.each(b, function (b, c) {
+ var d = m.type(c);
+ "function" === d ? a.unique && k.has(c) || h.push(c) : c && c.length && "string" !== d && f(c)
+ })
+ }(arguments), b ? e = h.length : c && (g = d, j(c))
+ }
+ return this
+ }, remove: function () {
+ return h && m.each(arguments, function (a, c) {
+ var d;
+ while ((d = m.inArray(c, h, d)) > -1)h.splice(d, 1), b && (e >= d && e--, f >= d && f--)
+ }), this
+ }, has: function (a) {
+ return a ? m.inArray(a, h) > -1 : !(!h || !h.length)
+ }, empty: function () {
+ return h = [], e = 0, this
+ }, disable: function () {
+ return h = i = c = void 0, this
+ }, disabled: function () {
+ return !h
+ }, lock: function () {
+ return i = void 0, c || k.disable(), this
+ }, locked: function () {
+ return !i
+ }, fireWith: function (a, c) {
+ return !h || d && !i || (c = c || [], c = [a, c.slice ? c.slice() : c], b ? i.push(c) : j(c)), this
+ }, fire: function () {
+ return k.fireWith(this, arguments), this
+ }, fired: function () {
+ return !!d
+ }
+ };
+ return k
+ }, m.extend({
+ Deferred: function (a) {
+ var b = [["resolve", "done", m.Callbacks("once memory"), "resolved"], ["reject", "fail", m.Callbacks("once memory"), "rejected"], ["notify", "progress", m.Callbacks("memory")]], c = "pending", d = {
+ state: function () {
+ return c
+ }, always: function () {
+ return e.done(arguments).fail(arguments), this
+ }, then: function () {
+ var a = arguments;
+ return m.Deferred(function (c) {
+ m.each(b, function (b, f) {
+ var g = m.isFunction(a[b]) && a[b];
+ e[f[1]](function () {
+ var a = g && g.apply(this, arguments);
+ a && m.isFunction(a.promise) ? a.promise().done(c.resolve).fail(c.reject).progress(c.notify) : c[f[0] + "With"](this === d ? c.promise() : this, g ? [a] : arguments)
+ })
+ }), a = null
+ }).promise()
+ }, promise: function (a) {
+ return null != a ? m.extend(a, d) : d
+ }
+ }, e = {};
+ return d.pipe = d.then, m.each(b, function (a, f) {
+ var g = f[2], h = f[3];
+ d[f[1]] = g.add, h && g.add(function () {
+ c = h
+ }, b[1 ^ a][2].disable, b[2][2].lock), e[f[0]] = function () {
+ return e[f[0] + "With"](this === e ? d : this, arguments), this
+ }, e[f[0] + "With"] = g.fireWith
+ }), d.promise(e), a && a.call(e, e), e
+ }, when: function (a) {
+ var b = 0, c = d.call(arguments), e = c.length, f = 1 !== e || a && m.isFunction(a.promise) ? e : 0, g = 1 === f ? a : m.Deferred(), h = function (a, b, c) {
+ return function (e) {
+ b[a] = this, c[a] = arguments.length > 1 ? d.call(arguments) : e, c === i ? g.notifyWith(b, c) : --f || g.resolveWith(b, c)
+ }
+ }, i, j, k;
+ if (e > 1)for (i = new Array(e), j = new Array(e), k = new Array(e); e > b; b++)c[b] && m.isFunction(c[b].promise) ? c[b].promise().done(h(b, k, c)).fail(g.reject).progress(h(b, j, i)) : --f;
+ return f || g.resolveWith(k, c), g.promise()
+ }
+ });
+ var H;
+ m.fn.ready = function (a) {
+ return m.ready.promise().done(a), this
+ }, m.extend({
+ isReady: !1, readyWait: 1, holdReady: function (a) {
+ a ? m.readyWait++ : m.ready(!0)
+ }, ready: function (a) {
+ if (a === !0 ? !--m.readyWait : !m.isReady) {
+ if (!y.body)return setTimeout(m.ready);
+ m.isReady = !0, a !== !0 && --m.readyWait > 0 || (H.resolveWith(y, [m]), m.fn.triggerHandler && (m(y).triggerHandler("ready"), m(y).off("ready")))
+ }
+ }
+ });
+ function I() {
+ y.addEventListener ? (y.removeEventListener("DOMContentLoaded", J, !1), a.removeEventListener("load", J, !1)) : (y.detachEvent("onreadystatechange", J), a.detachEvent("onload", J))
+ }
+
+ function J() {
+ (y.addEventListener || "load" === event.type || "complete" === y.readyState) && (I(), m.ready())
+ }
+
+ m.ready.promise = function (b) {
+ if (!H)if (H = m.Deferred(), "complete" === y.readyState)setTimeout(m.ready); else if (y.addEventListener)y.addEventListener("DOMContentLoaded", J, !1), a.addEventListener("load", J, !1); else {
+ y.attachEvent("onreadystatechange", J), a.attachEvent("onload", J);
+ var c = !1;
+ try {
+ c = null == a.frameElement && y.documentElement
+ } catch (d) {
+ }
+ c && c.doScroll && !function e() {
+ if (!m.isReady) {
+ try {
+ c.doScroll("left")
+ } catch (a) {
+ return setTimeout(e, 50)
+ }
+ I(), m.ready()
+ }
+ }()
+ }
+ return H.promise(b)
+ };
+ var K = "undefined", L;
+ for (L in m(k))break;
+ k.ownLast = "0" !== L, k.inlineBlockNeedsLayout = !1, m(function () {
+ var a, b, c, d;
+ c = y.getElementsByTagName("body")[0], c && c.style && (b = y.createElement("div"), d = y.createElement("div"), d.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px", c.appendChild(d).appendChild(b), typeof b.style.zoom !== K && (b.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1", k.inlineBlockNeedsLayout = a = 3 === b.offsetWidth, a && (c.style.zoom = 1)), c.removeChild(d))
+ }), function () {
+ var a = y.createElement("div");
+ if (null == k.deleteExpando) {
+ k.deleteExpando = !0;
+ try {
+ delete a.test
+ } catch (b) {
+ k.deleteExpando = !1
+ }
+ }
+ a = null
+ }(), m.acceptData = function (a) {
+ var b = m.noData[(a.nodeName + " ").toLowerCase()], c = +a.nodeType || 1;
+ return 1 !== c && 9 !== c ? !1 : !b || b !== !0 && a.getAttribute("classid") === b
+ };
+ var M = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, N = /([A-Z])/g;
+
+ function O(a, b, c) {
+ if (void 0 === c && 1 === a.nodeType) {
+ var d = "data-" + b.replace(N, "-$1").toLowerCase();
+ if (c = a.getAttribute(d), "string" == typeof c) {
+ try {
+ c = "true" === c ? !0 : "false" === c ? !1 : "null" === c ? null : +c + "" === c ? +c : M.test(c) ? m.parseJSON(c) : c
+ } catch (e) {
+ }
+ m.data(a, b, c)
+ } else c = void 0
+ }
+ return c
+ }
+
+ function P(a) {
+ var b;
+ for (b in a)if (("data" !== b || !m.isEmptyObject(a[b])) && "toJSON" !== b)return !1;
+
+ return !0
+ }
+
+ function Q(a, b, d, e) {
+ if (m.acceptData(a)) {
+ var f, g, h = m.expando, i = a.nodeType, j = i ? m.cache : a, k = i ? a[h] : a[h] && h;
+ if (k && j[k] && (e || j[k].data) || void 0 !== d || "string" != typeof b)return k || (k = i ? a[h] = c.pop() || m.guid++ : h), j[k] || (j[k] = i ? {} : {toJSON: m.noop}), ("object" == typeof b || "function" == typeof b) && (e ? j[k] = m.extend(j[k], b) : j[k].data = m.extend(j[k].data, b)), g = j[k], e || (g.data || (g.data = {}), g = g.data), void 0 !== d && (g[m.camelCase(b)] = d), "string" == typeof b ? (f = g[b], null == f && (f = g[m.camelCase(b)])) : f = g, f
+ }
+ }
+
+ function R(a, b, c) {
+ if (m.acceptData(a)) {
+ var d, e, f = a.nodeType, g = f ? m.cache : a, h = f ? a[m.expando] : m.expando;
+ if (g[h]) {
+ if (b && (d = c ? g[h] : g[h].data)) {
+ m.isArray(b) ? b = b.concat(m.map(b, m.camelCase)) : b in d ? b = [b] : (b = m.camelCase(b), b = b in d ? [b] : b.split(" ")), e = b.length;
+ while (e--)delete d[b[e]];
+ if (c ? !P(d) : !m.isEmptyObject(d))return
+ }
+ (c || (delete g[h].data, P(g[h]))) && (f ? m.cleanData([a], !0) : k.deleteExpando || g != g.window ? delete g[h] : g[h] = null)
+ }
+ }
+ }
+
+ m.extend({
+ cache: {}, noData: {"applet ": !0, "embed ": !0, "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"}, hasData: function (a) {
+ return a = a.nodeType ? m.cache[a[m.expando]] : a[m.expando], !!a && !P(a)
+ }, data: function (a, b, c) {
+ return Q(a, b, c)
+ }, removeData: function (a, b) {
+ return R(a, b)
+ }, _data: function (a, b, c) {
+ return Q(a, b, c, !0)
+ }, _removeData: function (a, b) {
+ return R(a, b, !0)
+ }
+ }), m.fn.extend({
+ data: function (a, b) {
+ var c, d, e, f = this[0], g = f && f.attributes;
+ if (void 0 === a) {
+ if (this.length && (e = m.data(f), 1 === f.nodeType && !m._data(f, "parsedAttrs"))) {
+ c = g.length;
+ while (c--)g[c] && (d = g[c].name, 0 === d.indexOf("data-") && (d = m.camelCase(d.slice(5)), O(f, d, e[d])));
+ m._data(f, "parsedAttrs", !0)
+ }
+ return e
+ }
+ return "object" == typeof a ? this.each(function () {
+ m.data(this, a)
+ }) : arguments.length > 1 ? this.each(function () {
+ m.data(this, a, b)
+ }) : f ? O(f, a, m.data(f, a)) : void 0
+ }, removeData: function (a) {
+ return this.each(function () {
+ m.removeData(this, a)
+ })
+ }
+ }), m.extend({
+ queue: function (a, b, c) {
+ var d;
+ return a ? (b = (b || "fx") + "queue", d = m._data(a, b), c && (!d || m.isArray(c) ? d = m._data(a, b, m.makeArray(c)) : d.push(c)), d || []) : void 0
+ }, dequeue: function (a, b) {
+ b = b || "fx";
+ var c = m.queue(a, b), d = c.length, e = c.shift(), f = m._queueHooks(a, b), g = function () {
+ m.dequeue(a, b)
+ };
+ "inprogress" === e && (e = c.shift(), d--), e && ("fx" === b && c.unshift("inprogress"), delete f.stop, e.call(a, g, f)), !d && f && f.empty.fire()
+ }, _queueHooks: function (a, b) {
+ var c = b + "queueHooks";
+ return m._data(a, c) || m._data(a, c, {
+ empty: m.Callbacks("once memory").add(function () {
+ m._removeData(a, b + "queue"), m._removeData(a, c)
+ })
+ })
+ }
+ }), m.fn.extend({
+ queue: function (a, b) {
+ var c = 2;
+ return "string" != typeof a && (b = a, a = "fx", c--), arguments.length < c ? m.queue(this[0], a) : void 0 === b ? this : this.each(function () {
+ var c = m.queue(this, a, b);
+ m._queueHooks(this, a), "fx" === a && "inprogress" !== c[0] && m.dequeue(this, a)
+ })
+ }, dequeue: function (a) {
+ return this.each(function () {
+ m.dequeue(this, a)
+ })
+ }, clearQueue: function (a) {
+ return this.queue(a || "fx", [])
+ }, promise: function (a, b) {
+ var c, d = 1, e = m.Deferred(), f = this, g = this.length, h = function () {
+ --d || e.resolveWith(f, [f])
+ };
+ "string" != typeof a && (b = a, a = void 0), a = a || "fx";
+ while (g--)c = m._data(f[g], a + "queueHooks"), c && c.empty && (d++, c.empty.add(h));
+ return h(), e.promise(b)
+ }
+ });
+ var S = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source, T = ["Top", "Right", "Bottom", "Left"], U = function (a, b) {
+ return a = b || a, "none" === m.css(a, "display") || !m.contains(a.ownerDocument, a)
+ }, V = m.access = function (a, b, c, d, e, f, g) {
+ var h = 0, i = a.length, j = null == c;
+ if ("object" === m.type(c)) {
+ e = !0;
+ for (h in c)m.access(a, b, h, c[h], !0, f, g)
+ } else if (void 0 !== d && (e = !0, m.isFunction(d) || (g = !0), j && (g ? (b.call(a, d), b = null) : (j = b, b = function (a, b, c) {
+ return j.call(m(a), c)
+ })), b))for (; i > h; h++)b(a[h], c, g ? d : d.call(a[h], h, b(a[h], c)));
+ return e ? a : j ? b.call(a) : i ? b(a[0], c) : f
+ }, W = /^(?:checkbox|radio)$/i;
+ !function () {
+ var a = y.createElement("input"), b = y.createElement("div"), c = y.createDocumentFragment();
+ if (b.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>", k.leadingWhitespace = 3 === b.firstChild.nodeType, k.tbody = !b.getElementsByTagName("tbody").length, k.htmlSerialize = !!b.getElementsByTagName("link").length, k.html5Clone = "<:nav></:nav>" !== y.createElement("nav").cloneNode(!0).outerHTML, a.type = "checkbox", a.checked = !0, c.appendChild(a), k.appendChecked = a.checked, b.innerHTML = "<textarea>x</textarea>", k.noCloneChecked = !!b.cloneNode(!0).lastChild.defaultValue, c.appendChild(b), b.innerHTML = "<input type='radio' checked='checked' name='t'/>", k.checkClone = b.cloneNode(!0).cloneNode(!0).lastChild.checked, k.noCloneEvent = !0, b.attachEvent && (b.attachEvent("onclick", function () {
+ k.noCloneEvent = !1
+ }), b.cloneNode(!0).click()), null == k.deleteExpando) {
+ k.deleteExpando = !0;
+ try {
+ delete b.test
+ } catch (d) {
+ k.deleteExpando = !1
+ }
+ }
+ }(), function () {
+ var b, c, d = y.createElement("div");
+ for (b in{submit: !0, change: !0, focusin: !0})c = "on" + b, (k[b + "Bubbles"] = c in a) || (d.setAttribute(c, "t"), k[b + "Bubbles"] = d.attributes[c].expando === !1);
+ d = null
+ }();
+ var X = /^(?:input|select|textarea)$/i, Y = /^key/, Z = /^(?:mouse|pointer|contextmenu)|click/, $ = /^(?:focusinfocus|focusoutblur)$/, _ = /^([^.]*)(?:\.(.+)|)$/;
+
+ function aa() {
+ return !0
+ }
+
+ function ba() {
+ return !1
+ }
+
+ function ca() {
+ try {
+ return y.activeElement
+ } catch (a) {
+ }
+ }
+
+ m.event = {
+ global: {},
+ add: function (a, b, c, d, e) {
+ var f, g, h, i, j, k, l, n, o, p, q, r = m._data(a);
+ if (r) {
+ c.handler && (i = c, c = i.handler, e = i.selector), c.guid || (c.guid = m.guid++), (g = r.events) || (g = r.events = {}), (k = r.handle) || (k = r.handle = function (a) {
+ return typeof m === K || a && m.event.triggered === a.type ? void 0 : m.event.dispatch.apply(k.elem, arguments)
+ }, k.elem = a), b = (b || "").match(E) || [""], h = b.length;
+ while (h--)f = _.exec(b[h]) || [], o = q = f[1], p = (f[2] || "").split(".").sort(), o && (j = m.event.special[o] || {}, o = (e ? j.delegateType : j.bindType) || o, j = m.event.special[o] || {}, l = m.extend({
+ type: o,
+ origType: q,
+ data: d,
+ handler: c,
+ guid: c.guid,
+ selector: e,
+ needsContext: e && m.expr.match.needsContext.test(e),
+ namespace: p.join(".")
+ }, i), (n = g[o]) || (n = g[o] = [], n.delegateCount = 0, j.setup && j.setup.call(a, d, p, k) !== !1 || (a.addEventListener ? a.addEventListener(o, k, !1) : a.attachEvent && a.attachEvent("on" + o, k))), j.add && (j.add.call(a, l), l.handler.guid || (l.handler.guid = c.guid)), e ? n.splice(n.delegateCount++, 0, l) : n.push(l), m.event.global[o] = !0);
+ a = null
+ }
+ },
+ remove: function (a, b, c, d, e) {
+ var f, g, h, i, j, k, l, n, o, p, q, r = m.hasData(a) && m._data(a);
+ if (r && (k = r.events)) {
+ b = (b || "").match(E) || [""], j = b.length;
+ while (j--)if (h = _.exec(b[j]) || [], o = q = h[1], p = (h[2] || "").split(".").sort(), o) {
+ l = m.event.special[o] || {}, o = (d ? l.delegateType : l.bindType) || o, n = k[o] || [], h = h[2] && new RegExp("(^|\\.)" + p.join("\\.(?:.*\\.|)") + "(\\.|$)"), i = f = n.length;
+ while (f--)g = n[f], !e && q !== g.origType || c && c.guid !== g.guid || h && !h.test(g.namespace) || d && d !== g.selector && ("**" !== d || !g.selector) || (n.splice(f, 1), g.selector && n.delegateCount--, l.remove && l.remove.call(a, g));
+ i && !n.length && (l.teardown && l.teardown.call(a, p, r.handle) !== !1 || m.removeEvent(a, o, r.handle), delete k[o])
+ } else for (o in k)m.event.remove(a, o + b[j], c, d, !0);
+ m.isEmptyObject(k) && (delete r.handle, m._removeData(a, "events"))
+ }
+ },
+ trigger: function (b, c, d, e) {
+ var f, g, h, i, k, l, n, o = [d || y], p = j.call(b, "type") ? b.type : b, q = j.call(b, "namespace") ? b.namespace.split(".") : [];
+ if (h = l = d = d || y, 3 !== d.nodeType && 8 !== d.nodeType && !$.test(p + m.event.triggered) && (p.indexOf(".") >= 0 && (q = p.split("."), p = q.shift(), q.sort()), g = p.indexOf(":") < 0 && "on" + p, b = b[m.expando] ? b : new m.Event(p, "object" == typeof b && b), b.isTrigger = e ? 2 : 3, b.namespace = q.join("."), b.namespace_re = b.namespace ? new RegExp("(^|\\.)" + q.join("\\.(?:.*\\.|)") + "(\\.|$)") : null, b.result = void 0, b.target || (b.target = d), c = null == c ? [b] : m.makeArray(c, [b]), k = m.event.special[p] || {}, e || !k.trigger || k.trigger.apply(d, c) !== !1)) {
+ if (!e && !k.noBubble && !m.isWindow(d)) {
+ for (i = k.delegateType || p, $.test(i + p) || (h = h.parentNode); h; h = h.parentNode)o.push(h), l = h;
+ l === (d.ownerDocument || y) && o.push(l.defaultView || l.parentWindow || a)
+ }
+ n = 0;
+ while ((h = o[n++]) && !b.isPropagationStopped())b.type = n > 1 ? i : k.bindType || p, f = (m._data(h, "events") || {})[b.type] && m._data(h, "handle"), f && f.apply(h, c), f = g && h[g], f && f.apply && m.acceptData(h) && (b.result = f.apply(h, c), b.result === !1 && b.preventDefault());
+ if (b.type = p, !e && !b.isDefaultPrevented() && (!k._default || k._default.apply(o.pop(), c) === !1) && m.acceptData(d) && g && d[p] && !m.isWindow(d)) {
+ l = d[g], l && (d[g] = null), m.event.triggered = p;
+ try {
+ d[p]()
+ } catch (r) {
+ }
+ m.event.triggered = void 0, l && (d[g] = l)
+ }
+ return b.result
+ }
+ },
+ dispatch: function (a) {
+ a = m.event.fix(a);
+ var b, c, e, f, g, h = [], i = d.call(arguments), j = (m._data(this, "events") || {})[a.type] || [], k = m.event.special[a.type] || {};
+ if (i[0] = a, a.delegateTarget = this, !k.preDispatch || k.preDispatch.call(this, a) !== !1) {
+ h = m.event.handlers.call(this, a, j), b = 0;
+ while ((f = h[b++]) && !a.isPropagationStopped()) {
+ a.currentTarget = f.elem, g = 0;
+ while ((e = f.handlers[g++]) && !a.isImmediatePropagationStopped())(!a.namespace_re || a.namespace_re.test(e.namespace)) && (a.handleObj = e, a.data = e.data, c = ((m.event.special[e.origType] || {}).handle || e.handler).apply(f.elem, i), void 0 !== c && (a.result = c) === !1 && (a.preventDefault(), a.stopPropagation()))
+ }
+ return k.postDispatch && k.postDispatch.call(this, a), a.result
+ }
+ },
+ handlers: function (a, b) {
+ var c, d, e, f, g = [], h = b.delegateCount, i = a.target;
+ if (h && i.nodeType && (!a.button || "click" !== a.type))for (; i != this; i = i.parentNode || this)if (1 === i.nodeType && (i.disabled !== !0 || "click" !== a.type)) {
+ for (e = [], f = 0; h > f; f++)d = b[f], c = d.selector + " ", void 0 === e[c] && (e[c] = d.needsContext ? m(c, this).index(i) >= 0 : m.find(c, this, null, [i]).length), e[c] && e.push(d);
+ e.length && g.push({elem: i, handlers: e})
+ }
+ return h < b.length && g.push({elem: this, handlers: b.slice(h)}), g
+ },
+ fix: function (a) {
+ if (a[m.expando])return a;
+ var b, c, d, e = a.type, f = a, g = this.fixHooks[e];
+ g || (this.fixHooks[e] = g = Z.test(e) ? this.mouseHooks : Y.test(e) ? this.keyHooks : {}), d = g.props ? this.props.concat(g.props) : this.props, a = new m.Event(f), b = d.length;
+ while (b--)c = d[b], a[c] = f[c];
+ return a.target || (a.target = f.srcElement || y), 3 === a.target.nodeType && (a.target = a.target.parentNode), a.metaKey = !!a.metaKey, g.filter ? g.filter(a, f) : a
+ },
+ props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
+ fixHooks: {},
+ keyHooks: {
+ props: "char charCode key keyCode".split(" "), filter: function (a, b) {
+ return null == a.which && (a.which = null != b.charCode ? b.charCode : b.keyCode), a
+ }
+ },
+ mouseHooks: {
+ props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), filter: function (a, b) {
+ var c, d, e, f = b.button, g = b.fromElement;
+ return null == a.pageX && null != b.clientX && (d = a.target.ownerDocument || y, e = d.documentElement, c = d.body, a.pageX = b.clientX + (e && e.scrollLeft || c && c.scrollLeft || 0) - (e && e.clientLeft || c && c.clientLeft || 0), a.pageY = b.clientY + (e && e.scrollTop || c && c.scrollTop || 0) - (e && e.clientTop || c && c.clientTop || 0)), !a.relatedTarget && g && (a.relatedTarget = g === a.target ? b.toElement : g), a.which || void 0 === f || (a.which = 1 & f ? 1 : 2 & f ? 3 : 4 & f ? 2 : 0), a
+ }
+ },
+ special: {
+ load: {noBubble: !0}, focus: {
+ trigger: function () {
+ if (this !== ca() && this.focus)try {
+ return this.focus(), !1
+ } catch (a) {
+ }
+ }, delegateType: "focusin"
+ }, blur: {
+ trigger: function () {
+ return this === ca() && this.blur ? (this.blur(), !1) : void 0
+ }, delegateType: "focusout"
+ }, click: {
+ trigger: function () {
+ return m.nodeName(this, "input") && "checkbox" === this.type && this.click ? (this.click(), !1) : void 0
+ }, _default: function (a) {
+ return m.nodeName(a.target, "a")
+ }
+ }, beforeunload: {
+ postDispatch: function (a) {
+ void 0 !== a.result && a.originalEvent && (a.originalEvent.returnValue = a.result)
+ }
+ }
+ },
+ simulate: function (a, b, c, d) {
+ var e = m.extend(new m.Event, c, {type: a, isSimulated: !0, originalEvent: {}});
+ d ? m.event.trigger(e, null, b) : m.event.dispatch.call(b, e), e.isDefaultPrevented() && c.preventDefault()
+ }
+ }, m.removeEvent = y.removeEventListener ? function (a, b, c) {
+ a.removeEventListener && a.removeEventListener(b, c, !1)
+ } : function (a, b, c) {
+ var d = "on" + b;
+ a.detachEvent && (typeof a[d] === K && (a[d] = null), a.detachEvent(d, c))
+ }, m.Event = function (a, b) {
+ return this instanceof m.Event ? (a && a.type ? (this.originalEvent = a, this.type = a.type, this.isDefaultPrevented = a.defaultPrevented || void 0 === a.defaultPrevented && a.returnValue === !1 ? aa : ba) : this.type = a, b && m.extend(this, b), this.timeStamp = a && a.timeStamp || m.now(), void(this[m.expando] = !0)) : new m.Event(a, b)
+ }, m.Event.prototype = {
+ isDefaultPrevented: ba, isPropagationStopped: ba, isImmediatePropagationStopped: ba, preventDefault: function () {
+ var a = this.originalEvent;
+ this.isDefaultPrevented = aa, a && (a.preventDefault ? a.preventDefault() : a.returnValue = !1)
+ }, stopPropagation: function () {
+ var a = this.originalEvent;
+ this.isPropagationStopped = aa, a && (a.stopPropagation && a.stopPropagation(), a.cancelBubble = !0)
+ }, stopImmediatePropagation: function () {
+ var a = this.originalEvent;
+ this.isImmediatePropagationStopped = aa, a && a.stopImmediatePropagation && a.stopImmediatePropagation(), this.stopPropagation()
+ }
+ }, m.each({mouseenter: "mouseover", mouseleave: "mouseout", pointerenter: "pointerover", pointerleave: "pointerout"}, function (a, b) {
+ m.event.special[a] = {
+ delegateType: b, bindType: b, handle: function (a) {
+ var c, d = this, e = a.relatedTarget, f = a.handleObj;
+ return (!e || e !== d && !m.contains(d, e)) && (a.type = f.origType, c = f.handler.apply(this, arguments), a.type = b), c
+ }
+ }
+ }), k.submitBubbles || (m.event.special.submit = {
+ setup: function () {
+ return m.nodeName(this, "form") ? !1 : void m.event.add(this, "click._submit keypress._submit", function (a) {
+ var b = a.target, c = m.nodeName(b, "input") || m.nodeName(b, "button") ? b.form : void 0;
+ c && !m._data(c, "submitBubbles") && (m.event.add(c, "submit._submit", function (a) {
+ a._submit_bubble = !0
+ }), m._data(c, "submitBubbles", !0))
+ })
+ }, postDispatch: function (a) {
+ a._submit_bubble && (delete a._submit_bubble, this.parentNode && !a.isTrigger && m.event.simulate("submit", this.parentNode, a, !0))
+ }, teardown: function () {
+ return m.nodeName(this, "form") ? !1 : void m.event.remove(this, "._submit")
+ }
+ }), k.changeBubbles || (m.event.special.change = {
+ setup: function () {
+ return X.test(this.nodeName) ? (("checkbox" === this.type || "radio" === this.type) && (m.event.add(this, "propertychange._change", function (a) {
+ "checked" === a.originalEvent.propertyName && (this._just_changed = !0)
+ }), m.event.add(this, "click._change", function (a) {
+ this._just_changed && !a.isTrigger && (this._just_changed = !1), m.event.simulate("change", this, a, !0)
+ })), !1) : void m.event.add(this, "beforeactivate._change", function (a) {
+ var b = a.target;
+ X.test(b.nodeName) && !m._data(b, "changeBubbles") && (m.event.add(b, "change._change", function (a) {
+ !this.parentNode || a.isSimulated || a.isTrigger || m.event.simulate("change", this.parentNode, a, !0)
+ }), m._data(b, "changeBubbles", !0))
+ })
+ }, handle: function (a) {
+ var b = a.target;
+ return this !== b || a.isSimulated || a.isTrigger || "radio" !== b.type && "checkbox" !== b.type ? a.handleObj.handler.apply(this, arguments) : void 0
+ }, teardown: function () {
+ return m.event.remove(this, "._change"), !X.test(this.nodeName)
+ }
+ }), k.focusinBubbles || m.each({focus: "focusin", blur: "focusout"}, function (a, b) {
+ var c = function (a) {
+ m.event.simulate(b, a.target, m.event.fix(a), !0)
+ };
+ m.event.special[b] = {
+ setup: function () {
+ var d = this.ownerDocument || this, e = m._data(d, b);
+ e || d.addEventListener(a, c, !0), m._data(d, b, (e || 0) + 1)
+ }, teardown: function () {
+ var d = this.ownerDocument || this, e = m._data(d, b) - 1;
+ e ? m._data(d, b, e) : (d.removeEventListener(a, c, !0), m._removeData(d, b))
+ }
+ }
+ }), m.fn.extend({
+ on: function (a, b, c, d, e) {
+ var f, g;
+ if ("object" == typeof a) {
+ "string" != typeof b && (c = c || b, b = void 0);
+ for (f in a)this.on(f, b, c, a[f], e);
+ return this
+ }
+ if (null == c && null == d ? (d = b, c = b = void 0) : null == d && ("string" == typeof b ? (d = c, c = void 0) : (d = c, c = b, b = void 0)), d === !1)d = ba; else if (!d)return this;
+ return 1 === e && (g = d, d = function (a) {
+ return m().off(a), g.apply(this, arguments)
+ }, d.guid = g.guid || (g.guid = m.guid++)), this.each(function () {
+ m.event.add(this, a, d, c, b)
+ })
+ }, one: function (a, b, c, d) {
+ return this.on(a, b, c, d, 1)
+ }, off: function (a, b, c) {
+ var d, e;
+ if (a && a.preventDefault && a.handleObj)return d = a.handleObj, m(a.delegateTarget).off(d.namespace ? d.origType + "." + d.namespace : d.origType, d.selector, d.handler), this;
+ if ("object" == typeof a) {
+ for (e in a)this.off(e, b, a[e]);
+ return this
+ }
+ return (b === !1 || "function" == typeof b) && (c = b, b = void 0), c === !1 && (c = ba), this.each(function () {
+ m.event.remove(this, a, c, b)
+ })
+ }, trigger: function (a, b) {
+ return this.each(function () {
+ m.event.trigger(a, b, this)
+ })
+ }, triggerHandler: function (a, b) {
+ var c = this[0];
+ return c ? m.event.trigger(a, b, c, !0) : void 0
+ }
+ });
+ function da(a) {
+ var b = ea.split("|"), c = a.createDocumentFragment();
+ if (c.createElement)while (b.length)c.createElement(b.pop());
+ return c
+ }
+
+ var ea = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", fa = / jQuery\d+="(?:null|\d+)"/g, ga = new RegExp("<(?:" + ea + ")[\\s/>]", "i"), ha = /^\s+/, ia = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, ja = /<([\w:]+)/, ka = /<tbody/i, la = /<|&#?\w+;/, ma = /<(?:script|style|link)/i, na = /checked\s*(?:[^=]|=\s*.checked.)/i, oa = /^$|\/(?:java|ecma)script/i, pa = /^true\/(.*)/, qa = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g, ra = {
+ option: [1, "<select multiple='multiple'>", "</select>"],
+ legend: [1, "<fieldset>", "</fieldset>"],
+ area: [1, "<map>", "</map>"],
+ param: [1, "<object>", "</object>"],
+ thead: [1, "<table>", "</table>"],
+ tr: [2, "<table><tbody>", "</tbody></table>"],
+ col: [2, "<table><tbody></tbody><colgroup>", "</colgroup></table>"],
+ td: [3, "<table><tbody><tr>", "</tr></tbody></table>"],
+ _default: k.htmlSerialize ? [0, "", ""] : [1, "X<div>", "</div>"]
+ }, sa = da(y), ta = sa.appendChild(y.createElement("div"));
+ ra.optgroup = ra.option, ra.tbody = ra.tfoot = ra.colgroup = ra.caption = ra.thead, ra.th = ra.td;
+ function ua(a, b) {
+ var c, d, e = 0, f = typeof a.getElementsByTagName !== K ? a.getElementsByTagName(b || "*") : typeof a.querySelectorAll !== K ? a.querySelectorAll(b || "*") : void 0;
+ if (!f)for (f = [], c = a.childNodes || a; null != (d = c[e]); e++)!b || m.nodeName(d, b) ? f.push(d) : m.merge(f, ua(d, b));
+ return void 0 === b || b && m.nodeName(a, b) ? m.merge([a], f) : f
+ }
+
+ function va(a) {
+ W.test(a.type) && (a.defaultChecked = a.checked)
+ }
+
+ function wa(a, b) {
+ return m.nodeName(a, "table") && m.nodeName(11 !== b.nodeType ? b : b.firstChild, "tr") ? a.getElementsByTagName("tbody")[0] || a.appendChild(a.ownerDocument.createElement("tbody")) : a
+ }
+
+ function xa(a) {
+ return a.type = (null !== m.find.attr(a, "type")) + "/" + a.type, a
+ }
+
+ function ya(a) {
+ var b = pa.exec(a.type);
+ return b ? a.type = b[1] : a.removeAttribute("type"), a
+ }
+
+ function za(a, b) {
+ for (var c, d = 0; null != (c = a[d]); d++)m._data(c, "globalEval", !b || m._data(b[d], "globalEval"))
+ }
+
+ function Aa(a, b) {
+ if (1 === b.nodeType && m.hasData(a)) {
+ var c, d, e, f = m._data(a), g = m._data(b, f), h = f.events;
+ if (h) {
+ delete g.handle, g.events = {};
+ for (c in h)for (d = 0, e = h[c].length; e > d; d++)m.event.add(b, c, h[c][d])
+ }
+ g.data && (g.data = m.extend({}, g.data))
+ }
+ }
+
+ function Ba(a, b) {
+ var c, d, e;
+ if (1 === b.nodeType) {
+ if (c = b.nodeName.toLowerCase(), !k.noCloneEvent && b[m.expando]) {
+ e = m._data(b);
+ for (d in e.events)m.removeEvent(b, d, e.handle);
+ b.removeAttribute(m.expando)
+ }
+ "script" === c && b.text !== a.text ? (xa(b).text = a.text, ya(b)) : "object" === c ? (b.parentNode && (b.outerHTML = a.outerHTML), k.html5Clone && a.innerHTML && !m.trim(b.innerHTML) && (b.innerHTML = a.innerHTML)) : "input" === c && W.test(a.type) ? (b.defaultChecked = b.checked = a.checked, b.value !== a.value && (b.value = a.value)) : "option" === c ? b.defaultSelected = b.selected = a.defaultSelected : ("input" === c || "textarea" === c) && (b.defaultValue = a.defaultValue)
+ }
+ }
+
+ m.extend({
+ clone: function (a, b, c) {
+ var d, e, f, g, h, i = m.contains(a.ownerDocument, a);
+ if (k.html5Clone || m.isXMLDoc(a) || !ga.test("<" + a.nodeName + ">") ? f = a.cloneNode(!0) : (ta.innerHTML = a.outerHTML, ta.removeChild(f = ta.firstChild)), !(k.noCloneEvent && k.noCloneChecked || 1 !== a.nodeType && 11 !== a.nodeType || m.isXMLDoc(a)))for (d = ua(f), h = ua(a), g = 0; null != (e = h[g]); ++g)d[g] && Ba(e, d[g]);
+ if (b)if (c)for (h = h || ua(a), d = d || ua(f), g = 0; null != (e = h[g]); g++)Aa(e, d[g]); else Aa(a, f);
+ return d = ua(f, "script"), d.length > 0 && za(d, !i && ua(a, "script")), d = h = e = null, f
+ }, buildFragment: function (a, b, c, d) {
+ for (var e, f, g, h, i, j, l, n = a.length, o = da(b), p = [], q = 0; n > q; q++)if (f = a[q], f || 0 === f)if ("object" === m.type(f))m.merge(p, f.nodeType ? [f] : f); else if (la.test(f)) {
+ h = h || o.appendChild(b.createElement("div")), i = (ja.exec(f) || ["", ""])[1].toLowerCase(), l = ra[i] || ra._default, h.innerHTML = l[1] + f.replace(ia, "<$1></$2>") + l[2], e = l[0];
+ while (e--)h = h.lastChild;
+ if (!k.leadingWhitespace && ha.test(f) && p.push(b.createTextNode(ha.exec(f)[0])), !k.tbody) {
+ f = "table" !== i || ka.test(f) ? "<table>" !== l[1] || ka.test(f) ? 0 : h : h.firstChild, e = f && f.childNodes.length;
+ while (e--)m.nodeName(j = f.childNodes[e], "tbody") && !j.childNodes.length && f.removeChild(j)
+ }
+ m.merge(p, h.childNodes), h.textContent = "";
+ while (h.firstChild)h.removeChild(h.firstChild);
+ h = o.lastChild
+ } else p.push(b.createTextNode(f));
+ h && o.removeChild(h), k.appendChecked || m.grep(ua(p, "input"), va), q = 0;
+ while (f = p[q++])if ((!d || -1 === m.inArray(f, d)) && (g = m.contains(f.ownerDocument, f), h = ua(o.appendChild(f), "script"), g && za(h), c)) {
+ e = 0;
+ while (f = h[e++])oa.test(f.type || "") && c.push(f)
+ }
+ return h = null, o
+ }, cleanData: function (a, b) {
+ for (var d, e, f, g, h = 0, i = m.expando, j = m.cache, l = k.deleteExpando, n = m.event.special; null != (d = a[h]); h++)if ((b || m.acceptData(d)) && (f = d[i], g = f && j[f])) {
+ if (g.events)for (e in g.events)n[e] ? m.event.remove(d, e) : m.removeEvent(d, e, g.handle);
+ j[f] && (delete j[f], l ? delete d[i] : typeof d.removeAttribute !== K ? d.removeAttribute(i) : d[i] = null, c.push(f))
+ }
+ }
+ }), m.fn.extend({
+ text: function (a) {
+ return V(this, function (a) {
+ return void 0 === a ? m.text(this) : this.empty().append((this[0] && this[0].ownerDocument || y).createTextNode(a))
+ }, null, a, arguments.length)
+ }, append: function () {
+ return this.domManip(arguments, function (a) {
+ if (1 === this.nodeType || 11 === this.nodeType || 9 === this.nodeType) {
+ var b = wa(this, a);
+ b.appendChild(a)
+ }
+ })
+ }, prepend: function () {
+ return this.domManip(arguments, function (a) {
+ if (1 === this.nodeType || 11 === this.nodeType || 9 === this.nodeType) {
+ var b = wa(this, a);
+ b.insertBefore(a, b.firstChild)
+ }
+ })
+ }, before: function () {
+ return this.domManip(arguments, function (a) {
+ this.parentNode && this.parentNode.insertBefore(a, this)
+ })
+ }, after: function () {
+ return this.domManip(arguments, function (a) {
+ this.parentNode && this.parentNode.insertBefore(a, this.nextSibling)
+ })
+ }, remove: function (a, b) {
+ for (var c, d = a ? m.filter(a, this) : this, e = 0; null != (c = d[e]); e++)b || 1 !== c.nodeType || m.cleanData(ua(c)), c.parentNode && (b && m.contains(c.ownerDocument, c) && za(ua(c, "script")), c.parentNode.removeChild(c));
+ return this
+ }, empty: function () {
+ for (var a, b = 0; null != (a = this[b]); b++) {
+ 1 === a.nodeType && m.cleanData(ua(a, !1));
+ while (a.firstChild)a.removeChild(a.firstChild);
+ a.options && m.nodeName(a, "select") && (a.options.length = 0)
+ }
+ return this
+ }, clone: function (a, b) {
+ return a = null == a ? !1 : a, b = null == b ? a : b, this.map(function () {
+ return m.clone(this, a, b)
+ })
+ }, html: function (a) {
+ return V(this, function (a) {
+ var b = this[0] || {}, c = 0, d = this.length;
+ if (void 0 === a)return 1 === b.nodeType ? b.innerHTML.replace(fa, "") : void 0;
+ if (!("string" != typeof a || ma.test(a) || !k.htmlSerialize && ga.test(a) || !k.leadingWhitespace && ha.test(a) || ra[(ja.exec(a) || ["", ""])[1].toLowerCase()])) {
+ a = a.replace(ia, "<$1></$2>");
+ try {
+ for (; d > c; c++)b = this[c] || {}, 1 === b.nodeType && (m.cleanData(ua(b, !1)), b.innerHTML = a);
+ b = 0
+ } catch (e) {
+ }
+ }
+ b && this.empty().append(a)
+ }, null, a, arguments.length)
+ }, replaceWith: function () {
+ var a = arguments[0];
+ return this.domManip(arguments, function (b) {
+ a = this.parentNode, m.cleanData(ua(this)), a && a.replaceChild(b, this)
+ }), a && (a.length || a.nodeType) ? this : this.remove()
+ }, detach: function (a) {
+ return this.remove(a, !0)
+ }, domManip: function (a, b) {
+ a = e.apply([], a);
+ var c, d, f, g, h, i, j = 0, l = this.length, n = this, o = l - 1, p = a[0], q = m.isFunction(p);
+ if (q || l > 1 && "string" == typeof p && !k.checkClone && na.test(p))return this.each(function (c) {
+ var d = n.eq(c);
+ q && (a[0] = p.call(this, c, d.html())), d.domManip(a, b)
+ });
+ if (l && (i = m.buildFragment(a, this[0].ownerDocument, !1, this), c = i.firstChild, 1 === i.childNodes.length && (i = c), c)) {
+ for (g = m.map(ua(i, "script"), xa), f = g.length; l > j; j++)d = i, j !== o && (d = m.clone(d, !0, !0), f && m.merge(g, ua(d, "script"))), b.call(this[j], d, j);
+ if (f)for (h = g[g.length - 1].ownerDocument, m.map(g, ya), j = 0; f > j; j++)d = g[j], oa.test(d.type || "") && !m._data(d, "globalEval") && m.contains(h, d) && (d.src ? m._evalUrl && m._evalUrl(d.src) : m.globalEval((d.text || d.textContent || d.innerHTML || "").replace(qa, "")));
+ i = c = null
+ }
+ return this
+ }
+ }), m.each({appendTo: "append", prependTo: "prepend", insertBefore: "before", insertAfter: "after", replaceAll: "replaceWith"}, function (a, b) {
+ m.fn[a] = function (a) {
+ for (var c, d = 0, e = [], g = m(a), h = g.length - 1; h >= d; d++)c = d === h ? this : this.clone(!0), m(g[d])[b](c), f.apply(e, c.get());
+ return this.pushStack(e)
+ }
+ });
+ var Ca, Da = {};
+
+ function Ea(b, c) {
+ var d, e = m(c.createElement(b)).appendTo(c.body), f = a.getDefaultComputedStyle && (d = a.getDefaultComputedStyle(e[0])) ? d.display : m.css(e[0], "display");
+ return e.detach(), f
+ }
+
+ function Fa(a) {
+ var b = y, c = Da[a];
+ return c || (c = Ea(a, b), "none" !== c && c || (Ca = (Ca || m("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement), b = (Ca[0].contentWindow || Ca[0].contentDocument).document, b.write(), b.close(), c = Ea(a, b), Ca.detach()), Da[a] = c), c
+ }
+
+ !function () {
+ var a;
+ k.shrinkWrapBlocks = function () {
+ if (null != a)return a;
+ a = !1;
+ var b, c, d;
+ return c = y.getElementsByTagName("body")[0], c && c.style ? (b = y.createElement("div"), d = y.createElement("div"), d.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px", c.appendChild(d).appendChild(b), typeof b.style.zoom !== K && (b.style.cssText = "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1", b.appendChild(y.createElement("div")).style.width = "5px", a = 3 !== b.offsetWidth), c.removeChild(d), a) : void 0
+ }
+ }();
+ var Ga = /^margin/, Ha = new RegExp("^(" + S + ")(?!px)[a-z%]+$", "i"), Ia, Ja, Ka = /^(top|right|bottom|left)$/;
+ a.getComputedStyle ? (Ia = function (b) {
+ return b.ownerDocument.defaultView.opener ? b.ownerDocument.defaultView.getComputedStyle(b, null) : a.getComputedStyle(b, null)
+ }, Ja = function (a, b, c) {
+ var d, e, f, g, h = a.style;
+ return c = c || Ia(a), g = c ? c.getPropertyValue(b) || c[b] : void 0, c && ("" !== g || m.contains(a.ownerDocument, a) || (g = m.style(a, b)), Ha.test(g) && Ga.test(b) && (d = h.width, e = h.minWidth, f = h.maxWidth, h.minWidth = h.maxWidth = h.width = g, g = c.width, h.width = d, h.minWidth = e, h.maxWidth = f)), void 0 === g ? g : g + ""
+ }) : y.documentElement.currentStyle && (Ia = function (a) {
+ return a.currentStyle
+ }, Ja = function (a, b, c) {
+ var d, e, f, g, h = a.style;
+ return c = c || Ia(a), g = c ? c[b] : void 0, null == g && h && h[b] && (g = h[b]), Ha.test(g) && !Ka.test(b) && (d = h.left, e = a.runtimeStyle, f = e && e.left, f && (e.left = a.currentStyle.left), h.left = "fontSize" === b ? "1em" : g, g = h.pixelLeft + "px", h.left = d, f && (e.left = f)), void 0 === g ? g : g + "" || "auto"
+ });
+ function La(a, b) {
+ return {
+ get: function () {
+ var c = a();
+ if (null != c)return c ? void delete this.get : (this.get = b).apply(this, arguments)
+ }
+ }
+ }
+
+ !function () {
+ var b, c, d, e, f, g, h;
+ if (b = y.createElement("div"), b.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>", d = b.getElementsByTagName("a")[0], c = d && d.style) {
+ c.cssText = "float:left;opacity:.5", k.opacity = "0.5" === c.opacity, k.cssFloat = !!c.cssFloat, b.style.backgroundClip = "content-box", b.cloneNode(!0).style.backgroundClip = "", k.clearCloneStyle = "content-box" === b.style.backgroundClip, k.boxSizing = "" === c.boxSizing || "" === c.MozBoxSizing || "" === c.WebkitBoxSizing, m.extend(k, {
+ reliableHiddenOffsets: function () {
+ return null == g && i(), g
+ }, boxSizingReliable: function () {
+ return null == f && i(), f
+ }, pixelPosition: function () {
+ return null == e && i(), e
+ }, reliableMarginRight: function () {
+ return null == h && i(), h
+ }
+ });
+ function i() {
+ var b, c, d, i;
+ c = y.getElementsByTagName("body")[0], c && c.style && (b = y.createElement("div"), d = y.createElement("div"), d.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px", c.appendChild(d).appendChild(b), b.style.cssText = "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute", e = f = !1, h = !0, a.getComputedStyle && (e = "1%" !== (a.getComputedStyle(b, null) || {}).top, f = "4px" === (a.getComputedStyle(b, null) || {width: "4px"}).width, i = b.appendChild(y.createElement("div")), i.style.cssText = b.style.cssText = "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0", i.style.marginRight = i.style.width = "0", b.style.width = "1px", h = !parseFloat((a.getComputedStyle(i, null) || {}).marginRight), b.removeChild(i)), b.innerHTML = "<table><tr><td></td><td>t</td></tr></table>", i = b.getElementsByTagName("td"), i[0].style.cssText = "margin:0;border:0;padding:0;display:none", g = 0 === i[0].offsetHeight, g && (i[0].style.display = "", i[1].style.display = "none", g = 0 === i[0].offsetHeight), c.removeChild(d))
+ }
+ }
+ }(), m.swap = function (a, b, c, d) {
+ var e, f, g = {};
+ for (f in b)g[f] = a.style[f], a.style[f] = b[f];
+ e = c.apply(a, d || []);
+ for (f in b)a.style[f] = g[f];
+ return e
+ };
+ var Ma = /alpha\([^)]*\)/i, Na = /opacity\s*=\s*([^)]*)/, Oa = /^(none|table(?!-c[ea]).+)/, Pa = new RegExp("^(" + S + ")(.*)$", "i"), Qa = new RegExp("^([+-])=(" + S + ")", "i"), Ra = {
+ position: "absolute",
+ visibility: "hidden",
+ display: "block"
+ }, Sa = {letterSpacing: "0", fontWeight: "400"}, Ta = ["Webkit", "O", "Moz", "ms"];
+
+ function Ua(a, b) {
+ if (b in a)return b;
+ var c = b.charAt(0).toUpperCase() + b.slice(1), d = b, e = Ta.length;
+ while (e--)if (b = Ta[e] + c, b in a)return b;
+ return d
+ }
+
+ function Va(a, b) {
+ for (var c, d, e, f = [], g = 0, h = a.length; h > g; g++)d = a[g], d.style && (f[g] = m._data(d, "olddisplay"), c = d.style.display, b ? (f[g] || "none" !== c || (d.style.display = ""), "" === d.style.display && U(d) && (f[g] = m._data(d, "olddisplay", Fa(d.nodeName)))) : (e = U(d), (c && "none" !== c || !e) && m._data(d, "olddisplay", e ? c : m.css(d, "display"))));
+ for (g = 0; h > g; g++)d = a[g], d.style && (b && "none" !== d.style.display && "" !== d.style.display || (d.style.display = b ? f[g] || "" : "none"));
+ return a
+ }
+
+ function Wa(a, b, c) {
+ var d = Pa.exec(b);
+ return d ? Math.max(0, d[1] - (c || 0)) + (d[2] || "px") : b
+ }
+
+ function Xa(a, b, c, d, e) {
+ for (var f = c === (d ? "border" : "content") ? 4 : "width" === b ? 1 : 0, g = 0; 4 > f; f += 2)"margin" === c && (g += m.css(a, c + T[f], !0, e)), d ? ("content" === c && (g -= m.css(a, "padding" + T[f], !0, e)), "margin" !== c && (g -= m.css(a, "border" + T[f] + "Width", !0, e))) : (g += m.css(a, "padding" + T[f], !0, e), "padding" !== c && (g += m.css(a, "border" + T[f] + "Width", !0, e)));
+ return g
+ }
+
+ function Ya(a, b, c) {
+ var d = !0, e = "width" === b ? a.offsetWidth : a.offsetHeight, f = Ia(a), g = k.boxSizing && "border-box" === m.css(a, "boxSizing", !1, f);
+ if (0 >= e || null == e) {
+ if (e = Ja(a, b, f), (0 > e || null == e) && (e = a.style[b]), Ha.test(e))return e;
+ d = g && (k.boxSizingReliable() || e === a.style[b]), e = parseFloat(e) || 0
+ }
+ return e + Xa(a, b, c || (g ? "border" : "content"), d, f) + "px"
+ }
+
+ m.extend({
+ cssHooks: {
+ opacity: {
+ get: function (a, b) {
+ if (b) {
+ var c = Ja(a, "opacity");
+ return "" === c ? "1" : c
+ }
+ }
+ }
+ },
+ cssNumber: {
+ columnCount: !0,
+ fillOpacity: !0,
+ flexGrow: !0,
+ flexShrink: !0,
+ fontWeight: !0,
+ lineHeight: !0,
+ opacity: !0,
+ order: !0,
+ orphans: !0,
+ widows: !0,
+ zIndex: !0,
+ zoom: !0
+ },
+ cssProps: {"float": k.cssFloat ? "cssFloat" : "styleFloat"},
+ style: function (a, b, c, d) {
+ if (a && 3 !== a.nodeType && 8 !== a.nodeType && a.style) {
+ var e, f, g, h = m.camelCase(b), i = a.style;
+ if (b = m.cssProps[h] || (m.cssProps[h] = Ua(i, h)), g = m.cssHooks[b] || m.cssHooks[h], void 0 === c)return g && "get" in g && void 0 !== (e = g.get(a, !1, d)) ? e : i[b];
+ if (f = typeof c, "string" === f && (e = Qa.exec(c)) && (c = (e[1] + 1) * e[2] + parseFloat(m.css(a, b)), f = "number"), null != c && c === c && ("number" !== f || m.cssNumber[h] || (c += "px"), k.clearCloneStyle || "" !== c || 0 !== b.indexOf("background") || (i[b] = "inherit"), !(g && "set" in g && void 0 === (c = g.set(a, c, d)))))try {
+ i[b] = c
+ } catch (j) {
+ }
+ }
+ },
+ css: function (a, b, c, d) {
+ var e, f, g, h = m.camelCase(b);
+ return b = m.cssProps[h] || (m.cssProps[h] = Ua(a.style, h)), g = m.cssHooks[b] || m.cssHooks[h], g && "get" in g && (f = g.get(a, !0, c)), void 0 === f && (f = Ja(a, b, d)), "normal" === f && b in Sa && (f = Sa[b]), "" === c || c ? (e = parseFloat(f), c === !0 || m.isNumeric(e) ? e || 0 : f) : f
+ }
+ }), m.each(["height", "width"], function (a, b) {
+ m.cssHooks[b] = {
+ get: function (a, c, d) {
+ return c ? Oa.test(m.css(a, "display")) && 0 === a.offsetWidth ? m.swap(a, Ra, function () {
+ return Ya(a, b, d)
+ }) : Ya(a, b, d) : void 0
+ }, set: function (a, c, d) {
+ var e = d && Ia(a);
+ return Wa(a, c, d ? Xa(a, b, d, k.boxSizing && "border-box" === m.css(a, "boxSizing", !1, e), e) : 0)
+ }
+ }
+ }), k.opacity || (m.cssHooks.opacity = {
+ get: function (a, b) {
+ return Na.test((b && a.currentStyle ? a.currentStyle.filter : a.style.filter) || "") ? .01 * parseFloat(RegExp.$1) + "" : b ? "1" : ""
+ }, set: function (a, b) {
+ var c = a.style, d = a.currentStyle, e = m.isNumeric(b) ? "alpha(opacity=" + 100 * b + ")" : "", f = d && d.filter || c.filter || "";
+ c.zoom = 1, (b >= 1 || "" === b) && "" === m.trim(f.replace(Ma, "")) && c.removeAttribute && (c.removeAttribute("filter"), "" === b || d && !d.filter) || (c.filter = Ma.test(f) ? f.replace(Ma, e) : f + " " + e)
+ }
+ }), m.cssHooks.marginRight = La(k.reliableMarginRight, function (a, b) {
+ return b ? m.swap(a, {display: "inline-block"}, Ja, [a, "marginRight"]) : void 0
+ }), m.each({margin: "", padding: "", border: "Width"}, function (a, b) {
+ m.cssHooks[a + b] = {
+ expand: function (c) {
+ for (var d = 0, e = {}, f = "string" == typeof c ? c.split(" ") : [c]; 4 > d; d++)e[a + T[d] + b] = f[d] || f[d - 2] || f[0];
+ return e
+ }
+ }, Ga.test(a) || (m.cssHooks[a + b].set = Wa)
+ }), m.fn.extend({
+ css: function (a, b) {
+ return V(this, function (a, b, c) {
+ var d, e, f = {}, g = 0;
+ if (m.isArray(b)) {
+ for (d = Ia(a), e = b.length; e > g; g++)f[b[g]] = m.css(a, b[g], !1, d);
+ return f
+ }
+ return void 0 !== c ? m.style(a, b, c) : m.css(a, b)
+ }, a, b, arguments.length > 1)
+ }, show: function () {
+ return Va(this, !0)
+ }, hide: function () {
+ return Va(this)
+ }, toggle: function (a) {
+ return "boolean" == typeof a ? a ? this.show() : this.hide() : this.each(function () {
+ U(this) ? m(this).show() : m(this).hide()
+ })
+ }
+ });
+ function Za(a, b, c, d, e) {
+ return new Za.prototype.init(a, b, c, d, e)
+ }
+
+ m.Tween = Za, Za.prototype = {
+ constructor: Za, init: function (a, b, c, d, e, f) {
+ this.elem = a, this.prop = c, this.easing = e || "swing", this.options = b, this.start = this.now = this.cur(), this.end = d, this.unit = f || (m.cssNumber[c] ? "" : "px")
+ }, cur: function () {
+ var a = Za.propHooks[this.prop];
+ return a && a.get ? a.get(this) : Za.propHooks._default.get(this)
+ }, run: function (a) {
+ var b, c = Za.propHooks[this.prop];
+ return this.options.duration ? this.pos = b = m.easing[this.easing](a, this.options.duration * a, 0, 1, this.options.duration) : this.pos = b = a, this.now = (this.end - this.start) * b + this.start, this.options.step && this.options.step.call(this.elem, this.now, this), c && c.set ? c.set(this) : Za.propHooks._default.set(this), this
+ }
+ }, Za.prototype.init.prototype = Za.prototype, Za.propHooks = {
+ _default: {
+ get: function (a) {
+ var b;
+ return null == a.elem[a.prop] || a.elem.style && null != a.elem.style[a.prop] ? (b = m.css(a.elem, a.prop, ""), b && "auto" !== b ? b : 0) : a.elem[a.prop]
+ }, set: function (a) {
+ m.fx.step[a.prop] ? m.fx.step[a.prop](a) : a.elem.style && (null != a.elem.style[m.cssProps[a.prop]] || m.cssHooks[a.prop]) ? m.style(a.elem, a.prop, a.now + a.unit) : a.elem[a.prop] = a.now
+ }
+ }
+ }, Za.propHooks.scrollTop = Za.propHooks.scrollLeft = {
+ set: function (a) {
+ a.elem.nodeType && a.elem.parentNode && (a.elem[a.prop] = a.now)
+ }
+ }, m.easing = {
+ linear: function (a) {
+ return a
+ }, swing: function (a) {
+ return .5 - Math.cos(a * Math.PI) / 2
+ }
+ }, m.fx = Za.prototype.init, m.fx.step = {};
+ var $a, _a, ab = /^(?:toggle|show|hide)$/, bb = new RegExp("^(?:([+-])=|)(" + S + ")([a-z%]*)$", "i"), cb = /queueHooks$/, db = [ib], eb = {
+ "*": [function (a, b) {
+ var c = this.createTween(a, b), d = c.cur(), e = bb.exec(b), f = e && e[3] || (m.cssNumber[a] ? "" : "px"), g = (m.cssNumber[a] || "px" !== f && +d) && bb.exec(m.css(c.elem, a)), h = 1, i = 20;
+ if (g && g[3] !== f) {
+ f = f || g[3], e = e || [], g = +d || 1;
+ do h = h || ".5", g /= h, m.style(c.elem, a, g + f); while (h !== (h = c.cur() / d) && 1 !== h && --i)
+ }
+ return e && (g = c.start = +g || +d || 0, c.unit = f, c.end = e[1] ? g + (e[1] + 1) * e[2] : +e[2]), c
+ }]
+ };
+
+ function fb() {
+ return setTimeout(function () {
+ $a = void 0
+ }), $a = m.now()
+ }
+
+ function gb(a, b) {
+ var c, d = {height: a}, e = 0;
+ for (b = b ? 1 : 0; 4 > e; e += 2 - b)c = T[e], d["margin" + c] = d["padding" + c] = a;
+ return b && (d.opacity = d.width = a), d
+ }
+
+ function hb(a, b, c) {
+ for (var d, e = (eb[b] || []).concat(eb["*"]), f = 0, g = e.length; g > f; f++)if (d = e[f].call(c, b, a))return d
+ }
+
+ function ib(a, b, c) {
+ var d, e, f, g, h, i, j, l, n = this, o = {}, p = a.style, q = a.nodeType && U(a), r = m._data(a, "fxshow");
+ c.queue || (h = m._queueHooks(a, "fx"), null == h.unqueued && (h.unqueued = 0, i = h.empty.fire, h.empty.fire = function () {
+ h.unqueued || i()
+ }), h.unqueued++, n.always(function () {
+ n.always(function () {
+ h.unqueued--, m.queue(a, "fx").length || h.empty.fire()
+ })
+ })), 1 === a.nodeType && ("height" in b || "width" in b) && (c.overflow = [p.overflow, p.overflowX, p.overflowY], j = m.css(a, "display"), l = "none" === j ? m._data(a, "olddisplay") || Fa(a.nodeName) : j, "inline" === l && "none" === m.css(a, "float") && (k.inlineBlockNeedsLayout && "inline" !== Fa(a.nodeName) ? p.zoom = 1 : p.display = "inline-block")), c.overflow && (p.overflow = "hidden", k.shrinkWrapBlocks() || n.always(function () {
+ p.overflow = c.overflow[0], p.overflowX = c.overflow[1], p.overflowY = c.overflow[2]
+ }));
+ for (d in b)if (e = b[d], ab.exec(e)) {
+ if (delete b[d], f = f || "toggle" === e, e === (q ? "hide" : "show")) {
+ if ("show" !== e || !r || void 0 === r[d])continue;
+ q = !0
+ }
+ o[d] = r && r[d] || m.style(a, d)
+ } else j = void 0;
+ if (m.isEmptyObject(o))"inline" === ("none" === j ? Fa(a.nodeName) : j) && (p.display = j); else {
+ r ? "hidden" in r && (q = r.hidden) : r = m._data(a, "fxshow", {}), f && (r.hidden = !q), q ? m(a).show() : n.done(function () {
+ m(a).hide()
+ }), n.done(function () {
+ var b;
+ m._removeData(a, "fxshow");
+ for (b in o)m.style(a, b, o[b])
+ });
+ for (d in o)g = hb(q ? r[d] : 0, d, n), d in r || (r[d] = g.start, q && (g.end = g.start, g.start = "width" === d || "height" === d ? 1 : 0))
+ }
+ }
+
+ function jb(a, b) {
+ var c, d, e, f, g;
+ for (c in a)if (d = m.camelCase(c), e = b[d], f = a[c], m.isArray(f) && (e = f[1], f = a[c] = f[0]), c !== d && (a[d] = f, delete a[c]), g = m.cssHooks[d], g && "expand" in g) {
+ f = g.expand(f), delete a[d];
+ for (c in f)c in a || (a[c] = f[c], b[c] = e)
+ } else b[d] = e
+ }
+
+ function kb(a, b, c) {
+ var d, e, f = 0, g = db.length, h = m.Deferred().always(function () {
+ delete i.elem
+ }), i = function () {
+ if (e)return !1;
+ for (var b = $a || fb(), c = Math.max(0, j.startTime + j.duration - b), d = c / j.duration || 0, f = 1 - d, g = 0, i = j.tweens.length; i > g; g++)j.tweens[g].run(f);
+ return h.notifyWith(a, [j, f, c]), 1 > f && i ? c : (h.resolveWith(a, [j]), !1)
+ }, j = h.promise({
+ elem: a,
+ props: m.extend({}, b),
+ opts: m.extend(!0, {specialEasing: {}}, c),
+ originalProperties: b,
+ originalOptions: c,
+ startTime: $a || fb(),
+ duration: c.duration,
+ tweens: [],
+ createTween: function (b, c) {
+ var d = m.Tween(a, j.opts, b, c, j.opts.specialEasing[b] || j.opts.easing);
+ return j.tweens.push(d), d
+ },
+ stop: function (b) {
+ var c = 0, d = b ? j.tweens.length : 0;
+ if (e)return this;
+ for (e = !0; d > c; c++)j.tweens[c].run(1);
+ return b ? h.resolveWith(a, [j, b]) : h.rejectWith(a, [j, b]), this
+ }
+ }), k = j.props;
+ for (jb(k, j.opts.specialEasing); g > f; f++)if (d = db[f].call(j, a, k, j.opts))return d;
+ return m.map(k, hb, j), m.isFunction(j.opts.start) && j.opts.start.call(a, j), m.fx.timer(m.extend(i, {
+ elem: a,
+ anim: j,
+ queue: j.opts.queue
+ })), j.progress(j.opts.progress).done(j.opts.done, j.opts.complete).fail(j.opts.fail).always(j.opts.always)
+ }
+
+ m.Animation = m.extend(kb, {
+ tweener: function (a, b) {
+ m.isFunction(a) ? (b = a, a = ["*"]) : a = a.split(" ");
+ for (var c, d = 0, e = a.length; e > d; d++)c = a[d], eb[c] = eb[c] || [], eb[c].unshift(b)
+ }, prefilter: function (a, b) {
+ b ? db.unshift(a) : db.push(a)
+ }
+ }), m.speed = function (a, b, c) {
+ var d = a && "object" == typeof a ? m.extend({}, a) : {complete: c || !c && b || m.isFunction(a) && a, duration: a, easing: c && b || b && !m.isFunction(b) && b};
+ return d.duration = m.fx.off ? 0 : "number" == typeof d.duration ? d.duration : d.duration in m.fx.speeds ? m.fx.speeds[d.duration] : m.fx.speeds._default, (null == d.queue || d.queue === !0) && (d.queue = "fx"), d.old = d.complete, d.complete = function () {
+ m.isFunction(d.old) && d.old.call(this), d.queue && m.dequeue(this, d.queue)
+ }, d
+ }, m.fn.extend({
+ fadeTo: function (a, b, c, d) {
+ return this.filter(U).css("opacity", 0).show().end().animate({opacity: b}, a, c, d)
+ }, animate: function (a, b, c, d) {
+ var e = m.isEmptyObject(a), f = m.speed(b, c, d), g = function () {
+ var b = kb(this, m.extend({}, a), f);
+ (e || m._data(this, "finish")) && b.stop(!0)
+ };
+ return g.finish = g, e || f.queue === !1 ? this.each(g) : this.queue(f.queue, g)
+ }, stop: function (a, b, c) {
+ var d = function (a) {
+ var b = a.stop;
+ delete a.stop, b(c)
+ };
+ return "string" != typeof a && (c = b, b = a, a = void 0), b && a !== !1 && this.queue(a || "fx", []), this.each(function () {
+ var b = !0, e = null != a && a + "queueHooks", f = m.timers, g = m._data(this);
+ if (e)g[e] && g[e].stop && d(g[e]); else for (e in g)g[e] && g[e].stop && cb.test(e) && d(g[e]);
+ for (e = f.length; e--;)f[e].elem !== this || null != a && f[e].queue !== a || (f[e].anim.stop(c), b = !1, f.splice(e, 1));
+ (b || !c) && m.dequeue(this, a)
+ })
+ }, finish: function (a) {
+ return a !== !1 && (a = a || "fx"), this.each(function () {
+ var b, c = m._data(this), d = c[a + "queue"], e = c[a + "queueHooks"], f = m.timers, g = d ? d.length : 0;
+ for (c.finish = !0, m.queue(this, a, []), e && e.stop && e.stop.call(this, !0), b = f.length; b--;)f[b].elem === this && f[b].queue === a && (f[b].anim.stop(!0), f.splice(b, 1));
+ for (b = 0; g > b; b++)d[b] && d[b].finish && d[b].finish.call(this);
+ delete c.finish
+ })
+ }
+ }), m.each(["toggle", "show", "hide"], function (a, b) {
+ var c = m.fn[b];
+ m.fn[b] = function (a, d, e) {
+ return null == a || "boolean" == typeof a ? c.apply(this, arguments) : this.animate(gb(b, !0), a, d, e)
+ }
+ }), m.each({
+ slideDown: gb("show"),
+ slideUp: gb("hide"),
+ slideToggle: gb("toggle"),
+ fadeIn: {opacity: "show"},
+ fadeOut: {opacity: "hide"},
+ fadeToggle: {opacity: "toggle"}
+ }, function (a, b) {
+ m.fn[a] = function (a, c, d) {
+ return this.animate(b, a, c, d)
+ }
+ }), m.timers = [], m.fx.tick = function () {
+ var a, b = m.timers, c = 0;
+ for ($a = m.now(); c < b.length; c++)a = b[c], a() || b[c] !== a || b.splice(c--, 1);
+ b.length || m.fx.stop(), $a = void 0
+ }, m.fx.timer = function (a) {
+ m.timers.push(a), a() ? m.fx.start() : m.timers.pop()
+ }, m.fx.interval = 13, m.fx.start = function () {
+ _a || (_a = setInterval(m.fx.tick, m.fx.interval))
+ }, m.fx.stop = function () {
+ clearInterval(_a), _a = null
+ }, m.fx.speeds = {slow: 600, fast: 200, _default: 400}, m.fn.delay = function (a, b) {
+ return a = m.fx ? m.fx.speeds[a] || a : a, b = b || "fx", this.queue(b, function (b, c) {
+ var d = setTimeout(b, a);
+ c.stop = function () {
+ clearTimeout(d)
+ }
+ })
+ }, function () {
+ var a, b, c, d, e;
+ b = y.createElement("div"), b.setAttribute("className", "t"), b.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>", d = b.getElementsByTagName("a")[0], c = y.createElement("select"), e = c.appendChild(y.createElement("option")), a = b.getElementsByTagName("input")[0], d.style.cssText = "top:1px", k.getSetAttribute = "t" !== b.className, k.style = /top/.test(d.getAttribute("style")), k.hrefNormalized = "/a" === d.getAttribute("href"), k.checkOn = !!a.value, k.optSelected = e.selected, k.enctype = !!y.createElement("form").enctype, c.disabled = !0, k.optDisabled = !e.disabled, a = y.createElement("input"), a.setAttribute("value", ""), k.input = "" === a.getAttribute("value"), a.value = "t", a.setAttribute("type", "radio"), k.radioValue = "t" === a.value
+ }();
+ var lb = /\r/g;
+ m.fn.extend({
+ val: function (a) {
+ var b, c, d, e = this[0];
+ {
+ if (arguments.length)return d = m.isFunction(a), this.each(function (c) {
+ var e;
+ 1 === this.nodeType && (e = d ? a.call(this, c, m(this).val()) : a, null == e ? e = "" : "number" == typeof e ? e += "" : m.isArray(e) && (e = m.map(e, function (a) {
+ return null == a ? "" : a + ""
+ })), b = m.valHooks[this.type] || m.valHooks[this.nodeName.toLowerCase()], b && "set" in b && void 0 !== b.set(this, e, "value") || (this.value = e))
+ });
+ if (e)return b = m.valHooks[e.type] || m.valHooks[e.nodeName.toLowerCase()], b && "get" in b && void 0 !== (c = b.get(e, "value")) ? c : (c = e.value, "string" == typeof c ? c.replace(lb, "") : null == c ? "" : c)
+ }
+ }
+ }), m.extend({
+ valHooks: {
+ option: {
+ get: function (a) {
+ var b = m.find.attr(a, "value");
+ return null != b ? b : m.trim(m.text(a))
+ }
+ }, select: {
+ get: function (a) {
+ for (var b, c, d = a.options, e = a.selectedIndex, f = "select-one" === a.type || 0 > e, g = f ? null : [], h = f ? e + 1 : d.length, i = 0 > e ? h : f ? e : 0; h > i; i++)if (c = d[i], !(!c.selected && i !== e || (k.optDisabled ? c.disabled : null !== c.getAttribute("disabled")) || c.parentNode.disabled && m.nodeName(c.parentNode, "optgroup"))) {
+ if (b = m(c).val(), f)return b;
+ g.push(b)
+ }
+ return g
+ }, set: function (a, b) {
+ var c, d, e = a.options, f = m.makeArray(b), g = e.length;
+ while (g--)if (d = e[g], m.inArray(m.valHooks.option.get(d), f) >= 0)try {
+ d.selected = c = !0
+ } catch (h) {
+ d.scrollHeight
+ } else d.selected = !1;
+ return c || (a.selectedIndex = -1), e
+ }
+ }
+ }
+ }), m.each(["radio", "checkbox"], function () {
+ m.valHooks[this] = {
+ set: function (a, b) {
+ return m.isArray(b) ? a.checked = m.inArray(m(a).val(), b) >= 0 : void 0
+ }
+ }, k.checkOn || (m.valHooks[this].get = function (a) {
+ return null === a.getAttribute("value") ? "on" : a.value
+ })
+ });
+ var mb, nb, ob = m.expr.attrHandle, pb = /^(?:checked|selected)$/i, qb = k.getSetAttribute, rb = k.input;
+ m.fn.extend({
+ attr: function (a, b) {
+ return V(this, m.attr, a, b, arguments.length > 1)
+ }, removeAttr: function (a) {
+ return this.each(function () {
+ m.removeAttr(this, a)
+ })
+ }
+ }), m.extend({
+ attr: function (a, b, c) {
+ var d, e, f = a.nodeType;
+ if (a && 3 !== f && 8 !== f && 2 !== f)return typeof a.getAttribute === K ? m.prop(a, b, c) : (1 === f && m.isXMLDoc(a) || (b = b.toLowerCase(), d = m.attrHooks[b] || (m.expr.match.bool.test(b) ? nb : mb)), void 0 === c ? d && "get" in d && null !== (e = d.get(a, b)) ? e : (e = m.find.attr(a, b), null == e ? void 0 : e) : null !== c ? d && "set" in d && void 0 !== (e = d.set(a, c, b)) ? e : (a.setAttribute(b, c + ""), c) : void m.removeAttr(a, b))
+ }, removeAttr: function (a, b) {
+ var c, d, e = 0, f = b && b.match(E);
+ if (f && 1 === a.nodeType)while (c = f[e++])d = m.propFix[c] || c, m.expr.match.bool.test(c) ? rb && qb || !pb.test(c) ? a[d] = !1 : a[m.camelCase("default-" + c)] = a[d] = !1 : m.attr(a, c, ""), a.removeAttribute(qb ? c : d)
+ }, attrHooks: {
+ type: {
+ set: function (a, b) {
+ if (!k.radioValue && "radio" === b && m.nodeName(a, "input")) {
+ var c = a.value;
+ return a.setAttribute("type", b), c && (a.value = c), b
+ }
+ }
+ }
+ }
+ }), nb = {
+ set: function (a, b, c) {
+ return b === !1 ? m.removeAttr(a, c) : rb && qb || !pb.test(c) ? a.setAttribute(!qb && m.propFix[c] || c, c) : a[m.camelCase("default-" + c)] = a[c] = !0, c
+ }
+ }, m.each(m.expr.match.bool.source.match(/\w+/g), function (a, b) {
+ var c = ob[b] || m.find.attr;
+ ob[b] = rb && qb || !pb.test(b) ? function (a, b, d) {
+ var e, f;
+ return d || (f = ob[b], ob[b] = e, e = null != c(a, b, d) ? b.toLowerCase() : null, ob[b] = f), e
+ } : function (a, b, c) {
+ return c ? void 0 : a[m.camelCase("default-" + b)] ? b.toLowerCase() : null
+ }
+ }), rb && qb || (m.attrHooks.value = {
+ set: function (a, b, c) {
+ return m.nodeName(a, "input") ? void(a.defaultValue = b) : mb && mb.set(a, b, c)
+ }
+ }), qb || (mb = {
+ set: function (a, b, c) {
+ var d = a.getAttributeNode(c);
+ return d || a.setAttributeNode(d = a.ownerDocument.createAttribute(c)), d.value = b += "", "value" === c || b === a.getAttribute(c) ? b : void 0
+ }
+ }, ob.id = ob.name = ob.coords = function (a, b, c) {
+ var d;
+ return c ? void 0 : (d = a.getAttributeNode(b)) && "" !== d.value ? d.value : null
+ }, m.valHooks.button = {
+ get: function (a, b) {
+ var c = a.getAttributeNode(b);
+ return c && c.specified ? c.value : void 0
+ }, set: mb.set
+ }, m.attrHooks.contenteditable = {
+ set: function (a, b, c) {
+ mb.set(a, "" === b ? !1 : b, c)
+ }
+ }, m.each(["width", "height"], function (a, b) {
+ m.attrHooks[b] = {
+ set: function (a, c) {
+ return "" === c ? (a.setAttribute(b, "auto"), c) : void 0
+ }
+ }
+ })), k.style || (m.attrHooks.style = {
+ get: function (a) {
+ return a.style.cssText || void 0
+ }, set: function (a, b) {
+ return a.style.cssText = b + ""
+ }
+ });
+ var sb = /^(?:input|select|textarea|button|object)$/i, tb = /^(?:a|area)$/i;
+ m.fn.extend({
+ prop: function (a, b) {
+ return V(this, m.prop, a, b, arguments.length > 1)
+ }, removeProp: function (a) {
+ return a = m.propFix[a] || a, this.each(function () {
+ try {
+ this[a] = void 0, delete this[a]
+ } catch (b) {
+ }
+ })
+ }
+ }), m.extend({
+ propFix: {"for": "htmlFor", "class": "className"}, prop: function (a, b, c) {
+ var d, e, f, g = a.nodeType;
+ if (a && 3 !== g && 8 !== g && 2 !== g)return f = 1 !== g || !m.isXMLDoc(a), f && (b = m.propFix[b] || b, e = m.propHooks[b]), void 0 !== c ? e && "set" in e && void 0 !== (d = e.set(a, c, b)) ? d : a[b] = c : e && "get" in e && null !== (d = e.get(a, b)) ? d : a[b]
+ }, propHooks: {
+ tabIndex: {
+ get: function (a) {
+ var b = m.find.attr(a, "tabindex");
+ return b ? parseInt(b, 10) : sb.test(a.nodeName) || tb.test(a.nodeName) && a.href ? 0 : -1
+ }
+ }
+ }
+ }), k.hrefNormalized || m.each(["href", "src"], function (a, b) {
+ m.propHooks[b] = {
+ get: function (a) {
+ return a.getAttribute(b, 4)
+ }
+ }
+ }), k.optSelected || (m.propHooks.selected = {
+ get: function (a) {
+ var b = a.parentNode;
+ return b && (b.selectedIndex, b.parentNode && b.parentNode.selectedIndex), null
+ }
+ }), m.each(["tabIndex", "readOnly", "maxLength", "cellSpacing", "cellPadding", "rowSpan", "colSpan", "useMap", "frameBorder", "contentEditable"], function () {
+ m.propFix[this.toLowerCase()] = this
+ }), k.enctype || (m.propFix.enctype = "encoding");
+ var ub = /[\t\r\n\f]/g;
+ m.fn.extend({
+ addClass: function (a) {
+ var b, c, d, e, f, g, h = 0, i = this.length, j = "string" == typeof a && a;
+ if (m.isFunction(a))return this.each(function (b) {
+ m(this).addClass(a.call(this, b, this.className))
+ });
+ if (j)for (b = (a || "").match(E) || []; i > h; h++)if (c = this[h], d = 1 === c.nodeType && (c.className ? (" " + c.className + " ").replace(ub, " ") : " ")) {
+ f = 0;
+ while (e = b[f++])d.indexOf(" " + e + " ") < 0 && (d += e + " ");
+ g = m.trim(d), c.className !== g && (c.className = g)
+ }
+ return this
+ }, removeClass: function (a) {
+ var b, c, d, e, f, g, h = 0, i = this.length, j = 0 === arguments.length || "string" == typeof a && a;
+ if (m.isFunction(a))return this.each(function (b) {
+ m(this).removeClass(a.call(this, b, this.className))
+ });
+ if (j)for (b = (a || "").match(E) || []; i > h; h++)if (c = this[h], d = 1 === c.nodeType && (c.className ? (" " + c.className + " ").replace(ub, " ") : "")) {
+ f = 0;
+ while (e = b[f++])while (d.indexOf(" " + e + " ") >= 0)d = d.replace(" " + e + " ", " ");
+ g = a ? m.trim(d) : "", c.className !== g && (c.className = g)
+ }
+ return this
+ }, toggleClass: function (a, b) {
+ var c = typeof a;
+ return "boolean" == typeof b && "string" === c ? b ? this.addClass(a) : this.removeClass(a) : this.each(m.isFunction(a) ? function (c) {
+ m(this).toggleClass(a.call(this, c, this.className, b), b)
+ } : function () {
+ if ("string" === c) {
+ var b, d = 0, e = m(this), f = a.match(E) || [];
+ while (b = f[d++])e.hasClass(b) ? e.removeClass(b) : e.addClass(b)
+ } else(c === K || "boolean" === c) && (this.className && m._data(this, "__className__", this.className), this.className = this.className || a === !1 ? "" : m._data(this, "__className__") || "")
+ })
+ }, hasClass: function (a) {
+ for (var b = " " + a + " ", c = 0, d = this.length; d > c; c++)if (1 === this[c].nodeType && (" " + this[c].className + " ").replace(ub, " ").indexOf(b) >= 0)return !0;
+ return !1
+ }
+ }), m.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "), function (a, b) {
+ m.fn[b] = function (a, c) {
+ return arguments.length > 0 ? this.on(b, null, a, c) : this.trigger(b)
+ }
+ }), m.fn.extend({
+ hover: function (a, b) {
+ return this.mouseenter(a).mouseleave(b || a)
+ }, bind: function (a, b, c) {
+ return this.on(a, null, b, c)
+ }, unbind: function (a, b) {
+ return this.off(a, null, b)
+ }, delegate: function (a, b, c, d) {
+ return this.on(b, a, c, d)
+ }, undelegate: function (a, b, c) {
+ return 1 === arguments.length ? this.off(a, "**") : this.off(b, a || "**", c)
+ }
+ });
+ var vb = m.now(), wb = /\?/, xb = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;
+ m.parseJSON = function (b) {
+ if (a.JSON && a.JSON.parse)return a.JSON.parse(b + "");
+ var c, d = null, e = m.trim(b + "");
+ return e && !m.trim(e.replace(xb, function (a, b, e, f) {
+ return c && b && (d = 0), 0 === d ? a : (c = e || b, d += !f - !e, "")
+ })) ? Function("return " + e)() : m.error("Invalid JSON: " + b)
+ }, m.parseXML = function (b) {
+ var c, d;
+ if (!b || "string" != typeof b)return null;
+ try {
+ a.DOMParser ? (d = new DOMParser, c = d.parseFromString(b, "text/xml")) : (c = new ActiveXObject("Microsoft.XMLDOM"), c.async = "false", c.loadXML(b))
+ } catch (e) {
+ c = void 0
+ }
+ return c && c.documentElement && !c.getElementsByTagName("parsererror").length || m.error("Invalid XML: " + b), c
+ };
+ var yb, zb, Ab = /#.*$/, Bb = /([?&])_=[^&]*/, Cb = /^(.*?):[ \t]*([^\r\n]*)\r?$/gm, Db = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, Eb = /^(?:GET|HEAD)$/, Fb = /^\/\//, Gb = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/, Hb = {}, Ib = {}, Jb = "*/".concat("*");
+ try {
+ zb = location.href
+ } catch (Kb) {
+ zb = y.createElement("a"), zb.href = "", zb = zb.href
+ }
+ yb = Gb.exec(zb.toLowerCase()) || [];
+ function Lb(a) {
+ return function (b, c) {
+ "string" != typeof b && (c = b, b = "*");
+ var d, e = 0, f = b.toLowerCase().match(E) || [];
+ if (m.isFunction(c))while (d = f[e++])"+" === d.charAt(0) ? (d = d.slice(1) || "*", (a[d] = a[d] || []).unshift(c)) : (a[d] = a[d] || []).push(c)
+ }
+ }
+
+ function Mb(a, b, c, d) {
+ var e = {}, f = a === Ib;
+
+ function g(h) {
+ var i;
+ return e[h] = !0, m.each(a[h] || [], function (a, h) {
+ var j = h(b, c, d);
+ return "string" != typeof j || f || e[j] ? f ? !(i = j) : void 0 : (b.dataTypes.unshift(j), g(j), !1)
+ }), i
+ }
+
+ return g(b.dataTypes[0]) || !e["*"] && g("*")
+ }
+
+ function Nb(a, b) {
+ var c, d, e = m.ajaxSettings.flatOptions || {};
+ for (d in b)void 0 !== b[d] && ((e[d] ? a : c || (c = {}))[d] = b[d]);
+ return c && m.extend(!0, a, c), a
+ }
+
+ function Ob(a, b, c) {
+ var d, e, f, g, h = a.contents, i = a.dataTypes;
+ while ("*" === i[0])i.shift(), void 0 === e && (e = a.mimeType || b.getResponseHeader("Content-Type"));
+ if (e)for (g in h)if (h[g] && h[g].test(e)) {
+ i.unshift(g);
+ break
+ }
+ if (i[0] in c)f = i[0]; else {
+ for (g in c) {
+ if (!i[0] || a.converters[g + " " + i[0]]) {
+ f = g;
+ break
+ }
+ d || (d = g)
+ }
+ f = f || d
+ }
+ return f ? (f !== i[0] && i.unshift(f), c[f]) : void 0
+ }
+
+ function Pb(a, b, c, d) {
+ var e, f, g, h, i, j = {}, k = a.dataTypes.slice();
+ if (k[1])for (g in a.converters)j[g.toLowerCase()] = a.converters[g];
+ f = k.shift();
+ while (f)if (a.responseFields[f] && (c[a.responseFields[f]] = b), !i && d && a.dataFilter && (b = a.dataFilter(b, a.dataType)), i = f, f = k.shift())if ("*" === f)f = i; else if ("*" !== i && i !== f) {
+ if (g = j[i + " " + f] || j["* " + f], !g)for (e in j)if (h = e.split(" "), h[1] === f && (g = j[i + " " + h[0]] || j["* " + h[0]])) {
+ g === !0 ? g = j[e] : j[e] !== !0 && (f = h[0], k.unshift(h[1]));
+ break
+ }
+ if (g !== !0)if (g && a["throws"])b = g(b); else try {
+ b = g(b)
+ } catch (l) {
+ return {state: "parsererror", error: g ? l : "No conversion from " + i + " to " + f}
+ }
+ }
+ return {state: "success", data: b}
+ }
+
+ m.extend({
+ active: 0,
+ lastModified: {},
+ etag: {},
+ ajaxSettings: {
+ url: zb,
+ type: "GET",
+ isLocal: Db.test(yb[1]),
+ global: !0,
+ processData: !0,
+ async: !0,
+ contentType: "application/x-www-form-urlencoded; charset=UTF-8",
+ accepts: {"*": Jb, text: "text/plain", html: "text/html", xml: "application/xml, text/xml", json: "application/json, text/javascript"},
+ contents: {xml: /xml/, html: /html/, json: /json/},
+ responseFields: {xml: "responseXML", text: "responseText", json: "responseJSON"},
+ converters: {"* text": String, "text html": !0, "text json": m.parseJSON, "text xml": m.parseXML},
+ flatOptions: {url: !0, context: !0}
+ },
+ ajaxSetup: function (a, b) {
+ return b ? Nb(Nb(a, m.ajaxSettings), b) : Nb(m.ajaxSettings, a)
+ },
+ ajaxPrefilter: Lb(Hb),
+ ajaxTransport: Lb(Ib),
+ ajax: function (a, b) {
+ "object" == typeof a && (b = a, a = void 0), b = b || {};
+ var c, d, e, f, g, h, i, j, k = m.ajaxSetup({}, b), l = k.context || k, n = k.context && (l.nodeType || l.jquery) ? m(l) : m.event, o = m.Deferred(), p = m.Callbacks("once memory"), q = k.statusCode || {}, r = {}, s = {}, t = 0, u = "canceled", v = {
+ readyState: 0,
+ getResponseHeader: function (a) {
+ var b;
+ if (2 === t) {
+ if (!j) {
+ j = {};
+ while (b = Cb.exec(f))j[b[1].toLowerCase()] = b[2]
+ }
+ b = j[a.toLowerCase()]
+ }
+ return null == b ? null : b
+ },
+ getAllResponseHeaders: function () {
+ return 2 === t ? f : null
+ },
+ setRequestHeader: function (a, b) {
+ var c = a.toLowerCase();
+ return t || (a = s[c] = s[c] || a, r[a] = b), this
+ },
+ overrideMimeType: function (a) {
+ return t || (k.mimeType = a), this
+ },
+ statusCode: function (a) {
+ var b;
+ if (a)if (2 > t)for (b in a)q[b] = [q[b], a[b]]; else v.always(a[v.status]);
+ return this
+ },
+ abort: function (a) {
+ var b = a || u;
+ return i && i.abort(b), x(0, b), this
+ }
+ };
+ if (o.promise(v).complete = p.add, v.success = v.done, v.error = v.fail, k.url = ((a || k.url || zb) + "").replace(Ab, "").replace(Fb, yb[1] + "//"), k.type = b.method || b.type || k.method || k.type, k.dataTypes = m.trim(k.dataType || "*").toLowerCase().match(E) || [""], null == k.crossDomain && (c = Gb.exec(k.url.toLowerCase()), k.crossDomain = !(!c || c[1] === yb[1] && c[2] === yb[2] && (c[3] || ("http:" === c[1] ? "80" : "443")) === (yb[3] || ("http:" === yb[1] ? "80" : "443")))), k.data && k.processData && "string" != typeof k.data && (k.data = m.param(k.data, k.traditional)), Mb(Hb, k, b, v), 2 === t)return v;
+ h = m.event && k.global, h && 0 === m.active++ && m.event.trigger("ajaxStart"), k.type = k.type.toUpperCase(), k.hasContent = !Eb.test(k.type), e = k.url, k.hasContent || (k.data && (e = k.url += (wb.test(e) ? "&" : "?") + k.data, delete k.data), k.cache === !1 && (k.url = Bb.test(e) ? e.replace(Bb, "$1_=" + vb++) : e + (wb.test(e) ? "&" : "?") + "_=" + vb++)), k.ifModified && (m.lastModified[e] && v.setRequestHeader("If-Modified-Since", m.lastModified[e]), m.etag[e] && v.setRequestHeader("If-None-Match", m.etag[e])), (k.data && k.hasContent && k.contentType !== !1 || b.contentType) && v.setRequestHeader("Content-Type", k.contentType), v.setRequestHeader("Accept", k.dataTypes[0] && k.accepts[k.dataTypes[0]] ? k.accepts[k.dataTypes[0]] + ("*" !== k.dataTypes[0] ? ", " + Jb + "; q=0.01" : "") : k.accepts["*"]);
+ for (d in k.headers)v.setRequestHeader(d, k.headers[d]);
+ if (k.beforeSend && (k.beforeSend.call(l, v, k) === !1 || 2 === t))return v.abort();
+ u = "abort";
+ for (d in{success: 1, error: 1, complete: 1})v[d](k[d]);
+ if (i = Mb(Ib, k, b, v)) {
+ v.readyState = 1, h && n.trigger("ajaxSend", [v, k]), k.async && k.timeout > 0 && (g = setTimeout(function () {
+ v.abort("timeout")
+ }, k.timeout));
+ try {
+ t = 1, i.send(r, x)
+ } catch (w) {
+ if (!(2 > t))throw w;
+ x(-1, w)
+ }
+ } else x(-1, "No Transport");
+ function x(a, b, c, d) {
+ var j, r, s, u, w, x = b;
+ 2 !== t && (t = 2, g && clearTimeout(g), i = void 0, f = d || "", v.readyState = a > 0 ? 4 : 0, j = a >= 200 && 300 > a || 304 === a, c && (u = Ob(k, v, c)), u = Pb(k, u, v, j), j ? (k.ifModified && (w = v.getResponseHeader("Last-Modified"), w && (m.lastModified[e] = w), w = v.getResponseHeader("etag"), w && (m.etag[e] = w)), 204 === a || "HEAD" === k.type ? x = "nocontent" : 304 === a ? x = "notmodified" : (x = u.state, r = u.data, s = u.error, j = !s)) : (s = x, (a || !x) && (x = "error", 0 > a && (a = 0))), v.status = a, v.statusText = (b || x) + "", j ? o.resolveWith(l, [r, x, v]) : o.rejectWith(l, [v, x, s]), v.statusCode(q), q = void 0, h && n.trigger(j ? "ajaxSuccess" : "ajaxError", [v, k, j ? r : s]), p.fireWith(l, [v, x]), h && (n.trigger("ajaxComplete", [v, k]), --m.active || m.event.trigger("ajaxStop")))
+ }
+
+ return v
+ },
+ getJSON: function (a, b, c) {
+ return m.get(a, b, c, "json")
+ },
+ getScript: function (a, b) {
+ return m.get(a, void 0, b, "script")
+ }
+ }), m.each(["get", "post"], function (a, b) {
+ m[b] = function (a, c, d, e) {
+ return m.isFunction(c) && (e = e || d, d = c, c = void 0), m.ajax({url: a, type: b, dataType: e, data: c, success: d})
+ }
+ }), m._evalUrl = function (a) {
+ return m.ajax({url: a, type: "GET", dataType: "script", async: !1, global: !1, "throws": !0})
+ }, m.fn.extend({
+ wrapAll: function (a) {
+ if (m.isFunction(a))return this.each(function (b) {
+ m(this).wrapAll(a.call(this, b))
+ });
+ if (this[0]) {
+ var b = m(a, this[0].ownerDocument).eq(0).clone(!0);
+ this[0].parentNode && b.insertBefore(this[0]), b.map(function () {
+ var a = this;
+ while (a.firstChild && 1 === a.firstChild.nodeType)a = a.firstChild;
+ return a
+ }).append(this)
+ }
+ return this
+ }, wrapInner: function (a) {
+ return this.each(m.isFunction(a) ? function (b) {
+ m(this).wrapInner(a.call(this, b))
+ } : function () {
+ var b = m(this), c = b.contents();
+ c.length ? c.wrapAll(a) : b.append(a)
+ })
+ }, wrap: function (a) {
+ var b = m.isFunction(a);
+ return this.each(function (c) {
+ m(this).wrapAll(b ? a.call(this, c) : a)
+ })
+ }, unwrap: function () {
+ return this.parent().each(function () {
+ m.nodeName(this, "body") || m(this).replaceWith(this.childNodes)
+ }).end()
+ }
+ }), m.expr.filters.hidden = function (a) {
+ return a.offsetWidth <= 0 && a.offsetHeight <= 0 || !k.reliableHiddenOffsets() && "none" === (a.style && a.style.display || m.css(a, "display"))
+ }, m.expr.filters.visible = function (a) {
+ return !m.expr.filters.hidden(a)
+ };
+ var Qb = /%20/g, Rb = /\[\]$/, Sb = /\r?\n/g, Tb = /^(?:submit|button|image|reset|file)$/i, Ub = /^(?:input|select|textarea|keygen)/i;
+
+ function Vb(a, b, c, d) {
+ var e;
+ if (m.isArray(b))m.each(b, function (b, e) {
+ c || Rb.test(a) ? d(a, e) : Vb(a + "[" + ("object" == typeof e ? b : "") + "]", e, c, d)
+ }); else if (c || "object" !== m.type(b))d(a, b); else for (e in b)Vb(a + "[" + e + "]", b[e], c, d)
+ }
+
+ m.param = function (a, b) {
+ var c, d = [], e = function (a, b) {
+ b = m.isFunction(b) ? b() : null == b ? "" : b, d[d.length] = encodeURIComponent(a) + "=" + encodeURIComponent(b)
+ };
+ if (void 0 === b && (b = m.ajaxSettings && m.ajaxSettings.traditional), m.isArray(a) || a.jquery && !m.isPlainObject(a))m.each(a, function () {
+ e(this.name, this.value)
+ }); else for (c in a)Vb(c, a[c], b, e);
+ return d.join("&").replace(Qb, "+")
+ }, m.fn.extend({
+ serialize: function () {
+ return m.param(this.serializeArray())
+ }, serializeArray: function () {
+ return this.map(function () {
+ var a = m.prop(this, "elements");
+ return a ? m.makeArray(a) : this
+ }).filter(function () {
+ var a = this.type;
+ return this.name && !m(this).is(":disabled") && Ub.test(this.nodeName) && !Tb.test(a) && (this.checked || !W.test(a))
+ }).map(function (a, b) {
+ var c = m(this).val();
+ return null == c ? null : m.isArray(c) ? m.map(c, function (a) {
+ return {name: b.name, value: a.replace(Sb, "\r\n")}
+ }) : {name: b.name, value: c.replace(Sb, "\r\n")}
+ }).get()
+ }
+ }), m.ajaxSettings.xhr = void 0 !== a.ActiveXObject ? function () {
+ return !this.isLocal && /^(get|post|head|put|delete|options)$/i.test(this.type) && Zb() || $b()
+ } : Zb;
+ var Wb = 0, Xb = {}, Yb = m.ajaxSettings.xhr();
+ a.attachEvent && a.attachEvent("onunload", function () {
+ for (var a in Xb)Xb[a](void 0, !0)
+ }), k.cors = !!Yb && "withCredentials" in Yb, Yb = k.ajax = !!Yb, Yb && m.ajaxTransport(function (a) {
+ if (!a.crossDomain || k.cors) {
+ var b;
+ return {
+ send: function (c, d) {
+ var e, f = a.xhr(), g = ++Wb;
+ if (f.open(a.type, a.url, a.async, a.username, a.password), a.xhrFields)for (e in a.xhrFields)f[e] = a.xhrFields[e];
+ a.mimeType && f.overrideMimeType && f.overrideMimeType(a.mimeType), a.crossDomain || c["X-Requested-With"] || (c["X-Requested-With"] = "XMLHttpRequest");
+ for (e in c)void 0 !== c[e] && f.setRequestHeader(e, c[e] + "");
+ f.send(a.hasContent && a.data || null), b = function (c, e) {
+ var h, i, j;
+ if (b && (e || 4 === f.readyState))if (delete Xb[g], b = void 0, f.onreadystatechange = m.noop, e)4 !== f.readyState && f.abort(); else {
+ j = {}, h = f.status, "string" == typeof f.responseText && (j.text = f.responseText);
+ try {
+ i = f.statusText
+ } catch (k) {
+ i = ""
+ }
+ h || !a.isLocal || a.crossDomain ? 1223 === h && (h = 204) : h = j.text ? 200 : 404
+ }
+ j && d(h, i, j, f.getAllResponseHeaders())
+ }, a.async ? 4 === f.readyState ? setTimeout(b) : f.onreadystatechange = Xb[g] = b : b()
+ }, abort: function () {
+ b && b(void 0, !0)
+ }
+ }
+ }
+ });
+ function Zb() {
+ try {
+ return new a.XMLHttpRequest
+ } catch (b) {
+ }
+ }
+
+ function $b() {
+ try {
+ return new a.ActiveXObject("Microsoft.XMLHTTP")
+ } catch (b) {
+ }
+ }
+
+ m.ajaxSetup({
+ accepts: {script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},
+ contents: {script: /(?:java|ecma)script/},
+ converters: {
+ "text script": function (a) {
+ return m.globalEval(a), a
+ }
+ }
+ }), m.ajaxPrefilter("script", function (a) {
+ void 0 === a.cache && (a.cache = !1), a.crossDomain && (a.type = "GET", a.global = !1)
+ }), m.ajaxTransport("script", function (a) {
+ if (a.crossDomain) {
+ var b, c = y.head || m("head")[0] || y.documentElement;
+ return {
+ send: function (d, e) {
+ b = y.createElement("script"), b.async = !0, a.scriptCharset && (b.charset = a.scriptCharset), b.src = a.url, b.onload = b.onreadystatechange = function (a, c) {
+ (c || !b.readyState || /loaded|complete/.test(b.readyState)) && (b.onload = b.onreadystatechange = null, b.parentNode && b.parentNode.removeChild(b), b = null, c || e(200, "success"))
+ }, c.insertBefore(b, c.firstChild)
+ }, abort: function () {
+ b && b.onload(void 0, !0)
+ }
+ }
+ }
+ });
+ var _b = [], ac = /(=)\?(?=&|$)|\?\?/;
+ m.ajaxSetup({
+ jsonp: "callback", jsonpCallback: function () {
+ var a = _b.pop() || m.expando + "_" + vb++;
+ return this[a] = !0, a
+ }
+ }), m.ajaxPrefilter("json jsonp", function (b, c, d) {
+ var e, f, g, h = b.jsonp !== !1 && (ac.test(b.url) ? "url" : "string" == typeof b.data && !(b.contentType || "").indexOf("application/x-www-form-urlencoded") && ac.test(b.data) && "data");
+ return h || "jsonp" === b.dataTypes[0] ? (e = b.jsonpCallback = m.isFunction(b.jsonpCallback) ? b.jsonpCallback() : b.jsonpCallback, h ? b[h] = b[h].replace(ac, "$1" + e) : b.jsonp !== !1 && (b.url += (wb.test(b.url) ? "&" : "?") + b.jsonp + "=" + e), b.converters["script json"] = function () {
+ return g || m.error(e + " was not called"), g[0]
+ }, b.dataTypes[0] = "json", f = a[e], a[e] = function () {
+ g = arguments
+ }, d.always(function () {
+ a[e] = f, b[e] && (b.jsonpCallback = c.jsonpCallback, _b.push(e)), g && m.isFunction(f) && f(g[0]), g = f = void 0
+ }), "script") : void 0
+ }), m.parseHTML = function (a, b, c) {
+ if (!a || "string" != typeof a)return null;
+ "boolean" == typeof b && (c = b, b = !1), b = b || y;
+ var d = u.exec(a), e = !c && [];
+ return d ? [b.createElement(d[1])] : (d = m.buildFragment([a], b, e), e && e.length && m(e).remove(), m.merge([], d.childNodes))
+ };
+ var bc = m.fn.load;
+ m.fn.load = function (a, b, c) {
+ if ("string" != typeof a && bc)return bc.apply(this, arguments);
+ var d, e, f, g = this, h = a.indexOf(" ");
+ return h >= 0 && (d = m.trim(a.slice(h, a.length)), a = a.slice(0, h)), m.isFunction(b) ? (c = b, b = void 0) : b && "object" == typeof b && (f = "POST"), g.length > 0 && m.ajax({
+ url: a,
+ type: f,
+ dataType: "html",
+ data: b
+ }).done(function (a) {
+ e = arguments, g.html(d ? m("<div>").append(m.parseHTML(a)).find(d) : a)
+ }).complete(c && function (a, b) {
+ g.each(c, e || [a.responseText, b, a])
+ }), this
+ }, m.each(["ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend"], function (a, b) {
+ m.fn[b] = function (a) {
+ return this.on(b, a)
+ }
+ }), m.expr.filters.animated = function (a) {
+ return m.grep(m.timers, function (b) {
+ return a === b.elem
+ }).length
+ };
+ var cc = a.document.documentElement;
+
+ function dc(a) {
+ return m.isWindow(a) ? a : 9 === a.nodeType ? a.defaultView || a.parentWindow : !1
+ }
+
+ m.offset = {
+ setOffset: function (a, b, c) {
+ var d, e, f, g, h, i, j, k = m.css(a, "position"), l = m(a), n = {};
+ "static" === k && (a.style.position = "relative"), h = l.offset(), f = m.css(a, "top"), i = m.css(a, "left"), j = ("absolute" === k || "fixed" === k) && m.inArray("auto", [f, i]) > -1, j ? (d = l.position(), g = d.top, e = d.left) : (g = parseFloat(f) || 0, e = parseFloat(i) || 0), m.isFunction(b) && (b = b.call(a, c, h)), null != b.top && (n.top = b.top - h.top + g), null != b.left && (n.left = b.left - h.left + e), "using" in b ? b.using.call(a, n) : l.css(n)
+ }
+ }, m.fn.extend({
+ offset: function (a) {
+ if (arguments.length)return void 0 === a ? this : this.each(function (b) {
+ m.offset.setOffset(this, a, b)
+ });
+ var b, c, d = {top: 0, left: 0}, e = this[0], f = e && e.ownerDocument;
+ if (f)return b = f.documentElement, m.contains(b, e) ? (typeof e.getBoundingClientRect !== K && (d = e.getBoundingClientRect()), c = dc(f), {
+ top: d.top + (c.pageYOffset || b.scrollTop) - (b.clientTop || 0),
+ left: d.left + (c.pageXOffset || b.scrollLeft) - (b.clientLeft || 0)
+ }) : d
+ }, position: function () {
+ if (this[0]) {
+ var a, b, c = {top: 0, left: 0}, d = this[0];
+ return "fixed" === m.css(d, "position") ? b = d.getBoundingClientRect() : (a = this.offsetParent(), b = this.offset(), m.nodeName(a[0], "html") || (c = a.offset()), c.top += m.css(a[0], "borderTopWidth", !0), c.left += m.css(a[0], "borderLeftWidth", !0)), {
+ top: b.top - c.top - m.css(d, "marginTop", !0),
+ left: b.left - c.left - m.css(d, "marginLeft", !0)
+ }
+ }
+ }, offsetParent: function () {
+ return this.map(function () {
+ var a = this.offsetParent || cc;
+ while (a && !m.nodeName(a, "html") && "static" === m.css(a, "position"))a = a.offsetParent;
+ return a || cc
+ })
+ }
+ }), m.each({scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function (a, b) {
+ var c = /Y/.test(b);
+ m.fn[a] = function (d) {
+ return V(this, function (a, d, e) {
+ var f = dc(a);
+ return void 0 === e ? f ? b in f ? f[b] : f.document.documentElement[d] : a[d] : void(f ? f.scrollTo(c ? m(f).scrollLeft() : e, c ? e : m(f).scrollTop()) : a[d] = e)
+ }, a, d, arguments.length, null)
+ }
+ }), m.each(["top", "left"], function (a, b) {
+ m.cssHooks[b] = La(k.pixelPosition, function (a, c) {
+ return c ? (c = Ja(a, b), Ha.test(c) ? m(a).position()[b] + "px" : c) : void 0
+ })
+ }), m.each({Height: "height", Width: "width"}, function (a, b) {
+ m.each({padding: "inner" + a, content: b, "": "outer" + a}, function (c, d) {
+ m.fn[d] = function (d, e) {
+ var f = arguments.length && (c || "boolean" != typeof d), g = c || (d === !0 || e === !0 ? "margin" : "border");
+ return V(this, function (b, c, d) {
+ var e;
+ return m.isWindow(b) ? b.document.documentElement["client" + a] : 9 === b.nodeType ? (e = b.documentElement, Math.max(b.body["scroll" + a], e["scroll" + a], b.body["offset" + a], e["offset" + a], e["client" + a])) : void 0 === d ? m.css(b, c, g) : m.style(b, c, d, g)
+ }, b, f ? d : void 0, f, null)
+ }
+ })
+ }), m.fn.size = function () {
+ return this.length
+ }, m.fn.andSelf = m.fn.addBack, "function" == typeof define && define.amd && define("jquery", [], function () {
+ return m
+ });
+ var ec = a.jQuery, fc = a.$;
+ return m.noConflict = function (b) {
+ return a.$ === m && (a.$ = fc), b && a.jQuery === m && (a.jQuery = ec), m
+ }, typeof b === K && (a.jQuery = a.$ = m), m
+});
new file mode 100644
--- /dev/null
+++ b/js/main.js
@@ -0,0 +1,14 @@
+function route(url) {
+ window.location.href = url;
+}
+
+$(document).ready(function () {
+ $('.clickable').click(function () {
+ var tidStr = $(this).attr('id');
+ var tid = tidStr.substring(3);
+
+ window.location.href = "/tickets/?tid=" + tid;
+ });
+
+ tinymce.init({selector: 'textarea'});
+});
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/library/log4php/Logger.php
@@ -0,0 +1,596 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+require dirname(__FILE__) . '/LoggerAutoloader.php';
+
+/**
+ * This is the central class in the log4php package. All logging operations
+ * are done through this class.
+ *
+ * The main logging methods are:
+ * <ul>
+ * <li>{@link trace()}</li>
+ * <li>{@link debug()}</li>
+ * <li>{@link info()}</li>
+ * <li>{@link warn()}</li>
+ * <li>{@link error()}</li>
+ * <li>{@link fatal()}</li>
+ * </ul>
+ *
+ * @package log4php
+ * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+ * @version SVN: $Id: Logger.php 1395241 2012-10-07 08:28:53Z ihabunek $
+ * @link http://logging.apache.org/log4php
+ */
+class Logger {
+
+ /**
+ * Logger additivity. If set to true then child loggers will inherit
+ * the appenders of their ancestors by default.
+ * @var boolean
+ */
+ private $additive = true;
+
+ /**
+ * The Logger's fully qualified class name.
+ * TODO: Determine if this is useful.
+ */
+ private $fqcn = 'Logger';
+
+ /** The assigned Logger level. */
+ private $level;
+
+ /** The name of this Logger instance. */
+ private $name;
+
+ /** The parent logger. Set to null if this is the root logger. */
+ private $parent;
+
+ /** A collection of appenders linked to this logger. */
+ private $appenders = array();
+
+ /**
+ * Constructor.
+ * @param string $name Name of the logger.
+ */
+ public function __construct($name) {
+ $this->name = $name;
+ }
+
+ /**
+ * Returns the logger name.
+ * @return string
+ */
+ public function getName() {
+ return $this->name;
+ }
+
+ /**
+ * Returns the parent Logger. Can be null if this is the root logger.
+ * @return Logger
+ */
+ public function getParent() {
+ return $this->parent;
+ }
+
+ // ******************************************
+ // *** Logging methods ***
+ // ******************************************
+
+ /**
+ * Log a message object with the TRACE level.
+ *
+ * @param mixed $message message
+ * @param Exception $throwable Optional throwable information to include
+ * in the logging event.
+ */
+ public function trace($message, $throwable = null) {
+ $this->log(LoggerLevel::getLevelTrace(), $message, $throwable);
+ }
+
+ /**
+ * Log a message object with the DEBUG level.
+ *
+ * @param mixed $message message
+ * @param Exception $throwable Optional throwable information to include
+ * in the logging event.
+ */
+ public function debug($message, $throwable = null) {
+ $this->log(LoggerLevel::getLevelDebug(), $message, $throwable);
+ }
+
+ /**
+ * Log a message object with the INFO Level.
+ *
+ * @param mixed $message message
+ * @param Exception $throwable Optional throwable information to include
+ * in the logging event.
+ */
+ public function info($message, $throwable = null) {
+ $this->log(LoggerLevel::getLevelInfo(), $message, $throwable);
+ }
+
+ /**
+ * Log a message with the WARN level.
+ *
+ * @param mixed $message message
+ * @param Exception $throwable Optional throwable information to include
+ * in the logging event.
+ */
+ public function warn($message, $throwable = null) {
+ $this->log(LoggerLevel::getLevelWarn(), $message, $throwable);
+ }
+
+ /**
+ * Log a message object with the ERROR level.
+ *
+ * @param mixed $message message
+ * @param Exception $throwable Optional throwable information to include
+ * in the logging event.
+ */
+ public function error($message, $throwable = null) {
+ $this->log(LoggerLevel::getLevelError(), $message, $throwable);
+ }
+
+ /**
+ * Log a message object with the FATAL level.
+ *
+ * @param mixed $message message
+ * @param Exception $throwable Optional throwable information to include
+ * in the logging event.
+ */
+ public function fatal($message, $throwable = null) {
+ $this->log(LoggerLevel::getLevelFatal(), $message, $throwable);
+ }
+
+ /**
+ * Log a message using the provided logging level.
+ *
+ * @param LoggerLevel $level The logging level.
+ * @param mixed $message Message to log.
+ * @param Exception $throwable Optional throwable information to include
+ * in the logging event.
+ */
+ public function log(LoggerLevel $level, $message, $throwable = null) {
+ if ($this->isEnabledFor($level)) {
+ $event = new LoggerLoggingEvent($this->fqcn, $this, $level, $message, null, $throwable);
+ $this->callAppenders($event);
+ }
+
+ // Forward the event upstream if additivity is turned on
+ if (isset($this->parent) && $this->getAdditivity()) {
+
+ // Use the event if already created
+ if (isset($event)) {
+ $this->parent->logEvent($event);
+ } else {
+ $this->parent->log($level, $message, $throwable);
+ }
+ }
+ }
+
+ /**
+ * Logs an already prepared logging event object.
+ * @param LoggerLoggingEvent $event
+ */
+ public function logEvent(LoggerLoggingEvent $event) {
+ if ($this->isEnabledFor($event->getLevel())) {
+ $this->callAppenders($event);
+ }
+
+ // Forward the event upstream if additivity is turned on
+ if (isset($this->parent) && $this->getAdditivity()) {
+ $this->parent->logEvent($event);
+ }
+ }
+
+ /**
+ * If assertion parameter evaluates as false, then logs the message
+ * using the ERROR level.
+ *
+ * @param bool $assertion
+ * @param string $msg message to log
+ */
+ public function assertLog($assertion = true, $msg = '') {
+ if ($assertion == false) {
+ $this->error($msg);
+ }
+ }
+
+ /**
+ * This method creates a new logging event and logs the event without
+ * further checks.
+ *
+ * It should not be called directly. Use {@link trace()}, {@link debug()},
+ * {@link info()}, {@link warn()}, {@link error()} and {@link fatal()}
+ * wrappers.
+ *
+ * @param string $fqcn Fully qualified class name of the Logger
+ * @param Exception $throwable Optional throwable information to include
+ * in the logging event.
+ * @param LoggerLevel $level log level
+ * @param mixed $message message to log
+ */
+ public function forcedLog($fqcn, $throwable, LoggerLevel $level, $message) {
+ $event = new LoggerLoggingEvent($fqcn, $this, $level, $message, null, $throwable);
+ $this->callAppenders($event);
+
+ // Forward the event upstream if additivity is turned on
+ if (isset($this->parent) && $this->getAdditivity()) {
+ $this->parent->logEvent($event);
+ }
+ }
+
+ /**
+ * Forwards the given logging event to all linked appenders.
+ * @param LoggerLoggingEvent $event
+ */
+ public function callAppenders($event) {
+ foreach ($this->appenders as $appender) {
+ $appender->doAppend($event);
+ }
+ }
+
+ // ******************************************
+ // *** Checker methods ***
+ // ******************************************
+
+ /**
+ * Check whether this Logger is enabled for a given Level passed as parameter.
+ *
+ * @param LoggerLevel level
+ * @return boolean
+ */
+ public function isEnabledFor(LoggerLevel $level) {
+ return $level->isGreaterOrEqual($this->getEffectiveLevel());
+ }
+
+ /**
+ * Check whether this Logger is enabled for the TRACE Level.
+ * @return boolean
+ */
+ public function isTraceEnabled() {
+ return $this->isEnabledFor(LoggerLevel::getLevelTrace());
+ }
+
+ /**
+ * Check whether this Logger is enabled for the DEBUG Level.
+ * @return boolean
+ */
+ public function isDebugEnabled() {
+ return $this->isEnabledFor(LoggerLevel::getLevelDebug());
+ }
+
+ /**
+ * Check whether this Logger is enabled for the INFO Level.
+ * @return boolean
+ */
+ public function isInfoEnabled() {
+ return $this->isEnabledFor(LoggerLevel::getLevelInfo());
+ }
+
+ /**
+ * Check whether this Logger is enabled for the WARN Level.
+ * @return boolean
+ */
+ public function isWarnEnabled() {
+ return $this->isEnabledFor(LoggerLevel::getLevelWarn());
+ }
+
+ /**
+ * Check whether this Logger is enabled for the ERROR Level.
+ * @return boolean
+ */
+ public function isErrorEnabled() {
+ return $this->isEnabledFor(LoggerLevel::getLevelError());
+ }
+
+ /**
+ * Check whether this Logger is enabled for the FATAL Level.
+ * @return boolean
+ */
+ public function isFatalEnabled() {
+ return $this->isEnabledFor(LoggerLevel::getLevelFatal());
+ }
+
+ // ******************************************
+ // *** Configuration methods ***
+ // ******************************************
+
+ /**
+ * Adds a new appender to the Logger.
+ * @param LoggerAppender $appender The appender to add.
+ */
+ public function addAppender($appender) {
+ $appenderName = $appender->getName();
+ $this->appenders[$appenderName] = $appender;
+ }
+
+ /** Removes all appenders from the Logger. */
+ public function removeAllAppenders() {
+ foreach ($this->appenders as $name => $appender) {
+ $this->removeAppender($name);
+ }
+ }
+
+ /**
+ * Remove the appender passed as parameter form the Logger.
+ * @param mixed $appender an appender name or a {@link LoggerAppender} instance.
+ */
+ public function removeAppender($appender) {
+ if ($appender instanceof LoggerAppender) {
+ $appender->close();
+ unset($this->appenders[$appender->getName()]);
+ } else if (is_string($appender) and isset($this->appenders[$appender])) {
+ $this->appenders[$appender]->close();
+ unset($this->appenders[$appender]);
+ }
+ }
+
+ /**
+ * Returns the appenders linked to this logger as an array.
+ * @return array collection of appender names
+ */
+ public function getAllAppenders() {
+ return $this->appenders;
+ }
+
+ /**
+ * Returns a linked appender by name.
+ * @return LoggerAppender
+ */
+ public function getAppender($name) {
+ return $this->appenders[$name];
+ }
+
+ /**
+ * Sets the additivity flag.
+ * @param boolean $additive
+ */
+ public function setAdditivity($additive) {
+ $this->additive = (bool)$additive;
+ }
+
+ /**
+ * Returns the additivity flag.
+ * @return boolean
+ */
+ public function getAdditivity() {
+ return $this->additive;
+ }
+
+ /**
+ * Starting from this Logger, search the Logger hierarchy for a non-null level and return it.
+ * @see LoggerLevel
+ * @return LoggerLevel or null
+ */
+ public function getEffectiveLevel() {
+ for ($logger = $this; $logger !== null; $logger = $logger->getParent()) {
+ if ($logger->getLevel() !== null) {
+ return $logger->getLevel();
+ }
+ }
+ }
+
+ /**
+ * Get the assigned Logger level.
+ * @return LoggerLevel The assigned level or null if none is assigned.
+ */
+ public function getLevel() {
+ return $this->level;
+ }
+
+ /**
+ * Set the Logger level.
+ *
+ * Use LoggerLevel::getLevelXXX() methods to get a LoggerLevel object, e.g.
+ * <code>$logger->setLevel(LoggerLevel::getLevelInfo());</code>
+ *
+ * @param LoggerLevel $level The level to set, or NULL to clear the logger level.
+ */
+ public function setLevel(LoggerLevel $level = null) {
+ $this->level = $level;
+ }
+
+ /**
+ * Checks whether an appender is attached to this logger instance.
+ *
+ * @param LoggerAppender $appender
+ * @return boolean
+ */
+ public function isAttached(LoggerAppender $appender) {
+ return isset($this->appenders[$appender->getName()]);
+ }
+
+ /**
+ * Sets the parent logger.
+ * @param Logger $logger
+ */
+ public function setParent(Logger $logger) {
+ $this->parent = $logger;
+ }
+
+ // ******************************************
+ // *** Static methods and properties ***
+ // ******************************************
+
+ /** The logger hierarchy used by log4php. */
+ private static $hierarchy;
+
+ /** Inidicates if log4php has been initialized */
+ private static $initialized = false;
+
+ /**
+ * Returns the hierarchy used by this Logger.
+ *
+ * Caution: do not use this hierarchy unless you have called initialize().
+ * To get Loggers, use the Logger::getLogger and Logger::getRootLogger
+ * methods instead of operating on on the hierarchy directly.
+ *
+ * @return LoggerHierarchy
+ */
+ public static function getHierarchy() {
+ if (!isset(self::$hierarchy)) {
+ self::$hierarchy = new LoggerHierarchy(new LoggerRoot());
+ }
+ return self::$hierarchy;
+ }
+
+ /**
+ * Returns a Logger by name. If it does not exist, it will be created.
+ *
+ * @param string $name The logger name
+ * @return Logger
+ */
+ public static function getLogger($name) {
+ if (!self::isInitialized()) {
+ self::configure();
+ }
+ return self::getHierarchy()->getLogger($name);
+ }
+
+ /**
+ * Returns the Root Logger.
+ * @return LoggerRoot
+ */
+ public static function getRootLogger() {
+ if (!self::isInitialized()) {
+ self::configure();
+ }
+ return self::getHierarchy()->getRootLogger();
+ }
+
+ /**
+ * Clears all Logger definitions from the logger hierarchy.
+ * @return boolean
+ */
+ public static function clear() {
+ return self::getHierarchy()->clear();
+ }
+
+ /**
+ * Destroy configurations for logger definitions
+ */
+ public static function resetConfiguration() {
+ self::getHierarchy()->resetConfiguration();
+ self::getHierarchy()->clear(); // TODO: clear or not?
+ self::$initialized = false;
+ }
+
+ /**
+ * Safely close all appenders.
+ * @deprecated This is no longer necessary due the appenders shutdown via
+ * destructors.
+ */
+ public static function shutdown() {
+ return self::getHierarchy()->shutdown();
+ }
+
+ /**
+ * check if a given logger exists.
+ *
+ * @param string $name logger name
+ * @return boolean
+ */
+ public static function exists($name) {
+ return self::getHierarchy()->exists($name);
+ }
+
+ /**
+ * Returns an array this whole Logger instances.
+ * @see Logger
+ * @return array
+ */
+ public static function getCurrentLoggers() {
+ return self::getHierarchy()->getCurrentLoggers();
+ }
+
+ /**
+ * Configures log4php.
+ *
+ * This method needs to be called before the first logging event has
+ * occured. If this method is not called before then the default
+ * configuration will be used.
+ *
+ * @param string|array $configuration Either a path to the configuration
+ * file, or a configuration array.
+ *
+ * @param string|LoggerConfigurator $configurator A custom
+ * configurator class: either a class name (string), or an object which
+ * implements the LoggerConfigurator interface. If left empty, the default
+ * configurator implementation will be used.
+ */
+ public static function configure($configuration = null, $configurator = null) {
+ self::resetConfiguration();
+ $configurator = self::getConfigurator($configurator);
+ $configurator->configure(self::getHierarchy(), $configuration);
+ self::$initialized = true;
+ }
+
+ /**
+ * Creates a logger configurator instance based on the provided
+ * configurator class. If no class is given, returns an instance of
+ * the default configurator.
+ *
+ * @param string|LoggerConfigurator $configurator The configurator class
+ * or LoggerConfigurator instance.
+ */
+ private static function getConfigurator($configurator = null) {
+ if ($configurator === null) {
+ return new LoggerConfiguratorDefault();
+ }
+
+ if (is_object($configurator)) {
+ if ($configurator instanceof LoggerConfigurator) {
+ return $configurator;
+ } else {
+ trigger_error("log4php: Given configurator object [$configurator] does not implement the LoggerConfigurator interface. Reverting to default configurator.", E_USER_WARNING);
+ return new LoggerConfiguratorDefault();
+ }
+ }
+
+ if (is_string($configurator)) {
+ if (!class_exists($configurator)) {
+ trigger_error("log4php: Specified configurator class [$configurator] does not exist. Reverting to default configurator.", E_USER_WARNING);
+ return new LoggerConfiguratorDefault();
+ }
+
+ $instance = new $configurator();
+
+ if (!($instance instanceof LoggerConfigurator)) {
+ trigger_error("log4php: Specified configurator class [$configurator] does not implement the LoggerConfigurator interface. Reverting to default configurator.", E_USER_WARNING);
+ return new LoggerConfiguratorDefault();
+ }
+
+ return $instance;
+ }
+
+ trigger_error("log4php: Invalid configurator specified. Expected either a string or a LoggerConfigurator instance. Reverting to default configurator.", E_USER_WARNING);
+ return new LoggerConfiguratorDefault();
+ }
+
+ /**
+ * Returns true if the log4php framework has been initialized.
+ * @return boolean
+ */
+ private static function isInitialized() {
+ return self::$initialized;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/LoggerAppender.php
@@ -0,0 +1,289 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Abstract class that defines output logs strategies.
+ *
+ * @version $Revision: 1374777 $
+ * @package log4php
+ */
+abstract class LoggerAppender extends LoggerConfigurable {
+
+ /**
+ * Set to true when the appender is closed. A closed appender will not
+ * accept any logging requests.
+ * @var boolean
+ */
+ protected $closed = false;
+
+ /**
+ * The first filter in the filter chain.
+ * @var LoggerFilter
+ */
+ protected $filter;
+
+ /**
+ * The appender's layout. Can be null if the appender does not use
+ * a layout.
+ * @var LoggerLayout
+ */
+ protected $layout;
+
+ /**
+ * Appender name. Used by other components to identify this appender.
+ * @var string
+ */
+ protected $name;
+
+ /**
+ * Appender threshold level. Events whose level is below the threshold
+ * will not be logged.
+ * @var LoggerLevel
+ */
+ protected $threshold;
+
+ /**
+ * Set to true if the appender requires a layout.
+ *
+ * True by default, appenders which do not use a layout should override
+ * this property to false.
+ *
+ * @var boolean
+ */
+ protected $requiresLayout = true;
+
+ /**
+ * Default constructor.
+ * @param string $name Appender name
+ */
+ public function __construct($name = '') {
+ $this->name = $name;
+
+ if ($this->requiresLayout) {
+ $this->layout = $this->getDefaultLayout();
+ }
+ }
+
+ public function __destruct() {
+ $this->close();
+ }
+
+ /**
+ * Returns the default layout for this appender. Can be overriden by
+ * derived appenders.
+ *
+ * @return LoggerLayout
+ */
+ public function getDefaultLayout() {
+ return new LoggerLayoutSimple();
+ }
+
+ /**
+ * Adds a filter to the end of the filter chain.
+ * @param LoggerFilter $filter add a new LoggerFilter
+ */
+ public function addFilter($filter) {
+ if ($this->filter === null) {
+ $this->filter = $filter;
+ } else {
+ $this->filter->addNext($filter);
+ }
+ }
+
+ /**
+ * Clears the filter chain by removing all the filters in it.
+ */
+ public function clearFilters() {
+ $this->filter = null;
+ }
+
+ /**
+ * Returns the first filter in the filter chain.
+ * The return value may be <i>null</i> if no is filter is set.
+ * @return LoggerFilter
+ */
+ public function getFilter() {
+ return $this->filter;
+ }
+
+ /**
+ * Returns the first filter in the filter chain.
+ * The return value may be <i>null</i> if no is filter is set.
+ * @return LoggerFilter
+ */
+ public function getFirstFilter() {
+ return $this->filter;
+ }
+
+ /**
+ * Performs threshold checks and invokes filters before delegating logging
+ * to the subclass' specific <i>append()</i> method.
+ * @see LoggerAppender::append()
+ * @param LoggerLoggingEvent $event
+ */
+ public function doAppend(LoggerLoggingEvent $event) {
+ if ($this->closed) {
+ return;
+ }
+
+ if (!$this->isAsSevereAsThreshold($event->getLevel())) {
+ return;
+ }
+
+ $filter = $this->getFirstFilter();
+ while ($filter !== null) {
+ switch ($filter->decide($event)) {
+ case LoggerFilter::DENY:
+ return;
+ case LoggerFilter::ACCEPT:
+ return $this->append($event);
+ case LoggerFilter::NEUTRAL:
+ $filter = $filter->getNext();
+ }
+ }
+ $this->append($event);
+ }
+
+ /**
+ * Sets the appender layout.
+ * @param LoggerLayout $layout
+ */
+ public function setLayout($layout) {
+ if ($this->requiresLayout()) {
+ $this->layout = $layout;
+ }
+ }
+
+ /**
+ * Returns the appender layout.
+ * @return LoggerLayout
+ */
+ public function getLayout() {
+ return $this->layout;
+ }
+
+ /**
+ * Configurators call this method to determine if the appender
+ * requires a layout.
+ *
+ * <p>If this method returns <i>true</i>, meaning that layout is required,
+ * then the configurator will configure a layout using the configuration
+ * information at its disposal. If this method returns <i>false</i>,
+ * meaning that a layout is not required, then layout configuration will be
+ * skipped even if there is available layout configuration
+ * information at the disposal of the configurator.</p>
+ *
+ * <p>In the rather exceptional case, where the appender
+ * implementation admits a layout but can also work without it, then
+ * the appender should return <i>true</i>.</p>
+ *
+ * @return boolean
+ */
+ public function requiresLayout() {
+ return $this->requiresLayout;
+ }
+
+ /**
+ * Retruns the appender name.
+ * @return string
+ */
+ public function getName() {
+ return $this->name;
+ }
+
+ /**
+ * Sets the appender name.
+ * @param string $name
+ */
+ public function setName($name) {
+ $this->name = $name;
+ }
+
+ /**
+ * Returns the appender's threshold level.
+ * @return LoggerLevel
+ */
+ public function getThreshold() {
+ return $this->threshold;
+ }
+
+ /**
+ * Sets the appender threshold.
+ *
+ * @param LoggerLevel|string $threshold Either a {@link LoggerLevel}
+ * object or a string equivalent.
+ * @see LoggerOptionConverter::toLevel()
+ */
+ public function setThreshold($threshold) {
+ $this->setLevel('threshold', $threshold);
+ }
+
+ /**
+ * Checks whether the message level is below the appender's threshold.
+ *
+ * If there is no threshold set, then the return value is always <i>true</i>.
+ *
+ * @param LoggerLevel $level
+ * @return boolean Returns true if level is greater or equal than
+ * threshold, or if the threshold is not set. Otherwise returns false.
+ */
+ public function isAsSevereAsThreshold($level) {
+ if ($this->threshold === null) {
+ return true;
+ }
+ return $level->isGreaterOrEqual($this->getThreshold());
+ }
+
+ /**
+ * Prepares the appender for logging.
+ *
+ * Derived appenders should override this method if option structure
+ * requires it.
+ */
+ public function activateOptions() {
+ $this->closed = false;
+ }
+
+ /**
+ * Forwards the logging event to the destination.
+ *
+ * Derived appenders should implement this method to perform actual logging.
+ *
+ * @param LoggerLoggingEvent $event
+ */
+ abstract protected function append(LoggerLoggingEvent $event);
+
+ /**
+ * Releases any resources allocated by the appender.
+ *
+ * Derived appenders should override this method to perform proper closing
+ * procedures.
+ */
+ public function close() {
+ $this->closed = true;
+ }
+
+ /** Triggers a warning for this logger with the given message. */
+ protected function warn($message) {
+ $id = get_class($this) . (empty($this->name) ? '' : ":{$this->name}");
+ trigger_error("log4php: [$id]: $message", E_USER_WARNING);
+ }
+
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/LoggerAppenderPool.php
@@ -0,0 +1,98 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Pool implmentation for LoggerAppender instances.
+ *
+ * The pool is used when configuring log4php. First all appender instances
+ * are created in the pool. Afterward, they are linked to loggers, each
+ * appender can be linked to multiple loggers. This makes sure duplicate
+ * appenders are not created.
+ *
+ * @version $Revision: 1350602 $
+ * @package log4php
+ */
+class LoggerAppenderPool {
+
+ /** Holds appenders indexed by their name */
+ public static $appenders = array();
+
+ /**
+ * Adds an appender to the pool.
+ * The appender must be named for this operation.
+ * @param LoggerAppender $appender
+ */
+ public static function add(LoggerAppender $appender) {
+ $name = $appender->getName();
+
+ if (empty($name)) {
+ trigger_error('log4php: Cannot add unnamed appender to pool.', E_USER_WARNING);
+ return;
+ }
+
+ if (isset(self::$appenders[$name])) {
+ trigger_error("log4php: Appender [$name] already exists in pool. Overwriting existing appender.", E_USER_WARNING);
+ }
+
+ self::$appenders[$name] = $appender;
+ }
+
+ /**
+ * Retrieves an appender from the pool by name.
+ * @param string $name Name of the appender to retrieve.
+ * @return LoggerAppender The named appender or NULL if no such appender
+ * exists in the pool.
+ */
+ public static function get($name) {
+ return isset(self::$appenders[$name]) ? self::$appenders[$name] : null;
+ }
+
+ /**
+ * Removes an appender from the pool by name.
+ * @param string $name Name of the appender to remove.
+ */
+ public static function delete($name) {
+ unset(self::$appenders[$name]);
+ }
+
+ /**
+ * Returns all appenders from the pool.
+ * @return array Array of LoggerAppender objects.
+ */
+ public static function getAppenders() {
+ return self::$appenders;
+ }
+
+ /**
+ * Checks whether an appender exists in the pool.
+ * @param string $name Name of the appender to look for.
+ * @return boolean TRUE if the appender with the given name exists.
+ */
+ public static function exists($name) {
+ return isset(self::$appenders[$name]);
+ }
+
+ /**
+ * Clears all appenders from the pool.
+ */
+ public static function clear() {
+ self::$appenders = array();
+ }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/library/log4php/LoggerAutoloader.php
@@ -0,0 +1,142 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+if (function_exists('__autoload')) {
+ trigger_error("log4php: It looks like your code is using an __autoload() function. log4php uses spl_autoload_register() which will bypass your __autoload() function and may break autoloading.", E_USER_WARNING);
+}
+
+spl_autoload_register(array('LoggerAutoloader', 'autoload'));
+
+/**
+ * Class autoloader.
+ *
+ * @package log4php
+ * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+ * @version $Revision: 1394956 $
+ */
+class LoggerAutoloader {
+
+ /** Maps classnames to files containing the class. */
+ private static $classes = array(
+
+ // Base
+ 'LoggerAppender' => '/LoggerAppender.php',
+ 'LoggerAppenderPool' => '/LoggerAppenderPool.php',
+ 'LoggerConfigurable' => '/LoggerConfigurable.php',
+ 'LoggerConfigurator' => '/LoggerConfigurator.php',
+ 'LoggerException' => '/LoggerException.php',
+ 'LoggerFilter' => '/LoggerFilter.php',
+ 'LoggerHierarchy' => '/LoggerHierarchy.php',
+ 'LoggerLevel' => '/LoggerLevel.php',
+ 'LoggerLocationInfo' => '/LoggerLocationInfo.php',
+ 'LoggerLoggingEvent' => '/LoggerLoggingEvent.php',
+ 'LoggerMDC' => '/LoggerMDC.php',
+ 'LoggerNDC' => '/LoggerNDC.php',
+ 'LoggerLayout' => '/LoggerLayout.php',
+ 'LoggerReflectionUtils' => '/LoggerReflectionUtils.php',
+ 'LoggerRoot' => '/LoggerRoot.php',
+ 'LoggerThrowableInformation' => '/LoggerThrowableInformation.php',
+
+ // Appenders
+ 'LoggerAppenderConsole' => '/appenders/LoggerAppenderConsole.php',
+ 'LoggerAppenderDailyFile' => '/appenders/LoggerAppenderDailyFile.php',
+ 'LoggerAppenderEcho' => '/appenders/LoggerAppenderEcho.php',
+ 'LoggerAppenderFile' => '/appenders/LoggerAppenderFile.php',
+ 'LoggerAppenderMail' => '/appenders/LoggerAppenderMail.php',
+ 'LoggerAppenderMailEvent' => '/appenders/LoggerAppenderMailEvent.php',
+ 'LoggerAppenderMongoDB' => '/appenders/LoggerAppenderMongoDB.php',
+ 'LoggerAppenderNull' => '/appenders/LoggerAppenderNull.php',
+ 'LoggerAppenderFirePHP' => '/appenders/LoggerAppenderFirePHP.php',
+ 'LoggerAppenderPDO' => '/appenders/LoggerAppenderPDO.php',
+ 'LoggerAppenderPhp' => '/appenders/LoggerAppenderPhp.php',
+ 'LoggerAppenderRollingFile' => '/appenders/LoggerAppenderRollingFile.php',
+ 'LoggerAppenderSocket' => '/appenders/LoggerAppenderSocket.php',
+ 'LoggerAppenderSyslog' => '/appenders/LoggerAppenderSyslog.php',
+
+ // Configurators
+ 'LoggerConfigurationAdapter' => '/configurators/LoggerConfigurationAdapter.php',
+ 'LoggerConfigurationAdapterINI' => '/configurators/LoggerConfigurationAdapterINI.php',
+ 'LoggerConfigurationAdapterPHP' => '/configurators/LoggerConfigurationAdapterPHP.php',
+ 'LoggerConfigurationAdapterXML' => '/configurators/LoggerConfigurationAdapterXML.php',
+ 'LoggerConfiguratorDefault' => '/configurators/LoggerConfiguratorDefault.php',
+
+ // Filters
+ 'LoggerFilterDenyAll' => '/filters/LoggerFilterDenyAll.php',
+ 'LoggerFilterLevelMatch' => '/filters/LoggerFilterLevelMatch.php',
+ 'LoggerFilterLevelRange' => '/filters/LoggerFilterLevelRange.php',
+ 'LoggerFilterStringMatch' => '/filters/LoggerFilterStringMatch.php',
+
+ // Helpers
+ 'LoggerFormattingInfo' => '/helpers/LoggerFormattingInfo.php',
+ 'LoggerOptionConverter' => '/helpers/LoggerOptionConverter.php',
+ 'LoggerPatternParser' => '/helpers/LoggerPatternParser.php',
+ 'LoggerUtils' => '/helpers/LoggerUtils.php',
+
+ // Pattern converters
+ 'LoggerPatternConverter' => '/pattern/LoggerPatternConverter.php',
+ 'LoggerPatternConverterClass' => '/pattern/LoggerPatternConverterClass.php',
+ 'LoggerPatternConverterCookie' => '/pattern/LoggerPatternConverterCookie.php',
+ 'LoggerPatternConverterDate' => '/pattern/LoggerPatternConverterDate.php',
+ 'LoggerPatternConverterEnvironment' => '/pattern/LoggerPatternConverterEnvironment.php',
+ 'LoggerPatternConverterFile' => '/pattern/LoggerPatternConverterFile.php',
+ 'LoggerPatternConverterLevel' => '/pattern/LoggerPatternConverterLevel.php',
+ 'LoggerPatternConverterLine' => '/pattern/LoggerPatternConverterLine.php',
+ 'LoggerPatternConverterLiteral' => '/pattern/LoggerPatternConverterLiteral.php',
+ 'LoggerPatternConverterLocation' => '/pattern/LoggerPatternConverterLocation.php',
+ 'LoggerPatternConverterLogger' => '/pattern/LoggerPatternConverterLogger.php',
+ 'LoggerPatternConverterMDC' => '/pattern/LoggerPatternConverterMDC.php',
+ 'LoggerPatternConverterMessage' => '/pattern/LoggerPatternConverterMessage.php',
+ 'LoggerPatternConverterMethod' => '/pattern/LoggerPatternConverterMethod.php',
+ 'LoggerPatternConverterNDC' => '/pattern/LoggerPatternConverterNDC.php',
+ 'LoggerPatternConverterNewLine' => '/pattern/LoggerPatternConverterNewLine.php',
+ 'LoggerPatternConverterProcess' => '/pattern/LoggerPatternConverterProcess.php',
+ 'LoggerPatternConverterRelative' => '/pattern/LoggerPatternConverterRelative.php',
+ 'LoggerPatternConverterRequest' => '/pattern/LoggerPatternConverterRequest.php',
+ 'LoggerPatternConverterServer' => '/pattern/LoggerPatternConverterServer.php',
+ 'LoggerPatternConverterSession' => '/pattern/LoggerPatternConverterSession.php',
+ 'LoggerPatternConverterSessionID' => '/pattern/LoggerPatternConverterSessionID.php',
+ 'LoggerPatternConverterSuperglobal' => '/pattern/LoggerPatternConverterSuperglobal.php',
+ 'LoggerPatternConverterThrowable' => '/pattern/LoggerPatternConverterThrowable.php',
+
+ // Layouts
+ 'LoggerLayoutHtml' => '/layouts/LoggerLayoutHtml.php',
+ 'LoggerLayoutPattern' => '/layouts/LoggerLayoutPattern.php',
+ 'LoggerLayoutSerialized' => '/layouts/LoggerLayoutSerialized.php',
+ 'LoggerLayoutSimple' => '/layouts/LoggerLayoutSimple.php',
+ 'LoggerLayoutTTCC' => '/layouts/LoggerLayoutTTCC.php',
+ 'LoggerLayoutXml' => '/layouts/LoggerLayoutXml.php',
+
+ // Renderers
+ 'LoggerRendererDefault' => '/renderers/LoggerRendererDefault.php',
+ 'LoggerRendererException' => '/renderers/LoggerRendererException.php',
+ 'LoggerRendererMap' => '/renderers/LoggerRendererMap.php',
+ 'LoggerRenderer' => '/renderers/LoggerRenderer.php',
+ );
+
+ /**
+ * Loads a class.
+ * @param string $className The name of the class to load.
+ */
+ public static function autoload($className) {
+ if (isset(self::$classes[$className])) {
+ include dirname(__FILE__) . self::$classes[$className];
+ }
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/LoggerConfigurable.php
@@ -0,0 +1,116 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * A base class from which all classes which have configurable properties are
+ * extended. Provides a generic setter with integrated validation.
+ *
+ * @package log4php
+ * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+ * @version $Revision $
+ * @since 2.2
+ */
+abstract class LoggerConfigurable {
+
+ /** Setter function for boolean type. */
+ protected function setBoolean($property, $value) {
+ try {
+ $this->$property = LoggerOptionConverter::toBooleanEx($value);
+ } catch (Exception $ex) {
+ $value = var_export($value, true);
+ $this->warn("Invalid value given for '$property' property: [$value]. Expected a boolean value. Property not changed.");
+ }
+ }
+
+ /** Setter function for integer type. */
+ protected function setInteger($property, $value) {
+ try {
+ $this->$property = LoggerOptionConverter::toIntegerEx($value);
+ } catch (Exception $ex) {
+ $value = var_export($value, true);
+ $this->warn("Invalid value given for '$property' property: [$value]. Expected an integer. Property not changed.");
+ }
+ }
+
+ /** Setter function for LoggerLevel values. */
+ protected function setLevel($property, $value) {
+ try {
+ $this->$property = LoggerOptionConverter::toLevelEx($value);
+ } catch (Exception $ex) {
+ $value = var_export($value, true);
+ $this->warn("Invalid value given for '$property' property: [$value]. Expected a level value. Property not changed.");
+ }
+ }
+
+ /** Setter function for integer type. */
+ protected function setPositiveInteger($property, $value) {
+ try {
+ $this->$property = LoggerOptionConverter::toPositiveIntegerEx($value);
+ } catch (Exception $ex) {
+ $value = var_export($value, true);
+ $this->warn("Invalid value given for '$property' property: [$value]. Expected a positive integer. Property not changed.");
+ }
+ }
+
+ /** Setter for file size. */
+ protected function setFileSize($property, $value) {
+ try {
+ $this->$property = LoggerOptionConverter::toFileSizeEx($value);
+ } catch (Exception $ex) {
+ $value = var_export($value, true);
+ $this->warn("Invalid value given for '$property' property: [$value]. Expected a file size value. Property not changed.");
+ }
+ }
+
+ /** Setter function for numeric type. */
+ protected function setNumeric($property, $value) {
+ try {
+ $this->$property = LoggerOptionConverter::toNumericEx($value);
+ } catch (Exception $ex) {
+ $value = var_export($value, true);
+ $this->warn("Invalid value given for '$property' property: [$value]. Expected a number. Property not changed.");
+ }
+ }
+
+ /** Setter function for string type. */
+ protected function setString($property, $value, $nullable = false) {
+ if ($value === null) {
+ if ($nullable) {
+ $this->$property = null;
+ } else {
+ $this->warn("Null value given for '$property' property. Expected a string. Property not changed.");
+ }
+ } else {
+ try {
+ $value = LoggerOptionConverter::toStringEx($value);
+ $this->$property = LoggerOptionConverter::substConstants($value);
+ } catch (Exception $ex) {
+ $value = var_export($value, true);
+ $this->warn("Invalid value given for '$property' property: [$value]. Expected a string. Property not changed.");
+ }
+ }
+ }
+
+ /** Triggers a warning. */
+ protected function warn($message) {
+ $class = get_class($this);
+ trigger_error("log4php: $class: $message", E_USER_WARNING);
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/LoggerConfigurator.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Interface for logger configurators.
+ *
+ * @package log4php
+ * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+ * @version $Revision: 1213710 $
+ * @since 2.2
+ */
+interface LoggerConfigurator {
+ /**
+ * Configures log4php based on the given configuration.
+ *
+ * All configurators implementations must implement this interface.
+ *
+ * @param LoggerHierarchy $hierarchy The hierarchy on which to perform
+ * the configuration.
+ * @param mixed $input Either path to the config file or the
+ * configuration as an array.
+ */
+ public function configure(LoggerHierarchy $hierarchy, $input = null);
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/library/log4php/LoggerException.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * LoggerException class
+ *
+ * @version $Revision: 1334369 $
+ * @package log4php
+ */
+class LoggerException extends Exception {
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/LoggerFilter.php
@@ -0,0 +1,126 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Users should extend this class to implement customized logging
+ * event filtering. Note that {@link LoggerCategory} and {@link LoggerAppender},
+ * the parent class of all standard
+ * appenders, have built-in filtering rules. It is suggested that you
+ * first use and understand the built-in rules before rushing to write
+ * your own custom filters.
+ *
+ * <p>This abstract class assumes and also imposes that filters be
+ * organized in a linear chain. The {@link #decide
+ * decide(LoggerLoggingEvent)} method of each filter is called sequentially,
+ * in the order of their addition to the chain.
+ *
+ * <p>The {@link decide()} method must return one
+ * of the integer constants {@link LoggerFilter::DENY},
+ * {@link LoggerFilter::NEUTRAL} or {@link LoggerFilter::ACCEPT}.
+ *
+ * <p>If the value {@link LoggerFilter::DENY} is returned, then the log event is
+ * dropped immediately without consulting with the remaining
+ * filters.
+ *
+ * <p>If the value {@link LoggerFilter::NEUTRAL} is returned, then the next filter
+ * in the chain is consulted. If there are no more filters in the
+ * chain, then the log event is logged. Thus, in the presence of no
+ * filters, the default behaviour is to log all logging events.
+ *
+ * <p>If the value {@link LoggerFilter::ACCEPT} is returned, then the log
+ * event is logged without consulting the remaining filters.
+ *
+ * <p>The philosophy of log4php filters is largely inspired from the
+ * Linux ipchains.
+ *
+ * @version $Revision: 1213283 $
+ * @package log4php
+ */
+abstract class LoggerFilter extends LoggerConfigurable {
+
+ /**
+ * The log event must be logged immediately without consulting with
+ * the remaining filters, if any, in the chain.
+ */
+ const ACCEPT = 1;
+
+ /**
+ * This filter is neutral with respect to the log event. The
+ * remaining filters, if any, should be consulted for a final decision.
+ */
+ const NEUTRAL = 0;
+
+ /**
+ * The log event must be dropped immediately without consulting
+ * with the remaining filters, if any, in the chain.
+ */
+ const DENY = -1;
+
+ /**
+ * @var LoggerFilter Points to the next {@link LoggerFilter} in the filter chain.
+ */
+ protected $next;
+
+ /**
+ * Usually filters options become active when set. We provide a
+ * default do-nothing implementation for convenience.
+ */
+ public function activateOptions() {
+ }
+
+ /**
+ * Decide what to do.
+ * <p>If the decision is {@link LoggerFilter::DENY}, then the event will be
+ * dropped. If the decision is {@link LoggerFilter::NEUTRAL}, then the next
+ * filter, if any, will be invoked. If the decision is {@link LoggerFilter::ACCEPT} then
+ * the event will be logged without consulting with other filters in
+ * the chain.
+ *
+ * @param LoggerLoggingEvent $event The {@link LoggerLoggingEvent} to decide upon.
+ * @return integer {@link LoggerFilter::NEUTRAL} or {@link LoggerFilter::DENY}|{@link LoggerFilter::ACCEPT}
+ */
+ public function decide(LoggerLoggingEvent $event) {
+ return self::NEUTRAL;
+ }
+
+ /**
+ * Adds a new filter to the filter chain this filter is a part of.
+ * If this filter has already and follow up filter, the param filter
+ * is passed on until it is the last filter in chain.
+ *
+ * @param $filter - the filter to add to this chain
+ */
+ public function addNext($filter) {
+ if ($this->next !== null) {
+ $this->next->addNext($filter);
+ } else {
+ $this->next = $filter;
+ }
+ }
+
+ /**
+ * Returns the next filter in this chain
+ * @return the next filter
+ */
+ public function getNext() {
+ return $this->next;
+ }
+
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/LoggerHierarchy.php
@@ -0,0 +1,257 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * This class is specialized in retrieving loggers by name and also maintaining
+ * the logger hierarchy. The logger hierarchy is dealing with the several Log-Levels
+ * Logger can have. From log4j website:
+ *
+ * "A logger is said to be an ancestor of another logger if its name followed
+ * by a dot is a prefix of the descendant logger name. A logger is said to be
+ * a parent of a child logger if there are no ancestors between itself and the
+ * descendant logger."
+ *
+ * Child Loggers do inherit their Log-Levels from their Ancestors. They can
+ * increase their Log-Level compared to their Ancestors, but they cannot decrease it.
+ *
+ * <p>The casual user does not have to deal with this class directly.</p>
+ *
+ * <p>The structure of the logger hierarchy is maintained by the
+ * getLogger method. The hierarchy is such that children link
+ * to their parent but parents do not have any pointers to their
+ * children. Moreover, loggers can be instantiated in any order, in
+ * particular descendant before ancestor.</p>
+ *
+ * <p>In case a descendant is created before a particular ancestor,
+ * then it creates a provision node for the ancestor and adds itself
+ * to the provision node. Other descendants of the same ancestor add
+ * themselves to the previously created provision node.</p>
+ *
+ * @version $Revision: 1394956 $
+ * @package log4php
+ */
+class LoggerHierarchy {
+
+ /** Array holding all Logger instances. */
+ protected $loggers = array();
+
+ /**
+ * The root logger.
+ * @var RootLogger
+ */
+ protected $root;
+
+ /**
+ * The logger renderer map.
+ * @var LoggerRendererMap
+ */
+ protected $rendererMap;
+
+ /**
+ * Main level threshold. Events with lower level will not be logged by any
+ * logger, regardless of it's configuration.
+ * @var LoggerLevel
+ */
+ protected $threshold;
+
+ /**
+ * Creates a new logger hierarchy.
+ * @param LoggerRoot $root The root logger.
+ */
+ public function __construct(LoggerRoot $root) {
+ $this->root = $root;
+ $this->setThreshold(LoggerLevel::getLevelAll());
+ $this->rendererMap = new LoggerRendererMap();
+ }
+
+ /**
+ * Clears all loggers.
+ */
+ public function clear() {
+ $this->loggers = array();
+ }
+
+ /**
+ * Check if the named logger exists in the hierarchy.
+ * @param string $name
+ * @return boolean
+ */
+ public function exists($name) {
+ return isset($this->loggers[$name]);
+ }
+
+ /**
+ * Returns all the currently defined loggers in this hierarchy as an array.
+ * @return array
+ */
+ public function getCurrentLoggers() {
+ return array_values($this->loggers);
+ }
+
+ /**
+ * Returns a named logger instance logger. If it doesn't exist, one is created.
+ *
+ * @param string $name Logger name
+ * @return Logger Logger instance.
+ */
+ public function getLogger($name) {
+ if (!isset($this->loggers[$name])) {
+ $logger = new Logger($name);
+
+ $nodes = explode('.', $name);
+ $firstNode = array_shift($nodes);
+
+ // if name is not a first node but another first node is their
+ if ($firstNode != $name and isset($this->loggers[$firstNode])) {
+ $logger->setParent($this->loggers[$firstNode]);
+ } else {
+ // if there is no father, set root logger as father
+ $logger->setParent($this->root);
+ }
+
+ // if there are more nodes than one
+ if (count($nodes) > 0) {
+ // find parent node
+ foreach ($nodes as $node) {
+ $parentNode = "$firstNode.$node";
+ if (isset($this->loggers[$parentNode]) and $parentNode != $name) {
+ $logger->setParent($this->loggers[$parentNode]);
+ }
+ $firstNode .= ".$node";
+ }
+ }
+
+ $this->loggers[$name] = $logger;
+ }
+
+ return $this->loggers[$name];
+ }
+
+ /**
+ * Returns the logger renderer map.
+ * @return LoggerRendererMap
+ */
+ public function getRendererMap() {
+ return $this->rendererMap;
+ }
+
+ /**
+ * Returns the root logger.
+ * @return LoggerRoot
+ */
+ public function getRootLogger() {
+ return $this->root;
+ }
+
+ /**
+ * Returns the main threshold level.
+ * @return LoggerLevel
+ */
+ public function getThreshold() {
+ return $this->threshold;
+ }
+
+ /**
+ * Returns true if the hierarchy is disabled for given log level and false
+ * otherwise.
+ * @return boolean
+ */
+ public function isDisabled(LoggerLevel $level) {
+ return ($this->threshold->toInt() > $level->toInt());
+ }
+
+ /**
+ * Reset all values contained in this hierarchy instance to their
+ * default.
+ *
+ * This removes all appenders from all loggers, sets
+ * the level of all non-root loggers to <i>null</i>,
+ * sets their additivity flag to <i>true</i> and sets the level
+ * of the root logger to {@link LOGGER_LEVEL_DEBUG}.
+ *
+ * <p>Existing loggers are not removed. They are just reset.
+ *
+ * <p>This method should be used sparingly and with care as it will
+ * block all logging until it is completed.</p>
+ */
+ public function resetConfiguration() {
+ $root = $this->getRootLogger();
+
+ $root->setLevel(LoggerLevel::getLevelDebug());
+ $this->setThreshold(LoggerLevel::getLevelAll());
+ $this->shutDown();
+
+ foreach ($this->loggers as $logger) {
+ $logger->setLevel(null);
+ $logger->setAdditivity(true);
+ $logger->removeAllAppenders();
+ }
+
+ $this->rendererMap->reset();
+ LoggerAppenderPool::clear();
+ }
+
+ /**
+ * Sets the main threshold level.
+ * @param LoggerLevel $l
+ */
+ public function setThreshold(LoggerLevel $threshold) {
+ $this->threshold = $threshold;
+ }
+
+ /**
+ * Shutting down a hierarchy will <i>safely</i> close and remove
+ * all appenders in all loggers including the root logger.
+ *
+ * The shutdown method is careful to close nested
+ * appenders before closing regular appenders. This is allows
+ * configurations where a regular appender is attached to a logger
+ * and again to a nested appender.
+ *
+ * @todo Check if the last paragraph is correct.
+ */
+ public function shutdown() {
+ $this->root->removeAllAppenders();
+
+ foreach ($this->loggers as $logger) {
+ $logger->removeAllAppenders();
+ }
+ }
+
+ /**
+ * Prints the current Logger hierarchy tree. Useful for debugging.
+ */
+ public function printHierarchy() {
+ $this->printHierarchyInner($this->getRootLogger(), 0);
+ }
+
+ private function printHierarchyInner(Logger $current, $level) {
+ for ($i = 0; $i < $level; $i++) {
+ echo ($i == $level - 1) ? "|--" : "| ";
+ }
+ echo $current->getName() . "\n";
+
+ foreach ($this->loggers as $logger) {
+ if ($logger->getParent() == $current) {
+ $this->printHierarchyInner($logger, $level + 1);
+ }
+ }
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/LoggerLayout.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Extend this abstract class to create your own log layout format.
+ *
+ * @version $Revision: 1213283 $
+ * @package log4php
+ */
+abstract class LoggerLayout extends LoggerConfigurable {
+ /**
+ * Activates options for this layout.
+ * Override this method if you have options to be activated.
+ */
+ public function activateOptions() {
+ return true;
+ }
+
+ /**
+ * Override this method to create your own layout format.
+ *
+ * @param LoggerLoggingEvent
+ * @return string
+ */
+ public function format(LoggerLoggingEvent $event) {
+ return $event->getRenderedMessage();
+ }
+
+ /**
+ * Returns the content type output by this layout.
+ * @return string
+ */
+ public function getContentType() {
+ return "text/plain";
+ }
+
+ /**
+ * Returns the footer for the layout format.
+ * @return string
+ */
+ public function getFooter() {
+ return null;
+ }
+
+ /**
+ * Returns the header for the layout format.
+ * @return string
+ */
+ public function getHeader() {
+ return null;
+ }
+
+ /** Triggers a warning for this layout with the given message. */
+ protected function warn($message) {
+ trigger_error("log4php: [" . get_class($this) . "]: $message", E_USER_WARNING);
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/LoggerLevel.php
@@ -0,0 +1,274 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Defines the minimum set of levels recognized by the system, that is
+ * <i>OFF</i>, <i>FATAL</i>, <i>ERROR</i>,
+ * <i>WARN</i>, <i>INFO</i>, <i>DEBUG</i> and
+ * <i>ALL</i>.
+ *
+ * <p>The <i>LoggerLevel</i> class may be subclassed to define a larger
+ * level set.</p>
+ *
+ * @version $Revision: 1379729 $
+ * @package log4php
+ * @since 0.5
+ */
+class LoggerLevel {
+
+ const OFF = 2147483647;
+ const FATAL = 50000;
+ const ERROR = 40000;
+ const WARN = 30000;
+ const INFO = 20000;
+ const DEBUG = 10000;
+ const TRACE = 5000;
+ const ALL = -2147483647;
+
+ /** Integer level value. */
+ private $level;
+
+ /** Contains a list of instantiated levels. */
+ private static $levelMap;
+
+ /** String representation of the level. */
+ private $levelStr;
+
+ /**
+ * Equivalent syslog level.
+ * @var integer
+ */
+ private $syslogEquivalent;
+
+ /**
+ * Constructor
+ *
+ * @param integer $level
+ * @param string $levelStr
+ * @param integer $syslogEquivalent
+ */
+ private function __construct($level, $levelStr, $syslogEquivalent) {
+ $this->level = $level;
+ $this->levelStr = $levelStr;
+ $this->syslogEquivalent = $syslogEquivalent;
+ }
+
+ /**
+ * Compares two logger levels.
+ *
+ * @param LoggerLevels $other
+ * @return boolean
+ */
+ public function equals($other) {
+ if ($other instanceof LoggerLevel) {
+ if ($this->level == $other->level) {
+ return true;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Returns an Off Level
+ * @return LoggerLevel
+ */
+ public static function getLevelOff() {
+ if (!isset(self::$levelMap[LoggerLevel::OFF])) {
+ self::$levelMap[LoggerLevel::OFF] = new LoggerLevel(LoggerLevel::OFF, 'OFF', LOG_ALERT);
+ }
+ return self::$levelMap[LoggerLevel::OFF];
+ }
+
+ /**
+ * Returns a Fatal Level
+ * @return LoggerLevel
+ */
+ public static function getLevelFatal() {
+ if (!isset(self::$levelMap[LoggerLevel::FATAL])) {
+ self::$levelMap[LoggerLevel::FATAL] = new LoggerLevel(LoggerLevel::FATAL, 'FATAL', LOG_ALERT);
+ }
+ return self::$levelMap[LoggerLevel::FATAL];
+ }
+
+ /**
+ * Returns an Error Level
+ * @return LoggerLevel
+ */
+ public static function getLevelError() {
+ if (!isset(self::$levelMap[LoggerLevel::ERROR])) {
+ self::$levelMap[LoggerLevel::ERROR] = new LoggerLevel(LoggerLevel::ERROR, 'ERROR', LOG_ERR);
+ }
+ return self::$levelMap[LoggerLevel::ERROR];
+ }
+
+ /**
+ * Returns a Warn Level
+ * @return LoggerLevel
+ */
+ public static function getLevelWarn() {
+ if (!isset(self::$levelMap[LoggerLevel::WARN])) {
+ self::$levelMap[LoggerLevel::WARN] = new LoggerLevel(LoggerLevel::WARN, 'WARN', LOG_WARNING);
+ }
+ return self::$levelMap[LoggerLevel::WARN];
+ }
+
+ /**
+ * Returns an Info Level
+ * @return LoggerLevel
+ */
+ public static function getLevelInfo() {
+ if (!isset(self::$levelMap[LoggerLevel::INFO])) {
+ self::$levelMap[LoggerLevel::INFO] = new LoggerLevel(LoggerLevel::INFO, 'INFO', LOG_INFO);
+ }
+ return self::$levelMap[LoggerLevel::INFO];
+ }
+
+ /**
+ * Returns a Debug Level
+ * @return LoggerLevel
+ */
+ public static function getLevelDebug() {
+ if (!isset(self::$levelMap[LoggerLevel::DEBUG])) {
+ self::$levelMap[LoggerLevel::DEBUG] = new LoggerLevel(LoggerLevel::DEBUG, 'DEBUG', LOG_DEBUG);
+ }
+ return self::$levelMap[LoggerLevel::DEBUG];
+ }
+
+ /**
+ * Returns a Trace Level
+ * @return LoggerLevel
+ */
+ public static function getLevelTrace() {
+ if (!isset(self::$levelMap[LoggerLevel::TRACE])) {
+ self::$levelMap[LoggerLevel::TRACE] = new LoggerLevel(LoggerLevel::TRACE, 'TRACE', LOG_DEBUG);
+ }
+ return self::$levelMap[LoggerLevel::TRACE];
+ }
+
+ /**
+ * Returns an All Level
+ * @return LoggerLevel
+ */
+ public static function getLevelAll() {
+ if (!isset(self::$levelMap[LoggerLevel::ALL])) {
+ self::$levelMap[LoggerLevel::ALL] = new LoggerLevel(LoggerLevel::ALL, 'ALL', LOG_DEBUG);
+ }
+ return self::$levelMap[LoggerLevel::ALL];
+ }
+
+ /**
+ * Return the syslog equivalent of this level as an integer.
+ * @return integer
+ */
+ public function getSyslogEquivalent() {
+ return $this->syslogEquivalent;
+ }
+
+ /**
+ * Returns <i>true</i> if this level has a higher or equal
+ * level than the level passed as argument, <i>false</i>
+ * otherwise.
+ *
+ * @param LoggerLevel $other
+ * @return boolean
+ */
+ public function isGreaterOrEqual($other) {
+ return $this->level >= $other->level;
+ }
+
+ /**
+ * Returns the string representation of this level.
+ * @return string
+ */
+ public function toString() {
+ return $this->levelStr;
+ }
+
+ /**
+ * Returns the string representation of this level.
+ * @return string
+ */
+ public function __toString() {
+ return $this->toString();
+ }
+
+ /**
+ * Returns the integer representation of this level.
+ * @return integer
+ */
+ public function toInt() {
+ return $this->level;
+ }
+
+ /**
+ * Convert the input argument to a level. If the conversion fails, then
+ * this method returns the provided default level.
+ *
+ * @param mixed $arg The value to convert to level.
+ * @param LoggerLevel $default Value to return if conversion is not possible.
+ * @return LoggerLevel
+ */
+ public static function toLevel($arg, $defaultLevel = null) {
+ if (is_int($arg)) {
+ switch ($arg) {
+ case self::ALL:
+ return self::getLevelAll();
+ case self::TRACE:
+ return self::getLevelTrace();
+ case self::DEBUG:
+ return self::getLevelDebug();
+ case self::INFO:
+ return self::getLevelInfo();
+ case self::WARN:
+ return self::getLevelWarn();
+ case self::ERROR:
+ return self::getLevelError();
+ case self::FATAL:
+ return self::getLevelFatal();
+ case self::OFF:
+ return self::getLevelOff();
+ default:
+ return $defaultLevel;
+ }
+ } else {
+ switch (strtoupper($arg)) {
+ case 'ALL':
+ return self::getLevelAll();
+ case 'TRACE':
+ return self::getLevelTrace();
+ case 'DEBUG':
+ return self::getLevelDebug();
+ case 'INFO':
+ return self::getLevelInfo();
+ case 'WARN':
+ return self::getLevelWarn();
+ case 'ERROR':
+ return self::getLevelError();
+ case 'FATAL':
+ return self::getLevelFatal();
+ case 'OFF':
+ return self::getLevelOff();
+ default:
+ return $defaultLevel;
+ }
+ }
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/LoggerLocationInfo.php
@@ -0,0 +1,103 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * The internal representation of caller location information.
+ *
+ * @version $Revision: 1379738 $
+ * @package log4php
+ * @since 0.3
+ */
+class LoggerLocationInfo {
+
+ /** The value to return when the location information is not available. */
+ const LOCATION_INFO_NA = 'NA';
+
+ /**
+ * Caller line number.
+ * @var integer
+ */
+ protected $lineNumber;
+
+ /**
+ * Caller file name.
+ * @var string
+ */
+ protected $fileName;
+
+ /**
+ * Caller class name.
+ * @var string
+ */
+ protected $className;
+
+ /**
+ * Caller method name.
+ * @var string
+ */
+ protected $methodName;
+
+ /**
+ * All the information combined.
+ * @var string
+ */
+ protected $fullInfo;
+
+ /**
+ * Instantiate location information based on a {@link PHP_MANUAL#debug_backtrace}.
+ *
+ * @param array $trace
+ * @param mixed $caller
+ */
+ public function __construct($trace, $fqcn = null) {
+ $this->lineNumber = isset($trace['line']) ? $trace['line'] : null;
+ $this->fileName = isset($trace['file']) ? $trace['file'] : null;
+ $this->className = isset($trace['class']) ? $trace['class'] : null;
+ $this->methodName = isset($trace['function']) ? $trace['function'] : null;
+ $this->fullInfo = $this->getClassName() . '.' . $this->getMethodName() .
+ '(' . $this->getFileName() . ':' . $this->getLineNumber() . ')';
+ }
+
+ /** Returns the caller class name. */
+ public function getClassName() {
+ return ($this->className === null) ? self::LOCATION_INFO_NA : $this->className;
+ }
+
+ /** Returns the caller file name. */
+ public function getFileName() {
+ return ($this->fileName === null) ? self::LOCATION_INFO_NA : $this->fileName;
+ }
+
+ /** Returns the caller line number. */
+ public function getLineNumber() {
+ return ($this->lineNumber === null) ? self::LOCATION_INFO_NA : $this->lineNumber;
+ }
+
+ /** Returns the caller method name. */
+ public function getMethodName() {
+ return ($this->methodName === null) ? self::LOCATION_INFO_NA : $this->methodName;
+ }
+
+ /** Returns the full information of the caller. */
+ public function getFullInfo() {
+ return ($this->fullInfo === null) ? self::LOCATION_INFO_NA : $this->fullInfo;
+ }
+
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/LoggerLoggingEvent.php
@@ -0,0 +1,370 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * The internal representation of logging event.
+ *
+ * @version $Revision: 1382273 $
+ * @package log4php
+ */
+class LoggerLoggingEvent {
+
+ private static $startTime;
+
+ /**
+ * @var string Fully Qualified Class Name of the calling category class.
+ */
+ private $fqcn;
+
+ /**
+ * @var Logger reference
+ */
+ private $logger;
+
+ /**
+ * The category (logger) name.
+ * This field will be marked as private in future
+ * releases. Please do not access it directly.
+ * Use the {@link getLoggerName()} method instead.
+ * @deprecated
+ */
+ private $categoryName;
+
+ /**
+ * Level of the logging event.
+ * @var LoggerLevel
+ */
+ protected $level;
+
+ /**
+ * The nested diagnostic context (NDC) of logging event.
+ * @var string
+ */
+ private $ndc;
+
+ /**
+ * Have we tried to do an NDC lookup? If we did, there is no need
+ * to do it again. Note that its value is always false when
+ * serialized. Thus, a receiving SocketNode will never use it's own
+ * (incorrect) NDC. See also writeObject method.
+ * @var boolean
+ */
+ private $ndcLookupRequired = true;
+
+ /**
+ * @var mixed The application supplied message of logging event.
+ */
+ private $message;
+
+ /**
+ * The application supplied message rendered through the log4php
+ * objet rendering mechanism. At present renderedMessage == message.
+ * @var string
+ */
+ private $renderedMessage;
+
+ /**
+ * The name of thread in which this logging event was generated.
+ * log4php saves here the process id via {@link PHP_MANUAL#getmypid getmypid()}
+ * @var mixed
+ */
+ private $threadName;
+
+ /**
+ * The number of seconds elapsed from 1/1/1970 until logging event
+ * was created plus microseconds if available.
+ * @var float
+ */
+ public $timeStamp;
+
+ /**
+ * @var LoggerLocationInfo Location information for the caller.
+ */
+ private $locationInfo;
+
+ /**
+ * @var LoggerThrowableInformation log4php internal representation of throwable
+ */
+ private $throwableInfo;
+
+ /**
+ * Instantiate a LoggingEvent from the supplied parameters.
+ *
+ * Except {@link $timeStamp} all the other fields of
+ * LoggerLoggingEvent are filled when actually needed.
+ *
+ * @param string $fqcn name of the caller class.
+ * @param mixed $logger The {@link Logger} category of this event or the logger name.
+ * @param LoggerLevel $level The level of this event.
+ * @param mixed $message The message of this event.
+ * @param integer $timeStamp the timestamp of this logging event.
+ * @param Exception $throwable The throwable associated with logging event
+ */
+ public function __construct($fqcn, $logger, LoggerLevel $level, $message, $timeStamp = null, $throwable = null) {
+ $this->fqcn = $fqcn;
+ if ($logger instanceof Logger) {
+ $this->logger = $logger;
+ $this->categoryName = $logger->getName();
+ } else {
+ $this->categoryName = strval($logger);
+ }
+ $this->level = $level;
+ $this->message = $message;
+ if ($timeStamp !== null && is_numeric($timeStamp)) {
+ $this->timeStamp = $timeStamp;
+ } else {
+ $this->timeStamp = microtime(true);
+ }
+
+ if ($throwable !== null && $throwable instanceof Exception) {
+ $this->throwableInfo = new LoggerThrowableInformation($throwable);
+ }
+ }
+
+ /**
+ * Returns the full qualified classname.
+ * TODO: PHP does contain namespaces in 5.3. Those should be returned too,
+ */
+ public function getFullQualifiedClassname() {
+ return $this->fqcn;
+ }
+
+ /**
+ * Set the location information for this logging event. The collected
+ * information is cached for future use.
+ *
+ * <p>This method uses {@link PHP_MANUAL#debug_backtrace debug_backtrace()} function (if exists)
+ * to collect informations about caller.</p>
+ * <p>It only recognize informations generated by {@link Logger} and its subclasses.</p>
+ * @return LoggerLocationInfo
+ */
+ public function getLocationInformation() {
+ if ($this->locationInfo === null) {
+
+ $locationInfo = array();
+ $trace = debug_backtrace();
+ $prevHop = null;
+ // make a downsearch to identify the caller
+ $hop = array_pop($trace);
+ while ($hop !== null) {
+ if (isset($hop['class'])) {
+ // we are sometimes in functions = no class available: avoid php warning here
+ $className = strtolower($hop['class']);
+ if (!empty($className) and ($className == 'logger' or
+ strtolower(get_parent_class($className)) == 'logger')
+ ) {
+ $locationInfo['line'] = $hop['line'];
+ $locationInfo['file'] = $hop['file'];
+ break;
+ }
+ }
+ $prevHop = $hop;
+ $hop = array_pop($trace);
+ }
+ $locationInfo['class'] = isset($prevHop['class']) ? $prevHop['class'] : 'main';
+ if (isset($prevHop['function']) and
+ $prevHop['function'] !== 'include' and
+ $prevHop['function'] !== 'include_once' and
+ $prevHop['function'] !== 'require' and
+ $prevHop['function'] !== 'require_once'
+ ) {
+
+ $locationInfo['function'] = $prevHop['function'];
+ } else {
+ $locationInfo['function'] = 'main';
+ }
+
+ $this->locationInfo = new LoggerLocationInfo($locationInfo, $this->fqcn);
+ }
+ return $this->locationInfo;
+ }
+
+ /**
+ * Return the level of this event. Use this form instead of directly
+ * accessing the {@link $level} field.
+ * @return LoggerLevel
+ */
+ public function getLevel() {
+ return $this->level;
+ }
+
+ /**
+ * Returns the logger which created the event.
+ * @return Logger
+ */
+ public function getLogger() {
+ return $this->logger;
+ }
+
+ /**
+ * Return the name of the logger. Use this form instead of directly
+ * accessing the {@link $categoryName} field.
+ * @return string
+ */
+ public function getLoggerName() {
+ return $this->categoryName;
+ }
+
+ /**
+ * Return the message for this logging event.
+ * @return mixed
+ */
+ public function getMessage() {
+ return $this->message;
+ }
+
+ /**
+ * This method returns the NDC for this event. It will return the
+ * correct content even if the event was generated in a different
+ * thread or even on a different machine. The {@link LoggerNDC::get()} method
+ * should <b>never</b> be called directly.
+ * @return string
+ */
+ public function getNDC() {
+ if ($this->ndcLookupRequired) {
+ $this->ndcLookupRequired = false;
+ $this->ndc = LoggerNDC::get();
+ }
+ return $this->ndc;
+ }
+
+ /**
+ * Returns the the context corresponding to the <code>key</code>
+ * parameter.
+ * @return string
+ */
+ public function getMDC($key) {
+ return LoggerMDC::get($key);
+ }
+
+ /**
+ * Returns the entire MDC context.
+ * @return array
+ */
+ public function getMDCMap() {
+ return LoggerMDC::getMap();
+ }
+
+ /**
+ * Render message.
+ * @return string
+ */
+ public function getRenderedMessage() {
+ if ($this->renderedMessage === null and $this->message !== null) {
+ if (is_string($this->message)) {
+ $this->renderedMessage = $this->message;
+ } else {
+ $rendererMap = Logger::getHierarchy()->getRendererMap();
+ $this->renderedMessage = $rendererMap->findAndRender($this->message);
+ }
+ }
+ return $this->renderedMessage;
+ }
+
+ /**
+ * Returns the time when the application started, as a UNIX timestamp
+ * with microseconds.
+ * @return float
+ */
+ public static function getStartTime() {
+ if (!isset(self::$startTime)) {
+ self::$startTime = microtime(true);
+ }
+ return self::$startTime;
+ }
+
+ /**
+ * @return float
+ */
+ public function getTimeStamp() {
+ return $this->timeStamp;
+ }
+
+ /**
+ * Returns the time in seconds passed from the beginning of execution to
+ * the time the event was constructed.
+ *
+ * @return float Seconds with microseconds in decimals.
+ */
+ public function getRelativeTime() {
+ return $this->timeStamp - self::$startTime;
+ }
+
+ /**
+ * Returns the time in milliseconds passed from the beginning of execution
+ * to the time the event was constructed.
+ *
+ * @deprecated This method has been replaced by getRelativeTime which
+ * does not perform unneccesary multiplication and formatting.
+ *
+ * @return integer
+ */
+ public function getTime() {
+ $eventTime = $this->getTimeStamp();
+ $eventStartTime = LoggerLoggingEvent::getStartTime();
+ return number_format(($eventTime - $eventStartTime) * 1000, 0, '', '');
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getThreadName() {
+ if ($this->threadName === null) {
+ $this->threadName = (string)getmypid();
+ }
+ return $this->threadName;
+ }
+
+ /**
+ * @return mixed LoggerThrowableInformation
+ */
+ public function getThrowableInformation() {
+ return $this->throwableInfo;
+ }
+
+ /**
+ * Serialize this object
+ * @return string
+ */
+ public function toString() {
+ serialize($this);
+ }
+
+ /**
+ * Avoid serialization of the {@link $logger} object
+ */
+ public function __sleep() {
+ return array(
+ 'fqcn',
+ 'categoryName',
+ 'level',
+ 'ndc',
+ 'ndcLookupRequired',
+ 'message',
+ 'renderedMessage',
+ 'threadName',
+ 'timeStamp',
+ 'locationInfo',
+ );
+ }
+
+}
+
+LoggerLoggingEvent::getStartTime();
new file mode 100644
--- /dev/null
+++ b/library/log4php/LoggerMDC.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * The LoggerMDC class provides _mapped diagnostic contexts_.
+ *
+ * A Mapped Diagnostic Context, or MDC in short, is an instrument for
+ * distinguishing interleaved log output from different sources. Log output
+ * is typically interleaved when a server handles multiple clients
+ * near-simultaneously.
+ *
+ * This class is similar to the {@link LoggerNDC} class except that
+ * it is based on a map instead of a stack.
+ *
+ * @version $Revision: 1343630 $
+ * @since 0.3
+ * @package log4php
+ */
+class LoggerMDC {
+
+ /** Holds the context map. */
+ private static $map = array();
+
+ /**
+ * Stores a context value as identified with the key parameter into the
+ * context map.
+ *
+ * @param string $key the key
+ * @param string $value the value
+ */
+ public static function put($key, $value) {
+ self::$map[$key] = $value;
+ }
+
+ /**
+ * Returns the context value identified by the key parameter.
+ *
+ * @param string $key The key.
+ * @return string The context or an empty string if no context found
+ * for given key.
+ */
+ public static function get($key) {
+ return isset(self::$map[$key]) ? self::$map[$key] : '';
+ }
+
+ /**
+ * Returns the contex map as an array.
+ * @return array The MDC context map.
+ */
+ public static function getMap() {
+ return self::$map;
+ }
+
+ /**
+ * Removes the the context identified by the key parameter.
+ *
+ * Only affects user mappings, not $_ENV or $_SERVER.
+ *
+ * @param string $key The key to be removed.
+ */
+ public static function remove($key) {
+ unset(self::$map[$key]);
+ }
+
+ /**
+ * Clears the mapped diagnostic context.
+ */
+ public static function clear() {
+ self::$map = array();
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/LoggerNDC.php
@@ -0,0 +1,203 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * The NDC class implements <i>nested diagnostic contexts</i>.
+ *
+ * NDC was defined by Neil Harrison in the article "Patterns for Logging
+ * Diagnostic Messages" part of the book <i>"Pattern Languages of
+ * Program Design 3"</i> edited by Martin et al.
+ *
+ * A Nested Diagnostic Context, or NDC in short, is an instrument
+ * to distinguish interleaved log output from different sources. Log
+ * output is typically interleaved when a server handles multiple
+ * clients near-simultaneously.
+ *
+ * This class is similar to the {@link LoggerMDC} class except that it is
+ * based on a stack instead of a map.
+ *
+ * Interleaved log output can still be meaningful if each log entry
+ * from different contexts had a distinctive stamp. This is where NDCs
+ * come into play.
+ *
+ * <b>Note that NDCs are managed on a per thread basis</b>.
+ *
+ * NDC operations such as {@link push()}, {@link pop()},
+ * {@link clear()}, {@link getDepth()} and {@link setMaxDepth()}
+ * affect the NDC of the <i>current</i> thread only. NDCs of other
+ * threads remain unaffected.
+ *
+ * For example, a servlet can build a per client request NDC
+ * consisting the clients host name and other information contained in
+ * the the request. <i>Cookies</i> are another source of distinctive
+ * information. To build an NDC one uses the {@link push()}
+ * operation.
+ *
+ * Simply put,
+ *
+ * - Contexts can be nested.
+ * - When entering a context, call <kbd>LoggerNDC::push()</kbd>
+ * As a side effect, if there is no nested diagnostic context for the
+ * current thread, this method will create it.
+ * - When leaving a context, call <kbd>LoggerNDC::pop()</kbd>
+ * - <b>When exiting a thread make sure to call {@link remove()}</b>
+ *
+ * There is no penalty for forgetting to match each
+ * <kbd>push</kbd> operation with a corresponding <kbd>pop</kbd>,
+ * except the obvious mismatch between the real application context
+ * and the context set in the NDC.
+ *
+ * If configured to do so, {@link LoggerPatternLayout} and {@link LoggerLayoutTTCC}
+ * instances automatically retrieve the nested diagnostic
+ * context for the current thread without any user intervention.
+ * Hence, even if a servlet is serving multiple clients
+ * simultaneously, the logs emanating from the same code (belonging to
+ * the same category) can still be distinguished because each client
+ * request will have a different NDC tag.
+ *
+ * Example:
+ *
+ * {@example ../../examples/php/ndc.php 19}<br>
+ *
+ * With the properties file:
+ *
+ * {@example ../../examples/resources/ndc.properties 18}<br>
+ *
+ * Will result in the following (notice the conn and client ids):
+ *
+ * <pre>
+ * 2009-09-13 19:04:27 DEBUG root conn=1234: just received a new connection in src/examples/php/ndc.php at 23
+ * 2009-09-13 19:04:27 DEBUG root conn=1234 client=ab23: some more messages that can in src/examples/php/ndc.php at 25
+ * 2009-09-13 19:04:27 DEBUG root conn=1234 client=ab23: now related to a client in src/examples/php/ndc.php at 26
+ * 2009-09-13 19:04:27 DEBUG root : back and waiting for new connections in src/examples/php/ndc.php at 29
+ * </pre>
+ *
+ * @version $Revision: 1350602 $
+ * @package log4php
+ * @since 0.3
+ */
+class LoggerNDC {
+
+ /** This is the repository of NDC stack */
+ private static $stack = array();
+
+ /**
+ * Clear any nested diagnostic information if any. This method is
+ * useful in cases where the same thread can be potentially used
+ * over and over in different unrelated contexts.
+ *
+ * <p>This method is equivalent to calling the {@link setMaxDepth()}
+ * method with a zero <var>maxDepth</var> argument.
+ */
+ public static function clear() {
+ self::$stack = array();
+ }
+
+ /**
+ * Never use this method directly, use the {@link LoggerLoggingEvent::getNDC()} method instead.
+ * @return array
+ */
+ public static function get() {
+ return implode(' ', self::$stack);
+ }
+
+ /**
+ * Get the current nesting depth of this diagnostic context.
+ *
+ * @see setMaxDepth()
+ * @return integer
+ */
+ public static function getDepth() {
+ return count(self::$stack);
+ }
+
+ /**
+ * Clients should call this method before leaving a diagnostic
+ * context.
+ *
+ * <p>The returned value is the value that was pushed last. If no
+ * context is available, then the empty string "" is returned.</p>
+ *
+ * @return string The innermost diagnostic context.
+ */
+ public static function pop() {
+ if (count(self::$stack) > 0) {
+ return array_pop(self::$stack);
+ } else {
+ return '';
+ }
+ }
+
+ /**
+ * Looks at the last diagnostic context at the top of this NDC
+ * without removing it.
+ *
+ * <p>The returned value is the value that was pushed last. If no
+ * context is available, then the empty string "" is returned.</p>
+ * @return string The innermost diagnostic context.
+ */
+ public static function peek() {
+ if (count(self::$stack) > 0) {
+ return end(self::$stack);
+ } else {
+ return '';
+ }
+ }
+
+ /**
+ * Push new diagnostic context information for the current thread.
+ *
+ * <p>The contents of the <var>message</var> parameter is
+ * determined solely by the client.
+ *
+ * @param string $message The new diagnostic context information.
+ */
+ public static function push($message) {
+ array_push(self::$stack, (string)$message);
+ }
+
+ /**
+ * Remove the diagnostic context for this thread.
+ */
+ public static function remove() {
+ LoggerNDC::clear();
+ }
+
+ /**
+ * Set maximum depth of this diagnostic context. If the current
+ * depth is smaller or equal to <var>maxDepth</var>, then no
+ * action is taken.
+ *
+ * <p>This method is a convenient alternative to multiple
+ * {@link pop()} calls. Moreover, it is often the case that at
+ * the end of complex call sequences, the depth of the NDC is
+ * unpredictable. The {@link setMaxDepth()} method circumvents
+ * this problem.
+ *
+ * @param integer $maxDepth
+ * @see getDepth()
+ */
+ public static function setMaxDepth($maxDepth) {
+ $maxDepth = (int)$maxDepth;
+ if (LoggerNDC::getDepth() > $maxDepth) {
+ self::$stack = array_slice(self::$stack, 0, $maxDepth);
+ }
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/LoggerReflectionUtils.php
@@ -0,0 +1,152 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Provides methods for reflective use on php objects
+ * @package log4php
+ */
+class LoggerReflectionUtils {
+ /** the target object */
+ private $obj;
+
+ /**
+ * Create a new LoggerReflectionUtils for the specified Object.
+ * This is done in prepartion for invoking {@link setProperty()}
+ * one or more times.
+ * @param object &$obj the object for which to set properties
+ */
+ public function __construct($obj) {
+ $this->obj = $obj;
+ }
+
+ /**
+ * Set the properties of an object passed as a parameter in one
+ * go. The <code>properties</code> are parsed relative to a
+ * <code>prefix</code>.
+ *
+ * @param object $obj The object to configure.
+ * @param array $properties An array containing keys and values.
+ * @param string $prefix Only keys having the specified prefix will be set.
+ */
+ // TODO: check, if this is really useful
+ public static function setPropertiesByObject($obj, $properties, $prefix) {
+ $pSetter = new LoggerReflectionUtils($obj);
+ return $pSetter->setProperties($properties, $prefix);
+ }
+
+
+ /**
+ * Set the properites for the object that match the
+ * <code>prefix</code> passed as parameter.
+ *
+ * Example:
+ *
+ * $arr['xxxname'] = 'Joe';
+ * $arr['xxxmale'] = true;
+ * and prefix xxx causes setName and setMale.
+ *
+ * @param array $properties An array containing keys and values.
+ * @param string $prefix Only keys having the specified prefix will be set.
+ */
+ public function setProperties($properties, $prefix) {
+ $len = strlen($prefix);
+ reset($properties);
+ while (list($key,) = each($properties)) {
+ if (strpos($key, $prefix) === 0) {
+ if (strpos($key, '.', ($len + 1)) > 0) {
+ continue;
+ }
+ $value = $properties[$key];
+ $key = substr($key, $len);
+ if ($key == 'layout' and ($this->obj instanceof LoggerAppender)) {
+ continue;
+ }
+ $this->setProperty($key, $value);
+ }
+ }
+ $this->activate();
+ }
+
+ /**
+ * Set a property on this PropertySetter's Object. If successful, this
+ * method will invoke a setter method on the underlying Object. The
+ * setter is the one for the specified property name and the value is
+ * determined partly from the setter argument type and partly from the
+ * value specified in the call to this method.
+ *
+ * <p>If the setter expects a String no conversion is necessary.
+ * If it expects an int, then an attempt is made to convert 'value'
+ * to an int using new Integer(value). If the setter expects a boolean,
+ * the conversion is by new Boolean(value).
+ *
+ * @param string $name name of the property
+ * @param string $value String value of the property
+ */
+ public function setProperty($name, $value) {
+ if ($value === null) {
+ return;
+ }
+
+ $method = "set" . ucfirst($name);
+
+ if (!method_exists($this->obj, $method)) {
+ throw new Exception("Error setting log4php property $name to $value: no method $method in class " . get_class($this->obj) . "!");
+ } else {
+ return call_user_func(array($this->obj, $method), $value);
+ }
+ }
+
+ public function activate() {
+ if (method_exists($this->obj, 'activateoptions')) {
+ return call_user_func(array($this->obj, 'activateoptions'));
+ }
+ }
+
+ /**
+ * Creates an instances from the given class name.
+ *
+ * @param string $classname
+ * @return an object from the class with the given classname
+ */
+ public static function createObject($class) {
+ if (!empty($class)) {
+ return new $class();
+ }
+ return null;
+ }
+
+ /**
+ * @param object $object
+ * @param string $name
+ * @param mixed $value
+ */
+ public static function setter($object, $name, $value) {
+ if (empty($name)) {
+ return false;
+ }
+ $methodName = 'set' . ucfirst($name);
+ if (method_exists($object, $methodName)) {
+ return call_user_func(array($object, $methodName), $value);
+ } else {
+ return false;
+ }
+ }
+
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/LoggerRoot.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * The root logger.
+ *
+ * @version $Revision: 1343190 $
+ * @package log4php
+ * @see Logger
+ */
+class LoggerRoot extends Logger {
+ /**
+ * Constructor
+ *
+ * @param integer $level initial log level
+ */
+ public function __construct(LoggerLevel $level = null) {
+ parent::__construct('root');
+
+ if ($level == null) {
+ $level = LoggerLevel::getLevelAll();
+ }
+ $this->setLevel($level);
+ }
+
+ /**
+ * @return LoggerLevel the level
+ */
+ public function getEffectiveLevel() {
+ return $this->getLevel();
+ }
+
+ /**
+ * Override level setter to prevent setting the root logger's level to
+ * null. Root logger must always have a level.
+ *
+ * @param LoggerLevel $level
+ */
+ public function setLevel(LoggerLevel $level = null) {
+ if (isset($level)) {
+ parent::setLevel($level);
+ } else {
+ trigger_error("log4php: Cannot set LoggerRoot level to null.", E_USER_WARNING);
+ }
+ }
+
+ /**
+ * Override parent setter. Root logger cannot have a parent.
+ * @param Logger $parent
+ */
+ public function setParent(Logger $parent) {
+ trigger_error("log4php: LoggerRoot cannot have a parent.", E_USER_WARNING);
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/LoggerThrowableInformation.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * The internal representation of throwables.
+ *
+ * @package log4php
+ * @since 2.1
+ */
+class LoggerThrowableInformation {
+
+ /** @var Exception Throwable to log */
+ private $throwable;
+
+ /** @var array Array of throwable messages */
+ private $throwableArray;
+
+ /**
+ * Create a new instance
+ *
+ * @param $throwable - a throwable as a exception
+ * @param $logger - Logger reference
+ */
+ public function __construct(Exception $throwable) {
+ $this->throwable = $throwable;
+ }
+
+ /**
+ * Return source exception
+ *
+ * @return Exception
+ */
+ public function getThrowable() {
+ return $this->throwable;
+ }
+
+ /**
+ * @desc Returns string representation of throwable
+ *
+ * @return array
+ */
+ public function getStringRepresentation() {
+ if (!is_array($this->throwableArray)) {
+ $renderer = new LoggerRendererException();
+
+ $this->throwableArray = explode("\n", $renderer->render($this->throwable));
+ }
+
+ return $this->throwableArray;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/appenders/LoggerAppenderConsole.php
@@ -0,0 +1,103 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * LoggerAppenderConsole appends log events either to the standard output
+ * stream (php://stdout) or the standard error stream (php://stderr).
+ *
+ * **Note**: Use this Appender with command-line php scripts. On web scripts
+ * this appender has no effects.
+ *
+ * This appender uses a layout.
+ *
+ * ## Configurable parameters: ##
+ *
+ * - **target** - the target stream: "stdout" or "stderr"
+ *
+ * @version $Revision: 1343601 $
+ * @package log4php
+ * @subpackage appenders
+ * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+ * @link http://logging.apache.org/log4php/docs/appenders/console.html Appender documentation
+ */
+class LoggerAppenderConsole extends LoggerAppender {
+
+ /** The standard otuput stream. */
+ const STDOUT = 'php://stdout';
+
+ /** The standard error stream.*/
+ const STDERR = 'php://stderr';
+
+ /** The 'target' parameter. */
+ protected $target = self::STDOUT;
+
+ /**
+ * Stream resource for the target stream.
+ * @var resource
+ */
+ protected $fp = null;
+
+ public function activateOptions() {
+ $this->fp = fopen($this->target, 'w');
+ if (is_resource($this->fp) && $this->layout !== null) {
+ fwrite($this->fp, $this->layout->getHeader());
+ }
+ $this->closed = (bool)is_resource($this->fp) === false;
+ }
+
+
+ public function close() {
+ if ($this->closed != true) {
+ if (is_resource($this->fp) && $this->layout !== null) {
+ fwrite($this->fp, $this->layout->getFooter());
+ fclose($this->fp);
+ }
+ $this->closed = true;
+ }
+ }
+
+ public function append(LoggerLoggingEvent $event) {
+ if (is_resource($this->fp) && $this->layout !== null) {
+ fwrite($this->fp, $this->layout->format($event));
+ }
+ }
+
+ /**
+ * Sets the 'target' parameter.
+ * @param string $target
+ */
+ public function setTarget($target) {
+ $value = trim($target);
+ if ($value == self::STDOUT || strtoupper($value) == 'STDOUT') {
+ $this->target = self::STDOUT;
+ } elseif ($value == self::STDERR || strtoupper($value) == 'STDERR') {
+ $this->target = self::STDERR;
+ } else {
+ $target = var_export($target);
+ $this->warn("Invalid value given for 'target' property: [$target]. Property not set.");
+ }
+ }
+
+ /**
+ * Returns the value of the 'target' parameter.
+ * @return string
+ */
+ public function getTarget() {
+ return $this->target;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/appenders/LoggerAppenderDailyFile.php
@@ -0,0 +1,128 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * An Appender that automatically creates a new logfile each day.
+ *
+ * The file is rolled over once a day. That means, for each day a new file
+ * is created. A formatted version of the date pattern is used as to create
+ * the file name using the {@link PHP_MANUAL#sprintf} function.
+ *
+ * This appender uses a layout.
+ *
+ * ##Configurable parameters:##
+ *
+ * - **datePattern** - Format for the date in the file path, follows formatting
+ * rules used by the PHP date() function. Default value: "Ymd".
+ * - **file** - Path to the target file. Should contain a %s which gets
+ * substituted by the date.
+ * - **append** - If set to true, the appender will append to the file,
+ * otherwise the file contents will be overwritten. Defaults to true.
+ *
+ * @version $Revision: 1382274 $
+ * @package log4php
+ * @subpackage appenders
+ * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+ * @link http://logging.apache.org/log4php/docs/appenders/daily-file.html Appender documentation
+ */
+class LoggerAppenderDailyFile extends LoggerAppenderFile {
+
+ /**
+ * The 'datePattern' parameter.
+ * Determines how date will be formatted in file name.
+ * @var string
+ */
+ protected $datePattern = "Ymd";
+
+ /**
+ * Current date which was used when opening a file.
+ * Used to determine if a rollover is needed when the date changes.
+ * @var string
+ */
+ protected $currentDate;
+
+ /** Additional validation for the date pattern. */
+ public function activateOptions() {
+ parent::activateOptions();
+
+ if (empty($this->datePattern)) {
+ $this->warn("Required parameter 'datePattern' not set. Closing appender.");
+ $this->closed = true;
+ return;
+ }
+ }
+
+ /**
+ * Appends a logging event.
+ *
+ * If the target file changes because of passage of time (e.g. at midnight)
+ * the current file is closed. A new file, with the new date, will be
+ * opened by the write() method.
+ */
+ public function append(LoggerLoggingEvent $event) {
+ $eventDate = $this->getDate($event->getTimestamp());
+
+ // Initial setting of current date
+ if (!isset($this->currentDate)) {
+ $this->currentDate = $eventDate;
+ } // Check if rollover is needed
+ else if ($this->currentDate !== $eventDate) {
+ $this->currentDate = $eventDate;
+
+ // Close the file if it's open.
+ // Note: $this->close() is not called here because it would set
+ // $this->closed to true and the appender would not recieve
+ // any more logging requests
+ if (is_resource($this->fp)) {
+ $this->write($this->layout->getFooter());
+ fclose($this->fp);
+ }
+ $this->fp = null;
+ }
+
+ parent::append($event);
+ }
+
+ /** Renders the date using the configured <var>datePattern<var>. */
+ protected function getDate($timestamp = null) {
+ return date($this->datePattern, $timestamp);
+ }
+
+ /**
+ * Determines target file. Replaces %s in file path with a date.
+ */
+ protected function getTargetFile() {
+ return str_replace('%s', $this->currentDate, $this->file);
+ }
+
+ /**
+ * Sets the 'datePattern' parameter.
+ * @param string $datePattern
+ */
+ public function setDatePattern($datePattern) {
+ $this->setString('datePattern', $datePattern);
+ }
+
+ /**
+ * Returns the 'datePattern' parameter.
+ * @return string
+ */
+ public function getDatePattern() {
+ return $this->datePattern;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/appenders/LoggerAppenderEcho.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * LoggerAppenderEcho uses the PHP echo() function to output events.
+ *
+ * This appender uses a layout.
+ *
+ * ## Configurable parameters: ##
+ *
+ * - **htmlLineBreaks** - If set to true, a <br /> element will be inserted
+ * before each line break in the logged message. Default is false.
+ *
+ * @version $Revision: 1337820 $
+ * @package log4php
+ * @subpackage appenders
+ * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+ * @link http://logging.apache.org/log4php/docs/appenders/echo.html Appender documentation
+ */
+class LoggerAppenderEcho extends LoggerAppender {
+ /**
+ * Used to mark first append. Set to false after first append.
+ * @var boolean
+ */
+ protected $firstAppend = true;
+
+ /**
+ * If set to true, a <br /> element will be inserted before each line
+ * break in the logged message. Default value is false. @var boolean
+ */
+ protected $htmlLineBreaks = false;
+
+ public function close() {
+ if ($this->closed != true) {
+ if (!$this->firstAppend) {
+ echo $this->layout->getFooter();
+ }
+ }
+ $this->closed = true;
+ }
+
+ public function append(LoggerLoggingEvent $event) {
+ if ($this->layout !== null) {
+ if ($this->firstAppend) {
+ echo $this->layout->getHeader();
+ $this->firstAppend = false;
+ }
+ $text = $this->layout->format($event);
+
+ if ($this->htmlLineBreaks) {
+ $text = nl2br($text);
+ }
+ echo $text;
+ }
+ }
+
+ /**
+ * Sets the 'htmlLineBreaks' parameter.
+ * @param boolean $value
+ */
+ public function setHtmlLineBreaks($value) {
+ $this->setBoolean('htmlLineBreaks', $value);
+ }
+
+ /**
+ * Returns the 'htmlLineBreaks' parameter.
+ * @returns boolean
+ */
+ public function getHtmlLineBreaks() {
+ return $this->htmlLineBreaks;
+ }
+}
+
new file mode 100644
--- /dev/null
+++ b/library/log4php/appenders/LoggerAppenderFile.php
@@ -0,0 +1,225 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * LoggerAppenderFile appends log events to a file.
+ *
+ * This appender uses a layout.
+ *
+ * ## Configurable parameters: ##
+ *
+ * - **file** - Path to the target file. Relative paths are resolved based on
+ * the working directory.
+ * - **append** - If set to true, the appender will append to the file,
+ * otherwise the file contents will be overwritten.
+ *
+ * @version $Revision: 1382274 $
+ * @package log4php
+ * @subpackage appenders
+ * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+ * @link http://logging.apache.org/log4php/docs/appenders/file.html Appender documentation
+ */
+class LoggerAppenderFile extends LoggerAppender {
+
+ /**
+ * If set to true, the file is locked before appending. This allows
+ * concurrent access. However, appending without locking is faster so
+ * it should be used where appropriate.
+ *
+ * TODO: make this a configurable parameter
+ *
+ * @var boolean
+ */
+ protected $locking = true;
+
+ /**
+ * If set to true, appends to file. Otherwise overwrites it.
+ * @var boolean
+ */
+ protected $append = true;
+
+ /**
+ * Path to the target file.
+ * @var string
+ */
+ protected $file;
+
+ /**
+ * The file resource.
+ * @var resource
+ */
+ protected $fp;
+
+ /**
+ * Helper function which can be easily overriden by daily file appender.
+ */
+ protected function getTargetFile() {
+ return $this->file;
+ }
+
+ /**
+ * Acquires the target file resource, creates the destination folder if
+ * necessary. Writes layout header to file.
+ *
+ * @return boolean FALSE if opening failed
+ */
+ protected function openFile() {
+ $file = $this->getTargetFile();
+
+ // Create the target folder if needed
+ if (!is_file($file)) {
+ $dir = dirname($file);
+
+ if (!is_dir($dir)) {
+ $success = mkdir($dir, 0777, true);
+ if ($success === false) {
+ $this->warn("Failed creating target directory [$dir]. Closing appender.");
+ $this->closed = true;
+ return false;
+ }
+ }
+ }
+
+ $mode = $this->append ? 'a' : 'w';
+ $this->fp = fopen($file, $mode);
+ if ($this->fp === false) {
+ $this->warn("Failed opening target file. Closing appender.");
+ $this->fp = null;
+ $this->closed = true;
+ return false;
+ }
+
+ // Required when appending with concurrent access
+ if ($this->append) {
+ fseek($this->fp, 0, SEEK_END);
+ }
+
+ // Write the header
+ $this->write($this->layout->getHeader());
+ }
+
+ /**
+ * Writes a string to the target file. Opens file if not already open.
+ * @param string $string Data to write.
+ */
+ protected function write($string) {
+ // Lazy file open
+ if (!isset($this->fp)) {
+ if ($this->openFile() === false) {
+ return; // Do not write if file open failed.
+ }
+ }
+
+ if ($this->locking) {
+ $this->writeWithLocking($string);
+ } else {
+ $this->writeWithoutLocking($string);
+ }
+ }
+
+ protected function writeWithLocking($string) {
+ if (flock($this->fp, LOCK_EX)) {
+ if (fwrite($this->fp, $string) === false) {
+ $this->warn("Failed writing to file. Closing appender.");
+ $this->closed = true;
+ }
+ flock($this->fp, LOCK_UN);
+ } else {
+ $this->warn("Failed locking file for writing. Closing appender.");
+ $this->closed = true;
+ }
+ }
+
+ protected function writeWithoutLocking($string) {
+ if (fwrite($this->fp, $string) === false) {
+ $this->warn("Failed writing to file. Closing appender.");
+ $this->closed = true;
+ }
+ }
+
+ public function activateOptions() {
+ if (empty($this->file)) {
+ $this->warn("Required parameter 'file' not set. Closing appender.");
+ $this->closed = true;
+ return;
+ }
+ }
+
+ public function close() {
+ if (is_resource($this->fp)) {
+ $this->write($this->layout->getFooter());
+ fclose($this->fp);
+ }
+ $this->fp = null;
+ $this->closed = true;
+ }
+
+ public function append(LoggerLoggingEvent $event) {
+ $this->write($this->layout->format($event));
+ }
+
+ /**
+ * Sets the 'file' parameter.
+ * @param string $file
+ */
+ public function setFile($file) {
+ $this->setString('file', $file);
+ }
+
+ /**
+ * Returns the 'file' parameter.
+ * @return string
+ */
+ public function getFile() {
+ return $this->file;
+ }
+
+ /**
+ * Returns the 'append' parameter.
+ * @return boolean
+ */
+ public function getAppend() {
+ return $this->append;
+ }
+
+ /**
+ * Sets the 'append' parameter.
+ * @param boolean $append
+ */
+ public function setAppend($append) {
+ $this->setBoolean('append', $append);
+ }
+
+ /**
+ * Sets the 'file' parmeter. Left for legacy reasons.
+ * @param string $fileName
+ * @deprecated Use setFile() instead.
+ */
+ public function setFileName($fileName) {
+ $this->setFile($fileName);
+ }
+
+ /**
+ * Returns the 'file' parmeter. Left for legacy reasons.
+ * @return string
+ * @deprecated Use getFile() instead.
+ */
+ public function getFileName() {
+ return $this->getFile();
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/appenders/LoggerAppenderFirePHP.php
@@ -0,0 +1,100 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Logs messages as HTTP headers using the FirePHP Insight API.
+ *
+ * This appender requires the FirePHP server library version 1.0 or later.
+ *
+ * ## Configurable parameters: ##
+ *
+ * - **target** - (string) The target to which messages will be sent. Possible options are
+ * 'page' (default), 'request', 'package' and 'controller'. For more details,
+ * see FirePHP documentation.
+ *
+ * This class was originally contributed by Bruce Ingalls (Bruce.Ingalls-at-gmail-dot-com).
+ *
+ * @link https://github.com/firephp/firephp FirePHP homepage.
+ * @link http://sourcemint.com/github.com/firephp/firephp/1:1.0.0b1rc6/-docs/Welcome FirePHP documentation.
+ * @link http://sourcemint.com/github.com/firephp/firephp/1:1.0.0b1rc6/-docs/Configuration/Constants FirePHP constants documentation.
+ * @link http://logging.apache.org/log4php/docs/appenders/firephp.html Appender documentation
+ *
+ * @version $Revision: 1343684 $
+ * @package log4php
+ * @subpackage appenders
+ * @since 2.3
+ */
+class LoggerAppenderFirePHP extends LoggerAppender {
+
+ /**
+ * Instance of the Insight console class.
+ * @var Insight_Plugin_Console
+ */
+ protected $console;
+
+ /**
+ * The target for log messages. Possible values are: 'page' (default),
+ * 'request', 'package' and 'contoller'.
+ */
+ protected $target = 'page';
+
+ public function activateOptions() {
+ if (method_exists('FirePHP', 'to')) {
+ $this->console = FirePHP::to($this->target)->console();
+ $this->closed = false;
+ } else {
+ $this->warn('FirePHP is not installed correctly. Closing appender.');
+ }
+ }
+
+ public function append(LoggerLoggingEvent $event) {
+ $msg = $event->getMessage();
+
+ // Skip formatting for objects and arrays which are handled by FirePHP.
+ if (!is_array($msg) && !is_object($msg)) {
+ $msg = $this->getLayout()->format($event);
+ }
+
+ switch ($event->getLevel()->toInt()) {
+ case LoggerLevel::TRACE:
+ case LoggerLevel::DEBUG:
+ $this->console->log($msg);
+ break;
+ case LoggerLevel::INFO:
+ $this->console->info($msg);
+ break;
+ case LoggerLevel::WARN:
+ $this->console->warn($msg);
+ break;
+ case LoggerLevel::ERROR:
+ case LoggerLevel::FATAL:
+ $this->console->error($msg);
+ break;
+ }
+ }
+
+ /** Returns the target. */
+ public function getTarget() {
+ return $this->target;
+ }
+
+ /** Sets the target. */
+ public function setTarget($target) {
+ $this->setString('target', $target);
+ }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/library/log4php/appenders/LoggerAppenderMail.php
@@ -0,0 +1,136 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * LoggerAppenderMail appends log events via email.
+ *
+ * This appender does not send individual emails for each logging requests but
+ * will collect them in a buffer and send them all in a single email once the
+ * appender is closed (i.e. when the script exists). Because of this, it may
+ * not appropriate for long running scripts, in which case
+ * LoggerAppenderMailEvent might be a better choice.
+ *
+ * This appender uses a layout.
+ *
+ * ## Configurable parameters: ##
+ *
+ * - **to** - Email address(es) to which the log will be sent. Multiple email
+ * addresses may be specified by separating them with a comma.
+ * - **from** - Email address which will be used in the From field.
+ * - **subject** - Subject of the email message.
+ *
+ * @version $Revision: 1337820 $
+ * @package log4php
+ * @subpackage appenders
+ * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+ * @link http://logging.apache.org/log4php/docs/appenders/mail.html Appender documentation
+ */
+class LoggerAppenderMail extends LoggerAppender {
+
+ /**
+ * Email address to put in From field of the email.
+ * @var string
+ */
+ protected $from = null;
+
+ /**
+ * The subject of the email.
+ * @var string
+ */
+ protected $subject = 'Log4php Report';
+
+ /**
+ * One or more comma separated email addresses to which to send the email.
+ * @var string
+ */
+ protected $to = null;
+
+ /**
+ * Indiciates whether this appender should run in dry mode.
+ * @deprecated
+ * @var boolean
+ */
+ protected $dry = false;
+
+ /**
+ * Buffer which holds the email contents before it is sent.
+ * @var string
+ */
+ protected $body = '';
+
+ public function append(LoggerLoggingEvent $event) {
+ if ($this->layout !== null) {
+ $this->body .= $this->layout->format($event);
+ }
+ }
+
+ public function close() {
+ if ($this->closed != true) {
+ $from = $this->from;
+ $to = $this->to;
+
+ if (!empty($this->body) and $from !== null and $to !== null and $this->layout !== null) {
+ $subject = $this->subject;
+ if (!$this->dry) {
+ mail(
+ $to, $subject,
+ $this->layout->getHeader() . $this->body . $this->layout->getFooter(),
+ "From: {$from}\r\n");
+ } else {
+ echo "DRY MODE OF MAIL APP.: Send mail to: " . $to . " with content: " . $this->body;
+ }
+ }
+ $this->closed = true;
+ }
+ }
+
+ /** Sets the 'subject' parameter. */
+ public function setSubject($subject) {
+ $this->setString('subject', $subject);
+ }
+
+ /** Returns the 'subject' parameter. */
+ public function getSubject() {
+ return $this->subject;
+ }
+
+ /** Sets the 'to' parameter. */
+ public function setTo($to) {
+ $this->setString('to', $to);
+ }
+
+ /** Returns the 'to' parameter. */
+ public function getTo() {
+ return $this->to;
+ }
+
+ /** Sets the 'from' parameter. */
+ public function setFrom($from) {
+ $this->setString('from', $from);
+ }
+
+ /** Returns the 'from' parameter. */
+ public function getFrom() {
+ return $this->from;
+ }
+
+ /** Enables or disables dry mode. */
+ public function setDry($dry) {
+ $this->setBoolean('dry', $dry);
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/appenders/LoggerAppenderMailEvent.php
@@ -0,0 +1,180 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * LoggerAppenderMailEvent appends individual log events via email.
+ *
+ * This appender is similar to LoggerAppenderMail, except that it sends each
+ * each log event in an individual email message at the time when it occurs.
+ *
+ * This appender uses a layout.
+ *
+ * ## Configurable parameters: ##
+ *
+ * - **to** - Email address(es) to which the log will be sent. Multiple email
+ * addresses may be specified by separating them with a comma.
+ * - **from** - Email address which will be used in the From field.
+ * - **subject** - Subject of the email message.
+ * - **smtpHost** - Used to override the SMTP server. Only works on Windows.
+ * - **port** - Used to override the default SMTP server port. Only works on
+ * Windows.
+ *
+ * @version $Revision: 1343601 $
+ * @package log4php
+ * @subpackage appenders
+ * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+ * @link http://logging.apache.org/log4php/docs/appenders/mail-event.html Appender documentation
+ */
+class LoggerAppenderMailEvent extends LoggerAppender {
+
+ /**
+ * Email address to put in From field of the email.
+ * @var string
+ */
+ protected $from;
+
+ /**
+ * Mail server port (widnows only).
+ * @var integer
+ */
+ protected $port = 25;
+
+ /**
+ * Mail server hostname (windows only).
+ * @var string
+ */
+ protected $smtpHost;
+
+ /**
+ * The subject of the email.
+ * @var string
+ */
+ protected $subject = 'Log4php Report';
+
+ /**
+ * One or more comma separated email addresses to which to send the email.
+ * @var string
+ */
+ protected $to = null;
+
+ /**
+ * Indiciates whether this appender should run in dry mode.
+ * @deprecated
+ * @var boolean
+ */
+ protected $dry = false;
+
+ public function activateOptions() {
+ if (empty($this->to)) {
+ $this->warn("Required parameter 'to' not set. Closing appender.");
+ $this->close = true;
+ return;
+ }
+
+ $sendmail_from = ini_get('sendmail_from');
+ if (empty($this->from) and empty($sendmail_from)) {
+ $this->warn("Required parameter 'from' not set. Closing appender.");
+ $this->close = true;
+ return;
+ }
+
+ $this->closed = false;
+ }
+
+ public function append(LoggerLoggingEvent $event) {
+ $smtpHost = $this->smtpHost;
+ $prevSmtpHost = ini_get('SMTP');
+ if (!empty($smtpHost)) {
+ ini_set('SMTP', $smtpHost);
+ }
+
+ $smtpPort = $this->port;
+ $prevSmtpPort = ini_get('smtp_port');
+ if ($smtpPort > 0 and $smtpPort < 65535) {
+ ini_set('smtp_port', $smtpPort);
+ }
+
+ // On unix only sendmail_path, which is PHP_INI_SYSTEM i.e. not changeable here, is used.
+
+ $addHeader = empty($this->from) ? '' : "From: {$this->from}\r\n";
+
+ if (!$this->dry) {
+ $result = mail($this->to, $this->subject, $this->layout->getHeader() . $this->layout->format($event) . $this->layout->getFooter($event), $addHeader);
+ } else {
+ echo "DRY MODE OF MAIL APP.: Send mail to: " . $this->to . " with additional headers '" . trim($addHeader) . "' and content: " . $this->layout->format($event);
+ }
+
+ ini_set('SMTP', $prevSmtpHost);
+ ini_set('smtp_port', $prevSmtpPort);
+ }
+
+ /** Sets the 'from' parameter. */
+ public function setFrom($from) {
+ $this->setString('from', $from);
+ }
+
+ /** Returns the 'from' parameter. */
+ public function getFrom() {
+ return $this->from;
+ }
+
+ /** Sets the 'port' parameter. */
+ public function setPort($port) {
+ $this->setPositiveInteger('port', $port);
+ }
+
+ /** Returns the 'port' parameter. */
+ public function getPort() {
+ return $this->port;
+ }
+
+ /** Sets the 'smtpHost' parameter. */
+ public function setSmtpHost($smtpHost) {
+ $this->setString('smtpHost', $smtpHost);
+ }
+
+ /** Returns the 'smtpHost' parameter. */
+ public function getSmtpHost() {
+ return $this->smtpHost;
+ }
+
+ /** Sets the 'subject' parameter. */
+ public function setSubject($subject) {
+ $this->setString('subject', $subject);
+ }
+
+ /** Returns the 'subject' parameter. */
+ public function getSubject() {
+ return $this->subject;
+ }
+
+ /** Sets the 'to' parameter. */
+ public function setTo($to) {
+ $this->setString('to', $to);
+ }
+
+ /** Returns the 'to' parameter. */
+ public function getTo() {
+ return $this->to;
+ }
+
+ /** Enables or disables dry mode. */
+ public function setDry($dry) {
+ $this->setBoolean('dry', $dry);
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/appenders/LoggerAppenderMongoDB.php
@@ -0,0 +1,361 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Appender for writing to MongoDB.
+ *
+ * This class was originally contributed by Vladimir Gorej.
+ *
+ * ## Configurable parameters: ##
+ *
+ * - **host** - Server on which mongodb instance is located.
+ * - **port** - Port on which the instance is bound.
+ * - **databaseName** - Name of the database to which to log.
+ * - **collectionName** - Name of the target collection within the given database.
+ * - **username** - Username used to connect to the database.
+ * - **password** - Password used to connect to the database.
+ * - **timeout** - For how long the driver should try to connect to the database (in milliseconds).
+ *
+ * @version $Revision: 1346363 $
+ * @package log4php
+ * @subpackage appenders
+ * @since 2.1
+ * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+ * @link http://logging.apache.org/log4php/docs/appenders/mongodb.html Appender documentation
+ * @link http://github.com/log4mongo/log4mongo-php Vladimir Gorej's original submission.
+ * @link http://www.mongodb.org/ MongoDB website.
+ */
+class LoggerAppenderMongoDB extends LoggerAppender {
+
+ // ******************************************
+ // ** Constants **
+ // ******************************************
+
+ /** Default prefix for the {@link $host}. */
+ const DEFAULT_MONGO_URL_PREFIX = 'mongodb://';
+
+ /** Default value for {@link $host}, without a prefix. */
+ const DEFAULT_MONGO_HOST = 'localhost';
+
+ /** Default value for {@link $port} */
+ const DEFAULT_MONGO_PORT = 27017;
+
+ /** Default value for {@link $databaseName} */
+ const DEFAULT_DB_NAME = 'log4php_mongodb';
+
+ /** Default value for {@link $collectionName} */
+ const DEFAULT_COLLECTION_NAME = 'logs';
+
+ /** Default value for {@link $timeout} */
+ const DEFAULT_TIMEOUT_VALUE = 3000;
+
+ // ******************************************
+ // ** Configurable parameters **
+ // ******************************************
+
+ /** Server on which mongodb instance is located. */
+ protected $host;
+
+ /** Port on which the instance is bound. */
+ protected $port;
+
+ /** Name of the database to which to log. */
+ protected $databaseName;
+
+ /** Name of the collection within the given database. */
+ protected $collectionName;
+
+ /** Username used to connect to the database. */
+ protected $userName;
+
+ /** Password used to connect to the database. */
+ protected $password;
+
+ /** Timeout value used when connecting to the database (in milliseconds). */
+ protected $timeout;
+
+ // ******************************************
+ // ** Member variables **
+ // ******************************************
+
+ /**
+ * Connection to the MongoDB instance.
+ * @var Mongo
+ */
+ protected $connection;
+
+ /**
+ * The collection to which log is written.
+ * @var MongoCollection
+ */
+ protected $collection;
+
+ public function __construct($name = '') {
+ parent::__construct($name);
+ $this->host = self::DEFAULT_MONGO_URL_PREFIX . self::DEFAULT_MONGO_HOST;
+ $this->port = self::DEFAULT_MONGO_PORT;
+ $this->databaseName = self::DEFAULT_DB_NAME;
+ $this->collectionName = self::DEFAULT_COLLECTION_NAME;
+ $this->timeout = self::DEFAULT_TIMEOUT_VALUE;
+ $this->requiresLayout = false;
+ }
+
+ /**
+ * Setup db connection.
+ * Based on defined options, this method connects to the database and
+ * creates a {@link $collection}.
+ */
+ public function activateOptions() {
+ try {
+ $this->connection = new Mongo(sprintf('%s:%d', $this->host, $this->port), array('timeout' => $this->timeout));
+ $db = $this->connection->selectDB($this->databaseName);
+ if ($this->userName !== null && $this->password !== null) {
+ $authResult = $db->authenticate($this->userName, $this->password);
+ if ($authResult['ok'] == floatval(0)) {
+ throw new Exception($authResult['errmsg'], $authResult['ok']);
+ }
+ }
+ $this->collection = $db->selectCollection($this->collectionName);
+ } catch (MongoConnectionException $ex) {
+ $this->closed = true;
+ $this->warn(sprintf('Failed to connect to mongo deamon: %s', $ex->getMessage()));
+ } catch (InvalidArgumentException $ex) {
+ $this->closed = true;
+ $this->warn(sprintf('Error while selecting mongo database: %s', $ex->getMessage()));
+ } catch (Exception $ex) {
+ $this->closed = true;
+ $this->warn('Invalid credentials for mongo database authentication');
+ }
+ }
+
+ /**
+ * Appends a new event to the mongo database.
+ *
+ * @param LoggerLoggingEvent $event
+ */
+ public function append(LoggerLoggingEvent $event) {
+ try {
+ if ($this->collection != null) {
+ $this->collection->insert($this->format($event));
+ }
+ } catch (MongoCursorException $ex) {
+ $this->warn(sprintf('Error while writing to mongo collection: %s', $ex->getMessage()));
+ }
+ }
+
+ /**
+ * Converts the logging event into an array which can be logged to mongodb.
+ *
+ * @param LoggerLoggingEvent $event
+ * @return array The array representation of the logging event.
+ */
+ protected function format(LoggerLoggingEvent $event) {
+ $timestampSec = (int)$event->getTimestamp();
+ $timestampUsec = (int)(($event->getTimestamp() - $timestampSec) * 1000000);
+
+ $document = array(
+ 'timestamp' => new MongoDate($timestampSec, $timestampUsec),
+ 'level' => $event->getLevel()->toString(),
+ 'thread' => (int)$event->getThreadName(),
+ 'message' => $event->getMessage(),
+ 'loggerName' => $event->getLoggerName()
+ );
+
+ $locationInfo = $event->getLocationInformation();
+ if ($locationInfo != null) {
+ $document['fileName'] = $locationInfo->getFileName();
+ $document['method'] = $locationInfo->getMethodName();
+ $document['lineNumber'] = ($locationInfo->getLineNumber() == 'NA') ? 'NA' : (int)$locationInfo->getLineNumber();
+ $document['className'] = $locationInfo->getClassName();
+ }
+
+ $throwableInfo = $event->getThrowableInformation();
+ if ($throwableInfo != null) {
+ $document['exception'] = $this->formatThrowable($throwableInfo->getThrowable());
+ }
+
+ return $document;
+ }
+
+ /**
+ * Converts an Exception into an array which can be logged to mongodb.
+ *
+ * Supports innner exceptions (PHP >= 5.3)
+ *
+ * @param Exception $ex
+ * @return array
+ */
+ protected function formatThrowable(Exception $ex) {
+ $array = array(
+ 'message' => $ex->getMessage(),
+ 'code' => $ex->getCode(),
+ 'stackTrace' => $ex->getTraceAsString(),
+ );
+
+ if (method_exists($ex, 'getPrevious') && $ex->getPrevious() !== null) {
+ $array['innerException'] = $this->formatThrowable($ex->getPrevious());
+ }
+
+ return $array;
+ }
+
+ /**
+ * Closes the connection to the logging database
+ */
+ public function close() {
+ if ($this->closed != true) {
+ $this->collection = null;
+ if ($this->connection !== null) {
+ $this->connection->close();
+ $this->connection = null;
+ }
+ $this->closed = true;
+ }
+ }
+
+ /**
+ * Sets the value of {@link $host} parameter.
+ * @param string $host
+ */
+ public function setHost($host) {
+ if (!preg_match('/^mongodb\:\/\//', $host)) {
+ $host = self::DEFAULT_MONGO_URL_PREFIX . $host;
+ }
+ $this->host = $host;
+ }
+
+ /**
+ * Returns the value of {@link $host} parameter.
+ * @return string
+ */
+ public function getHost() {
+ return $this->host;
+ }
+
+ /**
+ * Sets the value of {@link $port} parameter.
+ * @param int $port
+ */
+ public function setPort($port) {
+ $this->setPositiveInteger('port', $port);
+ }
+
+ /**
+ * Returns the value of {@link $port} parameter.
+ * @return int
+ */
+ public function getPort() {
+ return $this->port;
+ }
+
+ /**
+ * Sets the value of {@link $databaseName} parameter.
+ * @param string $databaseName
+ */
+ public function setDatabaseName($databaseName) {
+ $this->setString('databaseName', $databaseName);
+ }
+
+ /**
+ * Returns the value of {@link $databaseName} parameter.
+ * @return string
+ */
+ public function getDatabaseName() {
+ return $this->databaseName;
+ }
+
+ /**
+ * Sets the value of {@link $collectionName} parameter.
+ * @param string $collectionName
+ */
+ public function setCollectionName($collectionName) {
+ $this->setString('collectionName', $collectionName);
+ }
+
+ /**
+ * Returns the value of {@link $collectionName} parameter.
+ * @return string
+ */
+ public function getCollectionName() {
+ return $this->collectionName;
+ }
+
+ /**
+ * Sets the value of {@link $userName} parameter.
+ * @param string $userName
+ */
+ public function setUserName($userName) {
+ $this->setString('userName', $userName, true);
+ }
+
+ /**
+ * Returns the value of {@link $userName} parameter.
+ * @return string
+ */
+ public function getUserName() {
+ return $this->userName;
+ }
+
+ /**
+ * Sets the value of {@link $password} parameter.
+ * @param string $password
+ */
+ public function setPassword($password) {
+ $this->setString('password', $password, true);
+ }
+
+ /**
+ * Returns the value of {@link $password} parameter.
+ * @return string
+ */
+ public function getPassword() {
+ return $this->password;
+ }
+
+ /**
+ * Sets the value of {@link $timeout} parameter.
+ * @param int $timeout
+ */
+ public function setTimeout($timeout) {
+ $this->setPositiveInteger('timeout', $timeout);
+ }
+
+ /**
+ * Returns the value of {@link $timeout} parameter.
+ * @return int
+ */
+ public function getTimeout() {
+ return $this->timeout;
+ }
+
+ /**
+ * Returns the mongodb connection.
+ * @return Mongo
+ */
+ public function getConnection() {
+ return $this->connection;
+ }
+
+ /**
+ * Returns the active mongodb collection.
+ * @return MongoCollection
+ */
+ public function getCollection() {
+ return $this->collection;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/appenders/LoggerAppenderNull.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * A NullAppender merely exists, it never outputs a message to any device.
+ *
+ * This appender has no configurable parameters.
+ *
+ * @version $Revision: 1343601 $
+ * @package log4php
+ * @subpackage appenders
+ * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+ * @link http://logging.apache.org/log4php/docs/appenders/null.html Appender documentation
+ */
+class LoggerAppenderNull extends LoggerAppender {
+
+ /**
+ * This appender does not require a layout.
+ */
+ protected $requiresLayout = false;
+
+ /**
+ * Do nothing.
+ *
+ * @param LoggerLoggingEvent $event
+ */
+ public function append(LoggerLoggingEvent $event) {
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/appenders/LoggerAppenderPDO.php
@@ -0,0 +1,282 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * LoggerAppenderPDO appender logs to a database using the PHP's PDO extension.
+ *
+ * ## Configurable parameters: ##
+ *
+ * - dsn - The Data Source Name (DSN) used to connect to the database.
+ * - user - Username used to connect to the database.
+ * - password - Password used to connect to the database.
+ * - table - Name of the table to which log entries are be inserted.
+ * - insertSQL - Sets the insert statement for a logging event. Defaults
+ * to the correct one - change only if you are sure what you are doing.
+ * - insertPattern - The conversion pattern to use in conjuction with insert
+ * SQL. Must contain the same number of comma separated
+ * conversion patterns as there are question marks in the
+ * insertSQL.
+ *
+ * @version $Revision: 1374546 $
+ * @package log4php
+ * @subpackage appenders
+ * @since 2.0
+ * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+ * @link http://logging.apache.org/log4php/docs/appenders/pdo.html Appender documentation
+ */
+class LoggerAppenderPDO extends LoggerAppender {
+
+ // ******************************************
+ // *** Configurable parameters ***
+ // ******************************************
+
+ /**
+ * DSN string used to connect to the database.
+ * @see http://www.php.net/manual/en/pdo.construct.php
+ */
+ protected $dsn;
+
+ /** Database user name. */
+ protected $user;
+
+ /** Database password. */
+ protected $password;
+
+ /**
+ * The insert query.
+ *
+ * The __TABLE__ placeholder will be replaced by the table name from
+ * {@link $table}.
+ *
+ * The questionmarks are part of the prepared statement, and they must
+ * match the number of conversion specifiers in {@link insertPattern}.
+ */
+ protected $insertSQL = "INSERT INTO __TABLE__ (timestamp, logger, level, message, thread, file, line) VALUES (?, ?, ?, ?, ?, ?, ?)";
+
+ /**
+ * A comma separated list of {@link LoggerPatternLayout} format strings
+ * which replace the "?" in {@link $insertSQL}.
+ *
+ * Must contain the same number of comma separated conversion patterns as
+ * there are question marks in {@link insertSQL}.
+ *
+ * @see LoggerPatternLayout For conversion patterns.
+ */
+ protected $insertPattern = "%date{Y-m-d H:i:s},%logger,%level,%message,%pid,%file,%line";
+
+ /** Name of the table to which to append log events. */
+ protected $table = 'log4php_log';
+
+ /** The number of recconect attempts to make on failed append. */
+ protected $reconnectAttempts = 3;
+
+
+ // ******************************************
+ // *** Private memebers ***
+ // ******************************************
+
+ /**
+ * The PDO instance.
+ * @var PDO
+ */
+ protected $db;
+
+ /**
+ * Prepared statement for the insert query.
+ * @var PDOStatement
+ */
+ protected $preparedInsert;
+
+ /** This appender does not require a layout. */
+ protected $requiresLayout = false;
+
+
+ // ******************************************
+ // *** Appender methods ***
+ // ******************************************
+
+ /**
+ * Acquires a database connection based on parameters.
+ * Parses the insert pattern to create a chain of converters which will be
+ * used in forming query parameters from logging events.
+ */
+ public function activateOptions() {
+ try {
+ $this->establishConnection();
+ } catch (PDOException $e) {
+ $this->warn("Failed connecting to database. Closing appender. Error: " . $e->getMessage());
+ $this->close();
+ return;
+ }
+
+ // Parse the insert patterns; pattern parts are comma delimited
+ $pieces = explode(',', $this->insertPattern);
+ $converterMap = LoggerLayoutPattern::getDefaultConverterMap();
+ foreach ($pieces as $pattern) {
+ $parser = new LoggerPatternParser($pattern, $converterMap);
+ $this->converters[] = $parser->parse();
+ }
+
+ $this->closed = false;
+ }
+
+ /**
+ * Connects to the database, and prepares the insert query.
+ * @throws PDOException If connect or prepare fails.
+ */
+ protected function establishConnection() {
+ // Acquire database connection
+ $this->db = new PDO($this->dsn, $this->user, $this->password);
+ $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+
+ // Prepare the insert statement
+ $insertSQL = str_replace('__TABLE__', $this->table, $this->insertSQL);
+ $this->preparedInsert = $this->db->prepare($insertSQL);
+ }
+
+ /**
+ * Appends a new event to the database.
+ *
+ * If writing to database fails, it will retry by re-establishing the
+ * connection up to $reconnectAttempts times. If writing still fails,
+ * the appender will close.
+ */
+ public function append(LoggerLoggingEvent $event) {
+
+ for ($attempt = 1; $attempt <= $this->reconnectAttempts + 1; $attempt++) {
+ try {
+ // Attempt to write to database
+ $this->preparedInsert->execute($this->format($event));
+ $this->preparedInsert->closeCursor();
+ break;
+ } catch (PDOException $e) {
+ $this->warn("Failed writing to database: " . $e->getMessage());
+
+ // Close the appender if it's the last attempt
+ if ($attempt > $this->reconnectAttempts) {
+ $this->warn("Failed writing to database after {$this->reconnectAttempts} reconnect attempts. Closing appender.");
+ $this->close();
+ // Otherwise reconnect and try to write again
+ } else {
+ $this->warn("Attempting a reconnect (attempt $attempt of {$this->reconnectAttempts}).");
+ $this->establishConnection();
+ }
+ }
+ }
+ }
+
+ /**
+ * Converts the logging event to a series of database parameters by using
+ * the converter chain which was set up on activation.
+ */
+ protected function format(LoggerLoggingEvent $event) {
+ $params = array();
+ foreach ($this->converters as $converter) {
+ $buffer = '';
+ while ($converter !== null) {
+ $converter->format($buffer, $event);
+ $converter = $converter->next;
+ }
+ $params[] = $buffer;
+ }
+ return $params;
+ }
+
+ /**
+ * Closes the connection to the logging database
+ */
+ public function close() {
+ // Close the connection (if any)
+ $this->db = null;
+
+ // Close the appender
+ $this->closed = true;
+ }
+
+ // ******************************************
+ // *** Accessor methods ***
+ // ******************************************
+
+ /**
+ * Returns the active database handle or null if not established.
+ * @return PDO
+ */
+ public function getDatabaseHandle() {
+ return $this->db;
+ }
+
+ /** Sets the username. */
+ public function setUser($user) {
+ $this->setString('user', $user);
+ }
+
+ /** Returns the username. */
+ public function getUser($user) {
+ return $this->user;
+ }
+
+ /** Sets the password. */
+ public function setPassword($password) {
+ $this->setString('password', $password);
+ }
+
+ /** Returns the password. */
+ public function getPassword($password) {
+ return $this->password;
+ }
+
+ /** Sets the insert SQL. */
+ public function setInsertSQL($sql) {
+ $this->setString('insertSQL', $sql);
+ }
+
+ /** Returns the insert SQL. */
+ public function getInsertSQL($sql) {
+ return $this->insertSQL;
+ }
+
+ /** Sets the insert pattern. */
+ public function setInsertPattern($pattern) {
+ $this->setString('insertPattern', $pattern);
+ }
+
+ /** Returns the insert pattern. */
+ public function getInsertPattern($pattern) {
+ return $this->insertPattern;
+ }
+
+ /** Sets the table name. */
+ public function setTable($table) {
+ $this->setString('table', $table);
+ }
+
+ /** Returns the table name. */
+ public function getTable($table) {
+ return $this->table;
+ }
+
+ /** Sets the DSN string. */
+ public function setDSN($dsn) {
+ $this->setString('dsn', $dsn);
+ }
+
+ /** Returns the DSN string. */
+ public function getDSN($dsn) {
+ return $this->setString('dsn', $dsn);
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/appenders/LoggerAppenderPhp.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * LoggerAppenderPhp logs events by creating a PHP user-level message using
+ * the PHP's trigger_error()function.
+ *
+ * This appender has no configurable parameters.
+ *
+ * Levels are mapped as follows:
+ *
+ * - <b>level < WARN</b> mapped to E_USER_NOTICE
+ * - <b>WARN <= level < ERROR</b> mapped to E_USER_WARNING
+ * - <b>level >= ERROR</b> mapped to E_USER_ERROR
+ *
+ * @version $Revision: 1337820 $
+ * @package log4php
+ * @subpackage appenders
+ * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+ * @link http://logging.apache.org/log4php/docs/appenders/php.html Appender documentation
+ */
+class LoggerAppenderPhp extends LoggerAppender {
+
+ public function append(LoggerLoggingEvent $event) {
+ $level = $event->getLevel();
+ if ($level->isGreaterOrEqual(LoggerLevel::getLevelError())) {
+ trigger_error($this->layout->format($event), E_USER_ERROR);
+ } else if ($level->isGreaterOrEqual(LoggerLevel::getLevelWarn())) {
+ trigger_error($this->layout->format($event), E_USER_WARNING);
+ } else {
+ trigger_error($this->layout->format($event), E_USER_NOTICE);
+ }
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/appenders/LoggerAppenderRollingFile.php
@@ -0,0 +1,305 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * LoggerAppenderRollingFile writes logging events to a specified file. The
+ * file is rolled over after a specified size has been reached.
+ *
+ * This appender uses a layout.
+ *
+ * ## Configurable parameters: ##
+ *
+ * - **file** - Path to the target file.
+ * - **append** - If set to true, the appender will append to the file,
+ * otherwise the file contents will be overwritten.
+ * - **maxBackupIndex** - Maximum number of backup files to keep. Default is 1.
+ * - **maxFileSize** - Maximum allowed file size (in bytes) before rolling
+ * over. Suffixes "KB", "MB" and "GB" are allowed. 10KB = 10240 bytes, etc.
+ * Default is 10M.
+ * - **compress** - If set to true, rolled-over files will be compressed.
+ * Requires the zlib extension.
+ *
+ * @version $Revision: 1394975 $
+ * @package log4php
+ * @subpackage appenders
+ * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+ * @link http://logging.apache.org/log4php/docs/appenders/rolling-file.html Appender documentation
+ */
+class LoggerAppenderRollingFile extends LoggerAppenderFile {
+
+ /** Compressing backup files is done in chunks, this determines how large. */
+ const COMPRESS_CHUNK_SIZE = 102400; // 100KB
+
+ /**
+ * The maximum size (in bytes) that the output file is allowed to reach
+ * before being rolled over to backup files.
+ *
+ * The default maximum file size is 10MB (10485760 bytes). Maximum value
+ * for this option may depend on the file system.
+ *
+ * @var integer
+ */
+ protected $maxFileSize = 10485760;
+
+ /**
+ * Set the maximum number of backup files to keep around.
+ *
+ * Determines how many backup files are kept before the oldest is erased.
+ * This option takes a positive integer value. If set to zero, then there
+ * will be no backup files and the log file will be truncated when it
+ * reaches <var>maxFileSize</var>.
+ *
+ * There is one backup file by default.
+ *
+ * @var integer
+ */
+ protected $maxBackupIndex = 1;
+
+ /**
+ * The <var>compress</var> parameter determindes the compression with zlib.
+ * If set to true, the rollover files are compressed and saved with the .gz extension.
+ * @var boolean
+ */
+ protected $compress = false;
+
+ /**
+ * Set to true in the constructor if PHP >= 5.3.0. In that case clearstatcache
+ * supports conditional clearing of statistics.
+ * @var boolean
+ * @see http://php.net/manual/en/function.clearstatcache.php
+ */
+ private $clearConditional = false;
+
+ /**
+ * Get the maximum size that the output file is allowed to reach
+ * before being rolled over to backup files.
+ * @return integer
+ */
+ public function getMaximumFileSize() {
+ return $this->maxFileSize;
+ }
+
+ public function __construct($name = '') {
+ parent::__construct($name);
+ if (version_compare(PHP_VERSION, '5.3.0') >= 0) {
+ $this->clearConditional = true;
+ }
+ }
+
+ /**
+ * Implements the usual roll over behaviour.
+ *
+ * If MaxBackupIndex is positive, then files File.1, ..., File.MaxBackupIndex -1 are renamed to File.2, ..., File.MaxBackupIndex.
+ * Moreover, File is renamed File.1 and closed. A new File is created to receive further log output.
+ *
+ * If MaxBackupIndex is equal to zero, then the File is truncated with no backup files created.
+ *
+ * Rollover must be called while the file is locked so that it is safe for concurrent access.
+ *
+ * @throws LoggerException If any part of the rollover procedure fails.
+ */
+ private function rollOver() {
+ // If maxBackups <= 0, then there is no file renaming to be done.
+ if ($this->maxBackupIndex > 0) {
+ // Delete the oldest file, to keep Windows happy.
+ $file = $this->file . '.' . $this->maxBackupIndex;
+
+ if (file_exists($file) && !unlink($file)) {
+ throw new LoggerException("Unable to delete oldest backup file from [$file].");
+ }
+
+ // Map {(maxBackupIndex - 1), ..., 2, 1} to {maxBackupIndex, ..., 3, 2}
+ $this->renameArchievedLogs($this->file);
+
+ // Backup the active file
+ $this->moveToBackup($this->file);
+ }
+
+ // Truncate the active file
+ ftruncate($this->fp, 0);
+ rewind($this->fp);
+ }
+
+ private function moveToBackup($source) {
+ if ($this->compress) {
+ $target = $source . '.1.gz';
+ $this->compressFile($source, $target);
+ } else {
+ $target = $source . '.1';
+ copy($source, $target);
+ }
+ }
+
+ private function compressFile($source, $target) {
+ $target = 'compress.zlib://' . $target;
+
+ $fin = fopen($source, 'rb');
+ if ($fin === false) {
+ throw new LoggerException("Unable to open file for reading: [$source].");
+ }
+
+ $fout = fopen($target, 'wb');
+ if ($fout === false) {
+ throw new LoggerException("Unable to open file for writing: [$target].");
+ }
+
+ while (!feof($fin)) {
+ $chunk = fread($fin, self::COMPRESS_CHUNK_SIZE);
+ if (false === fwrite($fout, $chunk)) {
+ throw new LoggerException("Failed writing to compressed file.");
+ }
+ }
+
+ fclose($fin);
+ fclose($fout);
+ }
+
+ private function renameArchievedLogs($fileName) {
+ for ($i = $this->maxBackupIndex - 1; $i >= 1; $i--) {
+
+ $source = $fileName . "." . $i;
+ if ($this->compress) {
+ $source .= '.gz';
+ }
+
+ if (file_exists($source)) {
+ $target = $fileName . '.' . ($i + 1);
+ if ($this->compress) {
+ $target .= '.gz';
+ }
+
+ rename($source, $target);
+ }
+ }
+ }
+
+ /**
+ * Writes a string to the target file. Opens file if not already open.
+ * @param string $string Data to write.
+ */
+ protected function write($string) {
+ // Lazy file open
+ if (!isset($this->fp)) {
+ if ($this->openFile() === false) {
+ return; // Do not write if file open failed.
+ }
+ }
+
+ // Lock the file while writing and possible rolling over
+ if (flock($this->fp, LOCK_EX)) {
+
+ // Write to locked file
+ if (fwrite($this->fp, $string) === false) {
+ $this->warn("Failed writing to file. Closing appender.");
+ $this->closed = true;
+ }
+
+ // Stats cache must be cleared, otherwise filesize() returns cached results
+ // If supported (PHP 5.3+), clear only the state cache for the target file
+ if ($this->clearConditional) {
+ clearstatcache(true, $this->file);
+ } else {
+ clearstatcache();
+ }
+
+ // Rollover if needed
+ if (filesize($this->file) > $this->maxFileSize) {
+ try {
+ $this->rollOver();
+ } catch (LoggerException $ex) {
+ $this->warn("Rollover failed: " . $ex->getMessage() . " Closing appender.");
+ $this->closed = true;
+ }
+ }
+
+ flock($this->fp, LOCK_UN);
+ } else {
+ $this->warn("Failed locking file for writing. Closing appender.");
+ $this->closed = true;
+ }
+ }
+
+ public function activateOptions() {
+ parent::activateOptions();
+
+ if ($this->compress && !extension_loaded('zlib')) {
+ $this->warn("The 'zlib' extension is required for file compression. Disabling compression.");
+ $this->compression = false;
+ }
+ }
+
+ /**
+ * Set the 'maxBackupIndex' parameter.
+ * @param integer $maxBackupIndex
+ */
+ public function setMaxBackupIndex($maxBackupIndex) {
+ $this->setPositiveInteger('maxBackupIndex', $maxBackupIndex);
+ }
+
+ /**
+ * Returns the 'maxBackupIndex' parameter.
+ * @return integer
+ */
+ public function getMaxBackupIndex() {
+ return $this->maxBackupIndex;
+ }
+
+ /**
+ * Set the 'maxFileSize' parameter.
+ * @param mixed $maxFileSize
+ */
+ public function setMaxFileSize($maxFileSize) {
+ $this->setFileSize('maxFileSize', $maxFileSize);
+ }
+
+ /**
+ * Returns the 'maxFileSize' parameter.
+ * @return integer
+ */
+ public function getMaxFileSize() {
+ return $this->maxFileSize;
+ }
+
+ /**
+ * Set the 'maxFileSize' parameter (kept for backward compatibility).
+ * @param mixed $maxFileSize
+ * @deprecated Use setMaxFileSize() instead.
+ */
+ public function setMaximumFileSize($maxFileSize) {
+ $this->warn("The 'maximumFileSize' parameter is deprecated. Use 'maxFileSize' instead.");
+ return $this->setMaxFileSize($maxFileSize);
+ }
+
+ /**
+ * Sets the 'compress' parameter.
+ * @param boolean $compress
+ */
+ public function setCompress($compress) {
+ $this->setBoolean('compress', $compress);
+ }
+
+ /**
+ * Returns the 'compress' parameter.
+ * @param boolean
+ */
+ public function getCompress() {
+ return $this->compress;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/appenders/LoggerAppenderSocket.php
@@ -0,0 +1,122 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * LoggerAppenderSocket appends to a network socket.
+ *
+ * ## Configurable parameters: ##
+ *
+ * - **remoteHost** - Target remote host.
+ * - **port** - Target port (optional, defaults to 4446).
+ * - **timeout** - Connection timeout in seconds (optional, defaults to
+ * 'default_socket_timeout' from php.ini)
+ *
+ * The socket will by default be opened in blocking mode.
+ *
+ * @version $Revision: 1337820 $
+ * @package log4php
+ * @subpackage appenders
+ * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+ * @link http://logging.apache.org/log4php/docs/appenders/socket.html Appender documentation
+ */
+class LoggerAppenderSocket extends LoggerAppender {
+
+ /**
+ * Target host.
+ * @see http://php.net/manual/en/function.fsockopen.php
+ */
+ protected $remoteHost;
+
+ /** Target port */
+ protected $port = 4446;
+
+ /** Connection timeout in ms. */
+ protected $timeout;
+
+ // ******************************************
+ // *** Appender methods ***
+ // ******************************************
+
+ /** Override the default layout to use serialized. */
+ public function getDefaultLayout() {
+ return new LoggerLayoutSerialized();
+ }
+
+ public function activateOptions() {
+ if (empty($this->remoteHost)) {
+ $this->warn("Required parameter [remoteHost] not set. Closing appender.");
+ $this->closed = true;
+ return;
+ }
+
+ if (empty($this->timeout)) {
+ $this->timeout = ini_get("default_socket_timeout");
+ }
+
+ $this->closed = false;
+ }
+
+ public function append(LoggerLoggingEvent $event) {
+ $socket = fsockopen($this->remoteHost, $this->port, $errno, $errstr, $this->timeout);
+ if ($socket === false) {
+ $this->warn("Could not open socket to {$this->remoteHost}:{$this->port}. Closing appender.");
+ $this->closed = true;
+ return;
+ }
+
+ if (false === fwrite($socket, $this->layout->format($event))) {
+ $this->warn("Error writing to socket. Closing appender.");
+ $this->closed = true;
+ }
+ fclose($socket);
+ }
+
+ // ******************************************
+ // *** Accessor methods ***
+ // ******************************************
+
+ /** Sets the target host. */
+ public function setRemoteHost($hostname) {
+ $this->setString('remoteHost', $hostname);
+ }
+
+ /** Sets the target port */
+ public function setPort($port) {
+ $this->setPositiveInteger('port', $port);
+ }
+
+ /** Sets the timeout. */
+ public function setTimeout($timeout) {
+ $this->setPositiveInteger('timeout', $timeout);
+ }
+
+ /** Returns the target host. */
+ public function getRemoteHost() {
+ return $this->getRemoteHost();
+ }
+
+ /** Returns the target port. */
+ public function getPort() {
+ return $this->port;
+ }
+
+ /** Returns the timeout */
+ public function getTimeout() {
+ return $this->timeout;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/appenders/LoggerAppenderSyslog.php
@@ -0,0 +1,303 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Log events to a system log using the PHP syslog() function.
+ *
+ * This appenders requires a layout.
+ *
+ * ## Configurable parameters: ##
+ *
+ * - **ident** - The ident of the syslog message.
+ * - **priority** - The priority for the syslog message (used when overriding
+ * priority).
+ * - **facility** - The facility for the syslog message
+ * - **overridePriority** - If set to true, the message priority will always
+ * use the value defined in {@link $priority}, otherwise the priority will
+ * be determined by the message's log level.
+ * - **option** - The option value for the syslog message.
+ *
+ * Recognised syslog options are:
+ *
+ * - CONS - if there is an error while sending data to the system logger, write directly to the system console
+ * - NDELAY - open the connection to the logger immediately
+ * - ODELAY - delay opening the connection until the first message is logged (default)
+ * - PERROR - print log message also to standard error
+ * - PID - include PID with each message
+ *
+ * Multiple options can be set by delimiting them with a pipe character,
+ * e.g.: "CONS|PID|PERROR".
+ *
+ * Recognised syslog priorities are:
+ *
+ * - EMERG
+ * - ALERT
+ * - CRIT
+ * - ERR
+ * - WARNING
+ * - NOTICE
+ * - INFO
+ * - DEBUG
+ *
+ * Levels are mapped as follows:
+ *
+ * - <b>FATAL</b> to LOG_ALERT
+ * - <b>ERROR</b> to LOG_ERR
+ * - <b>WARN</b> to LOG_WARNING
+ * - <b>INFO</b> to LOG_INFO
+ * - <b>DEBUG</b> to LOG_DEBUG
+ * - <b>TRACE</b> to LOG_DEBUG
+ *
+ * @version $Revision: 1337820 $
+ * @package log4php
+ * @subpackage appenders
+ * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+ * @link http://logging.apache.org/log4php/docs/appenders/syslog.html Appender documentation
+ */
+class LoggerAppenderSyslog extends LoggerAppender {
+
+ /**
+ * The ident string is added to each message. Typically the name of your application.
+ *
+ * @var string
+ */
+ protected $ident = "Apache log4php";
+
+ /**
+ * The syslog priority to use when overriding priority. This setting is
+ * required if {@link overridePriority} is set to true.
+ *
+ * @var string
+ */
+ protected $priority;
+
+ /**
+ * The option used when opening the syslog connection.
+ *
+ * @var string
+ */
+ protected $option = 'PID|CONS';
+
+ /**
+ * The facility value indicates the source of the message.
+ *
+ * @var string
+ */
+ protected $facility = 'USER';
+
+ /**
+ * If set to true, the message priority will always use the value defined
+ * in {@link $priority}, otherwise the priority will be determined by the
+ * message's log level.
+ *
+ * @var string
+ */
+ protected $overridePriority = false;
+
+ /**
+ * Holds the int value of the {@link $priority}.
+ * @var int
+ */
+ private $intPriority;
+
+ /**
+ * Holds the int value of the {@link $facility}.
+ * @var int
+ */
+ private $intFacility;
+
+ /**
+ * Holds the int value of the {@link $option}.
+ * @var int
+ */
+ private $intOption;
+
+ /**
+ * Sets the {@link $ident}.
+ *
+ * @param string $ident
+ */
+ public function setIdent($ident) {
+ $this->ident = $ident;
+ }
+
+ /**
+ * Sets the {@link $priority}.
+ *
+ * @param string $priority
+ */
+ public function setPriority($priority) {
+ $this->priority = $priority;
+ }
+
+ /**
+ * Sets the {@link $facility}.
+ *
+ * @param string $facility
+ */
+ public function setFacility($facility) {
+ $this->facility = $facility;
+ }
+
+ /**
+ * Sets the {@link $overridePriority}.
+ *
+ * @param string $overridePriority
+ */
+ public function setOverridePriority($overridePriority) {
+ $this->overridePriority = $overridePriority;
+ }
+
+ /**
+ * Sets the 'option' parameter.
+ *
+ * @param string $option
+ */
+ public function setOption($option) {
+ $this->option = $option;
+ }
+
+ /**
+ * Returns the 'ident' parameter.
+ *
+ * @return string $ident
+ */
+ public function getIdent() {
+ return $this->ident;
+ }
+
+ /**
+ * Returns the 'priority' parameter.
+ *
+ * @return string
+ */
+ public function getPriority() {
+ return $this->priority;
+ }
+
+ /**
+ * Returns the 'facility' parameter.
+ *
+ * @return string
+ */
+ public function getFacility() {
+ return $this->facility;
+ }
+
+ /**
+ * Returns the 'overridePriority' parameter.
+ *
+ * @return string
+ */
+ public function getOverridePriority() {
+ return $this->overridePriority;
+ }
+
+ /**
+ * Returns the 'option' parameter.
+ *
+ * @return string
+ */
+ public function getOption() {
+ return $this->option;
+ }
+
+
+ public function activateOptions() {
+ $this->intPriority = $this->parsePriority();
+ $this->intOption = $this->parseOption();
+ $this->intFacility = $this->parseFacility();
+
+ $this->closed = false;
+ }
+
+ public function close() {
+ if ($this->closed != true) {
+ closelog();
+ $this->closed = true;
+ }
+ }
+
+ /**
+ * Appends the event to syslog.
+ *
+ * Log is opened and closed each time because if it is not closed, it
+ * can cause the Apache httpd server to log to whatever ident/facility
+ * was used in openlog().
+ *
+ * @see http://www.php.net/manual/en/function.syslog.php#97843
+ */
+ public function append(LoggerLoggingEvent $event) {
+ $priority = $this->getSyslogPriority($event->getLevel());
+ $message = $this->layout->format($event);
+
+ openlog($this->ident, $this->intOption, $this->intFacility);
+ syslog($priority, $message);
+ closelog();
+ }
+
+ /** Determines which syslog priority to use based on the given level. */
+ private function getSyslogPriority(LoggerLevel $level) {
+ if ($this->overridePriority) {
+ return $this->intPriority;
+ }
+ return $level->getSyslogEquivalent();
+ }
+
+ /** Parses a syslog option string and returns the correspodning int value. */
+ private function parseOption() {
+ $value = 0;
+ $options = explode('|', $this->option);
+
+ foreach ($options as $option) {
+ if (!empty($option)) {
+ $constant = "LOG_" . trim($option);
+ if (defined($constant)) {
+ $value |= constant($constant);
+ } else {
+ trigger_error("log4php: Invalid syslog option provided: $option. Whole option string: {$this->option}.", E_USER_WARNING);
+ }
+ }
+ }
+ return $value;
+ }
+
+ /** Parses the facility string and returns the corresponding int value. */
+ private function parseFacility() {
+ if (!empty($this->facility)) {
+ $constant = "LOG_" . trim($this->facility);
+ if (defined($constant)) {
+ return constant($constant);
+ } else {
+ trigger_error("log4php: Invalid syslog facility provided: {$this->facility}.", E_USER_WARNING);
+ }
+ }
+ }
+
+ /** Parses the priority string and returns the corresponding int value. */
+ private function parsePriority() {
+ if (!empty($this->priority)) {
+ $constant = "LOG_" . trim($this->priority);
+ if (defined($constant)) {
+ return constant($constant);
+ } else {
+ trigger_error("log4php: Invalid syslog priority provided: {$this->priority}.", E_USER_WARNING);
+ }
+ }
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/configurators/LoggerConfigurationAdapter.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * The interface for configurator adapters.
+ *
+ * Adapters convert configuration in several formats such as XML, ini and PHP
+ * file to a PHP array.
+ *
+ * @package log4php
+ * @subpackage configurators
+ * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+ * @version $Revision: 1343601 $
+ * @since 2.2
+ */
+interface LoggerConfigurationAdapter {
+ /** Converts the configuration file to PHP format usable by the configurator. */
+ public function convert($input);
+
+}
+
new file mode 100644
--- /dev/null
+++ b/library/log4php/configurators/LoggerConfigurationAdapterINI.php
@@ -0,0 +1,291 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Converts ini configuration files to a PHP array.
+ *
+ * These used to be called "properties" files (inherited from log4j), and that
+ * file extension is still supported.
+ *
+ * @package log4php
+ * @subpackage configurators
+ * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+ * @version $Revision: 1343601 $
+ * @since 2.2
+ */
+class LoggerConfigurationAdapterINI implements LoggerConfigurationAdapter {
+
+ /** Name to assign to the root logger. */
+ const ROOT_LOGGER_NAME = "root";
+
+ /** Prefix used for defining logger additivity. */
+ const ADDITIVITY_PREFIX = "log4php.additivity.";
+
+ /** Prefix used for defining logger threshold. */
+ const THRESHOLD_PREFIX = "log4php.threshold";
+
+ /** Prefix used for defining the root logger. */
+ const ROOT_LOGGER_PREFIX = "log4php.rootLogger";
+
+ /** Prefix used for defining a logger. */
+ const LOGGER_PREFIX = "log4php.logger.";
+
+ /** Prefix used for defining an appender. */
+ const APPENDER_PREFIX = "log4php.appender.";
+
+ /** Prefix used for defining a renderer. */
+ const RENDERER_PREFIX = "log4php.renderer.";
+
+ /** Holds the configuration. */
+ private $config = array();
+
+ /**
+ * Loads and parses the INI configuration file.
+ *
+ * @param string $url Path to the config file.
+ * @throws LoggerException
+ */
+ private function load($url) {
+ if (!file_exists($url)) {
+ throw new LoggerException("File [$url] does not exist.");
+ }
+
+ $properties = @parse_ini_file($url, true);
+ if ($properties === false) {
+ $error = error_get_last();
+ throw new LoggerException("Error parsing configuration file: {$error['message']}");
+ }
+
+ return $properties;
+ }
+
+ /**
+ * Converts the provided INI configuration file to a PHP array config.
+ *
+ * @param string $path Path to the config file.
+ * @throws LoggerException If the file cannot be loaded or parsed.
+ */
+ public function convert($path) {
+ // Load the configuration
+ $properties = $this->load($path);
+
+ // Parse threshold
+ if (isset($properties[self::THRESHOLD_PREFIX])) {
+ $this->config['threshold'] = $properties[self::THRESHOLD_PREFIX];
+ }
+
+ // Parse root logger
+ if (isset($properties[self::ROOT_LOGGER_PREFIX])) {
+ $this->parseLogger($properties[self::ROOT_LOGGER_PREFIX], self::ROOT_LOGGER_NAME);
+ }
+
+ $appenders = array();
+
+ foreach ($properties as $key => $value) {
+ // Parse loggers
+ if ($this->beginsWith($key, self::LOGGER_PREFIX)) {
+ $name = substr($key, strlen(self::LOGGER_PREFIX));
+ $this->parseLogger($value, $name);
+ }
+
+ // Parse additivity
+ if ($this->beginsWith($key, self::ADDITIVITY_PREFIX)) {
+ $name = substr($key, strlen(self::ADDITIVITY_PREFIX));
+ $this->config['loggers'][$name]['additivity'] = $value;
+ } // Parse appenders
+ else if ($this->beginsWith($key, self::APPENDER_PREFIX)) {
+ $this->parseAppender($key, $value);
+ } // Parse renderers
+ else if ($this->beginsWith($key, self::RENDERER_PREFIX)) {
+ $this->parseRenderer($key, $value);
+ }
+ }
+
+ return $this->config;
+ }
+
+
+ /**
+ * Parses a logger definition.
+ *
+ * Loggers are defined in the following manner:
+ * <pre>
+ * log4php.logger.<name> = [<level>], [<appender-ref>, <appender-ref>, ...]
+ * </pre>
+ *
+ * @param string $value The configuration value (level and appender-refs).
+ * @param string $name Logger name.
+ */
+ private function parseLogger($value, $name) {
+ // Value is divided by commas
+ $parts = explode(',', $value);
+ if (empty($value) || empty($parts)) {
+ return;
+ }
+
+ // The first value is the logger level
+ $level = array_shift($parts);
+
+ // The remaining values are appender references
+ $appenders = array();
+ while ($appender = array_shift($parts)) {
+ $appender = trim($appender);
+ if (!empty($appender)) {
+ $appenders[] = trim($appender);
+ }
+ }
+
+ // Find the target configuration
+ if ($name == self::ROOT_LOGGER_NAME) {
+ $this->config['rootLogger']['level'] = trim($level);
+ $this->config['rootLogger']['appenders'] = $appenders;
+ } else {
+ $this->config['loggers'][$name]['level'] = trim($level);
+ $this->config['loggers'][$name]['appenders'] = $appenders;
+ }
+ }
+
+ /**
+ * Parses an configuration line pertaining to an appender.
+ *
+ * Parses the following patterns:
+ *
+ * Appender class:
+ * <pre>
+ * log4php.appender.<name> = <class>
+ * </pre>
+ *
+ * Appender parameter:
+ * <pre>
+ * log4php.appender.<name>.<param> = <value>
+ * </pre>
+ *
+ * Appender threshold:
+ * <pre>
+ * log4php.appender.<name>.threshold = <level>
+ * </pre>
+ *
+ * Appender layout:
+ * <pre>
+ * log4php.appender.<name>.layout = <layoutClass>
+ * </pre>
+ *
+ * Layout parameter:
+ * <pre>
+ * log4php.appender.<name>.layout.<param> = <value>
+ * </pre>
+ *
+ * For example, a full appender config might look like:
+ * <pre>
+ * log4php.appender.myAppender = LoggerAppenderConsole
+ * log4php.appender.myAppender.threshold = info
+ * log4php.appender.myAppender.target = stdout
+ * log4php.appender.myAppender.layout = LoggerLayoutPattern
+ * log4php.appender.myAppender.layout.conversionPattern = "%d %c: %m%n"
+ * </pre>
+ *
+ * After parsing all these options, the following configuration can be
+ * found under $this->config['appenders']['myAppender']:
+ * <pre>
+ * array(
+ * 'class' => LoggerAppenderConsole,
+ * 'threshold' => info,
+ * 'params' => array(
+ * 'target' => 'stdout'
+ * ),
+ * 'layout' => array(
+ * 'class' => 'LoggerAppenderConsole',
+ * 'params' => array(
+ * 'conversionPattern' => '%d %c: %m%n'
+ * )
+ * )
+ * )
+ * </pre>
+ *
+ * @param string $key
+ * @param string $value
+ */
+ private function parseAppender($key, $value) {
+
+ // Remove the appender prefix from key
+ $subKey = substr($key, strlen(self::APPENDER_PREFIX));
+
+ // Divide the string by dots
+ $parts = explode('.', $subKey);
+ $count = count($parts);
+
+ // The first part is always the appender name
+ $name = trim($parts[0]);
+
+ // Only one part - this line defines the appender class
+ if ($count == 1) {
+ $this->config['appenders'][$name]['class'] = $value;
+ return;
+ } // Two parts - either a parameter, a threshold or layout class
+ else if ($count == 2) {
+
+ if ($parts[1] == 'layout') {
+ $this->config['appenders'][$name]['layout']['class'] = $value;
+ return;
+ } else if ($parts[1] == 'threshold') {
+ $this->config['appenders'][$name]['threshold'] = $value;
+ return;
+ } else {
+ $this->config['appenders'][$name]['params'][$parts[1]] = $value;
+ return;
+ }
+ } // Three parts - this can only be a layout parameter
+ else if ($count == 3) {
+ if ($parts[1] == 'layout') {
+ $this->config['appenders'][$name]['layout']['params'][$parts[2]] = $value;
+ return;
+ }
+ }
+
+ trigger_error("log4php: Don't know how to parse the following line: \"$key = $value\". Skipping.");
+ }
+
+ /**
+ * Parses a renderer definition.
+ *
+ * Renderers are defined as:
+ * <pre>
+ * log4php.renderer.<renderedClass> = <renderingClass>
+ * </pre>
+ *
+ * @param string $key log4php.renderer.<renderedClass>
+ * @param string $value <renderingClass>
+ */
+ private function parseRenderer($key, $value) {
+ // Remove the appender prefix from key
+ $renderedClass = substr($key, strlen(self::APPENDER_PREFIX));
+ $renderingClass = $value;
+
+ $this->config['renderers'][] = compact('renderedClass', 'renderingClass');
+ }
+
+ /** Helper method. Returns true if $str begins with $sub. */
+ private function beginsWith($str, $sub) {
+ return (strncmp($str, $sub, strlen($sub)) == 0);
+ }
+
+
+}
+
new file mode 100644
--- /dev/null
+++ b/library/log4php/configurators/LoggerConfigurationAdapterPHP.php
@@ -0,0 +1,83 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Converts PHP configuration files to a PHP array.
+ *
+ * The file should only hold the PHP config array preceded by "return".
+ *
+ * Example PHP config file:
+ * <code>
+ * <?php
+ * return array(
+ * 'rootLogger' => array(
+ * 'level' => 'info',
+ * 'appenders' => array('default')
+ * ),
+ * 'appenders' => array(
+ * 'default' => array(
+ * 'class' => 'LoggerAppenderEcho',
+ * 'layout' => array(
+ * 'class' => 'LoggerLayoutSimple'
+ * )
+ * )
+ * )
+ * )
+ * ?>
+ * </code>
+ *
+ * @package log4php
+ * @subpackage configurators
+ * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+ * @version $Revision: 1343601 $
+ * @since 2.2
+ */
+class LoggerConfigurationAdapterPHP implements LoggerConfigurationAdapter {
+ public function convert($url) {
+ if (!file_exists($url)) {
+ throw new LoggerException("File [$url] does not exist.");
+ }
+
+ // Load the config file
+ $data = @file_get_contents($url);
+ if ($data === false) {
+ $error = error_get_last();
+ throw new LoggerException("Error loading config file: {$error['message']}");
+ }
+
+ $config = @eval('?>' . $data);
+
+ if ($config === false) {
+ $error = error_get_last();
+ throw new LoggerException("Error parsing configuration: " . $error['message']);
+ }
+
+ if (empty($config)) {
+ throw new LoggerException("Invalid configuration: empty configuration array.");
+ }
+
+ if (!is_array($config)) {
+ throw new LoggerException("Invalid configuration: not an array.");
+ }
+
+ return $config;
+ }
+}
+
new file mode 100644
--- /dev/null
+++ b/library/log4php/configurators/LoggerConfigurationAdapterXML.php
@@ -0,0 +1,278 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Converts XML configuration files to a PHP array.
+ *
+ * @package log4php
+ * @subpackage configurators
+ * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+ * @version $Revision: 1394956 $
+ * @since 2.2
+ */
+class LoggerConfigurationAdapterXML implements LoggerConfigurationAdapter {
+ /** Path to the XML schema used for validation. */
+ const SCHEMA_PATH = '/../xml/log4php.xsd';
+
+ private $config = array(
+ 'appenders' => array(),
+ 'loggers' => array(),
+ 'renderers' => array(),
+ );
+
+ public function convert($url) {
+ $xml = $this->loadXML($url);
+
+ $this->parseConfiguration($xml);
+
+ // Parse the <root> node
+ if (isset($xml->root)) {
+ $this->parseRootLogger($xml->root);
+ }
+
+ // Process <logger> nodes
+ foreach ($xml->logger as $logger) {
+ $this->parseLogger($logger);
+ }
+
+ // Process <appender> nodes
+ foreach ($xml->appender as $appender) {
+ $this->parseAppender($appender);
+ }
+
+ // Process <renderer> nodes
+ foreach ($xml->renderer as $rendererNode) {
+ $this->parseRenderer($rendererNode);
+ }
+
+ // Process <defaultRenderer> node
+ foreach ($xml->defaultRenderer as $rendererNode) {
+ $this->parseDefaultRenderer($rendererNode);
+ }
+
+ return $this->config;
+ }
+
+ /**
+ * Loads and validates the XML.
+ * @param string $url Input XML.
+ */
+ private function loadXML($url) {
+ if (!file_exists($url)) {
+ throw new LoggerException("File [$url] does not exist.");
+ }
+
+ libxml_clear_errors();
+ $oldValue = libxml_use_internal_errors(true);
+
+ // Load XML
+ $xml = @simplexml_load_file($url);
+ if ($xml === false) {
+
+ $errorStr = "";
+ foreach (libxml_get_errors() as $error) {
+ $errorStr .= $error->message;
+ }
+
+ throw new LoggerException("Error loading configuration file: " . trim($errorStr));
+ }
+
+ libxml_clear_errors();
+ libxml_use_internal_errors($oldValue);
+
+ return $xml;
+ }
+
+ /**
+ * Parses the <configuration> node.
+ */
+ private function parseConfiguration(SimpleXMLElement $xml) {
+ $attributes = $xml->attributes();
+ if (isset($attributes['threshold'])) {
+ $this->config['threshold'] = (string)$attributes['threshold'];
+ }
+ }
+
+ /** Parses an <appender> node. */
+ private function parseAppender(SimpleXMLElement $node) {
+ $name = $this->getAttributeValue($node, 'name');
+ if (empty($name)) {
+ $this->warn("An <appender> node is missing the required 'name' attribute. Skipping appender definition.");
+ return;
+ }
+
+ $appender = array();
+ $appender['class'] = $this->getAttributeValue($node, 'class');
+
+ if (isset($node['threshold'])) {
+ $appender['threshold'] = $this->getAttributeValue($node, 'threshold');
+ }
+
+ if (isset($node->layout)) {
+ $appender['layout'] = $this->parseLayout($node->layout, $name);
+ }
+
+ if (count($node->param) > 0) {
+ $appender['params'] = $this->parseParameters($node);
+ }
+
+ foreach ($node->filter as $filterNode) {
+ $appender['filters'][] = $this->parseFilter($filterNode);
+ }
+
+ $this->config['appenders'][$name] = $appender;
+ }
+
+ /** Parses a <layout> node. */
+ private function parseLayout(SimpleXMLElement $node, $appenderName) {
+ $layout = array();
+ $layout['class'] = $this->getAttributeValue($node, 'class');
+
+ if (count($node->param) > 0) {
+ $layout['params'] = $this->parseParameters($node);
+ }
+
+ return $layout;
+ }
+
+ /** Parses any <param> child nodes returning them in an array. */
+ private function parseParameters($paramsNode) {
+ $params = array();
+
+ foreach ($paramsNode->param as $paramNode) {
+ if (empty($paramNode['name'])) {
+ $this->warn("A <param> node is missing the required 'name' attribute. Skipping parameter.");
+ continue;
+ }
+
+ $name = $this->getAttributeValue($paramNode, 'name');
+ $value = $this->getAttributeValue($paramNode, 'value');
+
+ $params[$name] = $value;
+ }
+
+ return $params;
+ }
+
+ /** Parses a <root> node. */
+ private function parseRootLogger(SimpleXMLElement $node) {
+ $logger = array();
+
+ if (isset($node->level)) {
+ $logger['level'] = $this->getAttributeValue($node->level, 'value');
+ }
+
+ $logger['appenders'] = $this->parseAppenderReferences($node);
+
+ $this->config['rootLogger'] = $logger;
+ }
+
+ /** Parses a <logger> node. */
+ private function parseLogger(SimpleXMLElement $node) {
+ $logger = array();
+
+ $name = $this->getAttributeValue($node, 'name');
+ if (empty($name)) {
+ $this->warn("A <logger> node is missing the required 'name' attribute. Skipping logger definition.");
+ return;
+ }
+
+ if (isset($node->level)) {
+ $logger['level'] = $this->getAttributeValue($node->level, 'value');
+ }
+
+ if (isset($node['additivity'])) {
+ $logger['additivity'] = $this->getAttributeValue($node, 'additivity');
+ }
+
+ $logger['appenders'] = $this->parseAppenderReferences($node);
+
+ // Check for duplicate loggers
+ if (isset($this->config['loggers'][$name])) {
+ $this->warn("Duplicate logger definition [$name]. Overwriting.");
+ }
+
+ $this->config['loggers'][$name] = $logger;
+ }
+
+ /**
+ * Parses a <logger> node for appender references and returns them in an array.
+ *
+ * Previous versions supported appender-ref, as well as appender_ref so both
+ * are parsed for backward compatibility.
+ */
+ private function parseAppenderReferences(SimpleXMLElement $node) {
+ $refs = array();
+ foreach ($node->appender_ref as $ref) {
+ $refs[] = $this->getAttributeValue($ref, 'ref');
+ }
+
+ foreach ($node->{'appender-ref'} as $ref) {
+ $refs[] = $this->getAttributeValue($ref, 'ref');
+ }
+
+ return $refs;
+ }
+
+ /** Parses a <filter> node. */
+ private function parseFilter($filterNode) {
+ $filter = array();
+ $filter['class'] = $this->getAttributeValue($filterNode, 'class');
+
+ if (count($filterNode->param) > 0) {
+ $filter['params'] = $this->parseParameters($filterNode);
+ }
+
+ return $filter;
+ }
+
+ /** Parses a <renderer> node. */
+ private function parseRenderer(SimpleXMLElement $node) {
+ $renderedClass = $this->getAttributeValue($node, 'renderedClass');
+ $renderingClass = $this->getAttributeValue($node, 'renderingClass');
+
+ $this->config['renderers'][] = compact('renderedClass', 'renderingClass');
+ }
+
+ /** Parses a <defaultRenderer> node. */
+ private function parseDefaultRenderer(SimpleXMLElement $node) {
+ $renderingClass = $this->getAttributeValue($node, 'renderingClass');
+
+ // Warn on duplicates
+ if (isset($this->config['defaultRenderer'])) {
+ $this->warn("Duplicate <defaultRenderer> node. Overwriting.");
+ }
+
+ $this->config['defaultRenderer'] = $renderingClass;
+ }
+
+ // ******************************************
+ // ** Helper methods **
+ // ******************************************
+
+ private function getAttributeValue(SimpleXMLElement $node, $name) {
+ return isset($node[$name]) ? (string)$node[$name] : null;
+ }
+
+ private function warn($message) {
+ trigger_error("log4php: " . $message, E_USER_WARNING);
+ }
+}
+
new file mode 100644
--- /dev/null
+++ b/library/log4php/configurators/LoggerConfiguratorDefault.php
@@ -0,0 +1,470 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Default implementation of the logger configurator.
+ *
+ * Configures log4php based on a provided configuration file or array.
+ *
+ * @package log4php
+ * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+ * @version $Revision: 1394956 $
+ * @since 2.2
+ */
+class LoggerConfiguratorDefault implements LoggerConfigurator {
+ /** XML configuration file format. */
+ const FORMAT_XML = 'xml';
+
+ /** PHP configuration file format. */
+ const FORMAT_PHP = 'php';
+
+ /** INI (properties) configuration file format. */
+ const FORMAT_INI = 'ini';
+
+ /** Defines which adapter should be used for parsing which format. */
+ private $adapters = array(
+ self::FORMAT_XML => 'LoggerConfigurationAdapterXML',
+ self::FORMAT_INI => 'LoggerConfigurationAdapterINI',
+ self::FORMAT_PHP => 'LoggerConfigurationAdapterPHP',
+ );
+
+ /** Default configuration; used if no configuration file is provided. */
+ private static $defaultConfiguration = array(
+ 'threshold' => 'ALL',
+ 'rootLogger' => array(
+ 'level' => 'DEBUG',
+ 'appenders' => array('default'),
+ ),
+ 'appenders' => array(
+ 'default' => array(
+ 'class' => 'LoggerAppenderEcho'
+ ),
+ ),
+ );
+
+ /** Holds the appenders before they are linked to loggers. */
+ private $appenders = array();
+
+ /**
+ * Configures log4php based on the given configuration. The input can
+ * either be a path to the config file, or a PHP array holding the
+ * configuration.
+ *
+ * If no configuration is given, or if the given configuration cannot be
+ * parsed for whatever reason, a warning will be issued, and log4php
+ * will use the default configuration contained in
+ * {@link $defaultConfiguration}.
+ *
+ * @param LoggerHierarchy $hierarchy The hierarchy on which to perform
+ * the configuration.
+ * @param string|array $input Either path to the config file or the
+ * configuration as an array. If not set, default configuration
+ * will be used.
+ */
+ public function configure(LoggerHierarchy $hierarchy, $input = null) {
+ $config = $this->parse($input);
+ $this->doConfigure($hierarchy, $config);
+ }
+
+ /**
+ * Parses the given configuration and returns the parsed configuration
+ * as a PHP array. Does not perform any configuration.
+ *
+ * If no configuration is given, or if the given configuration cannot be
+ * parsed for whatever reason, a warning will be issued, and the default
+ * configuration will be returned ({@link $defaultConfiguration}).
+ *
+ * @param string|array $input Either path to the config file or the
+ * configuration as an array. If not set, default configuration
+ * will be used.
+ * @return array The parsed configuration.
+ */
+ public function parse($input) {
+ // No input - use default configuration
+ if (!isset($input)) {
+ $config = self::$defaultConfiguration;
+ } // Array input - contains configuration within the array
+ else if (is_array($input)) {
+ $config = $input;
+ } // String input - contains path to configuration file
+ else if (is_string($input)) {
+ try {
+ $config = $this->parseFile($input);
+ } catch (LoggerException $e) {
+ $this->warn("Configuration failed. " . $e->getMessage() . " Using default configuration.");
+ $config = self::$defaultConfiguration;
+ }
+ } // Anything else is an error
+ else {
+ $this->warn("Invalid configuration param given. Reverting to default configuration.");
+ $config = self::$defaultConfiguration;
+ }
+
+ return $config;
+ }
+
+ /**
+ * Returns the default log4php configuration.
+ * @return array
+ */
+ public static function getDefaultConfiguration() {
+ return self::$defaultConfiguration;
+ }
+
+ /**
+ * Loads the configuration file from the given URL, determines which
+ * adapter to use, converts the configuration to a PHP array and
+ * returns it.
+ *
+ * @param string $url Path to the config file.
+ * @return The configuration from the config file, as a PHP array.
+ * @throws LoggerException If the configuration file cannot be loaded, or
+ * if the parsing fails.
+ */
+ private function parseFile($url) {
+
+ if (!file_exists($url)) {
+ throw new LoggerException("File not found at [$url].");
+ }
+
+ $type = $this->getConfigType($url);
+ $adapterClass = $this->adapters[$type];
+
+ $adapter = new $adapterClass();
+ return $adapter->convert($url);
+ }
+
+ /** Determines configuration file type based on the file extension. */
+ private function getConfigType($url) {
+ $info = pathinfo($url);
+ $ext = strtolower($info['extension']);
+
+ switch ($ext) {
+ case 'xml':
+ return self::FORMAT_XML;
+
+ case 'ini':
+ case 'properties':
+ return self::FORMAT_INI;
+
+ case 'php':
+ return self::FORMAT_PHP;
+
+ default:
+ throw new LoggerException("Unsupported configuration file extension: $ext");
+ }
+ }
+
+ /**
+ * Constructs the logger hierarchy based on configuration.
+ *
+ * @param LoggerHierarchy $hierarchy
+ * @param array $config
+ */
+ private function doConfigure(LoggerHierarchy $hierarchy, $config) {
+ if (isset($config['threshold'])) {
+ $threshold = LoggerLevel::toLevel($config['threshold']);
+ if (isset($threshold)) {
+ $hierarchy->setThreshold($threshold);
+ } else {
+ $this->warn("Invalid threshold value [{$config['threshold']}] specified. Ignoring threshold definition.");
+ }
+ }
+
+ // Configure appenders and add them to the appender pool
+ if (isset($config['appenders']) && is_array($config['appenders'])) {
+ foreach ($config['appenders'] as $name => $appenderConfig) {
+ $this->configureAppender($name, $appenderConfig);
+ }
+ }
+
+ // Configure root logger
+ if (isset($config['rootLogger'])) {
+ $this->configureRootLogger($hierarchy, $config['rootLogger']);
+ }
+
+ // Configure loggers
+ if (isset($config['loggers']) && is_array($config['loggers'])) {
+ foreach ($config['loggers'] as $loggerName => $loggerConfig) {
+ $this->configureOtherLogger($hierarchy, $loggerName, $loggerConfig);
+ }
+ }
+
+ // Configure renderers
+ if (isset($config['renderers']) && is_array($config['renderers'])) {
+ foreach ($config['renderers'] as $rendererConfig) {
+ $this->configureRenderer($hierarchy, $rendererConfig);
+ }
+ }
+
+ if (isset($config['defaultRenderer'])) {
+ $this->configureDefaultRenderer($hierarchy, $config['defaultRenderer']);
+ }
+ }
+
+ private function configureRenderer(LoggerHierarchy $hierarchy, $config) {
+ if (empty($config['renderingClass'])) {
+ $this->warn("Rendering class not specified. Skipping renderer definition.");
+ return;
+ }
+
+ if (empty($config['renderedClass'])) {
+ $this->warn("Rendered class not specified. Skipping renderer definition.");
+ return;
+ }
+
+ // Error handling performed by RendererMap
+ $hierarchy->getRendererMap()->addRenderer($config['renderedClass'], $config['renderingClass']);
+ }
+
+ private function configureDefaultRenderer(LoggerHierarchy $hierarchy, $class) {
+ if (empty($class)) {
+ $this->warn("Rendering class not specified. Skipping default renderer definition.");
+ return;
+ }
+
+ // Error handling performed by RendererMap
+ $hierarchy->getRendererMap()->setDefaultRenderer($class);
+ }
+
+ /**
+ * Configures an appender based on given config and saves it to
+ * {@link $appenders} array so it can be later linked to loggers.
+ * @param string $name Appender name.
+ * @param array $config Appender configuration options.
+ */
+ private function configureAppender($name, $config) {
+
+ // TODO: add this check to other places where it might be useful
+ if (!is_array($config)) {
+ $type = gettype($config);
+ $this->warn("Invalid configuration provided for appender [$name]. Expected an array, found <$type>. Skipping appender definition.");
+ return;
+ }
+
+ // Parse appender class
+ $class = $config['class'];
+ if (empty($class)) {
+ $this->warn("No class given for appender [$name]. Skipping appender definition.");
+ return;
+ }
+ if (!class_exists($class)) {
+ $this->warn("Invalid class [$class] given for appender [$name]. Class does not exist. Skipping appender definition.");
+ return;
+ }
+
+ // Instantiate the appender
+ $appender = new $class($name);
+ if (!($appender instanceof LoggerAppender)) {
+ $this->warn("Invalid class [$class] given for appender [$name]. Not a valid LoggerAppender class. Skipping appender definition.");
+ return;
+ }
+
+ // Parse the appender threshold
+ if (isset($config['threshold'])) {
+ $threshold = LoggerLevel::toLevel($config['threshold']);
+ if ($threshold instanceof LoggerLevel) {
+ $appender->setThreshold($threshold);
+ } else {
+ $this->warn("Invalid threshold value [{$config['threshold']}] specified for appender [$name]. Ignoring threshold definition.");
+ }
+ }
+
+ // Parse the appender layout
+ if ($appender->requiresLayout() && isset($config['layout'])) {
+ $this->createAppenderLayout($appender, $config['layout']);
+ }
+
+ // Parse filters
+ if (isset($config['filters']) && is_array($config['filters'])) {
+ foreach ($config['filters'] as $filterConfig) {
+ $this->createAppenderFilter($appender, $filterConfig);
+ }
+ }
+
+ // Set options if any
+ if (isset($config['params'])) {
+ $this->setOptions($appender, $config['params']);
+ }
+
+ // Activate and save for later linking to loggers
+ $appender->activateOptions();
+ $this->appenders[$name] = $appender;
+ }
+
+ /**
+ * Parses layout config, creates the layout and links it to the appender.
+ * @param LoggerAppender $appender
+ * @param array $config Layout configuration.
+ */
+ private function createAppenderLayout(LoggerAppender $appender, $config) {
+ $name = $appender->getName();
+ $class = $config['class'];
+ if (empty($class)) {
+ $this->warn("Layout class not specified for appender [$name]. Reverting to default layout.");
+ return;
+ }
+ if (!class_exists($class)) {
+ $this->warn("Nonexistant layout class [$class] specified for appender [$name]. Reverting to default layout.");
+ return;
+ }
+
+ $layout = new $class();
+ if (!($layout instanceof LoggerLayout)) {
+ $this->warn("Invalid layout class [$class] sepcified for appender [$name]. Reverting to default layout.");
+ return;
+ }
+
+ if (isset($config['params'])) {
+ $this->setOptions($layout, $config['params']);
+ }
+
+ $layout->activateOptions();
+ $appender->setLayout($layout);
+ }
+
+ /**
+ * Parses filter config, creates the filter and adds it to the appender's
+ * filter chain.
+ * @param LoggerAppender $appender
+ * @param array $config Filter configuration.
+ */
+ private function createAppenderFilter(LoggerAppender $appender, $config) {
+ $name = $appender->getName();
+ $class = $config['class'];
+ if (!class_exists($class)) {
+ $this->warn("Nonexistant filter class [$class] specified on appender [$name]. Skipping filter definition.");
+ return;
+ }
+
+ $filter = new $class();
+ if (!($filter instanceof LoggerFilter)) {
+ $this->warn("Invalid filter class [$class] sepcified on appender [$name]. Skipping filter definition.");
+ return;
+ }
+
+ if (isset($config['params'])) {
+ $this->setOptions($filter, $config['params']);
+ }
+
+ $filter->activateOptions();
+ $appender->addFilter($filter);
+ }
+
+ /**
+ * Configures the root logger
+ * @see configureLogger()
+ */
+ private function configureRootLogger(LoggerHierarchy $hierarchy, $config) {
+ $logger = $hierarchy->getRootLogger();
+ $this->configureLogger($logger, $config);
+ }
+
+ /**
+ * Configures a logger which is not root.
+ * @see configureLogger()
+ */
+ private function configureOtherLogger(LoggerHierarchy $hierarchy, $name, $config) {
+ // Get logger from hierarchy (this creates it if it doesn't already exist)
+ $logger = $hierarchy->getLogger($name);
+ $this->configureLogger($logger, $config);
+ }
+
+ /**
+ * Configures a logger.
+ *
+ * @param Logger $logger The logger to configure
+ * @param array $config Logger configuration options.
+ */
+ private function configureLogger(Logger $logger, $config) {
+ $loggerName = $logger->getName();
+
+ // Set logger level
+ if (isset($config['level'])) {
+ $level = LoggerLevel::toLevel($config['level']);
+ if (isset($level)) {
+ $logger->setLevel($level);
+ } else {
+ $this->warn("Invalid level value [{$config['level']}] specified for logger [$loggerName]. Ignoring level definition.");
+ }
+ }
+
+ // Link appenders to logger
+ if (isset($config['appenders'])) {
+ foreach ($config['appenders'] as $appenderName) {
+ if (isset($this->appenders[$appenderName])) {
+ $logger->addAppender($this->appenders[$appenderName]);
+ } else {
+ $this->warn("Nonexistnant appender [$appenderName] linked to logger [$loggerName].");
+ }
+ }
+ }
+
+ // Set logger additivity
+ if (isset($config['additivity'])) {
+ try {
+ $additivity = LoggerOptionConverter::toBooleanEx($config['additivity'], null);
+ $logger->setAdditivity($additivity);
+ } catch (Exception $ex) {
+ $this->warn("Invalid additivity value [{$config['additivity']}] specified for logger [$loggerName]. Ignoring additivity setting.");
+ }
+ }
+ }
+
+ /**
+ * Helper method which applies given options to an object which has setters
+ * for these options (such as appenders, layouts, etc.).
+ *
+ * For example, if options are:
+ * <code>
+ * array(
+ * 'file' => '/tmp/myfile.log',
+ * 'append' => true
+ * )
+ * </code>
+ *
+ * This method will call:
+ * <code>
+ * $object->setFile('/tmp/myfile.log')
+ * $object->setAppend(true)
+ * </code>
+ *
+ * If required setters do not exist, it will produce a warning.
+ *
+ * @param mixed $object The object to configure.
+ * @param unknown_type $options
+ */
+ private function setOptions($object, $options) {
+ foreach ($options as $name => $value) {
+ $setter = "set$name";
+ if (method_exists($object, $setter)) {
+ $object->$setter($value);
+ } else {
+ $class = get_class($object);
+ $this->warn("Nonexistant option [$name] specified on [$class]. Skipping.");
+ }
+ }
+ }
+
+ /** Helper method to simplify error reporting. */
+ private function warn($message) {
+ trigger_error("log4php: $message", E_USER_WARNING);
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/filters/LoggerFilterDenyAll.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * This filter drops all logging events.
+ *
+ * You can add this filter to the end of a filter chain to
+ * switch from the default "accept all unless instructed otherwise"
+ * filtering behaviour to a "deny all unless instructed otherwise"
+ * behaviour.
+ *
+ * <p>
+ * An example for this filter:
+ *
+ * {@example ../../examples/php/filter_denyall.php 19}
+ *
+ * <p>
+ * The corresponding XML file:
+ *
+ * {@example ../../examples/resources/filter_denyall.xml 18}
+ *
+ * @version $Revision: 883108 $
+ * @package log4php
+ * @subpackage filters
+ * @since 0.3
+ */
+class LoggerFilterDenyAll extends LoggerFilter {
+
+ /**
+ * Always returns the integer constant {@link LoggerFilter::DENY}
+ * regardless of the {@link LoggerLoggingEvent} parameter.
+ *
+ * @param LoggerLoggingEvent $event The {@link LoggerLoggingEvent} to filter.
+ * @return LoggerFilter::DENY Always returns {@link LoggerFilter::DENY}
+ */
+ public function decide(LoggerLoggingEvent $event) {
+ return LoggerFilter::DENY;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/filters/LoggerFilterLevelMatch.php
@@ -0,0 +1,100 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * This is a very simple filter based on level matching.
+ *
+ * <p>The filter admits two options <b><var>LevelToMatch</var></b> and
+ * <b><var>AcceptOnMatch</var></b>. If there is an exact match between the value
+ * of the <b><var>LevelToMatch</var></b> option and the level of the
+ * {@link LoggerLoggingEvent}, then the {@link decide()} method returns
+ * {@link LoggerFilter::ACCEPT} in case the <b><var>AcceptOnMatch</var></b>
+ * option value is set to <i>true</i>, if it is <i>false</i> then
+ * {@link LoggerFilter::DENY} is returned. If there is no match,
+ * {@link LoggerFilter::NEUTRAL} is returned.</p>
+ *
+ * <p>
+ * An example for this filter:
+ *
+ * {@example ../../examples/php/filter_levelmatch.php 19}
+ *
+ * <p>
+ * The corresponding XML file:
+ *
+ * {@example ../../examples/resources/filter_levelmatch.xml 18}
+ *
+ * @version $Revision: 1213283 $
+ * @package log4php
+ * @subpackage filters
+ * @since 0.6
+ */
+class LoggerFilterLevelMatch extends LoggerFilter {
+
+ /**
+ * Indicates if this event should be accepted or denied on match
+ * @var boolean
+ */
+ protected $acceptOnMatch = true;
+
+ /**
+ * The level, when to match
+ * @var LoggerLevel
+ */
+ protected $levelToMatch;
+
+ /**
+ * @param boolean $acceptOnMatch
+ */
+ public function setAcceptOnMatch($acceptOnMatch) {
+ $this->setBoolean('acceptOnMatch', $acceptOnMatch);
+ }
+
+ /**
+ * @param string $l the level to match
+ */
+ public function setLevelToMatch($level) {
+ $this->setLevel('levelToMatch', $level);
+ }
+
+ /**
+ * Return the decision of this filter.
+ *
+ * Returns {@link LoggerFilter::NEUTRAL} if the <b><var>LevelToMatch</var></b>
+ * option is not set or if there is not match. Otherwise, if there is a
+ * match, then the returned decision is {@link LoggerFilter::ACCEPT} if the
+ * <b><var>AcceptOnMatch</var></b> property is set to <i>true</i>. The
+ * returned decision is {@link LoggerFilter::DENY} if the
+ * <b><var>AcceptOnMatch</var></b> property is set to <i>false</i>.
+ *
+ * @param LoggerLoggingEvent $event
+ * @return integer
+ */
+ public function decide(LoggerLoggingEvent $event) {
+ if ($this->levelToMatch === null) {
+ return LoggerFilter::NEUTRAL;
+ }
+
+ if ($this->levelToMatch->equals($event->getLevel())) {
+ return $this->acceptOnMatch ? LoggerFilter::ACCEPT : LoggerFilter::DENY;
+ } else {
+ return LoggerFilter::NEUTRAL;
+ }
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/filters/LoggerFilterLevelRange.php
@@ -0,0 +1,138 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * This is a very simple filter based on level matching, which can be
+ * used to reject messages with priorities outside a certain range.
+ *
+ * <p>The filter admits three options <b><var>LevelMin</var></b>, <b><var>LevelMax</var></b>
+ * and <b><var>AcceptOnMatch</var></b>.</p>
+ *
+ * <p>If the level of the {@link LoggerLoggingEvent} is not between Min and Max
+ * (inclusive), then {@link LoggerFilter::DENY} is returned.</p>
+ *
+ * <p>If the Logging event level is within the specified range, then if
+ * <b><var>AcceptOnMatch</var></b> is <i>true</i>,
+ * {@link LoggerFilter::ACCEPT} is returned, and if
+ * <b><var>AcceptOnMatch</var></b> is <i>false</i>,
+ * {@link LoggerFilter::NEUTRAL} is returned.</p>
+ *
+ * <p>If <b><var>LevelMin</var></b> is not defined, then there is no
+ * minimum acceptable level (i.e. a level is never rejected for
+ * being too "low"/unimportant). If <b><var>LevelMax</var></b> is not
+ * defined, then there is no maximum acceptable level (ie a
+ * level is never rejected for being too "high"/important).</p>
+ *
+ * <p>Refer to the {@link LoggerAppender::setThreshold()} method
+ * available to <b>all</b> appenders extending {@link LoggerAppender}
+ * for a more convenient way to filter out events by level.</p>
+ *
+ * <p>
+ * An example for this filter:
+ *
+ * {@example ../../examples/php/filter_levelrange.php 19}
+ *
+ * <p>
+ * The corresponding XML file:
+ *
+ * {@example ../../examples/resources/filter_levelrange.xml 18}
+ *
+ * @author Simon Kitching
+ * @author based on the org.apache.log4j.varia.LevelRangeFilte Java code by Ceki Gülcü
+ *
+ * @version $Revision: 1213283 $
+ * @package log4php
+ * @subpackage filters
+ * @since 0.6
+ */
+class LoggerFilterLevelRange extends LoggerFilter {
+
+ /**
+ * @var boolean
+ */
+ protected $acceptOnMatch = true;
+
+ /**
+ * @var LoggerLevel
+ */
+ protected $levelMin;
+
+ /**
+ * @var LoggerLevel
+ */
+ protected $levelMax;
+
+ /**
+ * @param boolean $acceptOnMatch
+ */
+ public function setAcceptOnMatch($acceptOnMatch) {
+ $this->setBoolean('acceptOnMatch', $acceptOnMatch);
+ }
+
+ /**
+ * @param string $l the level min to match
+ */
+ public function setLevelMin($level) {
+ $this->setLevel('levelMin', $level);
+ }
+
+ /**
+ * @param string $l the level max to match
+ */
+ public function setLevelMax($level) {
+ $this->setLevel('levelMax', $level);
+ }
+
+ /**
+ * Return the decision of this filter.
+ *
+ * @param LoggerLoggingEvent $event
+ * @return integer
+ */
+ public function decide(LoggerLoggingEvent $event) {
+ $level = $event->getLevel();
+
+ if ($this->levelMin !== null) {
+ if ($level->isGreaterOrEqual($this->levelMin) == false) {
+ // level of event is less than minimum
+ return LoggerFilter::DENY;
+ }
+ }
+
+ if ($this->levelMax !== null) {
+ if ($level->toInt() > $this->levelMax->toInt()) {
+ // level of event is greater than maximum
+ // Alas, there is no Level.isGreater method. and using
+ // a combo of isGreaterOrEqual && !Equal seems worse than
+ // checking the int values of the level objects..
+ return LoggerFilter::DENY;
+ }
+ }
+
+ if ($this->acceptOnMatch) {
+ // this filter set up to bypass later filters and always return
+ // accept if level in range
+ return LoggerFilter::ACCEPT;
+ } else {
+ // event is ok for this filter; allow later filters to have a look..
+ return LoggerFilter::NEUTRAL;
+ }
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/filters/LoggerFilterStringMatch.php
@@ -0,0 +1,89 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * This is a very simple filter based on string matching.
+ *
+ * <p>The filter admits two options {@link $stringToMatch} and
+ * {@link $acceptOnMatch}. If there is a match (using {@link PHP_MANUAL#strpos}
+ * between the value of the {@link $stringToMatch} option and the message
+ * of the {@link LoggerLoggingEvent},
+ * then the {@link decide()} method returns {@link LoggerFilter::ACCEPT} if
+ * the <b>AcceptOnMatch</b> option value is true, if it is false then
+ * {@link LoggerFilter::DENY} is returned. If there is no match, {@link LoggerFilter::NEUTRAL}
+ * is returned.</p>
+ *
+ * <p>
+ * An example for this filter:
+ *
+ * {@example ../../examples/php/filter_stringmatch.php 19}
+ *
+ * <p>
+ * The corresponding XML file:
+ *
+ * {@example ../../examples/resources/filter_stringmatch.xml 18}
+ *
+ * @version $Revision: 1213283 $
+ * @package log4php
+ * @subpackage filters
+ * @since 0.3
+ */
+class LoggerFilterStringMatch extends LoggerFilter {
+
+ /**
+ * @var boolean
+ */
+ protected $acceptOnMatch = true;
+
+ /**
+ * @var string
+ */
+ protected $stringToMatch;
+
+ /**
+ * @param mixed $acceptOnMatch a boolean or a string ('true' or 'false')
+ */
+ public function setAcceptOnMatch($acceptOnMatch) {
+ $this->setBoolean('acceptOnMatch', $acceptOnMatch);
+ }
+
+ /**
+ * @param string $s the string to match
+ */
+ public function setStringToMatch($string) {
+ $this->setString('stringToMatch', $string);
+ }
+
+ /**
+ * @return integer a {@link LOGGER_FILTER_NEUTRAL} is there is no string match.
+ */
+ public function decide(LoggerLoggingEvent $event) {
+ $msg = $event->getRenderedMessage();
+
+ if ($msg === null or $this->stringToMatch === null) {
+ return LoggerFilter::NEUTRAL;
+ }
+
+ if (strpos($msg, $this->stringToMatch) !== false) {
+ return ($this->acceptOnMatch) ? LoggerFilter::ACCEPT : LoggerFilter::DENY;
+ }
+ return LoggerFilter::NEUTRAL;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/helpers/LoggerFormattingInfo.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * This class encapsulates the information obtained when parsing
+ * formatting modifiers in conversion modifiers.
+ *
+ * @package log4php
+ * @subpackage helpers
+ * @since 0.3
+ */
+class LoggerFormattingInfo {
+
+ /**
+ * Minimal output length. If output is shorter than this value, it will be
+ * padded with spaces.
+ */
+ public $min = 0;
+
+ /**
+ * Maximum output length. If output is longer than this value, it will be
+ * trimmed.
+ */
+ public $max = PHP_INT_MAX;
+
+ /**
+ * Whether to pad the string from the left. If set to false, the string
+ * will be padded from the right.
+ */
+ public $padLeft = true;
+
+ /**
+ * Whether to trim the string from the left. If set to false, the string
+ * will be trimmed from the right.
+ */
+ public $trimLeft = false;
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/helpers/LoggerOptionConverter.php
@@ -0,0 +1,232 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * A convenience class to convert property values to specific types.
+ *
+ * @version $Revision: 1374617 $
+ * @package log4php
+ * @subpackage helpers
+ * @since 0.5
+ */
+class LoggerOptionConverter {
+
+ /** String values which are converted to boolean TRUE. */
+ private static $trueValues = array('1', 'true', 'yes', 'on');
+
+ /**
+ * String values which are converted to boolean FALSE.
+ *
+ * Note that an empty string must convert to false, because
+ * parse_ini_file() which is used for parsing configuration
+ * converts the value _false_ to an empty string.
+ */
+ private static $falseValues = array('0', 'false', 'no', 'off', '');
+
+ /**
+ * Read a predefined var.
+ *
+ * It returns a value referenced by <var>$key</var> using this search criteria:
+ * - if <var>$key</var> is a constant then return it. Else
+ * - if <var>$key</var> is set in <var>$_ENV</var> then return it. Else
+ * - return <var>$def</var>.
+ *
+ * @param string $key The key to search for.
+ * @param string $def The default value to return.
+ * @return string the string value of the system property, or the default
+ * value if there is no property with that key.
+ */
+ public static function getSystemProperty($key, $def) {
+ if (defined($key)) {
+ return (string)constant($key);
+ } else if (isset($_SERVER[$key])) {
+ return (string)$_SERVER[$key];
+ } else if (isset($_ENV[$key])) {
+ return (string)$_ENV[$key];
+ } else {
+ return $def;
+ }
+ }
+
+ /** Converts $value to boolean, or throws an exception if not possible. */
+ public static function toBooleanEx($value) {
+ if (isset($value)) {
+ if (is_bool($value)) {
+ return $value;
+ }
+ $value = strtolower(trim($value));
+ if (in_array($value, self::$trueValues)) {
+ return true;
+ }
+ if (in_array($value, self::$falseValues)) {
+ return false;
+ }
+ }
+
+ throw new LoggerException("Given value [" . var_export($value, true) . "] cannot be converted to boolean.");
+ }
+
+ /**
+ * Converts $value to integer, or throws an exception if not possible.
+ * Floats cannot be converted to integer.
+ */
+ public static function toIntegerEx($value) {
+ if (is_integer($value)) {
+ return $value;
+ }
+ if (is_numeric($value) && ($value == (integer)$value)) {
+ return (integer)$value;
+ }
+
+ throw new LoggerException("Given value [" . var_export($value, true) . "] cannot be converted to integer.");
+ }
+
+ /**
+ * Converts $value to integer, or throws an exception if not possible.
+ * Floats cannot be converted to integer.
+ */
+ public static function toPositiveIntegerEx($value) {
+ if (is_integer($value) && $value > 0) {
+ return $value;
+ }
+ if (is_numeric($value) && ($value == (integer)$value) && $value > 0) {
+ return (integer)$value;
+ }
+
+ throw new LoggerException("Given value [" . var_export($value, true) . "] cannot be converted to a positive integer.");
+ }
+
+ /** Converts the value to a level. Throws an exception if not possible. */
+ public static function toLevelEx($value) {
+ if ($value instanceof LoggerLevel) {
+ return $value;
+ }
+ $level = LoggerLevel::toLevel($value);
+ if ($level === null) {
+ throw new LoggerException("Given value [" . var_export($value, true) . "] cannot be converted to a logger level.");
+ }
+ return $level;
+ }
+
+ /**
+ * Converts a value to a valid file size (integer).
+ *
+ * Supports 'KB', 'MB' and 'GB' suffixes, where KB = 1024 B etc.
+ *
+ * The final value will be rounded to the nearest integer.
+ *
+ * Examples:
+ * - '100' => 100
+ * - '100.12' => 100
+ * - '100KB' => 102400
+ * - '1.5MB' => 1572864
+ *
+ * @param mixed $value File size (optionally with suffix).
+ * @return integer Parsed file size.
+ */
+ public static function toFileSizeEx($value) {
+
+ if (empty($value)) {
+ throw new LoggerException("Empty value cannot be converted to a file size.");
+ }
+
+ if (is_numeric($value)) {
+ return (integer)$value;
+ }
+
+ if (!is_string($value)) {
+ throw new LoggerException("Given value [" . var_export($value, true) . "] cannot be converted to a file size.");
+ }
+
+ $str = strtoupper(trim($value));
+ $count = preg_match('/^([0-9.]+)(KB|MB|GB)?$/', $str, $matches);
+
+ if ($count > 0) {
+ $size = $matches[1];
+ $unit = $matches[2];
+
+ switch ($unit) {
+ case 'KB':
+ $size *= pow(1024, 1);
+ break;
+ case 'MB':
+ $size *= pow(1024, 2);
+ break;
+ case 'GB':
+ $size *= pow(1024, 3);
+ break;
+ }
+
+ return (integer)$size;
+ }
+
+ throw new LoggerException("Given value [$value] cannot be converted to a file size.");
+ }
+
+ /**
+ * Converts a value to string, or throws an exception if not possible.
+ *
+ * Objects can be converted to string if they implement the magic
+ * __toString() method.
+ *
+ */
+ public static function toStringEx($value) {
+ if (is_string($value)) {
+ return $value;
+ }
+ if (is_numeric($value)) {
+ return (string)$value;
+ }
+ if (is_object($value) && method_exists($value, '__toString')) {
+ return (string)$value;
+ }
+
+ throw new LoggerException("Given value [" . var_export($value, true) . "] cannot be converted to string.");
+ }
+
+ /**
+ * Performs value substitution for string options.
+ *
+ * An option can contain PHP constants delimited by '${' and '}'.
+ *
+ * E.g. for input string "some ${FOO} value", the method will attempt
+ * to substitute ${FOO} with the value of constant FOO if it exists.
+ *
+ * Therefore, if FOO is a constant, and it has value "bar", the resulting
+ * string will be "some bar value".
+ *
+ * If the constant is not defined, it will be replaced by an empty string,
+ * and the resulting string will be "some value".
+ *
+ * @param string $string String on which to perform substitution.
+ * @return string
+ */
+ public static function substConstants($string) {
+ preg_match_all('/\${([^}]+)}/', $string, $matches);
+
+ foreach ($matches[1] as $key => $match) {
+ $match = trim($match);
+ $search = $matches[0][$key];
+ $replacement = defined($match) ? constant($match) : '';
+ $string = str_replace($search, $replacement, $string);
+ }
+ return $string;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/helpers/LoggerPatternParser.php
@@ -0,0 +1,237 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Most of the work of the {@link LoggerPatternLayout} class
+ * is delegated to the {@link LoggerPatternParser} class.
+ *
+ * <p>It is this class that parses conversion patterns and creates
+ * a chained list of {@link LoggerPatternConverter} converters.</p>
+ *
+ * @version $Revision: 1395467 $
+ * @package log4php
+ * @subpackage helpers
+ *
+ * @since 0.3
+ */
+class LoggerPatternParser {
+
+ /** Escape character for conversion words in the conversion pattern. */
+ const ESCAPE_CHAR = '%';
+
+ /** Maps conversion words to relevant converters. */
+ private $converterMap;
+
+ /** Conversion pattern used in layout. */
+ private $pattern;
+
+ /** Regex pattern used for parsing the conversion pattern. */
+ private $regex;
+
+ /**
+ * First converter in the chain.
+ * @var LoggerPatternConverter
+ */
+ private $head;
+
+ /** Last converter in the chain. */
+ private $tail;
+
+ public function __construct($pattern, $converterMap) {
+ $this->pattern = $pattern;
+ $this->converterMap = $converterMap;
+
+ // Construct the regex pattern
+ $this->regex =
+ '/' . // Starting regex pattern delimiter
+ self::ESCAPE_CHAR . // Character which marks the start of the conversion pattern
+ '(?P<modifiers>[0-9.-]*)' . // Format modifiers (optional)
+ '(?P<word>[a-zA-Z]+)' . // The conversion word
+ '(?P<option>{[^}]*})?' . // Conversion option in braces (optional)
+ '/'; // Ending regex pattern delimiter
+ }
+
+ /**
+ * Parses the conversion pattern string, converts it to a chain of pattern
+ * converters and returns the first converter in the chain.
+ *
+ * @return LoggerPatternConverter
+ */
+ public function parse() {
+
+ // Skip parsing if the pattern is empty
+ if (empty($this->pattern)) {
+ $this->addLiteral('');
+ return $this->head;
+ }
+
+ // Find all conversion words in the conversion pattern
+ $count = preg_match_all($this->regex, $this->pattern, $matches, PREG_OFFSET_CAPTURE);
+ if ($count === false) {
+ $error = error_get_last();
+ throw new LoggerException("Failed parsing layotut pattern: {$error['message']}");
+ }
+
+ $prevEnd = 0;
+
+ foreach ($matches[0] as $key => $item) {
+
+ // Locate where the conversion command starts and ends
+ $length = strlen($item[0]);
+ $start = $item[1];
+ $end = $item[1] + $length;
+
+ // Find any literal expressions between matched commands
+ if ($start > $prevEnd) {
+ $literal = substr($this->pattern, $prevEnd, $start - $prevEnd);
+ $this->addLiteral($literal);
+ }
+
+ // Extract the data from the matched command
+ $word = !empty($matches['word'][$key]) ? $matches['word'][$key][0] : null;
+ $modifiers = !empty($matches['modifiers'][$key]) ? $matches['modifiers'][$key][0] : null;
+ $option = !empty($matches['option'][$key]) ? $matches['option'][$key][0] : null;
+
+ // Create a converter and add it to the chain
+ $this->addConverter($word, $modifiers, $option);
+
+ $prevEnd = $end;
+ }
+
+ // Add any trailing literals
+ if ($end < strlen($this->pattern)) {
+ $literal = substr($this->pattern, $end);
+ $this->addLiteral($literal);
+ }
+
+ return $this->head;
+ }
+
+ /**
+ * Adds a literal converter to the converter chain.
+ * @param string $string The string for the literal converter.
+ */
+ private function addLiteral($string) {
+ $converter = new LoggerPatternConverterLiteral($string);
+ $this->addToChain($converter);
+ }
+
+ /**
+ * Adds a non-literal converter to the converter chain.
+ *
+ * @param string $word The conversion word, used to determine which
+ * converter will be used.
+ * @param string $modifiers Formatting modifiers.
+ * @param string $option Option to pass to the converter.
+ */
+ private function addConverter($word, $modifiers, $option) {
+ $formattingInfo = $this->parseModifiers($modifiers);
+ $option = trim($option, "{} ");
+
+ if (isset($this->converterMap[$word])) {
+ $converter = $this->getConverter($word, $formattingInfo, $option);
+ $this->addToChain($converter);
+ } else {
+ trigger_error("log4php: Invalid keyword '%$word' in converison pattern. Ignoring keyword.", E_USER_WARNING);
+ }
+ }
+
+ /**
+ * Determines which converter to use based on the conversion word. Creates
+ * an instance of the converter using the provided formatting info and
+ * option and returns it.
+ *
+ * @param string $word The conversion word.
+ * @param LoggerFormattingInfo $info Formatting info.
+ * @param string $option Converter option.
+ *
+ * @throws LoggerException
+ *
+ * @return LoggerPatternConverter
+ */
+ private function getConverter($word, $info, $option) {
+ if (!isset($this->converterMap[$word])) {
+ throw new LoggerException("Invalid keyword '%$word' in converison pattern. Ignoring keyword.");
+ }
+
+ $converterClass = $this->converterMap[$word];
+ if (!class_exists($converterClass)) {
+ throw new LoggerException("Class '$converterClass' does not exist.");
+ }
+
+ $converter = new $converterClass($info, $option);
+ if (!($converter instanceof LoggerPatternConverter)) {
+ throw new LoggerException("Class '$converterClass' is not an instance of LoggerPatternConverter.");
+ }
+
+ return $converter;
+ }
+
+ /** Adds a converter to the chain and updates $head and $tail pointers. */
+ private function addToChain(LoggerPatternConverter $converter) {
+ if (!isset($this->head)) {
+ $this->head = $converter;
+ $this->tail = $this->head;
+ } else {
+ $this->tail->next = $converter;
+ $this->tail = $this->tail->next;
+ }
+ }
+
+ /**
+ * Parses the formatting modifiers and produces the corresponding
+ * LoggerFormattingInfo object.
+ *
+ * @param string $modifier
+ * @return LoggerFormattingInfo
+ * @throws LoggerException
+ */
+ private function parseModifiers($modifiers) {
+ $info = new LoggerFormattingInfo();
+
+ // If no modifiers are given, return default values
+ if (empty($modifiers)) {
+ return $info;
+ }
+
+ // Validate
+ $pattern = '/^(-?[0-9]+)?\.?-?[0-9]+$/';
+ if (!preg_match($pattern, $modifiers)) {
+ trigger_error("log4php: Invalid modifier in conversion pattern: [$modifiers]. Ignoring modifier.", E_USER_WARNING);
+ return $info;
+ }
+
+ $parts = explode('.', $modifiers);
+
+ if (!empty($parts[0])) {
+ $minPart = (integer)$parts[0];
+ $info->min = abs($minPart);
+ $info->padLeft = ($minPart > 0);
+ }
+
+ if (!empty($parts[1])) {
+ $maxPart = (integer)$parts[1];
+ $info->max = abs($maxPart);
+ $info->trimLeft = ($maxPart < 0);
+ }
+
+ return $info;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/helpers/LoggerUtils.php
@@ -0,0 +1,123 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Contains various helper methods.
+ *
+ * @package log4php
+ * @subpackage helpers
+ * @since 2.3
+ */
+class LoggerUtils {
+
+ /**
+ * Splits a fully qualified class name into fragments delimited by the
+ * namespace separator (\).
+ *
+ * For backward compatibility, a dot (.) can be used as a delimiter as
+ * well.
+ *
+ * @param string $name
+ *
+ * @return array Class name split into fragments.
+ */
+ public static function tokenizeClassName($name) {
+ $name = str_replace('.', '\\', $name);
+ $name = trim($name, ' \\');
+ $fragments = explode('\\', $name);
+
+ foreach ($fragments as $key => $fragment) {
+ if (trim($fragment) === '') {
+ unset($fragments[$key]);
+ }
+ }
+
+ return $fragments;
+ }
+
+ /**
+ * Attempts to shorten the given class name to the desired length.
+ *
+ * This is done by separating the class name into fragments (delimited
+ * by \ or .) and trimming individual fragments, starting with the left,
+ * until desired length has been reached.
+ *
+ * The final fragment (i.e. class name) will never be shortened so the
+ * result may still be longer than given length.
+ *
+ * @param string $name The (qualified) class name.
+ * @param integer $length The length to shorten to. If null or 0 is given,
+ * the name will be returned without shortening.
+ */
+ public static function shortenClassName($name, $length) {
+ if ($length === null || $length < 0) {
+ return $name;
+ }
+
+ $name = str_replace('.', '\\', $name);
+ $name = trim($name, ' \\');
+
+ // Check if any shortening is required
+ $currentLength = strlen($name);
+ if ($currentLength <= $length) {
+ return $name;
+ }
+
+ // Split name into fragments
+ $fragments = explode('\\', $name);
+
+ // If zero length is specified, return only last fragment
+ if ($length == 0) {
+ return array_pop($fragments);
+ }
+
+ // If the name splits to only one fragment, then it cannot be shortened
+ $count = count($fragments);
+ if ($count == 1) {
+ return $name;
+ }
+
+ foreach ($fragments as $key => &$fragment) {
+
+ // Never shorten last fragment
+ if ($key == $count - 1) {
+ break;
+ }
+
+ // Check for empty fragments (shouldn't happen but it's possible)
+ $fragLen = strlen($fragment);
+ if ($fragLen <= 1) {
+ continue;
+ }
+
+ // Shorten fragment to one character and check if total length satisfactory
+ $fragment = substr($fragment, 0, 1);
+ $currentLength = $currentLength - $fragLen + 1;
+
+ if ($currentLength <= $length) {
+ break;
+ }
+ }
+ unset($fragment);
+
+ return implode('\\', $fragments);
+ }
+}
+
new file mode 100644
--- /dev/null
+++ b/library/log4php/layouts/LoggerLayoutHtml.php
@@ -0,0 +1,214 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * This layout outputs events in a HTML table.
+ *
+ * Configurable parameters for this layout are:
+ *
+ * - title
+ * - locationInfo
+ *
+ * An example for this layout:
+ *
+ * {@example ../../examples/php/layout_html.php 19}<br>
+ *
+ * The corresponding XML file:
+ *
+ * {@example ../../examples/resources/layout_html.properties 18}
+ *
+ * The above will print a HTML table that looks, converted back to plain text, like the following:<br>
+ * <pre>
+ * Log session start time Wed Sep 9 00:11:30 2009
+ *
+ * Time Thread Level Category Message
+ * 0 8318 INFO root Hello World!
+ * </pre>
+ *
+ * @version $Revision: 1379731 $
+ * @package log4php
+ * @subpackage layouts
+ */
+class LoggerLayoutHtml extends LoggerLayout {
+ /**
+ * The <b>LocationInfo</b> option takes a boolean value. By
+ * default, it is set to false which means there will be no location
+ * information output by this layout. If the the option is set to
+ * true, then the file name and line number of the statement
+ * at the origin of the log statement will be output.
+ *
+ * <p>If you are embedding this layout within a {@link LoggerAppenderMail}
+ * or a {@link LoggerAppenderMailEvent} then make sure to set the
+ * <b>LocationInfo</b> option of that appender as well.
+ * @var boolean
+ */
+ protected $locationInfo = false;
+
+ /**
+ * The <b>Title</b> option takes a String value. This option sets the
+ * document title of the generated HTML document.
+ * Defaults to 'Log4php Log Messages'.
+ * @var string
+ */
+ protected $title = "Log4php Log Messages";
+
+ /**
+ * The <b>LocationInfo</b> option takes a boolean value. By
+ * default, it is set to false which means there will be no location
+ * information output by this layout. If the the option is set to
+ * true, then the file name and line number of the statement
+ * at the origin of the log statement will be output.
+ *
+ * <p>If you are embedding this layout within a {@link LoggerAppenderMail}
+ * or a {@link LoggerAppenderMailEvent} then make sure to set the
+ * <b>LocationInfo</b> option of that appender as well.
+ */
+ public function setLocationInfo($flag) {
+ $this->setBoolean('locationInfo', $flag);
+ }
+
+ /**
+ * Returns the current value of the <b>LocationInfo</b> option.
+ */
+ public function getLocationInfo() {
+ return $this->locationInfo;
+ }
+
+ /**
+ * The <b>Title</b> option takes a String value. This option sets the
+ * document title of the generated HTML document.
+ * Defaults to 'Log4php Log Messages'.
+ */
+ public function setTitle($title) {
+ $this->setString('title', $title);
+ }
+
+ /**
+ * @return string Returns the current value of the <b>Title</b> option.
+ */
+ public function getTitle() {
+ return $this->title;
+ }
+
+ /**
+ * @return string Returns the content type output by this layout, i.e "text/html".
+ */
+ public function getContentType() {
+ return "text/html";
+ }
+
+ /**
+ * @param LoggerLoggingEvent $event
+ * @return string
+ */
+ public function format(LoggerLoggingEvent $event) {
+ $sbuf = PHP_EOL . "<tr>" . PHP_EOL;
+
+ $sbuf .= "<td>";
+ $sbuf .= round(1000 * $event->getRelativeTime());
+ $sbuf .= "</td>" . PHP_EOL;
+
+ $sbuf .= "<td title=\"" . $event->getThreadName() . " thread\">";
+ $sbuf .= $event->getThreadName();
+ $sbuf .= "</td>" . PHP_EOL;
+
+ $sbuf .= "<td title=\"Level\">";
+
+ $level = $event->getLevel();
+
+ if ($level->equals(LoggerLevel::getLevelDebug())) {
+ $sbuf .= "<font color=\"#339933\">$level</font>";
+ } else if ($level->equals(LoggerLevel::getLevelWarn())) {
+ $sbuf .= "<font color=\"#993300\"><strong>$level</strong></font>";
+ } else {
+ $sbuf .= $level;
+ }
+ $sbuf .= "</td>" . PHP_EOL;
+
+ $sbuf .= "<td title=\"" . htmlentities($event->getLoggerName(), ENT_QUOTES) . " category\">";
+ $sbuf .= htmlentities($event->getLoggerName(), ENT_QUOTES);
+ $sbuf .= "</td>" . PHP_EOL;
+
+ if ($this->locationInfo) {
+ $locInfo = $event->getLocationInformation();
+ $sbuf .= "<td>";
+ $sbuf .= htmlentities($locInfo->getFileName(), ENT_QUOTES) . ':' . $locInfo->getLineNumber();
+ $sbuf .= "</td>" . PHP_EOL;
+ }
+
+ $sbuf .= "<td title=\"Message\">";
+ $sbuf .= htmlentities($event->getRenderedMessage(), ENT_QUOTES);
+ $sbuf .= "</td>" . PHP_EOL;
+
+ $sbuf .= "</tr>" . PHP_EOL;
+
+ if ($event->getNDC() != null) {
+ $sbuf .= "<tr><td bgcolor=\"#EEEEEE\" style=\"font-size : xx-small;\" colspan=\"6\" title=\"Nested Diagnostic Context\">";
+ $sbuf .= "NDC: " . htmlentities($event->getNDC(), ENT_QUOTES);
+ $sbuf .= "</td></tr>" . PHP_EOL;
+ }
+ return $sbuf;
+ }
+
+ /**
+ * @return string Returns appropriate HTML headers.
+ */
+ public function getHeader() {
+ $sbuf = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">" . PHP_EOL;
+ $sbuf .= "<html>" . PHP_EOL;
+ $sbuf .= "<head>" . PHP_EOL;
+ $sbuf .= "<title>" . $this->title . "</title>" . PHP_EOL;
+ $sbuf .= "<style type=\"text/css\">" . PHP_EOL;
+ $sbuf .= "<!--" . PHP_EOL;
+ $sbuf .= "body, table {font-family: arial,sans-serif; font-size: x-small;}" . PHP_EOL;
+ $sbuf .= "th {background: #336699; color: #FFFFFF; text-align: left;}" . PHP_EOL;
+ $sbuf .= "-->" . PHP_EOL;
+ $sbuf .= "</style>" . PHP_EOL;
+ $sbuf .= "</head>" . PHP_EOL;
+ $sbuf .= "<body bgcolor=\"#FFFFFF\" topmargin=\"6\" leftmargin=\"6\">" . PHP_EOL;
+ $sbuf .= "<hr size=\"1\" noshade>" . PHP_EOL;
+ $sbuf .= "Log session start time " . strftime('%c', time()) . "<br>" . PHP_EOL;
+ $sbuf .= "<br>" . PHP_EOL;
+ $sbuf .= "<table cellspacing=\"0\" cellpadding=\"4\" border=\"1\" bordercolor=\"#224466\" width=\"100%\">" . PHP_EOL;
+ $sbuf .= "<tr>" . PHP_EOL;
+ $sbuf .= "<th>Time</th>" . PHP_EOL;
+ $sbuf .= "<th>Thread</th>" . PHP_EOL;
+ $sbuf .= "<th>Level</th>" . PHP_EOL;
+ $sbuf .= "<th>Category</th>" . PHP_EOL;
+ if ($this->locationInfo) {
+ $sbuf .= "<th>File:Line</th>" . PHP_EOL;
+ }
+ $sbuf .= "<th>Message</th>" . PHP_EOL;
+ $sbuf .= "</tr>" . PHP_EOL;
+
+ return $sbuf;
+ }
+
+ /**
+ * @return string Returns the appropriate HTML footers.
+ */
+ public function getFooter() {
+ $sbuf = "</table>" . PHP_EOL;
+ $sbuf .= "<br>" . PHP_EOL;
+ $sbuf .= "</body></html>";
+
+ return $sbuf;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/layouts/LoggerLayoutPattern.php
@@ -0,0 +1,171 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * A flexible layout configurable with a pattern string.
+ *
+ * Configurable parameters:
+ *
+ * * converionPattern - A string which controls the formatting of logging
+ * events. See docs for full specification.
+ *
+ * @package log4php
+ * @subpackage layouts
+ * @version $Revision: 1395470 $
+ */
+class LoggerLayoutPattern extends LoggerLayout {
+
+ /** Default conversion pattern */
+ const DEFAULT_CONVERSION_PATTERN = '%date %-5level %logger %message%newline';
+
+ /** Default conversion TTCC Pattern */
+ const TTCC_CONVERSION_PATTERN = '%d [%t] %p %c %x - %m%n';
+
+ /** The conversion pattern. */
+ protected $pattern = self::DEFAULT_CONVERSION_PATTERN;
+
+ /** Maps conversion keywords to the relevant converter (default implementation). */
+ protected static $defaultConverterMap = array(
+ 'c' => 'LoggerPatternConverterLogger',
+ 'lo' => 'LoggerPatternConverterLogger',
+ 'logger' => 'LoggerPatternConverterLogger',
+
+ 'C' => 'LoggerPatternConverterClass',
+ 'class' => 'LoggerPatternConverterClass',
+
+ 'cookie' => 'LoggerPatternConverterCookie',
+
+ 'd' => 'LoggerPatternConverterDate',
+ 'date' => 'LoggerPatternConverterDate',
+
+ 'e' => 'LoggerPatternConverterEnvironment',
+ 'env' => 'LoggerPatternConverterEnvironment',
+
+ 'ex' => 'LoggerPatternConverterThrowable',
+ 'exception' => 'LoggerPatternConverterThrowable',
+ 'throwable' => 'LoggerPatternConverterThrowable',
+
+ 'F' => 'LoggerPatternConverterFile',
+ 'file' => 'LoggerPatternConverterFile',
+
+ 'l' => 'LoggerPatternConverterLocation',
+ 'location' => 'LoggerPatternConverterLocation',
+
+ 'L' => 'LoggerPatternConverterLine',
+ 'line' => 'LoggerPatternConverterLine',
+
+ 'm' => 'LoggerPatternConverterMessage',
+ 'msg' => 'LoggerPatternConverterMessage',
+ 'message' => 'LoggerPatternConverterMessage',
+
+ 'M' => 'LoggerPatternConverterMethod',
+ 'method' => 'LoggerPatternConverterMethod',
+
+ 'n' => 'LoggerPatternConverterNewLine',
+ 'newline' => 'LoggerPatternConverterNewLine',
+
+ 'p' => 'LoggerPatternConverterLevel',
+ 'le' => 'LoggerPatternConverterLevel',
+ 'level' => 'LoggerPatternConverterLevel',
+
+ 'r' => 'LoggerPatternConverterRelative',
+ 'relative' => 'LoggerPatternConverterRelative',
+
+ 'req' => 'LoggerPatternConverterRequest',
+ 'request' => 'LoggerPatternConverterRequest',
+
+ 's' => 'LoggerPatternConverterServer',
+ 'server' => 'LoggerPatternConverterServer',
+
+ 'ses' => 'LoggerPatternConverterSession',
+ 'session' => 'LoggerPatternConverterSession',
+
+ 'sid' => 'LoggerPatternConverterSessionID',
+ 'sessionid' => 'LoggerPatternConverterSessionID',
+
+ 't' => 'LoggerPatternConverterProcess',
+ 'pid' => 'LoggerPatternConverterProcess',
+ 'process' => 'LoggerPatternConverterProcess',
+
+ 'x' => 'LoggerPatternConverterNDC',
+ 'ndc' => 'LoggerPatternConverterNDC',
+
+ 'X' => 'LoggerPatternConverterMDC',
+ 'mdc' => 'LoggerPatternConverterMDC',
+ );
+
+ /** Maps conversion keywords to the relevant converter. */
+ protected $converterMap = array();
+
+ /**
+ * Head of a chain of Converters.
+ * @var LoggerPatternConverter
+ */
+ private $head;
+
+ /** Returns the default converter map. */
+ public static function getDefaultConverterMap() {
+ return self::$defaultConverterMap;
+ }
+
+ /** Constructor. Initializes the converter map. */
+ public function __construct() {
+ $this->converterMap = self::$defaultConverterMap;
+ }
+
+ /**
+ * Sets the conversionPattern option. This is the string which
+ * controls formatting and consists of a mix of literal content and
+ * conversion specifiers.
+ * @param array $conversionPattern
+ */
+ public function setConversionPattern($conversionPattern) {
+ $this->pattern = $conversionPattern;
+ }
+
+ /**
+ * Processes the conversion pattern and creates a corresponding chain of
+ * pattern converters which will be used to format logging events.
+ */
+ public function activateOptions() {
+ if (!isset($this->pattern)) {
+ throw new LoggerException("Mandatory parameter 'conversionPattern' is not set.");
+ }
+
+ $parser = new LoggerPatternParser($this->pattern, $this->converterMap);
+ $this->head = $parser->parse();
+ }
+
+ /**
+ * Produces a formatted string as specified by the conversion pattern.
+ *
+ * @param LoggerLoggingEvent $event
+ * @return string
+ */
+ public function format(LoggerLoggingEvent $event) {
+ $sbuf = '';
+ $converter = $this->head;
+ while ($converter !== null) {
+ $converter->format($sbuf, $event);
+ $converter = $converter->next;
+ }
+ return $sbuf;
+ }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/library/log4php/layouts/LoggerLayoutSerialized.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Layout which formats the events using PHP's serialize() function.
+ *
+ * Available options:
+ * - locationInfo - If set to true, the event's location information will also
+ * be serialized (slow, defaults to false).
+ *
+ * @version $Revision: 1334369 $
+ * @package log4php
+ * @subpackage layouts
+ * @since 2.2
+ */
+class LoggerLayoutSerialized extends LoggerLayout {
+
+ /** Whether to include the event's location information (slow). */
+ protected $locationInfo = false;
+
+ /** Sets the location information flag. */
+ public function setLocationInfo($value) {
+ $this->setBoolean('locationInfo', $value);
+ }
+
+ /** Returns the location information flag. */
+ public function getLocationInfo() {
+ return $this->locationInfo;
+ }
+
+ public function format(LoggerLoggingEvent $event) {
+ // If required, initialize the location data
+ if ($this->locationInfo) {
+ $event->getLocationInformation();
+ }
+ return serialize($event) . PHP_EOL;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/layouts/LoggerLayoutSimple.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * A simple layout.
+ *
+ * Returns the log statement in a format consisting of the
+ * <b>level</b>, followed by " - " and then the <b>message</b>.
+ *
+ * For example the following php and properties files
+ *
+ * {@example ../../examples/php/layout_simple.php 19}<br>
+ *
+ * {@example ../../examples/resources/layout_simple.properties 18}<br>
+ *
+ * would result in:
+ *
+ * <samp>INFO - Hello World!</samp>
+ *
+ * @version $Revision: 1213283 $
+ * @package log4php
+ * @subpackage layouts
+ */
+class LoggerLayoutSimple extends LoggerLayout {
+ /**
+ * Returns the log statement in a format consisting of the
+ * <b>level</b>, followed by " - " and then the
+ * <b>message</b>. For example,
+ * <samp> INFO - "A message" </samp>
+ *
+ * @param LoggerLoggingEvent $event
+ * @return string
+ */
+ public function format(LoggerLoggingEvent $event) {
+ $level = $event->getLevel();
+ $message = $event->getRenderedMessage();
+ return "$level - $message" . PHP_EOL;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/layouts/LoggerLayoutTTCC.php
@@ -0,0 +1,201 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * TTCC layout format consists of <b>t</b>ime, <b>t</b>hread, <b>c</b>ategory and nested
+ * diagnostic <b>c</b>ontext information, hence the name.
+ *
+ * <p>Each of the four fields can be individually enabled or
+ * disabled. The time format depends on the <b>DateFormat</b> used.</p>
+ *
+ * <p>If no dateFormat is specified it defaults to '%c'.
+ * See php {@link PHP_MANUAL#date} function for details.</p>
+ *
+ * Configurable parameters for this layout are:
+ * - {@link $threadPrinting} (true|false) enable/disable pid reporting.
+ * - {@link $categoryPrefixing} (true|false) enable/disable logger category reporting.
+ * - {@link $contextPrinting} (true|false) enable/disable NDC reporting.
+ * - {@link $microSecondsPrinting} (true|false) enable/disable micro seconds reporting in timestamp.
+ * - {@link $dateFormat} (string) set date format. See php {@link PHP_MANUAL#date} function for details.
+ *
+ * An example how to use this layout:
+ *
+ * {@example ../../examples/php/layout_ttcc.php 19}<br>
+ *
+ * {@example ../../examples/resources/layout_ttcc.properties 18}<br>
+ *
+ * The above would print:<br>
+ * <samp>02:28 [13714] INFO root - Hello World!</samp>
+ *
+ * @version $Revision: 1302503 $
+ * @package log4php
+ * @subpackage layouts
+ *
+ * @deprecated LoggerLayout TTCC is deprecated and will be removed in a future release. Please use
+ * LoggerLayoutPattern instead.
+ */
+class LoggerLayoutTTCC extends LoggerLayout {
+
+ // Internal representation of options
+ protected $threadPrinting = true;
+ protected $categoryPrefixing = true;
+ protected $contextPrinting = true;
+ protected $microSecondsPrinting = true;
+
+ /**
+ * @var string date format. See {@link PHP_MANUAL#strftime} for details
+ */
+ protected $dateFormat = '%c';
+
+ /**
+ * Constructor
+ *
+ * @param string date format
+ * @see dateFormat
+ */
+ public function __construct($dateFormat = '') {
+ $this->warn("LoggerLayout TTCC is deprecated and will be removed in a future release. Please use LoggerLayoutPattern instead.");
+ if (!empty($dateFormat)) {
+ $this->dateFormat = $dateFormat;
+ }
+ return;
+ }
+
+ /**
+ * The <b>ThreadPrinting</b> option specifies whether the name of the
+ * current thread is part of log output or not. This is true by default.
+ */
+ public function setThreadPrinting($threadPrinting) {
+ $this->setBoolean('threadPrinting', $threadPrinting);
+ }
+
+ /**
+ * @return boolean Returns value of the <b>ThreadPrinting</b> option.
+ */
+ public function getThreadPrinting() {
+ return $this->threadPrinting;
+ }
+
+ /**
+ * The <b>CategoryPrefixing</b> option specifies whether {@link Category}
+ * name is part of log output or not. This is true by default.
+ */
+ public function setCategoryPrefixing($categoryPrefixing) {
+ $this->setBoolean('categoryPrefixing', $categoryPrefixing);
+ }
+
+ /**
+ * @return boolean Returns value of the <b>CategoryPrefixing</b> option.
+ */
+ public function getCategoryPrefixing() {
+ return $this->categoryPrefixing;
+ }
+
+ /**
+ * The <b>ContextPrinting</b> option specifies log output will include
+ * the nested context information belonging to the current thread.
+ * This is true by default.
+ */
+ public function setContextPrinting($contextPrinting) {
+ $this->setBoolean('contextPrinting', $contextPrinting);
+ }
+
+ /**
+ * @return boolean Returns value of the <b>ContextPrinting</b> option.
+ */
+ public function getContextPrinting() {
+ return $this->contextPrinting;
+ }
+
+ /**
+ * The <b>MicroSecondsPrinting</b> option specifies if microseconds infos
+ * should be printed at the end of timestamp.
+ * This is true by default.
+ */
+ public function setMicroSecondsPrinting($microSecondsPrinting) {
+ $this->setBoolean('microSecondsPrinting', $microSecondsPrinting);
+ }
+
+ /**
+ * @return boolean Returns value of the <b>MicroSecondsPrinting</b> option.
+ */
+ public function getMicroSecondsPrinting() {
+ return $this->microSecondsPrinting;
+ }
+
+
+ public function setDateFormat($dateFormat) {
+ $this->setString('dateFormat', $dateFormat);
+ }
+
+ /**
+ * @return string
+ */
+ public function getDateFormat() {
+ return $this->dateFormat;
+ }
+
+ /**
+ * In addition to the level of the statement and message, the
+ * returned string includes time, thread, category.
+ * <p>Time, thread, category are printed depending on options.
+ *
+ * @param LoggerLoggingEvent $event
+ * @return string
+ */
+ public function format(LoggerLoggingEvent $event) {
+ $timeStamp = (float)$event->getTimeStamp();
+ $format = strftime($this->dateFormat, (int)$timeStamp);
+
+ if ($this->microSecondsPrinting) {
+ $usecs = floor(($timeStamp - (int)$timeStamp) * 1000);
+ $format .= sprintf(',%03d', $usecs);
+ }
+
+ $format .= ' ';
+
+ if ($this->threadPrinting) {
+ $format .= '[' . getmypid() . '] ';
+ }
+
+ $level = $event->getLevel();
+ $format .= $level . ' ';
+
+ if ($this->categoryPrefixing) {
+ $format .= $event->getLoggerName() . ' ';
+ }
+
+ if ($this->contextPrinting) {
+ $ndc = $event->getNDC();
+ if ($ndc != null) {
+ $format .= $ndc . ' ';
+ }
+ }
+
+ $format .= '- ' . $event->getRenderedMessage();
+ $format .= PHP_EOL;
+
+ return $format;
+ }
+
+ public function ignoresThrowable() {
+ return true;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/layouts/LoggerLayoutXml.php
@@ -0,0 +1,210 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * The output of the LoggerXmlLayout consists of a series of log4php:event elements.
+ *
+ * Configurable parameters:
+ * - {@link $locationInfo} - If set to true then the file name and line number
+ * of the origin of the log statement will be included in output.
+ * - {@link $log4jNamespace} - If set to true then log4j namespace will be used
+ * instead of log4php namespace. This can be usefull when using log viewers
+ * which can only parse the log4j namespace such as Apache Chainsaw.
+ *
+ * <p>It does not output a complete well-formed XML file.
+ * The output is designed to be included as an external entity in a separate file to form
+ * a correct XML file.</p>
+ *
+ * Example:
+ *
+ * {@example ../../examples/php/layout_xml.php 19}<br>
+ *
+ * {@example ../../examples/resources/layout_xml.properties 18}<br>
+ *
+ * The above would print:
+ *
+ * <pre>
+ * <log4php:eventSet xmlns:log4php="http://logging.apache.org/log4php/" version="0.3" includesLocationInfo="true">
+ * <log4php:event logger="root" level="INFO" thread="13802" timestamp="1252456226491">
+ * <log4php:message><![CDATA[Hello World!]]></log4php:message>
+ * <log4php:locationInfo class="main" file="examples/php/layout_xml.php" line="6" method="main" />
+ * </log4php:event>
+ * </log4php:eventSet>
+ * </pre>
+ *
+ * @version $Revision: 1213283 $
+ * @package log4php
+ * @subpackage layouts
+ */
+class LoggerLayoutXml extends LoggerLayout {
+ const LOG4J_NS_PREFIX = 'log4j';
+ const LOG4J_NS = 'http://jakarta.apache.org/log4j/';
+
+ const LOG4PHP_NS_PREFIX = 'log4php';
+ const LOG4PHP_NS = 'http://logging.apache.org/log4php/';
+
+ const CDATA_START = '<![CDATA[';
+ const CDATA_END = ']]>';
+ const CDATA_PSEUDO_END = ']]>';
+ const CDATA_EMBEDDED_END = ']]>]]><![CDATA[';
+
+ /**
+ * If set to true then the file name and line number of the origin of the
+ * log statement will be output.
+ * @var boolean
+ */
+ protected $locationInfo = true;
+
+ /**
+ * If set to true, log4j namespace will be used instead of the log4php
+ * namespace.
+ * @var boolean
+ */
+ protected $log4jNamespace = false;
+
+ /** The namespace in use. */
+ protected $namespace = self::LOG4PHP_NS;
+
+ /** The namespace prefix in use */
+ protected $namespacePrefix = self::LOG4PHP_NS_PREFIX;
+
+ public function activateOptions() {
+ if ($this->getLog4jNamespace()) {
+ $this->namespace = self::LOG4J_NS;
+ $this->namespacePrefix = self::LOG4J_NS_PREFIX;
+ } else {
+ $this->namespace = self::LOG4PHP_NS;
+ $this->namespacePrefix = self::LOG4PHP_NS_PREFIX;
+ }
+ }
+
+ /**
+ * @return string
+ */
+ public function getHeader() {
+ return "<{$this->namespacePrefix}:eventSet " .
+ "xmlns:{$this->namespacePrefix}=\"{$this->namespace}\" " .
+ "version=\"0.3\" " .
+ "includesLocationInfo=\"" . ($this->getLocationInfo() ? "true" : "false") . "\"" .
+ ">" . PHP_EOL;
+ }
+
+ /**
+ * Formats a {@link LoggerLoggingEvent} in conformance with the log4php.dtd.
+ *
+ * @param LoggerLoggingEvent $event
+ * @return string
+ */
+ public function format(LoggerLoggingEvent $event) {
+ $ns = $this->namespacePrefix;
+
+ $loggerName = $event->getLoggerName();
+ $timeStamp = number_format((float)($event->getTimeStamp() * 1000), 0, '', '');
+ $thread = $event->getThreadName();
+ $level = $event->getLevel()->toString();
+
+ $buf = "<$ns:event logger=\"{$loggerName}\" level=\"{$level}\" thread=\"{$thread}\" timestamp=\"{$timeStamp}\">" . PHP_EOL;
+ $buf .= "<$ns:message>";
+ $buf .= $this->encodeCDATA($event->getRenderedMessage());
+ $buf .= "</$ns:message>" . PHP_EOL;
+
+ $ndc = $event->getNDC();
+ if (!empty($ndc)) {
+ $buf .= "<$ns:NDC><![CDATA[";
+ $buf .= $this->encodeCDATA($ndc);
+ $buf .= "]]></$ns:NDC>" . PHP_EOL;
+ }
+
+ $mdcMap = $event->getMDCMap();
+ if (!empty($mdcMap)) {
+ $buf .= "<$ns:properties>" . PHP_EOL;
+ foreach ($mdcMap as $name => $value) {
+ $buf .= "<$ns:data name=\"$name\" value=\"$value\" />" . PHP_EOL;
+ }
+ $buf .= "</$ns:properties>" . PHP_EOL;
+ }
+
+ if ($this->getLocationInfo()) {
+ $locationInfo = $event->getLocationInformation();
+ $buf .= "<$ns:locationInfo " .
+ "class=\"" . $locationInfo->getClassName() . "\" " .
+ "file=\"" . htmlentities($locationInfo->getFileName(), ENT_QUOTES) . "\" " .
+ "line=\"" . $locationInfo->getLineNumber() . "\" " .
+ "method=\"" . $locationInfo->getMethodName() . "\" ";
+ $buf .= "/>" . PHP_EOL;
+ }
+
+ $buf .= "</$ns:event>" . PHP_EOL;
+
+ return $buf;
+ }
+
+ /**
+ * @return string
+ */
+ public function getFooter() {
+ return "</{$this->namespacePrefix}:eventSet>" . PHP_EOL;
+ }
+
+
+ /**
+ * Whether or not file name and line number will be included in the output.
+ * @return boolean
+ */
+ public function getLocationInfo() {
+ return $this->locationInfo;
+ }
+
+ /**
+ * The {@link $locationInfo} option takes a boolean value. By default,
+ * it is set to false which means there will be no location
+ * information output by this layout. If the the option is set to
+ * true, then the file name and line number of the statement at the
+ * origin of the log statement will be output.
+ */
+ public function setLocationInfo($flag) {
+ $this->setBoolean('locationInfo', $flag);
+ }
+
+ /**
+ * @return boolean
+ */
+ public function getLog4jNamespace() {
+ return $this->log4jNamespace;
+ }
+
+ /**
+ * @param boolean
+ */
+ public function setLog4jNamespace($flag) {
+ $this->setBoolean('log4jNamespace', $flag);
+ }
+
+ /**
+ * Encases a string in CDATA tags, and escapes any existing CDATA end
+ * tags already present in the string.
+ * @param string $string
+ */
+ private function encodeCDATA($string) {
+ $string = str_replace(self::CDATA_END, self::CDATA_EMBEDDED_END, $string);
+ return self::CDATA_START . $string . self::CDATA_END;
+ }
+}
+
new file mode 100644
--- /dev/null
+++ b/library/log4php/pattern/LoggerPatternConverter.php
@@ -0,0 +1,128 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * LoggerPatternConverter is an abstract class that provides the formatting
+ * functionality that derived classes need.
+ *
+ * <p>Conversion specifiers in a conversion patterns are parsed to
+ * individual PatternConverters. Each of which is responsible for
+ * converting a logging event in a converter specific manner.</p>
+ *
+ * @version $Revision: 1326626 $
+ * @package log4php
+ * @subpackage helpers
+ * @since 0.3
+ */
+abstract class LoggerPatternConverter {
+
+ /**
+ * Next converter in the converter chain.
+ * @var LoggerPatternConverter
+ */
+ public $next = null;
+
+ /**
+ * Formatting information, parsed from pattern modifiers.
+ * @var LoggerFormattingInfo
+ */
+ protected $formattingInfo;
+
+ /**
+ * Converter-specific formatting options.
+ * @var array
+ */
+ protected $option;
+
+ /**
+ * Constructor
+ * @param LoggerFormattingInfo $formattingInfo
+ * @param array $option
+ */
+ public function __construct(LoggerFormattingInfo $formattingInfo = null, $option = null) {
+ $this->formattingInfo = $formattingInfo;
+ $this->option = $option;
+ $this->activateOptions();
+ }
+
+ /**
+ * Called in constructor. Converters which need to process the options
+ * can override this method.
+ */
+ public function activateOptions() {
+ }
+
+ /**
+ * Converts the logging event to the desired format. Derived pattern
+ * converters must implement this method.
+ *
+ * @param LoggerLoggingEvent $event
+ */
+ abstract public function convert(LoggerLoggingEvent $event);
+
+ /**
+ * Converts the event and formats it according to setting in the
+ * Formatting information object.
+ *
+ * @param string &$sbuf string buffer to write to
+ * @param LoggerLoggingEvent $event Event to be formatted.
+ */
+ public function format(&$sbuf, $event) {
+ $string = $this->convert($event);
+
+ if (!isset($this->formattingInfo)) {
+ $sbuf .= $string;
+ return;
+ }
+
+ $fi = $this->formattingInfo;
+
+ // Empty string
+ if ($string === '' || is_null($string)) {
+ if ($fi->min > 0) {
+ $sbuf .= str_repeat(' ', $fi->min);
+ }
+ return;
+ }
+
+ $len = strlen($string);
+
+ // Trim the string if needed
+ if ($len > $fi->max) {
+ if ($fi->trimLeft) {
+ $sbuf .= substr($string, $len - $fi->max, $fi->max);
+ } else {
+ $sbuf .= substr($string, 0, $fi->max);
+ }
+ } // Add padding if needed
+ else if ($len < $fi->min) {
+ if ($fi->padLeft) {
+ $sbuf .= str_repeat(' ', $fi->min - $len);
+ $sbuf .= $string;
+ } else {
+ $sbuf .= $string;
+ $sbuf .= str_repeat(' ', $fi->min - $len);
+ }
+ } // No action needed
+ else {
+ $sbuf .= $string;
+ }
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/pattern/LoggerPatternConverterClass.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Returns the fully qualified class name of the class from which the logging
+ * request was issued.
+ *
+ * @package log4php
+ * @subpackage pattern
+ * @version $Revision: 1326626 $
+ * @since 2.3
+ */
+class LoggerPatternConverterClass extends LoggerPatternConverter {
+
+ /** Length to which to shorten the class name. */
+ private $length;
+
+ /** Holds processed class names. */
+ private $cache = array();
+
+ public function activateOptions() {
+ // Parse the option (desired output length)
+ if (isset($this->option) && is_numeric($this->option) && $this->option >= 0) {
+ $this->length = (integer)$this->option;
+ }
+ }
+
+ public function convert(LoggerLoggingEvent $event) {
+ $name = $event->getLocationInformation()->getClassName();
+
+ if (!isset($this->cache[$name])) {
+
+ // If length is set return shortened class name
+ if (isset($this->length)) {
+ $this->cache[$name] = LoggerUtils::shortenClassName($name, $this->length);
+ } // If no length is specified return the full class name
+ else {
+ $this->cache[$name] = $name;
+ }
+ }
+
+ return $this->cache[$name];
+ }
+}
+
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/library/log4php/pattern/LoggerPatternConverterCookie.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Returns a value from the $_COOKIE superglobal array corresponding to the
+ * given key. If no key is given, return all values.
+ *
+ * Options:
+ * [0] $_COOKIE key value
+ *
+ * @package log4php
+ * @subpackage pattern
+ * @version $Revision: 1326626 $
+ * @since 2.3
+ */
+class LoggerPatternConverterCookie extends LoggerPatternConverterSuperglobal {
+ protected $name = '_COOKIE';
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/library/log4php/pattern/LoggerPatternConverterDate.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Returns the date/time of the logging request.
+ *
+ * Option: the datetime format, as used by the date() function. If
+ * the option is not given, the default format 'c' will be used.
+ *
+ * There are several "special" values which can be given for this option:
+ * 'ISO8601', 'ABSOLUTE' and 'DATE'.
+ *
+ * @package log4php
+ * @subpackage pattern
+ * @version $Revision: 1326626 $
+ * @since 2.3
+ */
+class LoggerPatternConverterDate extends LoggerPatternConverter {
+
+ const DATE_FORMAT_ISO8601 = 'c';
+
+ const DATE_FORMAT_ABSOLUTE = 'H:i:s';
+
+ const DATE_FORMAT_DATE = 'd M Y H:i:s.u';
+
+ private $format = self::DATE_FORMAT_ISO8601;
+
+ private $specials = array(
+ 'ISO8601' => self::DATE_FORMAT_ISO8601,
+ 'ABSOLUTE' => self::DATE_FORMAT_ABSOLUTE,
+ 'DATE' => self::DATE_FORMAT_DATE,
+ );
+
+ private $useLocalDate = false;
+
+ public function activateOptions() {
+
+ // Parse the option (date format)
+ if (!empty($this->option)) {
+ if (isset($this->specials[$this->option])) {
+ $this->format = $this->specials[$this->option];
+ } else {
+ $this->format = $this->option;
+ }
+ }
+
+ // Check whether the pattern contains milliseconds (u)
+ if (preg_match('/(?<!\\\\)u/', $this->format)) {
+ $this->useLocalDate = true;
+ }
+ }
+
+ public function convert(LoggerLoggingEvent $event) {
+ if ($this->useLocalDate) {
+ return $this->date($this->format, $event->getTimeStamp());
+ }
+ return date($this->format, $event->getTimeStamp());
+ }
+
+ /**
+ * Currently, PHP date() function always returns zeros for milliseconds (u)
+ * on Windows. This is a replacement function for date() which correctly
+ * displays milliseconds on all platforms.
+ *
+ * It is slower than PHP date() so it should only be used if necessary.
+ */
+ private function date($format, $utimestamp) {
+ $timestamp = floor($utimestamp);
+ $ms = floor(($utimestamp - $timestamp) * 1000);
+ $ms = str_pad($ms, 3, '0', STR_PAD_LEFT);
+
+ return date(preg_replace('`(?<!\\\\)u`', $ms, $format), $timestamp);
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/pattern/LoggerPatternConverterEnvironment.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Returns a value from the $_ENV superglobal array corresponding to the
+ * given key.
+ *
+ * Options:
+ * [0] $_ENV key value
+ *
+ * @package log4php
+ * @subpackage pattern
+ * @version $Revision: 1326626 $
+ * @since 2.3
+ */
+class LoggerPatternConverterEnvironment extends LoggerPatternConverterSuperglobal {
+ protected $name = '_ENV';
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/pattern/LoggerPatternConverterFile.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Returns the name of the file from which the logging request was issued.
+ *
+ * @package log4php
+ * @subpackage pattern
+ * @version $Revision: 1326626 $
+ * @since 2.3
+ */
+class LoggerPatternConverterFile extends LoggerPatternConverter {
+
+ public function convert(LoggerLoggingEvent $event) {
+ return $event->getLocationInformation()->getFileName();
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/pattern/LoggerPatternConverterLevel.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Returns the event's level.
+ *
+ * @package log4php
+ * @subpackage pattern
+ * @version $Revision: 1326626 $
+ * @since 2.3
+ */
+class LoggerPatternConverterLevel extends LoggerPatternConverter {
+
+ public function convert(LoggerLoggingEvent $event) {
+ return $event->getLevel()->toString();
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/pattern/LoggerPatternConverterLine.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Returns the line number within the file from which the logging request was
+ * issued.
+ *
+ * @package log4php
+ * @subpackage pattern
+ * @version $Revision: 1326626 $
+ * @since 2.3
+ */
+class LoggerPatternConverterLine extends LoggerPatternConverter {
+
+ public function convert(LoggerLoggingEvent $event) {
+ return $event->getLocationInformation()->getLineNumber();
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/pattern/LoggerPatternConverterLiteral.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Returns the literal value passed in the constructor, without modifications.
+ *
+ * @package log4php
+ * @subpackage pattern
+ * @version $Revision: 1326626 $
+ * @since 2.3
+ */
+class LoggerPatternConverterLiteral extends LoggerPatternConverter {
+
+ private $literalValue;
+
+ public function __construct($literalValue) {
+ $this->literalValue = $literalValue;
+ }
+
+ public function convert(LoggerLoggingEvent $event) {
+ return $this->literalValue;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/pattern/LoggerPatternConverterLocation.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Returns the line number within the file from which the logging request was
+ * issued.
+ *
+ * @package log4php
+ * @subpackage pattern
+ * @version $Revision: 1326626 $
+ * @since 2.3
+ */
+class LoggerPatternConverterLocation extends LoggerPatternConverter {
+
+ public function convert(LoggerLoggingEvent $event) {
+ return
+ $event->getLocationInformation()->getClassName() . '.' .
+ $event->getLocationInformation()->getMethodName() . '(' .
+ $event->getLocationInformation()->getFileName() . ':' .
+ $event->getLocationInformation()->getLineNumber() . ')';
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/pattern/LoggerPatternConverterLogger.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Returns the name of the logger which created the logging request.
+ *
+ * Takes one option, which is an integer. If the option is given, the logger
+ * name will be shortened to the given length, if possible.
+ *
+ * @package log4php
+ * @subpackage pattern
+ * @version $Revision: 1326626 $
+ * @since 2.3
+ */
+class LoggerPatternConverterLogger extends LoggerPatternConverter {
+
+ /** Length to which to shorten the name. */
+ private $length;
+
+ /** Holds processed logger names. */
+ private $cache = array();
+
+ public function activateOptions() {
+ // Parse the option (desired output length)
+ if (isset($this->option) && is_numeric($this->option) && $this->option >= 0) {
+ $this->length = (integer)$this->option;
+ }
+ }
+
+ public function convert(LoggerLoggingEvent $event) {
+ $name = $event->getLoggerName();
+
+ if (!isset($this->cache[$name])) {
+
+ // If length is set return shortened logger name
+ if (isset($this->length)) {
+ $this->cache[$name] = LoggerUtils::shortenClassName($name, $this->length);
+ } // If no length is specified return full logger name
+ else {
+ $this->cache[$name] = $name;
+ }
+ }
+
+ return $this->cache[$name];
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/pattern/LoggerPatternConverterMDC.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Returns the Mapped Diagnostic Context value corresponding to the given key.
+ *
+ * Options:
+ * [0] the MDC key
+ *
+ * @package log4php
+ * @subpackage pattern
+ * @version $Revision: 1326626 $
+ * @since 2.3
+ */
+class LoggerPatternConverterMDC extends LoggerPatternConverter {
+
+ private $key;
+
+ public function activateOptions() {
+ if (isset($this->option) && $this->option !== '') {
+ $this->key = $this->option;
+ }
+ }
+
+ public function convert(LoggerLoggingEvent $event) {
+ if (isset($this->key)) {
+ return $event->getMDC($this->key);
+ } else {
+ $buff = array();
+ $map = $event->getMDCMap();
+ foreach ($map as $key => $value) {
+ $buff [] = "$key=$value";
+ }
+ return implode(', ', $buff);
+ }
+ }
+}
+
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/library/log4php/pattern/LoggerPatternConverterMessage.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Returns the logged message.
+ *
+ * @package log4php
+ * @subpackage pattern
+ * @version $Revision: 1326626 $
+ * @since 2.3
+ */
+class LoggerPatternConverterMessage extends LoggerPatternConverter {
+
+ public function convert(LoggerLoggingEvent $event) {
+ return $event->getRenderedMessage();
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/pattern/LoggerPatternConverterMethod.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Returns the name of the function or method from which the logging request
+ * was issued.
+ *
+ * @package log4php
+ * @subpackage pattern
+ * @version $Revision: 1326626 $
+ * @since 2.3
+ */
+class LoggerPatternConverterMethod extends LoggerPatternConverter {
+
+ public function convert(LoggerLoggingEvent $event) {
+ return $event->getLocationInformation()->getMethodName();
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/pattern/LoggerPatternConverterNDC.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Returns the full Nested Diagnostic Context.
+ *
+ * @package log4php
+ * @subpackage pattern
+ * @version $Revision: 1326626 $
+ * @since 2.3
+ */
+class LoggerPatternConverterNDC extends LoggerPatternConverter {
+
+ public function convert(LoggerLoggingEvent $event) {
+ return $event->getNDC();
+ }
+}
+
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/library/log4php/pattern/LoggerPatternConverterNewLine.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Returns platform-specific newline character(s).
+ *
+ * @package log4php
+ * @subpackage pattern
+ * @version $Revision: 1326626 $
+ * @since 2.3
+ */
+class LoggerPatternConverterNewLine extends LoggerPatternConverter {
+
+ public function convert(LoggerLoggingEvent $event) {
+ return PHP_EOL;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/pattern/LoggerPatternConverterProcess.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Returns the PID of the current process.
+ *
+ * @package log4php
+ * @subpackage pattern
+ * @version $Revision: 1326626 $
+ * @since 2.3
+ */
+class LoggerPatternConverterProcess extends LoggerPatternConverter {
+
+ public function convert(LoggerLoggingEvent $event) {
+ return getmypid();
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/pattern/LoggerPatternConverterRelative.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Returns the number of milliseconds elapsed since the start of the
+ * application until the creation of the logging event.
+ *
+ * @package log4php
+ * @subpackage pattern
+ * @version $Revision: 1379731 $
+ * @since 2.3
+ */
+class LoggerPatternConverterRelative extends LoggerPatternConverter {
+
+ public function convert(LoggerLoggingEvent $event) {
+ $ts = $event->getRelativeTime();
+ return number_format($ts, 4);
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/pattern/LoggerPatternConverterRequest.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Returns a value from the $_REQUEST superglobal array corresponding to the
+ * given key.
+ *
+ * Options:
+ * [0] $_REQUEST key value
+ *
+ * @package log4php
+ * @subpackage pattern
+ * @version $Revision: 1326626 $
+ * @since 2.3
+ */
+class LoggerPatternConverterRequest extends LoggerPatternConverterSuperglobal {
+ protected $name = '_REQUEST';
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/library/log4php/pattern/LoggerPatternConverterServer.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Returns a value from the $_SERVER superglobal array corresponding to the
+ * given key.
+ *
+ * Options:
+ * [0] $_SERVER key value
+ *
+ * @package log4php
+ * @subpackage pattern
+ * @version $Revision: 1326626 $
+ * @since 2.3
+ */
+class LoggerPatternConverterServer extends LoggerPatternConverterSuperglobal {
+ protected $name = '_SERVER';
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/pattern/LoggerPatternConverterSession.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Returns a value from the $_SESSION superglobal array corresponding to the
+ * given key.
+ *
+ * Options:
+ * [0] $_SESSION key value
+ *
+ * @package log4php
+ * @subpackage pattern
+ * @version $Revision: 1326626 $
+ * @since 2.3
+ */
+class LoggerPatternConverterSession extends LoggerPatternConverterSuperglobal {
+ protected $name = '_SESSION';
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/pattern/LoggerPatternConverterSessionID.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Returns the active session ID, or an empty string if out of session.
+ *
+ * @package log4php
+ * @subpackage pattern
+ * @version $Revision: 1326626 $
+ * @since 2.3
+ */
+class LoggerPatternConverterSessionID extends LoggerPatternConverter {
+ public function convert(LoggerLoggingEvent $event) {
+ return session_id();
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/pattern/LoggerPatternConverterSuperglobal.php
@@ -0,0 +1,100 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Returns a value from a superglobal array corresponding to the
+ * given key.
+ *
+ * Option: the key to look up within the superglobal array
+ *
+ * Also, it is possible that a superglobal variable is not populated by PHP
+ * because of the settings in the variables-order ini directive. In this case
+ * the converter will return an empty value.
+ *
+ * @see http://php.net/manual/en/language.variables.superglobals.php
+ * @see http://www.php.net/manual/en/ini.core.php#ini.variables-order
+ *
+ * @package log4php
+ * @subpackage pattern
+ * @version $Revision: 1326626 $
+ * @since 2.3
+ */
+abstract class LoggerPatternConverterSuperglobal extends LoggerPatternConverter {
+
+ /**
+ * Name of the superglobal variable, to be defined by subclasses.
+ * For example: "_SERVER" or "_ENV".
+ */
+ protected $name;
+
+ protected $value = '';
+
+ public function activateOptions() {
+ // Read the key from options array
+ if (isset($this->option) && $this->option !== '') {
+ $key = $this->option;
+ }
+
+ /*
+ * There is a bug in PHP which doesn't allow superglobals to be
+ * accessed when their name is stored in a variable, e.g.:
+ *
+ * $name = '_SERVER';
+ * $array = $$name;
+ *
+ * This code does not work when run from within a method (only when run
+ * in global scope). But the following code does work:
+ *
+ * $name = '_SERVER';
+ * global $$name;
+ * $array = $$name;
+ *
+ * That's why global is used here.
+ */
+ global ${$this->name};
+
+ // Check the given superglobal exists. It is possible that it is not initialized.
+ if (!isset(${$this->name})) {
+ $class = get_class($this);
+ trigger_error("log4php: $class: Cannot find superglobal variable \${$this->name}.", E_USER_WARNING);
+ return;
+ }
+
+ $source = ${$this->name};
+
+ // When the key is set, display the matching value
+ if (isset($key)) {
+ if (isset($source[$key])) {
+ $this->value = $source[$key];
+ }
+ } // When the key is not set, display all values
+ else {
+ $values = array();
+ foreach ($source as $key => $value) {
+ $values[] = "$key=$value";
+ }
+ $this->value = implode(', ', $values);
+ }
+ }
+
+ public function convert(LoggerLoggingEvent $event) {
+ return $this->value;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/pattern/LoggerPatternConverterThrowable.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Returns the throwable information linked to the logging event, if any.
+ *
+ * @package log4php
+ * @subpackage pattern
+ * @version $Revision: 1395470 $
+ * @since 2.3
+ */
+class LoggerPatternConverterThrowable extends LoggerPatternConverter {
+
+ public function convert(LoggerLoggingEvent $event) {
+ $info = $event->getThrowableInformation();
+ if (isset($info)) {
+ $ex = $info->getThrowable();
+ return (string)$ex . PHP_EOL;
+ }
+ return '';
+ }
+}
+
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/library/log4php/renderers/LoggerRenderer.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Implement this interface in order to render objects to strings.
+ *
+ * @version $Revision: 1394956 $
+ * @package log4php
+ * @subpackage renderers
+ * @since 0.3
+ */
+interface LoggerRenderer {
+ /**
+ * Renders the entity passed as <var>input</var> to a string.
+ * @param mixed $input The entity to render.
+ * @return string The rendered string.
+ */
+ public function render($input);
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/renderers/LoggerRendererDefault.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * The default renderer, which is used when no other renderer is found.
+ *
+ * Renders the input using <var>print_r</var>.
+ *
+ * @package log4php
+ * @subpackage renderers
+ * @since 0.3
+ */
+class LoggerRendererDefault implements LoggerRenderer {
+
+ /** @inheritdoc */
+ public function render($input) {
+ return print_r($input, true);
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/renderers/LoggerRendererException.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Renderer used for Exceptions.
+ *
+ * @package log4php
+ * @subpackage renderers
+ * @since 2.1
+ */
+class LoggerRendererException implements LoggerRenderer {
+
+ public function render($input) {
+
+ // Exception class has a very decent __toString method
+ // so let's just use that instead of writing lots of code.
+ return (string)$input;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/renderers/LoggerRendererMap.php
@@ -0,0 +1,186 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @package log4php
+ */
+
+/**
+ * Manages defined renderers and determines which renderer to use for a given
+ * input.
+ *
+ * @version $Revision: 1394956 $
+ * @package log4php
+ * @subpackage renderers
+ * @since 0.3
+ */
+class LoggerRendererMap {
+
+ /**
+ * Maps class names to appropriate renderers.
+ * @var array
+ */
+ private $map = array();
+
+ /**
+ * The default renderer to use if no specific renderer is found.
+ * @var LoggerRenderer
+ */
+ private $defaultRenderer;
+
+ public function __construct() {
+
+ // Set default config
+ $this->reset();
+ }
+
+ /**
+ * Adds a renderer to the map.
+ *
+ * If a renderer already exists for the given <var>$renderedClass</var> it
+ * will be overwritten without warning.
+ *
+ * @param string $renderedClass The name of the class which will be
+ * rendered by the renderer.
+ * @param string $renderingClass The name of the class which will
+ * perform the rendering.
+ */
+ public function addRenderer($renderedClass, $renderingClass) {
+ // Check the rendering class exists
+ if (!class_exists($renderingClass)) {
+ trigger_error("log4php: Failed adding renderer. Rendering class [$renderingClass] not found.");
+ return;
+ }
+
+ // Create the instance
+ $renderer = new $renderingClass();
+
+ // Check the class implements the right interface
+ if (!($renderer instanceof LoggerRenderer)) {
+ trigger_error("log4php: Failed adding renderer. Rendering class [$renderingClass] does not implement the LoggerRenderer interface.");
+ return;
+ }
+
+ // Convert to lowercase since class names in PHP are not case sensitive
+ $renderedClass = strtolower($renderedClass);
+
+ $this->map[$renderedClass] = $renderer;
+ }
+
+ /**
+ * Sets a custom default renderer class.
+ *
+ * TODO: there's code duplication here. This method is almost identical to
+ * addRenderer(). However, it has custom error messages so let it sit for
+ * now.
+ *
+ * @param string $renderingClass The name of the class which will
+ * perform the rendering.
+ */
+ public function setDefaultRenderer($renderingClass) {
+ // Check the class exists
+ if (!class_exists($renderingClass)) {
+ trigger_error("log4php: Failed setting default renderer. Rendering class [$renderingClass] not found.");
+ return;
+ }
+
+ // Create the instance
+ $renderer = new $renderingClass();
+
+ // Check the class implements the right interface
+ if (!($renderer instanceof LoggerRenderer)) {
+ trigger_error("log4php: Failed setting default renderer. Rendering class [$renderingClass] does not implement the LoggerRenderer interface.");
+ return;
+ }
+
+ $this->defaultRenderer = $renderer;
+ }
+
+ /**
+ * Returns the default renderer.
+ * @var LoggerRenderer
+ */
+ public function getDefaultRenderer() {
+ return $this->defaultRenderer;
+ }
+
+ /**
+ * Finds the appropriate renderer for the given <var>input</var>, and
+ * renders it (i.e. converts it to a string).
+ *
+ * @param mixed $input Input to render.
+ * @return string The rendered contents.
+ */
+ public function findAndRender($input) {
+ if ($input === null) {
+ return null;
+ }
+
+ // For objects, try to find a renderer in the map
+ if (is_object($input)) {
+ $renderer = $this->getByClassName(get_class($input));
+ if (isset($renderer)) {
+ return $renderer->render($input);
+ }
+ }
+
+ // Fall back to the default renderer
+ return $this->defaultRenderer->render($input);
+ }
+
+ /**
+ * Returns the appropriate renderer for a given object.
+ *
+ * @param mixed $object
+ * @return LoggerRenderer Or null if none found.
+ */
+ public function getByObject($object) {
+ if (!is_object($object)) {
+ return null;
+ }
+ return $this->getByClassName(get_class($object));
+ }
+
+ /**
+ * Returns the appropriate renderer for a given class name.
+ *
+ * If no renderer could be found, returns NULL.
+ *
+ * @param string $class
+ * @return LoggerRendererObject Or null if not found.
+ */
+ public function getByClassName($class) {
+ for (; !empty($class); $class = get_parent_class($class)) {
+ $class = strtolower($class);
+ if (isset($this->map[$class])) {
+ return $this->map[$class];
+ }
+ }
+ return null;
+ }
+
+ /** Empties the renderer map. */
+ public function clear() {
+ $this->map = array();
+ }
+
+ /** Resets the renderer map to it's default configuration. */
+ public function reset() {
+ $this->defaultRenderer = new LoggerRendererDefault();
+ $this->clear();
+ $this->addRenderer('Exception', 'LoggerRendererException');
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/log4php/xml/log4php.dtd
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+ <!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+ <!-- Authors: Chris Taylor, Ceki Gülcü. -->
+ <!-- Version: 1.2 -->
+
+ <!-- PHP Port Modifications Author: Marco Vassura -->
+ <!-- PHP dtd Version: $Revision: 823875 $ -->
+
+ <!-- A configuration element consists of optional renderer
+ elements,appender elements, categories and an optional root
+ element. -->
+ <!-- [log4php] -->
+ <!--
+ category instead of logger cannot be used. categoryFactory is not implemented in log4php.
+ -->
+ <!-- [/log4php] -->
+ <!ELEMENT log4php:configuration (renderer*, appender*,(logger)*,root?)>
+
+ <!-- The "threshold" attribute takes a level value such that all -->
+ <!-- logging statements with a level equal or below this value are -->
+ <!-- disabled. -->
+
+ <!-- Setting the "debug" enable the printing of internal log4j logging -->
+ <!-- statements. -->
+
+ <!-- By default, debug attribute is "null", meaning that we not do touch -->
+ <!-- internal log4j logging settings. The "null" value for the threshold -->
+ <!-- attribute can be misleading. The threshold field of a repository -->
+ <!-- cannot be set to null. The "null" value for the threshold attribute -->
+ <!-- simply means don't touch the threshold field, the threshold field -->
+ <!-- keeps its old value. -->
+
+ <!ATTLIST log4php:configuration
+ xmlns:log4php CDATA #FIXED "http://logging.apache.org/log4php"
+ threshold (all|debug|info|warn|error|fatal|off|null) "null"
+ >
+
+ <!-- renderer elements allow the user to customize the conversion of -->
+ <!-- message objects to String. -->
+ <!ELEMENT renderer EMPTY>
+ <!ATTLIST renderer
+ renderedClass CDATA #REQUIRED
+ renderingClass CDATA #REQUIRED
+ >
+
+ <!-- Appenders must have a name and a class. -->
+ <!-- Appenders may contain an error handler, a layout, optional parameters -->
+ <!-- and filters. They may also reference (or include) other appenders. -->
+ <!-- [log4php] -->
+ <!-- error handler tag has no effects since log4php does not handle errors. Defintion deleted. -->
+ <!-- [/log4php] -->
+ <!ELEMENT appender (param*, layout?, filter*, appender-ref*)>
+ <!ATTLIST appender
+ name ID #REQUIRED
+ class CDATA #REQUIRED
+ >
+
+ <!ELEMENT layout (param*)>
+ <!ATTLIST layout
+ class CDATA #REQUIRED
+ >
+
+ <!ELEMENT filter (param*)>
+ <!ATTLIST filter
+ class CDATA #REQUIRED
+ >
+
+
+ <!ELEMENT param EMPTY>
+ <!ATTLIST param
+ name CDATA #REQUIRED
+ value CDATA #REQUIRED
+ >
+
+ <!ELEMENT priority EMPTY>
+ <!ATTLIST priority
+ value CDATA #REQUIRED
+ >
+
+ <!ELEMENT level EMPTY>
+ <!ATTLIST level
+ value CDATA #REQUIRED
+ >
+
+ <!-- If no level element is specified, then the configurator MUST not -->
+ <!-- touch the level of the named logger. -->
+ <!ELEMENT logger (level?,appender-ref*)>
+ <!ATTLIST logger
+ name ID #REQUIRED
+ additivity (true|false) "true"
+ >
+
+ <!ELEMENT appender-ref EMPTY>
+ <!ATTLIST appender-ref
+ ref IDREF #REQUIRED
+ >
+
+ <!-- If no priority element is specified, then the configurator MUST not -->
+ <!-- touch the priority of root. -->
+ <!-- The root category always exists and cannot be subclassed. -->
+ <!ELEMENT root (param*, (priority|level)?, appender-ref*)>
+
+
+ <!-- ==================================================================== -->
+ <!-- A logging event -->
+ <!-- ==================================================================== -->
+ <!ELEMENT log4php:eventSet (log4php:event*)>
+ <!ATTLIST log4php:eventSet
+ xmlns:log4php CDATA #FIXED "http://www.vxr.it/log4php/"
+ version (0.2|0.3) "0.3"
+ includesLocationInfo (true|false) "true"
+ >
+
+ <!ELEMENT log4php:event (log4php:message, log4php:locationInfo?) >
+
+ <!-- The timestamp format is application dependent. -->
+ <!ATTLIST log4php:event
+ logger CDATA #REQUIRED
+ level CDATA #REQUIRED
+ thread CDATA #REQUIRED
+ timestamp CDATA #REQUIRED
+ >
+
+ <!ELEMENT log4php:message (#PCDATA)>
+ <!ELEMENT log4php:NDC (#PCDATA)>
+
+ <!ELEMENT log4php:locationInfo EMPTY>
+ <!ATTLIST log4php:locationInfo
+ class CDATA #REQUIRED
+ method CDATA #REQUIRED
+ file CDATA #REQUIRED
+ line CDATA #REQUIRED
+ >
new file mode 100644
--- /dev/null
+++ b/library/smarty/.gitattributes
@@ -0,0 +1,22 @@
+# Auto detect text files and perform LF normalization
+* text=auto
+
+# Custom for Visual Studio
+*.cs diff=csharp
+*.sln merge=union
+*.csproj merge=union
+*.vbproj merge=union
+*.fsproj merge=union
+*.dbproj merge=union
+
+# Standard to msysgit
+*.doc diff=astextplain
+*.DOC diff=astextplain
+*.docx diff=astextplain
+*.DOCX diff=astextplain
+*.dot diff=astextplain
+*.DOT diff=astextplain
+*.pdf diff=astextplain
+*.PDF diff=astextplain
+*.rtf diff=astextplain
+*.RTF diff=astextplain
new file mode 100644
--- /dev/null
+++ b/library/smarty/.gitignore
@@ -0,0 +1,222 @@
+#################
+## Eclipse
+#################
+
+*.pydevproject
+.project
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.classpath
+.settings/
+.loadpath
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# CDT-specific
+.cproject
+
+# PDT-specific
+.buildpath
+
+
+#################
+## Visual Studio
+#################
+
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.sln.docstates
+
+# Build results
+
+[Dd]ebug/
+[Rr]elease/
+x64/
+build/
+[Bb]in/
+[Oo]bj/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+*_i.c
+*_p.c
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.log
+*.scc
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opensdf
+*.sdf
+*.cachefile
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+*.ncrunch*
+.*crunch*.local.xml
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.Publish.xml
+*.pubxml
+
+# NuGet Packages Directory
+## TODO: If you have NuGet Package Restore enabled, uncomment the next line
+#packages/
+
+# Windows Azure Build Output
+csx
+*.build.csdef
+
+# Windows Store app package directory
+AppPackages/
+
+# Others
+sql/
+*.Cache
+ClientBin/
+[Ss]tyle[Cc]op.*
+~$*
+*~
+*.dbmdl
+*.[Pp]ublish.xml
+*.pfx
+*.publishsettings
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file to a newer
+# Visual Studio version. Backup files are not needed, because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+App_Data/*.mdf
+App_Data/*.ldf
+
+#############
+## Windows detritus
+#############
+
+# Windows image file caches
+Thumbs.db
+ehthumbs.db
+
+# Folder config file
+Desktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Mac crap
+.DS_Store
+
+
+#############
+## Python
+#############
+
+*.py[co]
+
+# Packages
+*.egg
+*.egg-info
+dist/
+build/
+eggs/
+parts/
+var/
+sdist/
+develop-eggs/
+.installed.cfg
+
+# Installer logs
+pip-log.txt
+
+# Unit test / coverage reports
+.coverage
+.tox
+
+#Translations
+*.mo
+
+#Mr Developer
+.mr.developer.cfg
+
+.idea/
+.idea\
+
+# Smarty
+lexer/*.php
+lexer/*.out
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/library/smarty/.travis.yml
@@ -0,0 +1,18 @@
+language: php
+
+php:
+ - 5.3
+ - 5.4
+ - 5.5
+ - 5.6
+
+allow_failures:
+ - php: hhvm
+
+install:
+ - git clone --depth=50 --branch=master git://github.com/smarty-php/smarty-phpunit.git
+
+script:
+ - cd smarty-phpunit
+ - phpunit ./
+
new file mode 100644
--- /dev/null
+++ b/library/smarty/COMPOSER_RELEASE_NOTES.txt
@@ -0,0 +1,29 @@
+
+
+Starting with Smarty 3.1.21 Composer has been configured to load the packages from github.
+
+*******************************************************************************
+* *
+* NOTE: Because of this change you must clear your local composer cache with *
+* the "composer clearcache" command *
+* *
+*******************************************************************************
+
+To get the latest stable version use
+ "require": {
+ "smarty/smarty": "~3.1"
+ }
+in your composer.json file.
+
+To get the trunk version use
+ "require": {
+ "smarty/smarty": "~3.1@dev"
+ }
+
+The "smarty/smarty" package will start at libs/.... subfolder.
+
+To retrieve the development and documentation folders add
+ "require-dev": {
+ "smarty/smarty-dev": "~3.1@dev"
+ }
+
new file mode 100644
--- /dev/null
+++ b/library/smarty/INHERITANCE_RELEASE_NOTES.txt
@@ -0,0 +1,35 @@
+In Smarty 3.1 template inheritance is a compile time process. All the extending of {block} tags
+is done at compile time and the parent and child templates are compiled in a single compiled template.
+{include} subtemplate could also {block} tags. Such subtemplate could not compiled by it's own because
+it could be used in other context where the {block} extended with a different result. For that reasion
+the compiled code of {include} subtemplates gets also merged in compiled inheritance template.
+
+Merging the code into a single compile template has some drawbacks.
+1. You could not use variable file names in {include} Smarty would use the {include} of compilation time.
+2. You could not use individual compile_id in {include}
+3. Seperate caching of subtemplate was not possible
+4. Any change of the template directory structure between calls was not necessarily seen.
+
+Starting with 3.1.15 some of the above conditions got checked and resulted in an exception. It turned out
+that a couple of users did use some of above and now got exceptions.
+
+To resolve this starting with 3.1.16 there is a new configuration parameter $inheritance_merge_compiled_includes.
+For most backward compatibility its default setting is true.
+With this setting all {include} subtemplate will be merge into the compiled inheritance template, but the above cases
+could be rejected by exception.
+
+
+If $smarty->inheritance_merge_compiled_includes = false; {include} subtemplate will not be merged.
+You must now manually merge all {include} subtemplate which do contain {block} tags. This is done by setting the "inline" option.
+{include file='foo.bar' inline}
+
+1. In case of a variable file name like {include file=$foo inline} you must use the variable in a compile_id $smarty->compile_id = $foo;
+2. If you use individual compile_id in {include file='foo.tpl' compile_id=$bar inline} it must be used in the
+ global compile_id as well $smarty->compile_id = $bar;
+3. If call templates with different template_dir configurations and a parent could same named child template from different folders
+ you must make the folder name part of the compile_id.
+
+
+In the upcomming major release Smarty 3.2 inheritance will no longer be a compile time process.
+All restrictions will be then removed.
+
new file mode 100644
--- /dev/null
+++ b/library/smarty/NEW_FEATURES.txt
@@ -0,0 +1,86 @@
+
+
+This file contains a brief description of new features which have been added to Smarty 3.1
+
+Smarty 3.1.22
+
+ Namespace support within templates
+ ==================================
+ Within templates you can now use namespace specifications on:
+ - Constants like foo\bar\FOO
+ - Class names like foo\bar\Baz::FOO, foo\bar\Baz::$foo, foo\bar\Baz::foo()
+ - PHP function names like foo\bar\baz()
+
+ Security
+ ========
+ - disable special $smarty variable -
+ The Smarty_Security class has the new property $disabled_special_smarty_vars.
+ It's an array which can be loaded with the $smarty special variable names like
+ 'template_object', 'template', 'current_dir' and others which will be disabled.
+ Note: That this security check is performed at compile time.
+
+ - limit template nesting -
+ Property $max_template_nesting of Smarty_Security does set the maximum template nesting level.
+ The main template is level 1. The nesting level is checked at run time. When the maximum will be exceeded
+ an Exception will be thrown. The default setting is 0 which does disable this check.
+
+ - trusted static methods -
+ The Smarty_Security class has the new property $trusted_static_methods to restrict access to static methods.
+ It's an nested array of trusted class and method names.
+ Format:
+ array (
+ 'class_1' => array('method_1', 'method_2'), // allowed methods
+ 'class_2' => array(), // all methods of class allowed
+ )
+ To disable access for all methods of all classes set $trusted_static_methods = null;
+ The default value is an empty array() which does enables all methods of all classes, but for backward compatibility
+ the setting of $static_classes will be checked.
+ Note: That this security check is performed at compile time.
+
+ - trusted static properties -
+ The Smarty_Security class has the new property $trusted_static_properties to restrict access to static properties.
+ It's an nested array of trusted class and property names.
+ Format:
+ array (
+ 'class_1' => array('prop_1', 'prop_2'), // allowed properties listed
+ 'class_2' => array(), // all properties of class allowed
+ }
+ To disable access for all properties of all classes set $trusted_static_properties = null;
+ The default value is an empty array() which does enables all properties of all classes, but for backward compatibility
+ the setting of $static_classes will be checked.
+ Note: That this security check is performed at compile time.
+
+ - trusted constants .
+ The Smarty_Security class has the new property $trusted_constants to restrict access to constants.
+ It's an array of trusted constant names.
+ Format:
+ array (
+ 'SMARTY_DIR' , // allowed constant
+ }
+ If the array is empty (default) the usage of constants can be controlled with the
+ Smarty_Security::$allow_constants property (default true)
+
+
+
+ Compiled Templates
+ ==================
+ Smarty does now automatically detects a change of the $merge_compiled_includes and $escape_html
+ property and creates different compiled templates files depending on the setting.
+
+ Same applies to config files and the $config_overwrite, $config_booleanize and
+ $config_read_hidden properties.
+
+ Debugging
+ =========
+ The layout of the debug window has been changed for better readability
+
+ New class constants
+ Smarty::DEBUG_OFF
+ Smarty::DEBUG_ON
+ Smarty::DEBUG_INDIVIDUAL
+ have been introduced for setting the $debugging property.
+
+ Smarty::DEBUG_INDIVIDUAL will create for each display() and fetch() call an individual gebug window.
+
+ .
+
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/library/smarty/README
@@ -0,0 +1,574 @@
+Smarty 3.x
+
+Author: Monte Ohrt <monte at ohrt dot com >
+Author: Uwe Tews
+
+AN INTRODUCTION TO SMARTY 3
+
+NOTICE FOR 3.1 release:
+
+Please see the SMARTY_3.1_NOTES.txt file that comes with the distribution.
+
+NOTICE for 3.0.5 release:
+
+Smarty now follows the PHP error_reporting level by default. If PHP does not mask E_NOTICE and you try to access an unset template variable, you will now get an E_NOTICE warning. To revert to the old behavior:
+
+$smarty->error_reporting = E_ALL & ~E_NOTICE;
+
+NOTICE for 3.0 release:
+
+IMPORTANT: Some API adjustments have been made between the RC4 and 3.0 release.
+We felt it is better to make these now instead of after a 3.0 release, then have to
+immediately deprecate APIs in 3.1. Online documentation has been updated
+to reflect these changes. Specifically:
+
+---- API CHANGES RC4 -> 3.0 ----
+
+$smarty->register->*
+$smarty->unregister->*
+$smarty->utility->*
+$samrty->cache->*
+
+Have all been changed to local method calls such as:
+
+$smarty->clearAllCache()
+$smarty->registerFoo()
+$smarty->unregisterFoo()
+$smarty->testInstall()
+etc.
+
+Registration of function, block, compiler, and modifier plugins have been
+consolidated under two API calls:
+
+$smarty->registerPlugin(...)
+$smarty->unregisterPlugin(...)
+
+Registration of pre, post, output and variable filters have been
+consolidated under two API calls:
+
+$smarty->registerFilter(...)
+$smarty->unregisterFilter(...)
+
+Please refer to the online documentation for all specific changes:
+
+http://www.smarty.net/documentation
+
+----
+
+The Smarty 3 API has been refactored to a syntax geared
+for consistency and modularity. The Smarty 2 API syntax is still supported, but
+will throw a deprecation notice. You can disable the notices, but it is highly
+recommended to adjust your syntax to Smarty 3, as the Smarty 2 syntax must run
+through an extra rerouting wrapper.
+
+Basically, all Smarty methods now follow the "fooBarBaz" camel case syntax. Also,
+all Smarty properties now have getters and setters. So for example, the property
+$smarty->cache_dir can be set with $smarty->setCacheDir('foo/') and can be
+retrieved with $smarty->getCacheDir().
+
+Some of the Smarty 3 APIs have been revoked such as the "is*" methods that were
+just duplicate functions of the now available "get*" methods.
+
+Here is a rundown of the Smarty 3 API:
+
+$smarty->fetch($template, $cache_id = null, $compile_id = null, $parent = null)
+$smarty->display($template, $cache_id = null, $compile_id = null, $parent = null)
+$smarty->isCached($template, $cache_id = null, $compile_id = null)
+$smarty->createData($parent = null)
+$smarty->createTemplate($template, $cache_id = null, $compile_id = null, $parent = null)
+$smarty->enableSecurity()
+$smarty->disableSecurity()
+$smarty->setTemplateDir($template_dir)
+$smarty->addTemplateDir($template_dir)
+$smarty->templateExists($resource_name)
+$smarty->loadPlugin($plugin_name, $check = true)
+$smarty->loadFilter($type, $name)
+$smarty->setExceptionHandler($handler)
+$smarty->addPluginsDir($plugins_dir)
+$smarty->getGlobal($varname = null)
+$smarty->getRegisteredObject($name)
+$smarty->getDebugTemplate()
+$smarty->setDebugTemplate($tpl_name)
+$smarty->assign($tpl_var, $value = null, $nocache = false)
+$smarty->assignGlobal($varname, $value = null, $nocache = false)
+$smarty->assignByRef($tpl_var, &$value, $nocache = false)
+$smarty->append($tpl_var, $value = null, $merge = false, $nocache = false)
+$smarty->appendByRef($tpl_var, &$value, $merge = false)
+$smarty->clearAssign($tpl_var)
+$smarty->clearAllAssign()
+$smarty->configLoad($config_file, $sections = null)
+$smarty->getVariable($variable, $_ptr = null, $search_parents = true, $error_enable = true)
+$smarty->getConfigVariable($variable)
+$smarty->getStreamVariable($variable)
+$smarty->getConfigVars($varname = null)
+$smarty->clearConfig($varname = null)
+$smarty->getTemplateVars($varname = null, $_ptr = null, $search_parents = true)
+$smarty->clearAllCache($exp_time = null, $type = null)
+$smarty->clearCache($template_name, $cache_id = null, $compile_id = null, $exp_time = null, $type = null)
+
+$smarty->registerPlugin($type, $tag, $callback, $cacheable = true, $cache_attr = array())
+
+$smarty->registerObject($object_name, $object_impl, $allowed = array(), $smarty_args = true, $block_methods = array())
+
+$smarty->registerFilter($type, $function_name)
+$smarty->registerResource($resource_type, $function_names)
+$smarty->registerDefaultPluginHandler($function_name)
+$smarty->registerDefaultTemplateHandler($function_name)
+
+$smarty->unregisterPlugin($type, $tag)
+$smarty->unregisterObject($object_name)
+$smarty->unregisterFilter($type, $function_name)
+$smarty->unregisterResource($resource_type)
+
+$smarty->compileAllTemplates($extension = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null)
+$smarty->clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null)
+$smarty->testInstall()
+
+// then all the getters/setters, available for all properties. Here are a few:
+
+$caching = $smarty->getCaching(); // get $smarty->caching
+$smarty->setCaching(true); // set $smarty->caching
+$smarty->setDeprecationNotices(false); // set $smarty->deprecation_notices
+$smarty->setCacheId($id); // set $smarty->cache_id
+$debugging = $smarty->getDebugging(); // get $smarty->debugging
+
+
+FILE STRUCTURE
+
+The Smarty 3 file structure is similar to Smarty 2:
+
+/libs/
+ Smarty.class.php
+/libs/sysplugins/
+ internal.*
+/libs/plugins/
+ function.mailto.php
+ modifier.escape.php
+ ...
+
+A lot of Smarty 3 core functionality lies in the sysplugins directory; you do
+not need to change any files here. The /libs/plugins/ folder is where Smarty
+plugins are located. You can add your own here, or create a separate plugin
+directory, just the same as Smarty 2. You will still need to create your own
+/cache/, /templates/, /templates_c/, /configs/ folders. Be sure /cache/ and
+/templates_c/ are writable.
+
+The typical way to use Smarty 3 should also look familiar:
+
+require('Smarty.class.php');
+$smarty = new Smarty;
+$smarty->assign('foo','bar');
+$smarty->display('index.tpl');
+
+
+However, Smarty 3 works completely different on the inside. Smarty 3 is mostly
+backward compatible with Smarty 2, except for the following items:
+
+*) Smarty 3 is PHP 5 only. It will not work with PHP 4.
+*) The {php} tag is disabled by default. Enable with $smarty->allow_php_tag=true.
+*) Delimiters surrounded by whitespace are no longer treated as Smarty tags.
+ Therefore, { foo } will not compile as a tag, you must use {foo}. This change
+ Makes Javascript/CSS easier to work with, eliminating the need for {literal}.
+ This can be disabled by setting $smarty->auto_literal = false;
+*) The Smarty 3 API is a bit different. Many Smarty 2 API calls are deprecated
+ but still work. You will want to update your calls to Smarty 3 for maximum
+ efficiency.
+
+
+There are many things that are new to Smarty 3. Here are the notable items:
+
+LEXER/PARSER
+============
+
+Smarty 3 now uses a lexing tokenizer for its parser/compiler. Basically, this
+means Smarty has some syntax additions that make life easier such as in-template
+math, shorter/intuitive function parameter options, infinite function recursion,
+more accurate error handling, etc.
+
+
+WHAT IS NEW IN SMARTY TEMPLATE SYNTAX
+=====================================
+
+Smarty 3 allows expressions almost anywhere. Expressions can include PHP
+functions as long as they are not disabled by the security policy, object
+methods and properties, etc. The {math} plugin is no longer necessary but
+is still supported for BC.
+
+Examples:
+{$x+$y} will output the sum of x and y.
+{$foo = strlen($bar)} function in assignment
+{assign var=foo value= $x+$y} in attributes
+{$foo = myfunct( ($x+$y)*3 )} as function parameter
+{$foo[$x+3]} as array index
+
+Smarty tags can be used as values within other tags.
+Example: {$foo={counter}+3}
+
+Smarty tags can also be used inside double quoted strings.
+Example: {$foo="this is message {counter}"}
+
+You can define arrays within templates.
+Examples:
+{assign var=foo value=[1,2,3]}
+{assign var=foo value=['y'=>'yellow','b'=>'blue']}
+Arrays can be nested.
+{assign var=foo value=[1,[9,8],3]}
+
+There is a new short syntax supported for assigning variables.
+Example: {$foo=$bar+2}
+
+You can assign a value to a specific array element. If the variable exists but
+is not an array, it is converted to an array before the new values are assigned.
+Examples:
+{$foo['bar']=1}
+{$foo['bar']['blar']=1}
+
+You can append values to an array. If the variable exists but is not an array,
+it is converted to an array before the new values are assigned.
+Example: {$foo[]=1}
+
+You can use a PHP-like syntax for accessing array elements, as well as the
+original "dot" notation.
+Examples:
+{$foo[1]} normal access
+{$foo['bar']}
+{$foo['bar'][1]}
+{$foo[$x+$x]} index may contain any expression
+{$foo[$bar[1]]} nested index
+{$foo[section_name]} smarty section access, not array access!
+
+The original "dot" notation stays, and with improvements.
+Examples:
+{$foo.a.b.c} => $foo['a']['b']['c']
+{$foo.a.$b.c} => $foo['a'][$b]['c'] with variable index
+{$foo.a.{$b+4}.c} => $foo['a'][$b+4]['c'] with expression as index
+{$foo.a.{$b.c}} => $foo['a'][$b['c']] with nested index
+
+note that { and } are used to address ambiguties when nesting the dot syntax.
+
+Variable names themselves can be variable and contain expressions.
+Examples:
+$foo normal variable
+$foo_{$bar} variable name containing other variable
+$foo_{$x+$y} variable name containing expressions
+$foo_{$bar}_buh_{$blar} variable name with multiple segments
+{$foo_{$x}} will output the variable $foo_1 if $x has a value of 1.
+
+Object method chaining is implemented.
+Example: {$object->method1($x)->method2($y)}
+
+{for} tag added for looping (replacement for {section} tag):
+{for $x=0, $y=count($foo); $x<$y; $x++} .... {/for}
+Any number of statements can be used separated by comma as the first
+inital expression at {for}.
+
+{for $x = $start to $end step $step} ... {/for}is in the SVN now .
+You can use also
+{for $x = $start to $end} ... {/for}
+In this case the step value will be automaticall 1 or -1 depending on the start and end values.
+Instead of $start and $end you can use any valid expression.
+Inside the loop the following special vars can be accessed:
+$x@iteration = number of iteration
+$x@total = total number of iterations
+$x@first = true on first iteration
+$x@last = true on last iteration
+
+
+The Smarty 2 {section} syntax is still supported.
+
+New shorter {foreach} syntax to loop over an array.
+Example: {foreach $myarray as $var}...{/foreach}
+
+Within the foreach loop, properties are access via:
+
+$var@key foreach $var array key
+$var@iteration foreach current iteration count (1,2,3...)
+$var@index foreach current index count (0,1,2...)
+$var@total foreach $var array total
+$var@first true on first iteration
+$var@last true on last iteration
+
+The Smarty 2 {foreach} tag syntax is still supported.
+
+NOTE: {$bar[foo]} still indicates a variable inside of a {section} named foo.
+If you want to access an array element with index foo, you must use quotes
+such as {$bar['foo']}, or use the dot syntax {$bar.foo}.
+
+while block tag is now implemented:
+{while $foo}...{/while}
+{while $x lt 10}...{/while}
+
+Direct access to PHP functions:
+Just as you can use PHP functions as modifiers directly, you can now access
+PHP functions directly, provided they are permitted by security settings:
+{time()}
+
+There is a new {function}...{/function} block tag to implement a template function.
+This enables reuse of code sequences like a plugin function. It can call itself recursively.
+Template function must be called with the new {call name=foo...} tag.
+
+Example:
+
+Template file:
+{function name=menu level=0}
+ <ul class="level{$level}">
+ {foreach $data as $entry}
+ {if is_array($entry)}
+ <li>{$entry@key}</li>
+ {call name=menu data=$entry level=$level+1}
+ {else}
+ <li>{$entry}</li>
+ {/if}
+ {/foreach}
+ </ul>
+{/function}
+
+{$menu = ['item1','item2','item3' => ['item3-1','item3-2','item3-3' =>
+ ['item3-3-1','item3-3-2']],'item4']}
+
+{call name=menu data=$menu}
+
+
+Generated output:
+ * item1
+ * item2
+ * item3
+ o item3-1
+ o item3-2
+ o item3-3
+ + item3-3-1
+ + item3-3-2
+ * item4
+
+The function tag itself must have the "name" attribute. This name is the tag
+name when calling the function. The function tag may have any number of
+additional attributes. These will be default settings for local variables.
+
+New {nocache} block function:
+{nocache}...{/nocache} will declare a section of the template to be non-cached
+when template caching is enabled.
+
+New nocache attribute:
+You can declare variable/function output as non-cached with the nocache attribute.
+Examples:
+
+{$foo nocache=true}
+{$foo nocache} /* same */
+
+{foo bar="baz" nocache=true}
+{foo bar="baz" nocache} /* same */
+
+{time() nocache=true}
+{time() nocache} /* same */
+
+Or you can also assign the variable in your script as nocache:
+$smarty->assign('foo',$something,true); // third param is nocache setting
+{$foo} /* non-cached */
+
+$smarty.current_dir returns the directory name of the current template.
+
+You can use strings directly as templates with the "string" resource type.
+Examples:
+$smarty->display('string:This is my template, {$foo}!'); // php
+{include file="string:This is my template, {$foo}!"} // template
+
+
+
+VARIABLE SCOPE / VARIABLE STORAGE
+=================================
+
+In Smarty 2, all assigned variables were stored within the Smarty object.
+Therefore, all variables assigned in PHP were accessible by all subsequent
+fetch and display template calls.
+
+In Smarty 3, we have the choice to assign variables to the main Smarty object,
+to user-created data objects, and to user-created template objects.
+These objects can be chained. The object at the end of a chain can access all
+variables belonging to that template and all variables within the parent objects.
+The Smarty object can only be the root of a chain, but a chain can be isolated
+from the Smarty object.
+
+All known Smarty assignment interfaces will work on the data and template objects.
+
+Besides the above mentioned objects, there is also a special storage area for
+global variables.
+
+A Smarty data object can be created as follows:
+$data = $smarty->createData(); // create root data object
+$data->assign('foo','bar'); // assign variables as usual
+$data->config_load('my.conf'); // load config file
+
+$data= $smarty->createData($smarty); // create data object having a parent link to
+the Smarty object
+
+$data2= $smarty->createData($data); // create data object having a parent link to
+the $data data object
+
+A template object can be created by using the createTemplate method. It has the
+same parameter assignments as the fetch() or display() method.
+Function definition:
+function createTemplate($template, $cache_id = null, $compile_id = null, $parent = null)
+
+The first parameter can be a template name, a smarty object or a data object.
+
+Examples:
+$tpl = $smarty->createTemplate('mytpl.tpl'); // create template object not linked to any parent
+$tpl->assign('foo','bar'); // directly assign variables
+$tpl->config_load('my.conf'); // load config file
+
+$tpl = $smarty->createTemplate('mytpl.tpl',$smarty); // create template having a parent link to the Smarty object
+$tpl = $smarty->createTemplate('mytpl.tpl',$data); // create template having a parent link to the $data object
+
+The standard fetch() and display() methods will implicitly create a template object.
+If the $parent parameter is not specified in these method calls, the template object
+is will link back to the Smarty object as it's parent.
+
+If a template is called by an {include...} tag from another template, the
+subtemplate links back to the calling template as it's parent.
+
+All variables assigned locally or from a parent template are accessible. If the
+template creates or modifies a variable by using the {assign var=foo...} or
+{$foo=...} tags, these new values are only known locally (local scope). When the
+template exits, none of the new variables or modifications can be seen in the
+parent template(s). This is same behavior as in Smarty 2.
+
+With Smarty 3, we can assign variables with a scope attribute which allows the
+availablility of these new variables or modifications globally (ie in the parent
+templates.)
+
+Possible scopes are local, parent, root and global.
+Examples:
+{assign var=foo value='bar'} // no scope is specified, the default 'local'
+{$foo='bar'} // same, local scope
+{assign var=foo value='bar' scope='local'} // same, local scope
+
+{assign var=foo value='bar' scope='parent'} // Values will be available to the parent object
+{$foo='bar' scope='parent'} // (normally the calling template)
+
+{assign var=foo value='bar' scope='root'} // Values will be exported up to the root object, so they can
+{$foo='bar' scope='root'} // be seen from all templates using the same root.
+
+{assign var=foo value='bar' scope='global'} // Values will be exported to global variable storage,
+{$foo='bar' scope='global'} // they are available to any and all templates.
+
+
+The scope attribute can also be attached to the {include...} tag. In this case,
+the specified scope will be the default scope for all assignments within the
+included template.
+
+
+PLUGINS
+=======
+
+Smarty3 are following the same coding rules as in Smarty2.
+The only difference is that the template object is passed as additional third parameter.
+
+smarty_plugintype_name (array $params, object $smarty, object $template)
+
+The Smarty 2 plugins are still compatible as long as they do not make use of specific Smarty2 internals.
+
+
+TEMPLATE INHERITANCE:
+=====================
+
+With template inheritance you can define blocks, which are areas that can be
+overriden by child templates, so your templates could look like this:
+
+parent.tpl:
+<html>
+ <head>
+ <title>{block name='title'}My site name{/block}</title>
+ </head>
+ <body>
+ <h1>{block name='page-title'}Default page title{/block}</h1>
+ <div id="content">
+ {block name='content'}
+ Default content
+ {/block}
+ </div>
+ </body>
+</html>
+
+child.tpl:
+{extends file='parent.tpl'}
+{block name='title'}
+Child title
+{/block}
+
+grandchild.tpl:
+{extends file='child.tpl'}
+{block name='title'}Home - {$smarty.block.parent}{/block}
+{block name='page-title'}My home{/block}
+{block name='content'}
+ {foreach $images as $img}
+ <img src="{$img.url}" alt="{$img.description}" />
+ {/foreach}
+{/block}
+
+We redefined all the blocks here, however in the title block we used {$smarty.block.parent},
+which tells Smarty to insert the default content from the parent template in its place.
+The content block was overriden to display the image files, and page-title has also be
+overriden to display a completely different title.
+
+If we render grandchild.tpl we will get this:
+<html>
+ <head>
+ <title>Home - Child title</title>
+ </head>
+ <body>
+ <h1>My home</h1>
+ <div id="content">
+ <img src="/example.jpg" alt="image" />
+ <img src="/example2.jpg" alt="image" />
+ <img src="/example3.jpg" alt="image" />
+ </div>
+ </body>
+</html>
+
+NOTE: In the child templates everything outside the {extends} or {block} tag sections
+is ignored.
+
+The inheritance tree can be as big as you want (meaning you can extend a file that
+extends another one that extends another one and so on..), but be aware that all files
+have to be checked for modifications at runtime so the more inheritance the more overhead you add.
+
+Instead of defining the parent/child relationships with the {extends} tag in the child template you
+can use the resource as follow:
+
+$smarty->display('extends:parent.tpl|child.tpl|grandchild.tpl');
+
+Child {block} tags may optionally have a append or prepend attribute. In this case the parent block content
+is appended or prepended to the child block content.
+
+{block name='title' append} My title {/block}
+
+
+PHP STREAMS:
+============
+
+(see online documentation)
+
+VARIBLE FILTERS:
+================
+
+(see online documentation)
+
+
+STATIC CLASS ACCESS AND NAMESPACE SUPPORT
+=========================================
+
+You can register a class with optional namespace for the use in the template like:
+
+$smarty->register->templateClass('foo','name\name2\myclass');
+
+In the template you can use it like this:
+{foo::method()} etc.
+
+
+=======================
+
+Please look through it and send any questions/suggestions/etc to the forums.
+
+http://www.phpinsider.com/smarty-forum/viewtopic.php?t=14168
+
+Monte and Uwe
new file mode 100644
--- /dev/null
+++ b/library/smarty/README.md
@@ -0,0 +1,52 @@
+#Smarty 3 template engine
+##Distribution repository
+
+*Read the NEW_FEATURES file for recent extensions to Smarty 3.1 functionality*
+
+Smarty versions 3.1.11 or later are now on github and can be installed with Composer.
+
+
+The "smarty/smarty" package will start at libs/.... subfolder.
+
+To get the latest stable version of Smarty 3.1 use
+
+ "require": {
+ "smarty/smarty": "~3.1"
+ }
+
+in your composer.json file.
+
+ To get the trunk version use
+
+ "require": {
+ "smarty/smarty": "~3.1@dev"
+ }
+
+For a specific version use something like
+
+ "require": {
+ "smarty/smarty": "3.1.19"
+ }
+
+PHPUnit test can be installed by corresponding composer entries like
+
+ "require": {
+ "smarty/smarty-phpunit": "3.1.19"
+ }
+
+Similar applies for the lexer/parser generator
+
+ "require": {
+ "smarty/smarty-lexer": "3.1.19"
+ }
+
+Or you could use
+
+ "require": {
+ "smarty/smarty-dev": "3.1.19"
+ }
+
+Which is a wrapper to install all 3 packages
+
+
+Composer can also be used for Smarty2 versions 2.6.24 to 2.6.28
new file mode 100644
--- /dev/null
+++ b/library/smarty/SMARTY_2_BC_NOTES.txt
@@ -0,0 +1,109 @@
+= Known incompatibilities with Smarty 2 =
+
+== Syntax ==
+
+Smarty 3 API has a new syntax. Much of the Smarty 2 syntax is supported
+by a wrapper but deprecated. See the README that comes with Smarty 3 for more
+information.
+
+The {$array|@mod} syntax has always been a bit confusing, where an "@" is required
+to apply a modifier to an array instead of the individual elements. Normally you
+always want the modifier to apply to the variable regardless of its type. In Smarty 3,
+{$array|mod} and {$array|@mod} behave identical. It is safe to drop the "@" and the
+modifier will still apply to the array. If you really want the modifier to apply to
+each array element, you must loop the array in-template, or use a custom modifier that
+supports array iteration. Most smarty functions already escape values where necessary
+such as {html_options}
+
+== PHP Version ==
+Smarty 3 is PHP 5 only. It will not work with PHP 4.
+
+== {php} Tag ==
+The {php} tag is disabled by default. The use of {php} tags is
+deprecated. It can be enabled with $smarty->allow_php_tag=true.
+
+But if you scatter PHP code which belongs together into several
+{php} tags it may not work any longer.
+
+== Delimiters and whitespace ==
+Delimiters surrounded by whitespace are no longer treated as Smarty tags.
+Therefore, { foo } will not compile as a tag, you must use {foo}. This change
+Makes Javascript/CSS easier to work with, eliminating the need for {literal}.
+This can be disabled by setting $smarty->auto_literal = false;
+
+== Unquoted Strings ==
+Smarty 2 was a bit more forgiving (and ambiguous) when it comes to unquoted strings
+in parameters. Smarty3 is more restrictive. You can still pass strings without quotes
+so long as they contain no special characters. (anything outside of A-Za-z0-9_)
+
+For example filename strings must be quoted
+<source lang="smarty">
+{include file='path/foo.tpl'}
+</source>
+
+== Extending the Smarty class ==
+Smarty 3 makes use of the __construct method for initialization. If you are extending
+the Smarty class, its constructor is not called implicitly if the your child class defines
+its own constructor. In order to run Smarty's constructor, a call to parent::__construct()
+within your child constructor is required.
+
+<source lang="php">
+class MySmarty extends Smarty {
+ function __construct() {
+ parent::__construct();
+
+ // your initialization code goes here
+
+ }
+}
+</source>
+
+== Autoloader ==
+Smarty 3 does register its own autoloader with spl_autoload_register. If your code has
+an existing __autoload function then this function must be explicitly registered on
+the __autoload stack. See http://us3.php.net/manual/en/function.spl-autoload-register.php
+for further details.
+
+== Plugin Filenames ==
+Smarty 3 optionally supports the PHP spl_autoloader. The autoloader requires filenames
+to be lower case. Because of this, Smarty plugin file names must also be lowercase.
+In Smarty 2, mixed case file names did work.
+
+== Scope of Special Smarty Variables ==
+In Smarty 2 the special Smarty variables $smarty.section... and $smarty.foreach...
+had global scope. If you had loops with the same name in subtemplates you could accidentally
+overwrite values of parent template.
+
+In Smarty 3 these special Smarty variable have only local scope in the template which
+is defining the loop. If you need their value in a subtemplate you have to pass them
+as parameter.
+<source lang="smarty">
+{include file='path/foo.tpl' index=$smarty.section.foo.index}
+</source>
+
+== SMARTY_RESOURCE_CHAR_SET ==
+Smarty 3 sets the constant SMARTY_RESOURCE_CHAR_SET to utf-8 as default template charset.
+This is now used also on modifiers like escape as default charset. If your templates use
+other charsets make sure that you define the constant accordingly. Otherwise you may not
+get any output.
+
+== newline at {if} tags ==
+A \n was added to the compiled code of the {if},{else},{elseif},{/if} tags to get output of newlines as expected by the template source.
+If one of the {if} tags is at the line end you will now get a newline in the HTML output.
+
+== trigger_error() ==
+The API function trigger_error() has been removed because it did just map to PHP trigger_error.
+However it's still included in the Smarty2 API wrapper.
+
+== Smarty constants ==
+The constants
+SMARTY_PHP_PASSTHRU
+SMARTY_PHP_QUOTE
+SMARTY_PHP_REMOVE
+SMARTY_PHP_ALLOW
+have been replaced with class constants
+Smarty::PHP_PASSTHRU
+Smarty::PHP_QUOTE
+Smarty::PHP_REMOVE
+Smarty::PHP_ALLOW
+
new file mode 100644
--- /dev/null
+++ b/library/smarty/SMARTY_3.0_BC_NOTES.txt
@@ -0,0 +1,24 @@
+== Smarty2 backward compatibility ==
+All Smarty2 specific API functions and deprecated functionallity has been moved
+to the SmartyBC class.
+
+== {php} Tag ==
+The {php} tag is no longer available in the standard Smarty calls.
+The use of {php} tags is deprecated and only available in the SmartyBC class.
+
+== {include_php} Tag ==
+The {include_php} tag is no longer available in the standard Smarty calls.
+The use of {include_php} tags is deprecated and only available in the SmartyBC class.
+
+== php template resource ==
+The support of the php template resource is removed.
+
+== $cache_dir, $compile_dir, $config_dir, $template_dir access ==
+The mentioned properties can't be accessed directly any longer. You must use
+corresponding getter/setters like addConfigDir(), setConfigDir(), getConfigDir()
+
+== obsolete Smarty class properties ==
+The following no longer used properties are removed:
+$allow_php_tag
+$allow_php_template
+$deprecation_notices
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/library/smarty/SMARTY_3.1_NOTES.txt
@@ -0,0 +1,306 @@
+Smarty 3.1 Notes
+================
+
+Smarty 3.1 is a departure from 2.0 compatibility. Most notably, all
+backward compatibility has been moved to a separate class file named
+SmartyBC.class.php. If you require compatibility with 2.0, you will
+need to use this class.
+
+Some differences from 3.0 are also present. 3.1 begins the journey of
+requiring setters/getters for property access. So far this is only
+implemented on the five directory properties: template_dir,
+plugins_dir, configs_dir, compile_dir and cache_dir. These properties
+are now protected, it is required to use the setters/getters instead.
+That said, direct property access will still work, however slightly
+slower since they will now fall through __set() and __get() and in
+turn passed through the setter/getter methods. 3.2 will exhibit a full
+list of setter/getter methods for all (currently) public properties,
+so code-completion in your IDE will work as expected.
+
+There is absolutely no PHP allowed in templates any more. All
+deprecated features of Smarty 2.0 are gone. Again, use the SmartyBC
+class if you need any backward compatibility.
+
+Internal Changes
+
+ Full UTF-8 Compatibility
+
+The plugins shipped with Smarty 3.1 have been rewritten to fully
+support UTF-8 strings if Multibyte String is available. Without
+MBString UTF-8 cannot be handled properly. For those rare cases where
+templates themselves have to juggle encodings, the new modifiers
+to_charset and from_charset may come in handy.
+
+ Plugin API and Performance
+
+All Plugins (modifiers, functions, blocks, resources,
+default_template_handlers, etc) are now receiving the
+Smarty_Internal_Template instance, where they were supplied with the
+Smarty instance in Smarty 3.0. *. As The Smarty_Internal_Template
+mimics the behavior of Smarty, this API simplification should not
+require any changes to custom plugins.
+
+The plugins shipped with Smarty 3.1 have been rewritten for better
+performance. Most notably {html_select_date} and {html_select_time}
+have been improved vastly. Performance aside, plugins have also been
+reviewed and generalized in their API. {html_select_date} and
+{html_select_time} now share almost all available options.
+
+The escape modifier now knows the $double_encode option, which will
+prevent entities from being encoded again.
+
+The capitalize modifier now know the $lc_rest option, which makes sure
+all letters following a captial letter are lower-cased.
+
+The count_sentences modifier now accepts (.?!) as
+legitimate endings of a sentence - previously only (.) was
+accepted
+
+The new unescape modifier is there to reverse the effects of the
+escape modifier. This applies to the escape formats html, htmlall and
+entity.
+
+ default_template_handler_func
+
+The invocation of $smarty->$default_template_handler_func had to be
+altered. Instead of a Smarty_Internal_Template, the fifth argument is
+now provided with the Smarty instance. New footprint:
+
+
+/**
+ * Default Template Handler
+ *
+ * called when Smarty's file: resource is unable to load a requested file
+ *
+ * @param string $type resource type (e.g. "file", "string", "eval", "resource")
+ * @param string $name resource name (e.g. "foo/bar.tpl")
+ * @param string &$content template's content
+ * @param integer &$modified template's modification time
+ * @param Smarty $smarty Smarty instance
+ * @return string|boolean path to file or boolean true if $content and $modified
+ * have been filled, boolean false if no default template
+ * could be loaded
+ */
+function default_template_handler_func($type, $name, &$content, &$modified, Smarty $smarty) {
+ if (false) {
+ // return corrected filepath
+ return "/tmp/some/foobar.tpl";
+ } elseif (false) {
+ // return a template directly
+ $content = "the template source";
+ $modified = time();
+ return true;
+ } else {
+ // tell smarty that we failed
+ return false;
+ }
+}
+
+ Stuff done to the compiler
+
+Many performance improvements have happened internally. One notable
+improvement is that all compiled templates are now handled as PHP
+functions. This speeds up repeated templates tremendously, as each one
+calls an (in-memory) PHP function instead of performing another file
+include/scan.
+
+New Features
+
+ Template syntax
+
+ {block}..{/block}
+
+The {block} tag has a new hide option flag. It does suppress the block
+content if no corresponding child block exists.
+EXAMPLE:
+parent.tpl
+{block name=body hide} child content "{$smarty.block.child}" was
+inserted {block}
+In the above example the whole block will be suppressed if no child
+block "body" is existing.
+
+ {setfilter}..{/setfilter}
+
+The new {setfilter} block tag allows the definition of filters which
+run on variable output.
+SYNTAX:
+{setfilter filter1|filter2|filter3....}
+Smarty3 will lookup up matching filters in the following search order:
+1. varibale filter plugin in plugins_dir.
+2. a valid modifier. A modifier specification will also accept
+additional parameter like filter2:'foo'
+3. a PHP function
+{/setfilter} will turn previous filter setting off again.
+{setfilter} tags can be nested.
+EXAMPLE:
+{setfilter filter1}
+ {$foo}
+ {setfilter filter2}
+ {$bar}
+ {/setfilter}
+ {$buh}
+{/setfilter}
+{$blar}
+In the above example filter1 will run on the output of $foo, filter2
+on $bar, filter1 again on $buh and no filter on $blar.
+NOTES:
+- {$foo nofilter} will suppress the filters
+- These filters will run in addition to filters defined by
+registerFilter('variable',...), autoLoadFilter('variable',...) and
+defined default modifier.
+- {setfilter} will effect only the current template, not included
+subtemplates.
+
+ Resource API
+
+Smarty 3.1 features a new approach to resource management. The
+Smarty_Resource API allows simple, yet powerful integration of custom
+resources for templates and configuration files. It offers simple
+functions for loading data from a custom resource (e.g. database) as
+well as define new template types adhering to the special
+non-compiling (e,g, plain php) and non-compile-caching (e.g. eval:
+resource type) resources.
+
+See demo/plugins/resource.mysql.php for an example custom database
+resource.
+
+Note that old-fashioned registration of callbacks for resource
+management has been deprecated but is still possible with SmartyBC.
+
+ CacheResource API
+
+In line with the Resource API, the CacheResource API offers a more
+comfortable handling of output-cache data. With the
+Smarty_CacheResource_Custom accessing databases is made simple. With
+the introduction of Smarty_CacheResource_KeyValueStore the
+implementation of resources like memcache or APC became a no-brainer;
+simple hash-based storage systems are now supporting hierarchical
+output-caches.
+
+See demo/plugins/cacheresource.mysql.php for an example custom
+database CacheResource.
+See demo/plugins/cacheresource.memcache.php for an example custom
+memcache CacheResource using the KeyValueStore helper.
+
+Note that old-fashioned registration of $cache_handler is not possible
+anymore. As the functionality had not been ported to Smarty 3.0.x
+properly, it has been dropped from 3.1 completely.
+
+Locking facilities have been implemented to avoid concurrent cache
+generation. Enable cache locking by setting
+$smarty->cache_locking = true;
+
+ Relative Paths in Templates (File-Resource)
+
+As of Smarty 3.1 {include file="../foo.tpl"} and {include
+file="./foo.tpl"} will resolve relative to the template they're in.
+Relative paths are available with {include file="..."} and
+{extends file="..."}. As $smarty->fetch('../foo.tpl') and
+$smarty->fetch('./foo.tpl') cannot be relative to a template, an
+exception is thrown.
+
+ Addressing a specific $template_dir
+
+Smarty 3.1 introduces the $template_dir index notation.
+$smarty->fetch('[foo]bar.tpl') and {include file="[foo]bar.tpl"}
+require the template bar.tpl to be loaded from $template_dir['foo'];
+Smarty::setTemplateDir() and Smarty::addTemplateDir() offer ways to
+define indexes along with the actual directories.
+
+ Mixing Resources in extends-Resource
+
+Taking the php extends: template resource one step further, it is now
+possible to mix resources within an extends: call like
+$smarty->fetch("extends:file:foo.tpl|db:bar.tpl");
+
+To make eval: and string: resources available to the inheritance
+chain, eval:base64:TPL_STRING and eval:urlencode:TPL_STRING have been
+introduced. Supplying the base64 or urlencode flags will trigger
+decoding the TPL_STRING in with either base64_decode() or urldecode().
+
+ extends-Resource in template inheritance
+
+Template based inheritance may now inherit from php's extends:
+resource like {extends file="extends:foo.tpl|db:bar.tpl"}.
+
+ New Smarty property escape_html
+
+$smarty->escape_html = true will autoescape all template variable
+output by calling htmlspecialchars({$output}, ENT_QUOTES,
+SMARTY_RESOURCE_CHAR_SET).
+NOTE:
+This is a compile time option. If you change the setting you must make
+sure that the templates get recompiled.
+
+ New option at Smarty property compile_check
+
+The automatic recompilation of modified templates can now be
+controlled by the following settings:
+$smarty->compile_check = COMPILECHECK_OFF (false) - template files
+will not be checked
+$smarty->compile_check = COMPILECHECK_ON (true) - template files will
+always be checked
+$smarty->compile_check = COMPILECHECK_CACHEMISS - template files will
+be checked if caching is enabled and there is no existing cache file
+or it has expired
+
+ Automatic recompilation on Smarty version change
+
+Templates will now be automatically recompiled on Smarty version
+changes to avoide incompatibillities in the compiled code. Compiled
+template checked against the current setting of the SMARTY_VERSION
+constant.
+
+ default_config_handler_func()
+
+Analogous to the default_template_handler_func()
+default_config_handler_func() has been introduced.
+
+ default_plugin_handler_func()
+
+An optional default_plugin_handler_func() can be defined which gets called
+by the compiler on tags which can't be resolved internally or by plugins.
+The default_plugin_handler() can map tags to plugins on the fly.
+
+New getters/setters
+
+The following setters/getters will be part of the official
+documentation, and will be strongly recommended. Direct property
+access will still work for the foreseeable future... it will be
+transparently routed through the setters/getters, and consequently a
+bit slower.
+
+array|string getTemplateDir( [string $index] )
+replaces $smarty->template_dir; and $smarty->template_dir[$index];
+Smarty setTemplateDir( array|string $path )
+replaces $smarty->template_dir = "foo"; and $smarty->template_dir =
+array("foo", "bar");
+Smarty addTemplateDir( array|string $path, [string $index])
+replaces $smarty->template_dir[] = "bar"; and
+$smarty->template_dir[$index] = "bar";
+
+array|string getConfigDir( [string $index] )
+replaces $smarty->config_dir; and $smarty->config_dir[$index];
+Smarty setConfigDir( array|string $path )
+replaces $smarty->config_dir = "foo"; and $smarty->config_dir =
+array("foo", "bar");
+Smarty addConfigDir( array|string $path, [string $index])
+replaces $smarty->config_dir[] = "bar"; and
+$smarty->config_dir[$index] = "bar";
+
+array getPluginsDir()
+replaces $smarty->plugins_dir;
+Smarty setPluginsDir( array|string $path )
+replaces $smarty->plugins_dir = "foo";
+Smarty addPluginsDir( array|string $path )
+replaces $smarty->plugins_dir[] = "bar";
+
+string getCompileDir()
+replaces $smarty->compile_dir;
+Smarty setCompileDir( string $path )
+replaces $smarty->compile_dir = "foo";
+
+string getCacheDir()
+replaces $smarty->cache_dir;
+Smarty setCacheDir( string $path )
+replaces $smarty->cache_dir;
new file mode 100644
--- /dev/null
+++ b/library/smarty/change_log.txt
@@ -0,0 +1,2649 @@
+ ===== 3.1.27===== (18.06.2015)
+18.06.2015
+ - bugfix another update on file path normalization failed on path containing something like "/.foo/" https://github.com/smarty-php/smarty/issues/56
+
+ ===== 3.1.26===== (18.06.2015)
+18.06.2015
+ - bugfix file path normalization failed on path containing something like "/.foo/" https://github.com/smarty-php/smarty/issues/56
+
+17.06.2015
+ - bugfix calling a plugin with nocache option but no other attributes like {foo nocache} caused call to undefined function https://github.com/smarty-php/smarty/issues/55
+
+ ===== 3.1.25===== (15.06.2015)
+ 15.06.2015
+ - optimization of smarty_cachereource_keyvaluestore.php code
+
+ 14.06.2015
+ - bugfix a relative sub template path could fail if template_dir path did contain /../ https://github.com/smarty-php/smarty/issues/50
+ - optimization rework of path normalization
+ - bugfix an output tag with variable, modifier followed by an operator like {$foo|modifier+1} did fail https://github.com/smarty-php/smarty/issues/53
+
+ 13.06.2015
+ - bugfix a custom cache resource using smarty_cachereource_keyvaluestore.php did fail if php.ini mbstring.func_overload = 2 (forum topic 25568)
+
+ 11.06.2015
+ - bugfix the lexer could hang on very large quoted strings (forum topic 25570)
+
+ 08.06.2015
+ - bugfix using {$foo} as array index like $bar.{$foo} or in double quoted string like "some {$foo} thing" failed https://github.com/smarty-php/smarty/issues/49
+
+ 04.06.2015
+ - bugfix possible error message on unset() while compiling {block} tags https://github.com/smarty-php/smarty/issues/46
+
+ 01.06.2015
+ - bugfix <?xml ... ?> including template variables broken since 3.1.22 https://github.com/smarty-php/smarty/issues/47
+
+ 27.05.2015
+ - bugfix {include} with variable file name must not create by default individual cache file (since 3.1.22) https://github.com/smarty-php/smarty/issues/43
+
+ 24.05.2015
+ - bugfix if condition string 'neq' broken due to a typo https://github.com/smarty-php/smarty/issues/42
+
+ ===== 3.1.24===== (23.05.2015)
+ 23.05.2015
+ - improvement on php_handling to allow very large PHP sections, better error handling
+ - improvement allow extreme large comment sections (forum 25538)
+
+ 21.05.2015
+ - bugfix broken PHP 5.2 compatibility when compiling <?php tags https://github.com/smarty-php/smarty/issues/40
+ - bugfix named {foreach} comparison like $smarty.foreach.foobar.index > 1 did compile into wrong code https://github.com/smarty-php/smarty/issues/41
+
+ 19.05.2015
+ - bugfix compiler did overwrite existing variable value when setting the nocache attribute https://github.com/smarty-php/smarty/issues/39
+ - bugfix output filter trimwhitespace could run into the pcre.backtrack_limit on large output (code.google issue 220)
+ - bugfix compiler could run into the pcre.backtrack_limit on larger comment or {php} tag sections (forum 25538)
+
+ 18.05.2015
+ - improvement introduce shortcuts in lexer/parser rules for most frequent terms for higher
+ compilation speed
+
+ 16.05.2015
+ - bugfix {php}{/php} did work just for single lines https://github.com/smarty-php/smarty/issues/33
+ - improvement remove not needed ?><?php transitions from compiled code
+ - improvement reduce number of lexer tokens on operators and if conditions
+ - improvement higher compilation speed by modified lexer/parser generator at "smarty/smarty-lexer"
+
+ 13.05.2015
+ - improvement remove not needed ?><?php transitions from compiled code
+ - improvement of debugging:
+ - use fresh Smarty object to display the debug console because of possible problems when the Smarty
+ was extended or Smarty properties had been modified in the class source
+ - display Smarty version number
+ - Truncate lenght of Origin display and extend strin value display to 80 character
+ - bugfix in Smarty_Security 'nl2br' should be a trusted modifier, not PHP function (code.google issue 223)
+
+ 12.05.2015
+ - bugfix {$smarty.constant.TEST} did fail on undefined constant https://github.com/smarty-php/smarty/issues/28
+ - bugfix access to undefined config variable like {#undef#} did fail https://github.com/smarty-php/smarty/issues/29
+ - bugfix in nested {foreach} saved item attributes got overwritten https://github.com/smarty-php/smarty/issues/33
+
+ ===== 3.1.23 ===== (12.05.2015)
+ 12.05.2015
+ - bugfix of smaller performance issue introduce in 3.1.22 when caching is enabled
+ - bugfix missig entry for smarty-temmplate-config in autoloader
+
+ ===== 3.1.22 ===== tag was deleted because 3.1.22 did fail caused by the missing entry for smarty-temmplate-config in autoloader
+ 10.05.2015
+ - bugfix custom cache resource did not observe compile_id and cache_id when $cache_locking == true
+ - bugfix cache lock was not handled correctly after timeout when $cache_locking == true
+ - improvement added constants for $debugging
+
+ 07.05.2015
+ - improvement of the debugging console. Read NEW_FEATURES.txt
+ - optimization of resource class loading
+
+ 06.05.2015
+ - bugfix in 3.1.22-dev cache resource must not be loaded for subtemplates
+ - bugfix/improvement in 3.1.22-dev cache locking did not work as expected
+
+ 05.05.2015
+ - optimization on cache update when main template is modified
+ - optimization move <?php ?> handling from parser to new compiler module
+
+ 05.05.2015
+ - bugfix code could be messed up when {tags} are used in multiple attributes https://github.com/smarty-php/smarty/issues/23
+
+ 04.05.2015
+ - bugfix Smarty_Resource::parseResourceName incompatible with Google AppEngine (https://github.com/smarty-php/smarty/issues/22)
+ - improvement use is_file() checks to avoid errors suppressed by @ which could still cause problems (https://github.com/smarty-php/smarty/issues/24)
+
+ 28.04.2015
+ - bugfix plugins of merged subtemplates not loaded in 3.1.22-dev (forum topic 25508) 2nd fix
+
+ 28.04.2015
+ - bugfix plugins of merged subtemplates not loaded in 3.1.22-dev (forum topic 25508)
+
+ 23.04.2015
+ - bugfix a nocache template variable used as parameter at {insert} was by mistake cached
+
+ 20.04.2015
+ - bugfix at a template function containing nocache code a parmeter could overwrite a template variable of same name
+
+ 27.03.2015
+ - bugfix Smarty_Security->allow_constants=false; did also disable true, false and null (change of 16.03.2015)
+ - improvement added a whitelist for trusted constants to security Smarty_Security::$trusted_constants (forum topic 25471)
+
+ 20.03.2015
+ - bugfix make sure that function properties get saved only in compiled files containing the fuction definition {forum topic 25452}
+ - bugfix correct update of global variable values on exit of template functions. (reported under Smarty Developers)
+
+ 16.03.2015
+ - bugfix problems with {function}{/function} and {call} tags in different subtemplate cache files {forum topic 25452}
+ - bugfix Smarty_Security->allow_constants=false; did not disallow direct usage of defined constants like {SMARTY_DIR} {forum topic 25457}
+ - bugfix {block}{/block} tags did not work inside double quoted strings https://github.com/smarty-php/smarty/issues/18
+
+
+ 15.03.2015
+ - bugfix $smarty->compile_check must be restored before rendering of a just updated cache file {forum 25452}
+
+ 14.03.2015
+ - bugfix {nocache} {/nocache} tags corrupted code when used within a nocache section caused by a nocache template variable.
+
+ - bugfix template functions defined with {function} in an included subtemplate could not be called in nocache
+ mode with {call... nocache} if the subtemplate had it's own cache file {forum 25452}
+
+ 10.03.2015
+ - bugfix {include ... nocache} whith variable file or compile_id attribute was not executed in nocache mode.
+
+ 12.02.2015
+ - bugfix multiple Smarty::fetch() of same template when $smarty->merge_compiled_includes = true; could cause function already defined error
+
+ 11.02.2015
+ - bugfix recursive {includes} did create E_NOTICE message when $smarty->merge_compiled_includes = true; (github issue #16)
+
+ 22.01.2015
+ - new feature security can now control access to static methods and properties
+ see also NEW_FEATURES.txt
+
+ 21.01.2015
+ - bugfix clearCompiledTemplates(), clearAll() and clear() could try to delete whole drive at wrong path permissions because realpath() fail (forum 25397)
+ - bugfix 'self::' and 'parent::' was interpreted in template syntax as static class
+
+ 04.01.2015
+ - push last weeks changes to github
+
+ - different optimizations
+ - improvement automatically create different versions of compiled templates and config files depending
+ on property settings.
+ - optimization restructure template processing by moving code into classes it better belongs to
+ - optimization restructure config file processing
+
+ 31.12.2014
+ - bugfix use function_exists('mb_get_info') for setting Smarty::$_MBSTRING.
+ Function mb_split could be overloaded depending on php.ini mbstring.func_overload
+
+
+ 29.12.2014
+ - new feature security can now limit the template nesting level by property $max_template_nesting
+ see also NEW_FEATURES.txt (forum 25370)
+
+ 29.12.2014
+ - new feature security can now disable special $smarty variables listed in property $disabled_special_smarty_vars
+ see also NEW_FEATURES.txt (forum 25370)
+
+ 27.12.2014
+ - bugfix clear internal _is_file_cache when plugins_dir was modified
+
+ 13.12.2014
+ - improvement optimization of lexer and parser resulting in a up to 30% higher compiling speed
+
+ 11.12.2014
+ - bugfix resolve parser ambiguity between constant print tag {CONST} and other smarty tags after change of 09.12.2014
+
+ 09.12.2014
+ - bugfix variables $null, $true and $false did not work after the change of 12.11.2014 (forum 25342)
+ - bugfix call of template function by a variable name did not work after latest changes (forum 25342)
+
+ 23.11.2014
+ - bugfix a plugin with attached modifier could fail if the tag was immediately followed by another Smarty tag (since 3.1.21) (forum 25326)
+
+ 13.11.2014
+ - improvement move autoload code into Autoloader.php. Use Composer autoloader when possible
+
+ 12.11.2014
+ - new feature added support of namespaces to template code
+
+ 08.11.2014 - 10.11.2014
+ - bugfix subtemplate called in nocache mode could be called with wrong compile_id when it did change on one of the calling templates
+ - improvement add code of template functions called in nocache mode dynamically to cache file (related to bugfix of 01.11.2014)
+ - bugfix Debug Console did not include all data from merged compiled subtemplates
+
+ 04.11.2014
+ - new feature $smarty->debug = true; => overwrite existing Debug Console window (old behaviour)
+ $smarty->debug = 2; => individual Debug Console window by template name
+
+ 03.11.2014
+ - bugfix Debug Console did not show included subtemplates since 3.1.17 (forum 25301)
+ - bugfix Modifier debug_print_var did not limit recursion or prevent recursive object display at Debug Console
+ (ATTENTION: parameter order has changed to be able to specify maximum recursion)
+ - bugfix Debug consol did not include subtemplate information with $smarty->merge_compiled_includes = true
+ - improvement The template variables are no longer displayed as objects on the Debug Console
+ - improvement $smarty->createData($parent = null, $name = null) new optional name parameter for display at Debug Console
+ - addition of some hooks for future extension of Debug Console
+
+ 01.11.2014
+ - bugfix and enhancement on subtemplate {include} and template {function} tags.
+ * Calling a template which has a nocache section could fail if it was called from a cached and a not cached subtemplate.
+ * Calling the same subtemplate cached and not cached with the $smarty->merge_compiled_includes enabled could cause problems
+ * Many smaller related changes
+
+ 30.10.2014
+ - bugfix access to class constant by object like {$object::CONST} or variable class name {$class::CONST} did not work (forum 25301)
+
+ 26.10.2014
+ - bugfix E_NOTICE message was created during compilation when ASP tags '<%' or '%>' are in template source text
+ - bugfix merge_compiled_includes option failed when caching enables and same subtemplate was included cached and not cached
+
+ ===== 3.1.21 ===== (18.10.2014)
+ 18.10.2014
+ - composer moved to github
+
+ 17.10.2014
+ - bugfix on $php_handling security and optimization of smarty_internal_parsetree (Thue Kristensen)
+
+ 16.10.2014
+ - bugfix composer.json update
+
+ 15.10.2014
+ - bugfix calling a new created cache file with fetch() and Smarty::CACHING_LIFETIME_SAVED multiple times did fail (forum 22350)
+
+ 14.10.2014
+ - bugfix any tag placed within "<script language=php>" will throw a security exception to close all thinkable holes
+ - bugfix classmap in root composer.json should start at "libs/..."
+ - improvement cache is_file(file_exists) results of loadPlugin() to avoid unnecessary calls during compilation (Issue 201}
+
+ 12.10.2014
+ - bugfix a comment like "<script{*foo*} language=php>" bypassed $php_handling checking (Thue Kristensen)
+ - bugfix change of 08.10.2014 could create E_NOTICE meassage when using "<?php" tags
+ - bugfix "<script language=php>" with $php_handling PHP_PASSTHRU was executed in {nocache} sections
+
+ ===== 3.1.20 ===== (09.10.2014)
+ 08.10.2014
+ - bugfix security mode of "<script language=php>" must be controlled by $php_handling property (Thue Kristensen)
+
+ 01.10.2014
+ - bugfix template resource of inheritance blocks could get invalid if the default resource type is not 'file'(Issue 202)
+ - bugfix existing child {block} tag must override parent {block} tag append / prepend setting (topic 25259)
+
+ 02.08.2014
+ - bugfix modifier wordwrap did output break string wrong if first word was exceeding length with cut = true (topic 25193)
+
+ 24.07.2014
+ - bugfix cache clear when cache folder does not exist
+
+ 16.07.2014
+ - enhancement remove BOM automatically from template source (topic 25161)
+
+ 04.07.2014
+ - bugfix the bufix of 02.06.2014 broke correct handling of child templates with same name but different template folders in extends resource (issue 194 and topic 25099)
+
+ ===== 3.1.19 ===== (30.06.2014)
+ 20.06.2014
+ - bugfix template variables could not be passed as parameter in {include} when the include was in a {nocache} section (topic 25131)
+
+ 17.06.2014
+ - bugfix large template text of some charsets could cause parsing errors (topic 24630)
+
+ 08.06.2014
+ - bugfix registered objects did not work after spelling fixes of 06.06.2014
+ - bugfix {block} tags within {literal} .. {/literal} got not displayed correctly (topic 25024)
+ - bugfix UNC WINDOWS PATH like "\\psf\path\to\dir" did not work as template directory (Issue 192)
+ - bugfix {html_image} security check did fail on files relative to basedir (Issue 191)
+
+ 06.06.2014
+ - fixed PHPUnit outputFilterTrimWhitespaceTests.php assertion of test result
+ - fixed spelling, PHPDoc , minor errors, code cleanup
+
+ 02.06.2014
+ - using multiple cwd with relative template dirs could result in identical compiled file names. (issue 194 and topic 25099)
+
+ 19.04.2014
+ - bugfix calling createTemplate(template, data) with empty data array caused notice of array to string conversion (Issue 189)
+ - bugfix clearCompiledTemplate() did not delete files on WINDOWS when a compile_id was specified
+
+ 18.04.2014
+ - revert bugfix of 5.4.2014 because %-e date format is not supported on all operating systems
+
+ ===== 3.1.18 ===== (07.04.2014)
+ 06.04.2014
+ - bugfix template inheritance fail when using custom resource after patch of 8.3.2014 (Issue 187)
+ - bugfix update of composer file (Issue 168 and 184)
+
+ 05.04.2014
+ - bugfix default date format leads to extra spaces when displaying dates with single digit days (Issue 165)
+
+ 26.03.2014
+ - bugfix Smart_Resource_Custom should not lowercase the resource name (Issue 183)
+
+ 24.03.2014
+ - bugfix using a {foreach} property like @iteration could fail when used in inheritance parent templates (Issue 182)
+
+ 20.03.2014
+ - bugfix $smarty->auto_literal and mbsting.func_overload 2, 6 or 7 did fail (forum topic 24899)
+
+ 18.03.2014
+ - revert change of 17.03.2014
+
+17.03.2014
+ - bugfix $smarty->auto_literal and mbsting.func_overload 2, 6 or 7 did fail (forum topic 24899)
+
+ 15.03.2014
+ - bugfix Smarty_CacheResource_Keyvaluestore did use different keys on read/writes and clearCache() calls (Issue 169)
+
+ 13.03.2014
+ - bugfix clearXxx() change of 27.1.2014 did not work when specifing cache_id or compile_id (forum topic 24868 and 24867)
+
+ ===== 3.1.17 =====
+ 08.03.2014
+ - bugfix relative file path {include} within {block} of child templates did throw exception on first call (Issue 177)
+
+ 17.02.2014
+ - bugfix Smarty failed when executing PHP on HHVM (Hip Hop 2.4) because uniqid('',true) does return string with ',' (forum topic 20343)
+
+ 16.02.2014
+ - bugfix a '//' or '\\' in template_dir path could produce wrong path on relative filepath in {include} (Issue 175)
+
+ 05.02.2014
+ - bugfix shared.literal_compiler_param.php did throw an exception when literal did contain a '-' (smarty-developers group)
+
+ 27.01.2014
+ - bugfix $smarty->debugging = true; did show the variable of the $smarty object not the variables used in display() call (forum topic 24764)
+ - bugfix clearCompiledTemplate(), clearAll() and clear() should use realpath to avoid possible exception from RecursiveDirectoryIterator (Issue 171)
+
+ 26.01.2014
+ - bugfix undo block nesting checks for {nocache} for reasons like forum topic 23280 (forum topic 24762)
+
+ 18.01.2014
+ - bugfix the compiler did fail when using template inheritance and recursive {include} (smarty-developers group)
+
+ 11.01.2014
+ - bugfix "* }" (spaces before right delimiter) was interpreted by mistake as comment end tag (Issue 170)
+ - internals content cache should be clear when updating cache file
+
+ 08.01.2014
+ - bugfix Smarty_CacheResource_Custom did not handle template resource type specifications on clearCache() calls (Issue 169)
+ - bugfix SmartyBC.class.php should use require_once to load Smarty.class.php (forum topic 24683)
+
+ ===== 3.1.16 =====
+ 15.12.2013
+ - bugfix {include} with {block} tag handling (forum topic 24599, 24594, 24682) (Issue 161)
+ Read 3.1.16_RELEASE_NOTES for more details
+ - enhancement additional debug output at $smarty->_parserdebug = true;
+
+ 07.11.2013
+ - bugfix too restrictive handling of {include} within {block} tags. 3.1.15 did throw errors where 3.1.14 did not (forum topic 24599)
+ - bugfix compiler could fail if PHP mbstring.func_overload is enabled (Issue 164)
+
+ 28.10.2013
+ - bugfix variable resource name at custom resource plugin did not work within {block} tags (Issue 163)
+ - bugfix notice "Trying to get property of non-object" removed (Issue 163)
+ - bugfix correction of modifier capitalize fix from 3.10.2013 (issue 159)
+ - bugfix multiple {block}s with same name in parent did not work (forum topic 24631)
+
+ 20.10.2013
+ - bugfix a variable file name at {extends} tag did fail (forum topic 24618)
+
+ 14.10.2013
+ - bugfix yesterdays fix could result in an undefined variable
+
+ 13.10.2013
+ - bugfix variable names on {include} in template inheritance did unextepted error message (forum topic 24594) (Issue 161)
+.- bugfix relative includes with same name like {include './foo.tpl'} from different folder failed (forum topic 24590)(Issue 161)
+
+ 04.10.2013
+ - bugfix variable file names at {extends} had been disbabled by mistake with the rewrite of
+ template inheritance of 24.08.2013 (forum topic 24585)
+
+03.10.2013
+ - bugfix loops using modifier capitalize did eat up memory (issue 159)
+
+ ===== Smarty 3.1.15 =====
+01.10.2013
+ - use current delimiters in compiler error messages (issue 157)
+ - improvement on performance when using error handler and multiple template folders (issue 152)
+
+17.09.2013
+ - improvement added patch for additional SmartyCompilerException properties for better access to scource information (forum topic 24559)
+
+16.09.2013
+ - bugfix recompiled templates did not show on first request with zend opcache cache (forum topic 24320)
+
+13.09.2013
+ - bugfix html_select_time defaulting error for the Meridian dropdown (forum topic 24549)
+
+09.09.2012
+- bugfix incorrect compiled code with array(object,method) callback at registered Variable Filter (forum topic 24542)
+
+27.08.2013
+- bugfix delimiter followed by linebreak did not work as auto literal after update from 24.08.2013 (forum topic 24518)
+
+24.08.2013
+- bugfix and enhancement
+ Because several recent problems with template inheritance the {block} tag compiler has been rewriten
+ - Error messages shown now the correct child template file and line number
+ - The compiler could fail on some larger UTF-8 text block (forum topic 24455)
+ - The {strip} tag can now be placed outside {block} tags in child templates (forum topic 24289)
+- change SmartyException::$escape is now false by default
+- change PHP traceback has been remove for SmartyException and SmartyCompilerException
+
+14.08.2013
+- bugfix compiled filepath of config file did not observe different config_dir (forum topic 24493)
+
+13.08.2013
+- bugfix the internal resource cache did not observe config_dir changes (forum topic 24493)
+
+12.08.2013
+- bugfix internal $tmpx variables must be unique over all inheritance templates (Issue 149)
+
+10.08.2013
+- bugfix a newline was eaten when a <?xml ... ?> was passed by a Smarty variable and caching was enabled (forum topic 24482)
+
+29.07.2013
+- bugfix headers already send warning thrown when using 'SMARTY_DEBUG=on' from URL (Issue 148)
+
+27.07.2013
+- enhancement allow access to properties of registered opjects for Smarty2 BC (forum topic 24344)
+
+26.07.2013
+- bugfix template inheritance nesting problem (forum topic 24387)
+
+15.7.2013
+- update code generated by PSR-2 standards fixer which introduced PHP 5.4 incompatibilities of 14.7.2013
+
+14.7.2013
+- bugfix increase of internal maximum parser stacksize to allow more complex tag code {forum topic 24426}
+- update for PHP 5.4 compatibility
+- reformat source to PSR-2 standard
+
+12.7.2013
+- bugfix Do not remove '//' from file path at normalization (Issue 142)
+
+2.7.2013
+- bugfix trimwhitespace would replace captured items in wrong order (forum topic 24387)
+
+===== Smarty-3.1.14 =====
+27.06.2013
+- bugfix removed PHP 5.5 deprecated preg_replace /e option in modifier capitalize (forum topic 24389)
+
+17.06.2013
+- fixed spelling in sources and documentation (from smarty-developers forum Veres Lajos)
+- enhancement added constant SMARTY::CLEAR_EXPIRED for the change of 26.05.2013 (forum topic 24310)
+- bugfix added smarty_security.php to composer.json (Issue 135)
+
+26.05.2013
+- enhancement an expire_time of -1 in clearCache() and clearAllCache() will delete outdated cache files
+ by their individual cache_lifetime used at creation (forum topic 24310)
+
+21.05.2013
+- bugfix modifier strip_tags:true was compiled into wrong code (Forum Topic 24287)
+- bugfix /n after ?> in Smarty.class.php did start output buffering (Issue 138)
+
+25.04.2013
+- bugfix escape and wordrap modifier could be compiled into wrong code when used in {nocache}{/nocache}
+ section but caching is disabled (Forum Topic 24260)
+
+05.04.2013
+- bugfix post filter must not run when compiling inheritance child blocks (Forum Topic 24094)
+- bugfix after the fix for Issue #130 compiler exceptions got double escaped (Forum Topic 24199)
+
+28.02.2013
+- bugfix nocache blocks could be lost when using CACHING_LIFETIME_SAVED (Issue #133)
+- bugfix Compile ID gets nulled when compiling child blocks (Issue #134)
+
+
+24.01.2013
+- bugfix wrong tag type in smarty_internal_templatecompilerbase.php could cause wrong plugin search order (Forum Topic 24028)
+
+===== Smarty-3.1.13 =====
+13.01.2013
+- enhancement allow to disable exception message escaping by SmartyException::$escape = false; (Issue #130)
+
+09.01.2013
+- bugfix compilation did fail when a prefilter did modify an {extends} tag c
+- bugfix template inheritance could fail if nested {block} tags in childs did contain {$smarty.block.child} (Issue #127)
+- bugfix template inheritance could fail if {block} tags in childs did have similar name as used plugins (Issue #128)
+- added abstract method declaration doCompile() in Smarty_Internal_TemplateCompilerBase (Forum Topic 23969)
+
+06.01.2013
+- Allow '://' URL syntax in template names of stream resources (Issue #129)
+
+27.11.2012
+- bugfix wrong variable usage in smarty_internal_utility.php (Issue #125)
+
+26.11.2012
+- bugfix global variable assigned within template function are not seen after template function exit (Forum Topic 23800)
+
+24.11.2012
+- made SmartyBC loadable via composer (Issue #124)
+
+20.11.2012
+- bugfix assignGlobal() called from plugins did not work (Forum Topic 23771)
+
+13.11.2012
+- adding attribute "strict" to html_options, html_checkboxes, html_radios to only print disabled/readonly attributes if their values are true or "disabled"/"readonly" (Issue #120)
+
+01.11.2012
+- bugfix muteExcpetedErrors() would screw up for non-readable paths (Issue #118)
+
+===== Smarty-3.1.12 =====
+14.09.2012
+- bugfix template inheritance failed to compile with delimiters {/ and /} (Forum Topic 23008)
+
+11.09.2012
+- bugfix escape Smarty exception messages to avoid possible script execution
+
+10.09.2012
+- bugfix tag option flags and shorttag attributes did not work when rdel started with '=' (Forum Topic 22979)
+
+31.08.2012
+- bugfix resolving relative paths broke in some circumstances (Issue #114)
+
+22.08.2012
+- bugfix test MBString availability through mb_split, as it could've been compiled without regex support (--enable-mbregex).
+ Either we get MBstring's full package, or we pretend it's not there at all.
+
+21.08.2012
+- bugfix $auto_literal = false did not work with { block} tags in child templates
+ (problem was reintroduced after fix in 3.1.7)(Forum Topic 20581)
+
+17.08.2012
+- bugfix compiled code of nocache sections could contain wrong escaping (Forum Topic 22810)
+
+15.08.2012
+- bugfix template inheritance did produce wrong code if subtemplates with {block} was
+ included several times (from smarty-developers forum)
+
+14.08.2012
+- bugfix PHP5.2 compatibility compromised by SplFileInfo::getBasename() (Issue 110)
+
+01.08.2012
+- bugfix avoid PHP error on $smarty->configLoad(...) with invalid section specification (Forum Topic 22608)
+
+30.07.2012
+-bugfix {assign} in a nocache section should not overwrite existing variable values
+ during compilation (issue 109)
+
+28.07.2012
+- bugfix array access of config variables did not work (Forum Topic 22527)
+
+19.07.2012
+- bugfix the default plugin handler did create wrong compiled code for static class methods
+ from external script files (issue 108)
+
+===== Smarty-3.1.11 =====
+30.06.2012
+- bugfix {block.. hide} did not work as nested child (Forum Topic 22216)
+
+25.06.2012
+- bugfix the default plugin handler did not allow static class methods for modifier (issue 85)
+
+24.06.2012
+- bugfix escape modifier support for PHP < 5.2.3 (Forum Topic 21176)
+
+11.06.2012
+- bugfix the patch for Topic 21856 did break tabs between tag attributes (Forum Topic 22124)
+
+===== Smarty-3.1.10 =====
+09.06.2012
+- bugfix the compiler did ignore registered compiler plugins for closing tags (Forum Topic 22094)
+- bugfix the patch for Topic 21856 did break multiline tags (Forum Topic 22124)
+
+===== Smarty-3.1.9 =====
+07.06.2012
+- bugfix fetch() and display() with relative paths (Issue 104)
+- bugfix treat "0000-00-00" as 0 in modifier.date_format (Issue 103)
+
+24.05.2012
+- bugfix Smarty_Internal_Write_File::writeFile() could cause race-conditions on linux systems (Issue 101)
+- bugfix attribute parameter names of plugins may now contain also "-" and ":" (Forum Topic 21856)
+- bugfix add compile_id to cache key of of source (Issue 97)
+
+22.05.2012
+- bugfix recursive {include} within {section} did fail (Smarty developer group)
+
+12.05.2012
+- bugfix {html_options} did not properly escape values (Issue 98)
+
+03.05.2012
+- bugfix make HTTP protocall version variable (issue 96)
+
+02.05.2012
+- bugfix {nocache}{block}{plugin}... did produce wrong compiled code when caching is disabled (Forum Topic 21572, issue 95)
+
+12.04.2012
+- bugfix Smarty did eat the linebreak after the <?xml...?> closing tag (Issue 93)
+- bugfix concurrent cache updates could create a warning (Forum Topic 21403)
+
+08.04.2012
+- bugfix "\\" was not escaped correctly when generating nocache code (Forum Topic 21364)
+
+30.03.2012
+- bugfix template inheritance did not throw exception when a parent template was deleted (issue 90)
+
+27.03.2012
+- bugfix prefilter did run multiple times on inline subtemplates compiled into several main templates (Forum Topic 21325)
+- bugfix implement Smarty2's behaviour of variables assigned by reference in SmartyBC. {assign} will affect all references.
+ (issue 88)
+
+21.03.2012
+- bugfix compileAllTemplates() and compileAllConfig() did not return the number of compiled files (Forum Topic 21286)
+
+13.03.2012
+- correction of yesterdays bugfix (Forum Topic 21175 and 21182)
+
+12.03.2012
+- bugfix a double quoted string of "$foo" did not compile into PHP "$foo" (Forum Topic 21175)
+- bugfix template inheritance did set $merge_compiled_includes globally true
+
+03.03.2012
+- optimization of compiling speed when same modifier was used several times
+
+02.03.2012
+- enhancement the default plugin handler can now also resolve undefined modifier (Smarty::PLUGIN_MODIFIER)
+ (Issue 85)
+
+===== Smarty-3.1.8 =====
+19.02.2012
+- bugfix {include} could result in a fatal error if used in appended or prepended nested {block} tags
+ (reported by mh and Issue 83)
+- enhancement added Smarty special variable $smarty.template_object to return the current template object (Forum Topic 20289)
+
+
+07.02.2012
+- bugfix increase entropy of internal function names in compiled and cached template files (Forum Topic 20996)
+- enhancement cacheable parameter added to default plugin handler, same functionality as in registerPlugin (request by calguy1000)
+
+06.02.2012
+- improvement stream_resolve_include_path() added to Smarty_Internal_Get_Include_Path (Forum Topic 20980)
+- bugfix fetch('extends:foo.tpl') always yielded $source->exists == true (Forum Topic 20980)
+- added modifier unescape:"url", fix (Forum Topic 20980)
+- improvement replaced some calls of preg_replace with str_replace (Issue 73)
+
+30.01.2012
+- bugfix Smarty_Security internal $_resource_dir cache wasn't properly propagated
+
+27.01.2012
+- bugfix Smarty did not a template name of "0" (Forum Topic 20895)
+
+20.01.2012
+- bugfix typo in Smarty_Internal_Get_IncludePath did cause runtime overhead (Issue 74)
+- improvment remove unneeded assigments (Issue 75 and 76)
+- fixed typo in template parser
+- bugfix output filter must not run before writing cache when template does contain nocache code (Issue 71)
+
+02.01.2012
+- bugfix {block foo nocache} did not load plugins within child {block} in nocache mode (Forum Topic 20753)
+
+29.12.2011
+- bugfix enable more entropy in Smarty_Internal_Write_File for "more uniqueness" and Cygwin compatibility (Forum Topic 20724)
+- bugfix embedded quotes in single quoted strings did not compile correctly in {nocache} sections (Forum Topic 20730)
+
+28.12.2011
+- bugfix Smarty's internal header code must be excluded from postfilters (issue 71)
+
+22.12.2011
+- bugfix the new lexer of 17.12.2011 did fail if mbstring.func_overload != 0 (issue 70) (Forum Topic 20680)
+- bugfix template inheritace did fail if mbstring.func_overload != 0 (issue 70) (Forum Topic 20680)
+
+20.12.2011
+- bugfix template inheritance: {$smarty.block.child} in nested child {block} tags did not return
+ content after {$smarty.block.child} (Forum Topic 20564)
+
+===== Smarty-3.1.7 =====
+18.12.2011
+- bugfix strings ending with " in multiline strings of config files failed to compile (issue #67)
+- added chaining to Smarty_Internal_Templatebase
+- changed unloadFilter() to not return a boolean in favor of chaining and API conformity
+- bugfix unregisterObject() raised notice when object to unregister did not exist
+- changed internals to use Smarty::$_MBSTRING ($_CHARSET, $_DATE_FORMAT) for better unit testing
+- added Smarty::$_UTF8_MODIFIER for proper PCRE charset handling (Forum Topic 20452)
+- added Smarty_Security::isTrustedUri() and Smarty_Security::$trusted_uri to validate
+ remote resource calls through {fetch} and {html_image} (Forum Topic 20627)
+
+17.12.2011
+- improvement of compiling speed by new handling of plain text blocks in the lexer/parser (issue #68)
+
+16.12.2011
+- bugfix the source exits flag and timestamp was not setup when template was in php include path (issue #69)
+
+9.12.2011
+- bugfix {capture} tags around recursive {include} calls did throw exception (Forum Topic 20549)
+- bugfix $auto_literal = false did not work with { block} tags in child templates (Forum Topic 20581)
+- bugfix template inheritance: do not include code of {include} in overloaded {block} into compiled
+ parent template (Issue #66}
+- bugfix template inheritance: {$smarty.block.child} in nested child {block} tags did not return expected
+ result (Forum Topic 20564)
+
+===== Smarty-3.1.6 =====
+30.11.2011
+- bugfix is_cache() for individual cached subtemplates with $smarty->caching = CACHING_OFF did produce
+ an exception (Forum Topic 20531)
+
+29.11.2011
+- bugfix added exception if the default plugin handler did return a not static callback (Forum Topic 20512)
+
+25.11.2011
+- bugfix {html_select_date} and {html_slecet_time} did not default to current time if "time" was not specified
+ since r4432 (issue 60)
+
+24.11.2011
+- bugfix a subtemplate later used as main template did use old variable values
+
+21.11.2011
+- bugfix cache file could include unneeded modifier plugins under certain condition
+
+18.11.2011
+- bugfix declare all directory properties private to map direct access to getter/setter also on extended Smarty class
+
+16.11.2011
+- bugfix Smarty_Resource::load() did not always return a proper resource handler (Forum Topic 20414)
+- added escape argument to html_checkboxes and html_radios (Forum Topic 20425)
+
+===== Smarty-3.1.5 =====
+14.11.2011
+- bugfix allow space between function name and open bracket (forum topic 20375)
+
+09.11.2011
+- bugfix different behaviour of uniqid() on cygwin. See https://bugs.php.net/bug.php?id=34908
+ (forum topic 20343)
+
+01.11.2011
+- bugfix {if} and {while} tags without condition did not throw a SmartyCompilerException (Issue #57)
+- bugfix multiline strings in config files could fail on longer strings (reopened Issue #55)
+
+22.10.2011
+- bugfix smarty_mb_from_unicode() would not decode unicode-points properly
+- bugfix use catch Exception instead UnexpectedValueException in
+ clearCompiledTemplate to be PHP 5.2 compatible
+
+21.10.2011
+- bugfix apostrophe in plugins_dir path name failed (forum topic 20199)
+- improvement sha1() for array keys longer than 150 characters
+- add Smarty::$allow_ambiguous_resources to activate unique resource handling (Forum Topic 20128)
+
+20.10.2011
+- @silenced unlink() in Smarty_Internal_Write_File since debuggers go haywire without it.
+- bugfix Smarty::clearCompiledTemplate() threw an Exception if $cache_id was not present in $compile_dir when $use_sub_dirs = true.
+- bugfix {html_select_date} and {html_select_time} did not properly handle empty time arguments (Forum Topic 20190)
+- improvement removed unnecessary sha1()
+
+19.10.2011
+- revert PHP4 constructor message
+- fixed PHP4 constructor message
+
+===== Smarty-3.1.4 =====
+19.10.2011
+- added exception when using PHP4 style constructor
+
+16.10.2011
+- bugfix testInstall() did not propery check cache_dir and compile_dir
+
+15.10.2011
+- bugfix Smarty_Resource and Smarty_CacheResource runtime caching (Forum Post 75264)
+
+14.10.2011
+- bugfix unique_resource did not properly apply to compiled resources (Forum Topic 20128)
+- add locking to custom resources (Forum Post 75252)
+- add Smarty_Internal_Template::clearCache() to accompany isCached() fetch() etc.
+
+13.10.2011
+- add caching for config files in Smarty_Resource
+- bugfix disable of caching after isCached() call did not work (Forum Topic 20131)
+- add concept unique_resource to combat potentially ambiguous template_resource values when custom resource handlers are used (Forum Topic 20128)
+- bugfix multiline strings in config files could fail on longer strings (Issue #55)
+
+11.10.2011
+- add runtime checks for not matching {capture}/{/capture} calls (Forum Topic 20120)
+
+10.10.2011
+- bugfix variable name typo in {html_options} and {html_checkboxes} (Issue #54)
+- bugfix <?xml> tag did create wrong output when caching enabled and the tag was in included subtemplate
+- bugfix Smarty_CacheResource_mysql example was missing strtotime() calls
+
+===== Smarty-3.1.3 =====
+07.10.2011
+- improvement removed html comments from {mailto} (Forum Topic 20092)
+- bugfix testInstall() would not show path to internal plugins_dir (Forum Post 74627)
+- improvement testInstall() now showing resolved paths and checking the include_path if necessary
+- bugfix html_options plugin did not handle object values properly (Issue #49, Forum Topic 20049)
+- improvement html_checkboxes and html_radios to accept null- and object values, and label_ids attribute
+- improvement removed some unnecessary count()s
+- bugfix parent pointer was not set when fetch() for other template was called on template object
+
+06.10.2011
+- bugfix switch lexer internals depending on mbstring.func_overload
+- bugfix start_year and end_year of {html_select_date} did not use current year as offset base (Issue #53)
+
+05.10.2011
+- bugfix of problem introduced with r4342 by replacing strlen() with isset()
+- add environment configuration issue with mbstring.func_overload Smarty cannot compensate for (Issue #45)
+- bugfix nofilter tag option did not disable default modifier
+- bugfix html_options plugin did not handle null- and object values properly (Issue #49, Forum Topic 20049)
+
+04.10.2011
+- bugfix assign() in plugins called in subtemplates did change value also in parent template
+- bugfix of problem introduced with r4342 on math plugin
+- bugfix output filter should not run on individually cached subtemplates
+- add unloadFilter() method
+- bugfix has_nocache_code flag was not reset before compilation
+
+===== Smarty-3.1.2 =====
+03.10.2011
+- improvement add internal $joined_template_dir property instead computing it on the fly several times
+
+01.10.2011
+- improvement replaced most in_array() calls by more efficient isset() on array_flip()ed haystacks
+- improvement replaced some strlen($foo) > 3 calls by isset($foo[3])
+- improvement Smarty_Internal_Utility::clearCompiledTemplate() removed redundant strlen()s
+
+29.09.2011
+- improvement of Smarty_Internal_Config::loadConfigVars() dropped the in_array for index look up
+
+28.09.2011
+- bugfix on template functions called nocache calling other template functions
+
+27.09.2011
+- bugfix possible warning "attempt to modify property of non-object" in {section} (issue #34)
+- added chaining to Smarty_Internal_Data so $smarty->assign('a',1)->assign('b',2); is possible now
+- bugfix remove race condition when a custom resource did change timestamp during compilation
+- bugfix variable property did not work on objects variable in template
+- bugfix smarty_make_timestamp() failed to process DateTime objects properly
+- bugfix wrong resource could be used on compile check of custom resource
+
+26.09.2011
+- bugfix repeated calls to same subtemplate did not make use of cached template object
+
+24.09.2011
+- removed internal muteExpectedErrors() calls in favor of having the implementor call this once from his application
+- optimized muteExpectedErrors() to pass errors to the latest registered error handler, if appliccable
+- added compile_dir and cache_dir to list of muted directories
+- improvment better error message for undefined templates at {include}
+
+23.09.2011
+- remove unused properties
+- optimization use real function instead anonymous function for preg_replace_callback
+- bugfix a relative {include} in child template blocks failed
+- bugfix direct setting of $template_dir, $config_dir, $plugins_dir in __construct() of an
+ extended Smarty class created problems
+- bugfix error muting was not implemented for cache locking
+
+===== Smarty 3.1.1 =====
+22.09.2011
+- bugfix {foreachelse} does fail if {section} was nested inside {foreach}
+- bugfix debug.tpl did not display correctly when it was compiled with escape_html = true
+
+21.09.2011
+- bugfix look for mixed case plugin file names as in 3.0 if not found try all lowercase
+- added $error_muting to suppress error messages even for badly implemented error_handlers
+- optimized autoloader
+- reverted ./ and ../ handling in fetch() and display() - they're allowed again
+
+20.09.2011
+- bugfix removed debug echo output while compiling template inheritance
+- bugfix relative paths in $template_dir broke relative path resolving in {include "../foo.tpl"}
+- bugfix {include} did not work inside nested {block} tags
+- bugfix {assign} with scope root and global did not work in all cases
+
+19.09.2011
+- bugfix regression in Smarty_CacheReource_KeyValueStore introduced by r4261
+- bugfix output filter shall not run on included subtemplates
+
+18.09.2011
+- bugfix template caching did not care about file.tpl in different template_dir
+- bugfix {include $file} was broken when merge_compiled_incluges = true
+- bugfix {include} was broken when merge_compiled_incluges = true and same indluded template
+ was used in different main templates in one compilation run
+- bugfix for Smarty2 style compiler plugins on unnamed attribute passing like {tag $foo $bar}
+- bugfix debug.tpl did not display correctly when it was compiled with escape_html = true
+
+17.09.2011
+- bugfix lock_id for file resource would create invalid filepath
+- bugfix resource caching did not care about file.tpl in different template_dir
+
+===== Smarty 3.1.0 =====
+15/09/2011
+- optimization of {foreach}; call internal _count() method only when "total" or "last" {foreach} properties are used
+
+11/09/2011
+- added unregisterObject() method
+
+06/09/2011
+- bugfix isset() did not work in templates on config variables
+
+03/09/2011
+- bugfix createTemplate() must default to cache_id and compile_id of Smarty object
+- bugfix Smarty_CacheResource_KeyValueStore must include $source->uid in cache filepath to keep templates with same
+ name but different folders separated
+- added cacheresource.apc.php example in demo folder
+
+02/09/2011
+- bugfix cache lock file must use absolute filepath
+
+01/09/2011
+- update of cache locking
+
+30/08/2011
+- added locking mechanism to CacheResource API (implemented with File and KeyValueStores)
+
+28/08/2011
+- bugfix clearCompileTemplate() did not work for specific template subfolder or resource
+
+27/08/2011
+- bugfix {$foo|bar+1} did create syntax error
+
+26/08/2011
+- bugfix when generating nocache code which contains double \
+- bugfix handle race condition if cache file was deleted between filemtime and include
+
+17/08/2011
+- bugfix CacheResource_Custom bad internal fetch() call
+
+15/08/2011
+- bugfix CacheResource would load content twice for KeyValueStore and Custom handlers
+
+06/08/2011
+- bugfix {include} with scope attribute could execute in wrong scope
+- optimization of compile_check processing
+
+03/08/2011
+- allow comment tags to comment {block} tags out in child templates
+
+26/07/2011
+- bugfix experimental getTags() method did not work
+
+24/07/2011
+- sure opened output buffers are closed on exception
+- bugfix {foreach} did not work on IteratorAggregate
+
+22/07/2011
+- clear internal caches on clearAllCache(), clearCache(), clearCompiledTemplate()
+
+21/07/2011
+- bugfix value changes of variable values assigned to Smarty object could not be seen on repeated $smarty->fetch() calls
+
+17/07/2011
+- bugfix {$smarty.block.child} did drop a notice at undefined child
+
+15/07/2011
+- bugfix individual cache_lifetime of {include} did not work correctly inside {block} tags
+- added caches for Smarty_Internal_TemplateSource and Smarty_Internal_TemplateCompiled to reduce I/O for multiple cache_id rendering
+
+14/07/2011
+- made Smarty::loadPlugin() respect the include_path if required
+
+13/07/2011
+- optimized internal file write functionality
+- bugfix PHP did eat line break on nocache sections
+- fixed typo of Smarty_Security properties $allowed_modifiers and $disabled_modifiers
+
+06/07/2011
+- bugfix variable modifier must run befor gereral filtering/escaping
+
+04/07/2011
+- bugfix use (?P<name>) syntax at preg_match as some pcre libraries failed on (?<name>)
+- some performance improvement when using generic getter/setter on template objects
+
+30/06/2011
+- bugfix generic getter/setter of Smarty properties used on template objects did throw exception
+- removed is_dir and is_readable checks from directory setters for better performance
+
+28/06/2011
+- added back support of php template resource as undocumented feature
+- bugfix automatic recompilation on version change could drop undefined index notice on old 3.0 cache and compiled files
+- update of README_3_1_DEV.txt and moved into the distribution folder
+- improvement show first characters of eval and string templates instead sha1 Uid in debug window
+
+===== Smarty 3.1-RC1 =====
+25/06/2011
+- revert change of 17/06/2011. $_smarty varibale removed. call loadPlugin() from inside plugin code if required
+- code cleanup, remove no longer used properties and methods
+- update of PHPdoc comments
+
+23/06/2011
+- bugfix {html_select_date} would not respect current time zone
+
+19/06/2011
+- added $errors argument to testInstall() functions to suppress output.
+- added plugin-file checks to testInstall()
+
+18/06/2011
+- bugfix mixed use of same subtemplate inline and not inline in same script could cause a warning during compilation
+
+17/06/2011
+- bugfix/change use $_smarty->loadPlugin() when loading nested depending plugins via loadPlugin
+- bugfix {include ... inline} within {block}...{/block} did fail
+
+16/06/2011
+- bugfix do not overwrite '$smarty' template variable when {include ... scope=parent} is called
+- bugfix complete empty inline subtemplates did fail
+
+15/06/2011
+- bugfix template variables where not accessable within inline subtemplates
+
+12/06/2011
+- bugfix removed unneeded merging of template variable when fetching includled subtemplates
+
+10/06/2011
+- made protected properties $template_dir, $plugins_dir, $cache_dir, $compile_dir, $config_dir accessible via magic methods
+
+09/06/2011
+- fix smarty security_policy issue in plugins {html_image} and {fetch}
+
+05/06/2011
+- update of SMARTY_VERSION
+- bugfix made getTags() working again
+
+04/06/2011
+- allow extends resource in file attribute of {extends} tag
+
+03/06/2011
+- added {setfilter} tag to set filters for variable output
+- added escape_html property to control autoescaping of variable output
+
+27/05/2011
+- added allowed/disabled tags and modifiers in security for sandboxing
+
+23/05/2011
+- added base64: and urlencode: arguments to eval and string resource types
+
+22/05/2011
+- made time-attribute of {html_select_date} and {html_select_time} accept arrays as defined by attributes prefix and field_array
+
+13/05/2011
+- remove setOption / getOption calls from SamrtyBC class
+
+02/05/2011
+- removed experimental setOption() getOption() methods
+- output returned content also on opening tag calls of block plugins
+- rewrite of default plugin handler
+- compile code of variable filters for better performance
+
+20/04/2011
+- allow {php} {include_php} tags and PHP_ALLOW handling only with the SmartyBC class
+- removed support of php template resource
+
+20/04/2011
+- added extendsall resource example
+- optimization of template variable access
+- optimization of subtemplate handling {include}
+- optimization of template class
+
+01/04/2011
+- bugfix quote handling in capitalize modifier
+
+28/03/2011
+- bugfix stripslashes() requried when using PCRE e-modifier
+
+04/03/2011
+- upgrade to new PHP_LexerGenerator version 0.4.0 for better performance
+
+27/02/2011
+- ignore .svn folders when clearing cache and compiled files
+- string resources do not need a modify check
+
+26/02/2011
+- replaced smarty_internal_wrapper by SmartyBC class
+- load utility functions as static methods instead through __call()
+- bugfix in extends resource when subresources are used
+- optimization of modify checks
+
+25/02/2011
+- use $smarty->error_unassigned to control NOTICE handling on unassigned variables
+
+21/02/2011
+- added new new compile_check mode COMPILECHECK_CACHEMISS
+- corrected new cloning behaviour of createTemplate()
+- do no longer store the compiler object as property in the compile_tag classes to avoid possible memory leaks
+ during compilation
+
+19/02/2011
+- optimizations on merge_compiled_includes handling
+- a couple of optimizations and bugfixes related to new resource structure
+
+17/02/2011
+- changed ./ and ../ behaviour
+
+14/02/2011
+- added {block ... hide} option to suppress block if no child is defined
+
+13/02/2011
+- update handling of recursive subtemplate calls
+- bugfix replace $smarty->triggerError() by exception in smarty_internal_resource_extends.php
+
+12/02/2011
+- new class Smarty_Internal_TemplateBase with shared methods of Smarty and Template objects
+- optimizations of template processing
+- made register... methods permanet
+- code for default_plugin_handler
+- add automatic recompilation at version change
+
+04/02/2011
+- change in Smarty_CacheResource_Custom
+- bugfix cache_lifetime did not compile correctly at {include} after last update
+- moved isCached processing into CacheResource class
+- bugfix new CacheResource API did not work with disabled compile_check
+
+03/02/2011
+- handle template content as function to improve speed on multiple calls of same subtemplate and isCached()/display() calls
+- bugfixes and improvents in the new resource API
+- optimizations of template class code
+
+25/01/2011
+- optimized function html_select_time
+
+22/01/2011
+- added Smarty::$use_include_path configuration directive for Resource API
+
+21/01/2011
+- optimized function html_select_date
+
+19/01/2011
+- optimized outputfilter trimwhitespace
+
+18/01/2011
+- bugfix Config to use Smarty_Resource to fetch sources
+- optimized Smarty_Security's isTrustedDir() and isTrustedPHPDir()
+
+17/01/2011
+- bugfix HTTP headers for CGI SAPIs
+
+16/01/2011
+- optimized internals of Smarty_Resource and Smarty_CacheResource
+
+14/01/2011
+- added modifiercompiler escape to improve performance of escaping html, htmlall, url, urlpathinfo, quotes, javascript
+- added support to choose template_dir to load from: [index]filename.tpl
+
+12/01/2011
+- added unencode modifier to revert results of encode modifier
+- added to_charset and from_charset modifier for character encoding
+
+11/01/2011
+- added SMARTY_MBSTRING to generalize MBString detection
+- added argument $lc_rest to modifier.capitalize to lower-case anything but the first character of a word
+- changed strip modifier to consider unicode white-space, too
+- changed wordwrap modifier to accept UTF-8 strings
+- changed count_sentences modifier to consider unicode characters and treat sequences delimited by ? and ! as sentences, too
+- added argument $double_encode to modifier.escape (applies to html and htmlall only)
+- changed escape modifier to be UTF-8 compliant
+- changed textformat block to be UTF-8 compliant
+- optimized performance of mailto function
+- fixed spacify modifier so characters are not prepended and appended, made it unicode compatible
+- fixed truncate modifier to properly use mb_string if possible
+- removed UTF-8 frenzy from count_characters modifier
+- fixed count_words modifier to treat "hello-world" as a single word like str_count_words() does
+- removed UTF-8 frenzy from upper modifier
+- removed UTF-8 frenzy from lower modifier
+
+01/01/2011
+- optimize smarty_modified_escape for hex, hexentity, decentity.
+
+28/12/2010
+- changed $tpl_vars, $config_vars and $parent to belong to Smarty_Internal_Data
+- added Smarty::registerCacheResource() for dynamic cache resource object registration
+
+27/12/2010
+- added Smarty_CacheResource API and refactored existing cache resources accordingly
+- added Smarty_CacheResource_Custom and Smarty_CacheResource_Mysql
+
+26/12/2010
+- added Smarty_Resource API and refactored existing resources accordingly
+- added Smarty_Resource_Custom and Smarty_Resource_Mysql
+- bugfix Smarty::createTemplate() to return properly cloned template instances
+
+24/12/2010
+- optimize smarty_function_escape_special_chars() for PHP >= 5.2.3
+
+===== SVN 3.0 trunk =====
+14/05/2011
+- bugfix error handling at stream resources
+
+13/05/2011
+- bugfix condition starting with "-" did fail at {if} and {while} tags
+
+22/04/2011
+- bugfix allow only fixed string as file attribute at {extends} tag
+
+01/04/2011
+- bugfix do not run filters and default modifier when displaying the debug template
+- bugfix of embedded double quotes within multi line strings (""")
+
+29/03/2011
+- bugfix on error message in smarty_internal_compile_block.php
+- bugfix mb handling in strip modifier
+- bugfix for Smarty2 style registered compiler function on unnamed attribute passing like {tag $foo $bar}
+
+17/03/2011
+- bugfix on default {function} parameters when {function} was used in nocache sections
+- bugfix on compiler object destruction. compiler_object property was by mistake unset.
+
+09/03/2011
+-bugfix a variable filter should run before modifiers on an output tag (see change of 23/07/2010)
+
+08/03/2011
+- bugfix loading config file without section should load only defaults
+
+03/03/2011
+- bugfix "smarty" template variable was not recreated when cached templated had expired
+- bugfix internal rendered_content must be cleared after subtemplate was included
+
+01/03/2011
+- bugfix replace modifier did not work in 3.0.7 on systems without multibyte support
+- bugfix {$smarty.template} could return in 3.0.7 parent template name instead of
+ child name when it needed to compile
+
+25/02/2011
+- bugfix for Smarty2 style compiler plugins on unnamed attribute passing like {tag $foo $bar}
+
+24/02/2011
+- bugfix $smarty->clearCache('some.tpl') did by mistake cache the template object
+
+18/02/2011
+- bugfix removed possible race condition when isCached() was called for an individually cached subtemplate
+- bugfix force default debug.tpl to be loaded by the file resource
+
+17/02/2011
+-improvement not to delete files starting with '.' from cache and template_c folders on clearCompiledTemplate() and clearCache()
+
+16/02/2011
+-fixed typo in exception message of Smarty_Internal_Template
+-improvement allow leading spaces on } tag closing if auto_literal is enabled
+
+13/02/2011
+- bufix replace $smarty->triggerError() by exception
+- removed obsolete {popup_init..} plugin from demo templates
+- bugfix replace $smarty->triggerError() by exception in smarty_internal_resource_extends.php
+
+===== Smarty 3.0.7 =====
+09/02/2011
+- patched vulnerability when using {$smarty.template}
+
+01/02/2011
+- removed assert() from config and template parser
+
+31/01/2011
+- bugfix the lexer/parser did fail on special characters like VT
+
+16/01/2011
+-bugfix of ArrayAccess object handling in internal _count() method
+-bugfix of Iterator object handling in internal _count() method
+
+14/01/2011
+-bugfix removed memory leak while processing compileAllTemplates
+
+12/01/2011
+- bugfix in {if} and {while} tag compiler when using assignments as condition and nocache mode
+
+10/01/2011
+- bugfix when using {$smarty.block.child} and name of {block} was in double quoted string
+- bugfix updateParentVariables() was called twice when leaving {include} processing
+
+- bugfix mb_str_replace in replace and escape modifiers work with utf8
+
+31/12/2010
+- bugfix dynamic configuration of $debugging_crtl did not work
+- bugfix default value of $config_read_hidden changed to false
+- bugfix format of attribute array on compiler plugins
+- bugfix getTemplateVars() could return value from wrong scope
+
+28/12/2010
+- bugfix multiple {append} tags failed to compile.
+
+22/12/2010
+- update do not clone the Smarty object an internal createTemplate() calls to increase performance
+
+21/12/2010
+- update html_options to support class and id attrs
+
+17/12/2010
+- bugfix added missing support of $cache_attrs for registered plugins
+
+15/12/2010
+- bugfix assignment as condition in {while} did drop an E_NOTICE
+
+14/12/2010
+- bugfix when passing an array as default parameter at {function} tag
+
+13/12/2010
+- bugfix {$smarty.template} in child template did not return right content
+- bugfix Smarty3 did not search the PHP include_path for template files
+
+===== Smarty 3.0.6 =====
+
+12/12/2010
+- bugfix fixed typo regarding yesterdays change to allow streamWrapper
+
+11/12/2010
+- bugfix nested block tags in template inheritance child templates did not work correctly
+- bugfix {$smarty.current_dir} in child template did not point to dir of child template
+- bugfix changed code when writing temporary compiled files to allow stream_wrapper
+
+06/12/2010
+- bugfix getTemplateVars() should return 'null' instead dropping E_NOTICE on an unassigned variable
+
+05/12/2010
+- bugfix missing declaration of $smarty in Smarty class
+- bugfix empty($foo) in {if} did drop a notice when $foo was not assigned
+
+01/12/2010
+- improvement of {debug} tag output
+
+27/11/2010
+-change run output filter before cache file is written. (same as in Smarty2)
+
+24/11/2011
+-bugfix on parser at !$foo|modifier
+-change parser logic when assignments used as condition in {if] and {while} to allow assign to array element
+
+23/11/2011
+-bugfix allow integer as attribute name in plugin calls
+-change trimm whitespace from error message, removed long list of expected tokens
+
+22/11/2010
+- bugfix on template inheritance when an {extends} tag was inserted by a prefilter
+- added error message for illegal variable file attributes at {extends...} tags
+
+===== Smarty 3.0.5 =====
+
+
+19/11/2010
+- bugfix on block plugins with modifiers
+
+18/11/2010
+- change on handling of unassigned template variable -- default will drop E_NOTICE
+- bugfix on Smarty2 wrapper load_filter() did not work
+
+17/11/2010
+- bugfix on {call} with variable function name
+- bugfix on {block} if name did contain '-'
+- bugfix in function.fetch.php , referece to undefined $smarty
+
+16/11/2010
+- bugfix whitespace in front of "<?php" in smarty_internal_compile_private_block_plugin.php
+- bugfix {$smarty.now} did compile incorrectly
+- bugfix on reset(),end(),next(),prev(),current() within templates
+- bugfix on default parameter for {function}
+
+15/11/2010
+- bugfix when using {$smarty.session} as object
+- bugfix scoping problem on $smarty object passed to filters
+- bugfix captured content could not be accessed globally
+- bugfix Smarty2 wrapper functions could not be call from within plugins
+
+===== Smarty 3.0.4 =====
+
+14/11/2010
+- bugfix isset() did not allow multiple parameter
+- improvment of some error messages
+- bugfix html_image did use removed property $request_use_auto_globals
+- small performace patch in Smarty class
+
+13/11/2010
+- bugfix overloading problem when $smarty->fetch()/display() have been used in plugins
+ (introduced with 3.0.2)
+- code cleanup
+
+===== Smarty 3.0.3 =====
+
+13/11/2010
+- bugfix on {debug}
+- reverted location of loadPlugin() to Smarty class
+- fixed comments in plugins
+- fixed internal_config (removed unwanted code line)
+- improvement remove last linebreak from {function} definition
+
+===== Smarty 3.0.2 =====
+
+12/11/2010
+- reactivated $error_reporting property handling
+- fixed typo in compile_continue
+- fixed security in {fetch} plugin
+- changed back plugin parameters to two. second is template object
+ with transparent access to Smarty object
+- fixed {config_load} scoping form compile time to run time
+
+===== Smarty 3.0.0 =====
+
+
+
+11/11/2010
+- major update including some API changes
+
+10/11/2010
+- observe compile_id also for config files
+
+09/11/2010
+-bugfix on complex expressions as start value for {for} tag
+request_use_auto_globals
+04/11/2010
+- bugfix do not allow access of dynamic and private object members of assigned objects when
+ security is enabled.
+
+01/11/2010
+- bugfix related to E_NOTICE change. {if empty($foo)} did fail when $foo contained a string
+
+28/10/2010
+- bugfix on compiling modifiers within $smarty special vars like {$smarty.post.{$foo|lower}}
+
+27/10/2010
+- bugfix default parameter values did not work for template functions included with {include}
+
+25/10/2010
+- bugfix for E_NOTICE change, array elements did not work as modifier parameter
+
+20/10/2010
+- bugfix for the E_NOTICE change
+
+19/10/2010
+- change Smarty does no longer mask out E_NOTICE by default during template processing
+
+13/10/2010
+- bugfix removed ambiguity between ternary and stream variable in template syntax
+- bugfix use caching properties of template instead of smarty object when compiling child {block}
+- bugfix {*block}...{/block*} did throw an exception in template inheritance
+- bugfix on template inheritance using nested eval or string resource in {extends} tags
+- bugfix on output buffer handling in isCached() method
+
+===== RC4 =====
+
+01/10/2010
+- added {break} and {continue} tags for flow control of {foreach},{section},{for} and {while} loops
+- change of 'string' resource. It's no longer evaluated and compiled files are now stored
+- new 'eval' resource which evaluates a template without saving the compiled file
+- change in isCached() method to allow multiple calls for the same template
+
+25/09/2010
+- bugfix on some compiling modifiers
+
+24/09/2010
+- bugfix merge_compiled_includes flag was not restored correctly in {block} tag
+
+22/09/2010
+- bugfix on default modifier
+
+18/09/2010
+- bugfix untility compileAllConfig() did not create sha1 code for compiled template file names if template_dir was defined with no trailing DS
+- bugfix on templateExists() for extends resource
+
+17/09/2010
+- bugfix {$smarty.template} and {$smarty.current_dir} did not compile correctly within {block} tags
+- bugfix corrected error message on missing template files in extends resource
+- bugfix untility compileAllTemplates() did not create sha1 code for compiled template file names if template_dir was defined with no trailing DS
+
+16/09/2010
+- bugfix when a doublequoted modifier parameter did contain Smarty tags and ':'
+
+15/09/2010
+- bugfix resolving conflict between '<%'/'%>' as custom Smarty delimiter and ASP tags
+- use ucfirst for resource name on internal resource class names
+
+12/09/2010
+- bugfix for change of 08/09/2010 (final {block} tags in subtemplates did not produce correct results)
+
+10/09/2010
+- bugfix for change of 08/09/2010 (final {block} tags in subtemplates did not produce correct results)
+
+08/09/2010
+- allow multiple template inheritance branches starting in subtemplates
+
+07/09/2010
+- bugfix {counter} and {cycle} plugin assigned result to smarty variable not in local(template) scope
+- bugfix templates containing just {strip} {/strip} tags did produce an error
+
+
+23/08/2010
+- fixed E_STRICT errors for uninitialized variables
+
+22/08/2010
+- added attribute cache_id to {include} tag
+
+13/08/2010
+- remove exception_handler property from Smarty class
+- added Smarty's own exceptions SmartyException and SmartyCompilerException
+
+09/08/2010
+- bugfix on modifier with doublequoted strings as parameter containing embedded tags
+
+06/08/2010
+- bugfix when cascading some modifier like |strip|strip_tags modifier
+
+05/08/2010
+- added plugin type modifiercompiler to produce compiled modifier code
+- changed standard modifier plugins to the compiling versions whenever possible
+- bugfix in nocache sections {include} must not cache the subtemplate
+
+02/08/2010
+- bugfix strip did not work correctly in conjunction with comment lines
+
+31/07/2010
+- bugfix on nocache attribute at {assign} and {append}
+
+30/07/2010
+- bugfix passing scope attributes in doublequoted strings did not work at {include} {assign} and {append}
+
+25/07/2010
+- another bugfix of change from 23/07/2010 when compiling modifier
+
+24/07/2010
+- bugfix of change from 23/07/2010 when compiling modifier
+
+23/07/2010
+- changed execution order. A variable filter does now run before modifiers on output of variables
+- bugfix use always { and } as delimiter for debug.tpl
+
+
+22/07/2010
+- bugfix in templateExists() method
+
+20/07/2010
+- fixed handling of { strip } tag with whitespaces
+
+15/07/2010
+- bufix {$smarty.template} does include now the relative path, not just filename
+
+===== RC3 =====
+
+
+
+
+15/07/2010
+- make the date_format modifier work also on objects of the DateTime class
+- implementation of parsetrees in the parser to close security holes and remove unwanted empty line in HTML output
+
+08/07/2010
+- bugfix on assigning multidimensional arrays within templates
+- corrected bugfix for truncate modifier
+
+07/07/2010
+- bugfix the truncate modifier needs to check if the string is utf-8 encoded or not
+- bugfix support of script files relative to trusted_dir
+
+06/07/2010
+- create exception on recursive {extends} calls
+- fixed reported line number at "unexpected closing tag " exception
+- bugfix on escape:'mail' modifier
+- drop exception if 'item' variable is equal 'from' variable in {foreach} tag
+
+01/07/2010
+- removed call_user_func_array calls for optimization of compiled code when using registered modifiers and plugins
+
+25/06/2010
+- bugfix escaping " when block tags are used within doublequoted strings
+
+24/06/2010
+- replace internal get_time() calls with standard PHP5 microtime(true) calls in Smarty_Internal_Utility
+- added $smarty->register->templateClass() and $smarty->unregister->templateClass() methods for supporting static classes with namespace
+
+
+22/06/2010
+- allow spaces between typecast and value in template syntax
+- bugfix get correct count of traversables in {foreach} tag
+
+21/06/2010
+- removed use of PHP shortags SMARTY_PHP_PASSTHRU mode
+- improved speed of cache->clear() when a compile_id was specified and use_sub_dirs is true
+
+20/06/2010
+- replace internal get_time() calls with standard PHP5 microtime(true) calls
+- closed security hole when php.ini asp_tags = on
+
+18/06/2010
+- added __toString method to the Smarty_Variable class
+
+
+14/06/2010
+- make handling of Smarty comments followed by newline BC to Smarty2
+
+
+===== RC2 =====
+
+
+
+13/06/2010
+- bugfix Smarty3 did not handle hexadecimals like 0x0F as numerical value
+- bugifx Smarty3 did not accept numerical constants like .1 or 2. (without a leading or trailing digit)
+
+11/06/2010
+- bugfix the lexer did fail on larger {literal} ... {/literal} sections
+
+03/06/2010
+- bugfix on calling template functions like Smarty tags
+
+01/06/2010
+- bugfix on template functions used with template inheritance
+- removed /* vim: set expandtab: */ comments
+- bugfix of auto literal problem introduce with fix of 31/05/2010
+
+31/05/2010
+- bugfix the parser did not allow some smarty variables with special name like $for, $if, $else and others.
+
+27/05/2010
+- bugfix on object chaining using variable properties
+- make scope of {counter} and {cycle} tags again global as in Smarty2
+
+26/05/2010
+- bugfix removed decrepated register_resource call in smarty_internal_template.php
+
+25/05/2010
+- rewrite of template function handling to improve speed
+- bugfix on file dependency when merge_compiled_includes = true
+
+
+16/05/2010
+- bugfix when passing parameter with numeric name like {foo 1='bar' 2='blar'}
+
+14/05/2010
+- bugfix compile new config files if compile_check and force_compile = false
+- added variable static classes names to template syntax
+
+11/05/2010
+- bugfix make sure that the cache resource is loaded in all conditions when template methods getCached... are called externally
+- reverted the change 0f 30/04/2010. With the exception of forward references template functions can be again called by a standard tag.
+
+10/05/2010
+- bugfix on {foreach} and {for} optimizations of 27/04/2010
+
+09/05/2010
+- update of template and config file parser because of minor parser generator bugs
+
+07/05/2010
+- bugfix on {insert}
+
+06/05/2010
+- bugfix when merging compiled templates and objects are passed as parameter of the {include} tag
+
+05/05/2010
+- bugfix on {insert} to cache parameter
+- implementation of $smarty->default_modifiers as in Smarty2
+- bugfix on getTemplateVars method
+
+01/05/2010
+- bugfix on handling of variable method names at object chaning
+
+30/04/2010
+- bugfix when comparing timestamps in sysplugins/smarty_internal_config.php
+- work around of a substr_compare bug in older PHP5 versions
+- bugfix on template inheritance for tag names starting with "block"
+- bugfix on {function} tag with name attribute in doublequoted strings
+- fix to make calling of template functions unambiguously by madatory usage of the {call} tag
+
+===== RC1 =====
+
+27/04/2010
+- change default of $debugging_ctrl to 'NONE'
+- optimization of compiled code of {foreach} and {for} loops
+- change of compiler for config variables
+
+27/04/2010
+- bugfix in $smarty->cache->clear() method. (do not cache template object)
+
+
+17/04/2010
+- security fix in {math} plugin
+
+
+12/04/2010
+- bugfix in smarty_internal_templatecompilerbase (overloaded property)
+- removed parser restrictions in using true,false and null as ID
+
+07/04/2010
+- bugfix typo in smarty_internal_templatecompilerbase
+
+31/03/2010
+- compile locking by touching old compiled files to avoid concurrent compilations
+
+29/03/2010
+- bugfix allow array definitions as modifier parameter
+- bugfix observe compile_check property when loading config files
+- added the template object as third filter parameter
+
+25/03/2010
+- change of utility->compileAllTemplates() log messages
+- bugfix on nocache code in {function} tags
+- new method utility->compileAllConfig() to compile all config files
+
+24/03/2010
+- bugfix on register->modifier() error messages
+
+23/03/2010
+- bugfix on template inheritance when calling multiple child/parent relations
+- bugfix on caching mode SMARTY_CACHING_LIFETIME_SAVED and cache_lifetime = 0
+
+22/03/2010
+- bugfix make directory separator operating system independend in compileAllTemplates()
+
+21/03/2010
+- removed unused code in compileAllTemplates()
+
+19/03/2010
+- bugfix for multiple {/block} tags on same line
+
+17/03/2010
+- bugfix make $smarty->cache->clear() function independent from caching status
+
+16/03/2010
+- bugfix on assign attribute at registered template objects
+- make handling of modifiers on expression BC to Smarty2
+
+15/03/2010
+- bugfix on block plugin calls
+
+11/03/2010
+- changed parsing of <?php and ?> back to Smarty2 behaviour
+
+08/03/2010
+- bugfix on uninitialized properties in smarty_internal_template
+- bugfix on $smarty->disableSecurity()
+
+04/03/2010
+- bugfix allow uppercase chars in registered resource names
+- bugfix on accessing chained objects of static classes
+
+01/03/2010
+- bugfix on nocache code in {block} tags if child template was included by {include}
+
+27/02/2010
+- allow block tags inside double quoted string
+
+26/02/2010
+- cache modified check implemented
+- support of access to a class constant from an object (since PHP 5.3)
+
+24/02/2010
+- bugfix on expressions in doublequoted string enclosed in backticks
+- added security property $static_classes for static class security
+
+18/02/2010
+- bugfix on parsing Smarty tags inside <?xml ... ?>
+- bugfix on truncate modifier
+
+17/02/2010
+- removed restriction that modifiers did require surrounding parenthesis in some cases
+- added {$smarty.block.child} special variable for template inheritance
+
+16/02/2010
+- bugfix on <?xml ... ?> tags for all php_handling modes
+- bugfix on parameter of variablefilter.htmlspecialchars.php plugin
+
+14/02/2010
+- added missing _plugins property in smarty.class.php
+- bugfix $smarty.const... inside doublequoted strings and backticks was compiled into wrong PHP code
+
+12/02/2010
+- bugfix on nested {block} tags
+- changed Smarty special variable $smarty.parent to $smarty.block.parent
+- added support of nested {bock} tags
+
+10/02/2010
+- avoid possible notice on $smarty->cache->clear(...), $smarty->clear_cache(....)
+- allow Smarty tags inside <? ... ?> tags in SMARTY_PHP_QUOTE and SMARTY_PHP_PASSTHRU mode
+- bugfix at new "for" syntax like {for $x=1 to 10 step 2}
+
+09/02/2010
+- added $smarty->_tag_stack for tracing block tag hierarchy
+
+08/02/2010
+- bugfix use template fullpath at §smarty->cache->clear(...), $smarty->clear_cache(....)
+- bugfix of cache filename on extended templates when force_compile=true
+
+07/02/2010
+- bugfix on changes of 05/02/2010
+- preserve line endings type form template source
+- API changes (see README file)
+
+05/02/2010
+- bugfix on modifier and block plugins with same name
+
+02/02/2010
+- retaining newlines at registered functions and function plugins
+
+01/25/2010
+- bugfix cache resource was not loaded when caching was globally off but enabled at a template object
+- added test that $_SERVER['SCRIPT_NAME'] does exist in Smarty.class.php
+
+01/22/2010
+- new method $smarty->createData([$parent]) for creating a data object (required for bugfixes below)
+- bugfix config_load() method now works also on a data object
+- bugfix get_config_vars() method now works also on a data and template objects
+- bugfix clear_config() method now works also on a data and template objects
+
+01/19/2010
+- bugfix on plugins if same plugin was called from a nocache section first and later from a cached section
+
+
+###beta 7###
+
+
+01/17/2010
+- bugfix on $smarty.const... in double quoted strings
+
+01/16/2010
+- internal change of config file lexer/parser on handling of section names
+- bugfix on registered objects (format parameter of register_object was not handled correctly)
+
+01/14/2010
+- bugfix on backslash within single quoted strings
+- bugfix allow absolute filepath for config files
+- bugfix on special Smarty variable $smarty.cookies
+- revert handling of newline on no output tags like {if...}
+- allow special characters in config file section names for Smarty2 BC
+
+01/13/2010
+- bugfix on {if} tags
+
+01/12/2010
+- changed back modifier handling in parser. Some restrictions still apply:
+ if modifiers are used in side {if...} expression or in mathematical expressions
+ parentheses must be used.
+- bugfix the {function..} tag did not accept the name attribute in double quotes
+- closed possible security hole at <?php ... ?> tags
+- bugfix of config file parser on large config files
+
+
+###beta 6####
+
+01/11/2010
+- added \n to the compiled code of the {if},{else},{elseif},{/if} tags to get output of newlines as expected by the template source
+- added missing support of insert plugins
+- added optional nocache attribute to {block} tags in parent template
+- updated <?php...?> handling supporting now heredocs and newdocs. (thanks to Thue Jnaus Kristensen)
+
+01/09/2010
+- bugfix on nocache {block} tags in parent templates
+
+01/08/2010
+- bugfix on variable filters. filter/nofilter attributes did not work on output statements
+
+01/07/2010
+- bugfix on file dependency at template inheritance
+- bugfix on nocache code at template inheritance
+
+01/06/2010
+- fixed typo in smarty_internal_resource_registered
+- bugfix for custom delimiter at extends resource and {extends} tag
+
+01/05/2010
+- bugfix sha1() calculations at extends resource and some general improvments on sha1() handling
+
+
+01/03/2010
+- internal change on building cache files
+
+01/02/2010
+- update cached_timestamp at the template object after cache file is written to avoid possible side effects
+- use internally always SMARTY_CACHING_LIFETIME_* constants
+
+01/01/2010
+- bugfix for obtaining plugins which must be included (related to change of 12/30/2009)
+- bugfix for {php} tag (trow an exception if allow_php_tag = false)
+
+12/31/2009
+- optimization of generated code for doublequoted strings containing variables
+- rewrite of {function} tag handling
+ - can now be declared in an external subtemplate
+ - can contain nocache sections (nocache_hash handling)
+ - can be called in noccache sections (nocache_hash handling)
+ - new {call..} tag to call template functions with a variable name {call name=$foo}
+- fixed nocache_hash handling in merged compiled templates
+
+12/30/2009
+- bugfix for plugins defined in the script as smarty_function_foo
+
+12/29/2009
+- use sha1() for filepath encoding
+- updates on nocache_hash handling
+- internal change on merging some data
+- fixed cache filename for custom resources
+
+12/28/2009
+- update for security fixes
+- make modifier plugins always trusted
+- fixed bug loading modifiers in child template at template inheritance
+
+12/27/2009
+--- this is a major update with a couple of internal changes ---
+- new config file lexer/parser (thanks to Thue Jnaus Kristensen)
+- template lexer/parser fixes for PHP and {literal} handing (thanks to Thue Jnaus Kristensen)
+- fix on registered plugins with different type but same name
+- rewrite of plugin handling (optimized execution speed)
+- closed a security hole regarding PHP code injection into cache files
+- fixed bug in clear cache handling
+- Renamed a couple of internal classes
+- code cleanup for merging compiled templates
+- couple of runtime optimizations (still not all done)
+- update of getCachedTimestamp()
+- fixed bug on modifier plugins at nocache output
+
+12/19/2009
+- bugfix on comment lines in config files
+
+12/17/2009
+- bugfix of parent/global variable update at included/merged subtemplates
+- encode final template filepath into filename of compiled and cached files
+- fixed {strip} handling in auto literals
+
+12/16/2009
+- update of changelog
+- added {include file='foo.tpl' inline} inline option to merge compiled code of subtemplate into the calling template
+
+12/14/2009
+- fixed sideefect of last modification (objects in array index did not work anymore)
+
+12/13/2009
+- allow boolean negation ("!") as operator on variables outside {if} tag
+
+12/12/2009
+- bugfix on single quotes inside {function} tag
+- fix short append/prepend attributes in {block} tags
+
+12/11/2009
+- bugfix on clear_compiled_tpl (avoid possible warning)
+
+12/10/2009
+- bugfix on {function} tags and template inheritance
+
+12/05/2009
+- fixed problem when a cached file was fetched several times
+- removed unneeded lexer code
+
+12/04/2009
+- added max attribute to for loop
+- added security mode allow_super_globals
+
+12/03/2009
+- template inheritance: child templates can now call functions defined by the {function} tag in the parent template
+- added {for $foo = 1 to 5 step 2} syntax
+- bugfix for {$foo.$x.$y.$z}
+
+12/01/2009
+- fixed parsing of names of special formated tags like if,elseif,while,for,foreach
+- removed direct access to constants in templates because of some syntax problems
+- removed cache resource plugin for mysql from the distribution
+- replaced most hard errors (exceptions) by softerrors(trigger_error) in plugins
+- use $template_class property for template class name when compiling {include},{eval} and {extends} tags
+
+11/30/2009
+- map 'true' to SMARTY_CACHING_LIFETIME_CURRENT for the $smarty->caching parameter
+- allow {function} tags within {block} tags
+
+11/28/2009
+- ignore compile_id at debug template
+- added direct access to constants in templates
+- some lexer/parser optimizations
+
+11/27/2009
+- added cache resource MYSQL plugin
+
+11/26/2009
+- bugfix on nested doublequoted strings
+- correct line number on unknown tag error message
+- changed {include} compiled code
+- fix on checking dynamic varibales with error_unassigned = true
+
+11/25/2009
+- allow the following writing for boolean: true, TRUE, True, false, FALSE, False
+- {strip} tag functionality rewritten
+
+11/24/2009
+- bugfix for $smarty->config_overwrite = false
+
+11/23/2009
+- suppress warnings on unlink caused by race conditions
+- correct line number on unknown tag error message
+
+------- beta 5
+11/23/2009
+- fixed configfile parser for text starting with a numeric char
+- the default_template_handler_func may now return a filepath to a template source
+
+11/20/2009
+- bugfix for empty config files
+- convert timestamps of registered resources to integer
+
+11/19/2009
+- compiled templates are no longer touched with the filemtime of template source
+
+11/18/2009
+- allow integer as attribute name in plugin calls
+
+------- beta 4
+11/18/2009
+- observe umask settings when setting file permissions
+- avoide unneeded cache file creation for subtemplates which did occur in some situations
+- make $smarty->_current_file available during compilation for Smarty2 BC
+
+11/17/2009
+- sanitize compile_id and cache_id (replace illegal chars with _)
+- use _dir_perms and _file_perms properties at file creation
+- new constant SMARTY_RESOURCE_DATE_FORMAT (default '%b %e, %Y') which is used as default format in modifier date_format
+- added {foreach $array as $key=>$value} syntax
+- renamed extend tag and resource to extends: {extends file='foo.tol'} , $smarty->display('extends:foo.tpl|bar.tpl);
+- bugfix cycle plugin
+
+11/15/2009
+- lexer/parser optimizations on quoted strings
+
+11/14/2009
+- bugfix on merging compiled templates when source files got removed or renamed.
+- bugfix modifiers on registered object tags
+- fixed locaion where outputfilters are running
+- fixed config file definitions at EOF
+- fix on merging compiled templates with nocache sections in nocache includes
+- parser could run into a PHP error on wrong file attribute
+
+11/12/2009
+- fixed variable filenames in {include_php} and {insert}
+- added scope to Smarty variables in the {block} tag compiler
+- fix on nocache code in child {block} tags
+
+11/11/2009
+- fixed {foreachelse}, {forelse}, {sectionelse} compiled code at nocache variables
+- removed checking for reserved variables
+- changed debugging handling
+
+11/10/2009
+- fixed preg_qoute on delimiters
+
+11/09/2009
+- lexer/parser bugfix
+- new SMARTY_SPL_AUTOLOAD constant to control the autoloader option
+- bugfix for {function} block tags in included templates
+
+11/08/2009
+- fixed alphanumeric array index
+- bugfix on complex double quoted strings
+
+11/05/2009
+- config_load method can now be called on data and template objects
+
+11/04/2009
+- added typecasting support for template variables
+- bugfix on complex indexed special Smarty variables
+
+11/03/2009
+- fixed parser error on objects with special smarty vars
+- fixed file dependency for {incude} inside {block} tag
+- fixed not compiling on non existing compiled templates when compile_check = false
+- renamed function names of autoloaded Smarty methods to Smarty_Method_....
+- new security_class property (default is Smarty_Security)
+
+11/02/2009
+- added neq,lte,gte,mod as aliases to if conditions
+- throw exception on illegal Smarty() constructor calls
+
+10/31/2009
+- change of filenames in sysplugins folder for internal spl_autoload function
+- lexer/parser changed for increased compilation speed
+
+10/27/2009
+- fixed missing quotes in include_php.php
+
+10/27/2009
+- fixed typo in method.register_resource
+- pass {} through as literal
+
+10/26/2009
+- merge only compiled subtemplates into the compiled code of the main template
+
+10/24/2009
+- fixed nocache vars at internal block tags
+- fixed merging of recursive includes
+
+10/23/2009
+- fixed nocache var problem
+
+10/22/2009
+- fix trimwhitespace outputfilter parameter
+
+10/21/2009
+- added {$foo++}{$foo--} syntax
+- buxfix changed PHP "if (..):" to "if (..){" because of possible bad code when concenating PHP tags
+- autoload Smarty internal classes
+- fixed file dependency for config files
+- some code optimizations
+- fixed function definitions on some autoloaded methods
+- fixed nocache variable inside if condition of {if} tag
+
+10/20/2009
+- check at compile time for variable filter to improve rendering speed if no filter is used
+- fixed bug at combination of {elseif} tag and {...} in double quoted strings of static class parameter
+
+10/19/2009
+- fixed compiled template merging on variable double quoted strings as name
+- fixed bug in caching mode 2 and cache_lifetime -1
+- fixed modifier support on block tags
+
+10/17/2009
+- remove ?>\n<?php and ?><?php sequences from compiled template
+
+10/15/2009
+- buxfix on assigning array elements inside templates
+- parser bugfix on array access
+
+10/15/2009
+- allow bit operator '&' inside {if} tag
+- implementation of ternary operator
+
+10/13/2009
+- do not recompile evaluated templates if reused just with other data
+- recompile config files when config properties did change
+- some lexer/parser otimizations
+
+10/11/2009
+- allow {block} tags inside included templates
+- bugfix for resource plugins in Smarty2 format
+- some optimizations of internal.template.php
+
+10/11/2009
+- fixed bug when template with same name is used with different data objects
+- fixed bug with double quoted name attribute at {insert} tag
+- reenabled assign_by_ref and append_by_ref methods
+
+10/07/2009
+- removed block nesting checks for {capture}
+
+10/05/2009
+- added support of "isinstance" to {if} tag
+
+10/03/2009
+- internal changes to improve performance
+- fix registering of filters for classes
+
+10/01/2009
+- removed default timezone setting
+- reactivated PHP resource for simple PHP templates. Must set allow_php_templates = true to enable
+- {PHP} tag can be enabled by allow_php_tag = true
+
+09/30/2009
+- fixed handling template_exits method for all resource types
+- bugfix for other cache resources than file
+- the methods assign_by_ref is now wrapped to assign, append_by_ref to append
+- allow arrays of variables pass in display, fetch and createTemplate calls
+ $data = array('foo'=>'bar','foo2'=>'blar');
+ $smarty->display('my.tpl',$data);
+
+09/29/2009
+- changed {php} tag handling
+- removed support of Smarty::instance()
+- removed support of PHP resource type
+- improved execution speed of {foreach} tags
+- fixed bug in {section} tag
+
+09/23/2009
+- improvements and bugfix on {include} tag handling
+NOTICE: existing compiled template and cache files must be deleted
+
+09/19/2009
+- replace internal "eval()" calls by "include" during rendering process
+- speed improvment for templates which have included subtemplates
+ the compiled code of included templates is merged into the compiled code of the parent template
+- added logical operator "xor" for {if} tag
+- changed parameter ordering for Smarty2 BC
+ fetch($template, $cache_id = null, $compile_id = null, $parent = null)
+ display($template, $cache_id = null, $compile_id = null, $parent = null)
+ createTemplate($template, $cache_id = null, $compile_id = null, $parent = null)
+- property resource_char_set is now replaced by constant SMARTY_RESOURCE_CHAR_SET
+- fixed handling of classes in registered blocks
+- speed improvement of lexer on text sections
+
+09/01/2009
+- dropped nl2br as plugin
+- added '<>' as comparission operator in {if} tags
+- cached caching_lifetime property to cache_liftime for backward compatibility with Smarty2.
+ {include} optional attribute is also now cache_lifetime
+- fixed trigger_error method (moved into Smarty class)
+- version is now Beta!!!
+
+
+08/30/2009
+- some speed optimizations on loading internal plugins
+
+
+08/29/2009
+- implemented caching of registered Resources
+- new property 'auto_literal'. if true(default) '{ ' and ' }' interpreted as literal, not as Smarty delimiter
+
+
+08/28/2009
+- Fix on line breaks inside {if} tags
+
+08/26/2009
+- implemented registered resources as in Smarty2. NOTE: caching does not work yet
+- new property 'force_cache'. if true it forces the creation of a new cache file
+- fixed modifiers on arrays
+- some speed optimization on loading internal classes
+
+
+08/24/2009
+- fixed typo in lexer definition for '!==' operator
+- bugfix - the ouput of plugins was not cached
+- added global variable SCRIPT_NAME
+
+08/21/2009
+- fixed problems whitespace in conjuction with custom delimiters
+- Smarty tags can now be used as value anywhere
+
+08/18/2009
+- definition of template class name moded in internal.templatebase.php
+- whitespace parser changes
+
+08/12/2009
+- fixed parser problems
+
+08/11/2009
+- fixed parser problems with custom delimiter
+
+08/10/2009
+- update of mb support in plugins
+
+
+08/09/2009
+- fixed problems with doublequoted strings at name attribute of {block} tag
+- bugfix at scope attribute of {append} tag
+
+08/08/2009
+- removed all internal calls of Smarty::instance()
+- fixed code in double quoted strings
+
+08/05/2009
+- bugfix mb_string support
+- bugfix of \n.\t etc in double quoted strings
+
+07/29/2009
+- added syntax for variable config vars like #$foo#
+
+07/28/2009
+- fixed parsing of $smarty.session vars containing objects
+
+07/22/2009
+- fix of "$" handling in double quoted strings
+
+07/21/2009
+- fix that {$smarty.current_dir} return correct value within {block} tags.
+
+07/20/2009
+- drop error message on unmatched {block} {/block} pairs
+
+07/01/2009
+- fixed smarty_function_html_options call in plugin function.html_select_date.php (missing ,)
+
+06/24/2009
+- fixed smarty_function_html_options call in plugin function.html_select_date.php
+
+06/22/2009
+- fix on \n and spaces inside smarty tags
+- removed request_use_auto_globals propert as it is no longer needed because Smarty 3 will always run under PHP 5
+
+
+06/18/2009
+- fixed compilation of block plugins when caching enabled
+- added $smarty.current_dir which returns the current working directory
+
+06/14/2009
+- fixed array access on super globals
+- allow smarty tags within xml tags
+
+06/13/2009
+- bugfix at extend resource: create unique files for compiled template and cache for each combination of template files
+- update extend resource to handle appen and prepend block attributes
+- instantiate classes of plugins instead of calling them static
+
+06/03/2009
+- fixed repeat at block plugins
+
+05/25/2009
+- fixed problem with caching of compiler plugins
+
+05/14/2009
+- fixed directory separator handling
+
+05/09/2009
+- syntax change for stream variables
+- fixed bug when using absolute template filepath and caching
+
+05/08/2009
+- fixed bug of {nocache} tag in included templates
+
+05/06/2009
+- allow that plugins_dir folder names can end without directory separator
+
+05/05/2009
+- fixed E_STRICT incompabilities
+- {function} tag bug fix
+- security policy definitions have been moved from plugins folder to file Security.class.php in libs folder
+- added allow_super_global configuration to security
+
+04/30/2009
+- functions defined with the {function} tag now always have global scope
+
+04/29/2009
+- fixed problem with directory setter methods
+- allow that cache_dir can end without directory separator
+
+04/28/2009
+- the {function} tag can no longer overwrite standard smarty tags
+- inherit functions defined by the {fuction} tag into subtemplates
+- added {while <statement>} sytax to while tag
+
+04/26/2009
+- added trusted stream checking to security
+- internal changes at file dependency check for caching
+
+04/24/2009
+- changed name of {template} tag to {function}
+- added new {template} tag
+
+04/23/2009
+- fixed access of special smarty variables from included template
+
+04/22/2009
+- unified template stream syntax with standard Smarty resource syntax $smarty->display('mystream:mytemplate')
+
+04/21/2009
+- change of new style syntax for forach. Now: {foreach $array as $var} like in PHP
+
+04/20/2009
+- fixed "$foo.bar ..." variable replacement in double quoted strings
+- fixed error in {include} tag with variable file attribute
+
+04/18/2009
+- added stream resources ($smarty->display('mystream://mytemplate'))
+- added stream variables {$mystream:myvar}
+
+04/14/2009
+- fixed compile_id handling on {include} tags
+- fixed append/prepend attributes in {block} tag
+- added {if 'expression' is in 'array'} syntax
+- use crc32 as hash for compiled config files.
+
+04/13/2009
+- fixed scope problem with parent variables when appending variables within templates.
+- fixed code for {block} without childs (possible sources for notice errors removed)
+
+04/12/2009
+- added append and prepend attribute to {block} tag
+
+04/11/2009
+- fixed variables in 'file' attribute of {extend} tag
+- fixed problems in modifiers (if mb string functions not present)
+
+04/10/2009
+- check if mb string functions available otherwise fallback to normal string functions
+- added global variable scope SMARTY_GLOBAL_SCOPE
+- enable 'variable' filter by default
+- fixed {$smarty.block.parent.foo}
+- implementation of a 'variable' filter as replacement for default modifier
+
+04/09/2009
+- fixed execution of filters defined by classes
+- compile the always the content of {block} tags to make shure that the filters are running over it
+- syntax corrections on variable object property
+- syntax corrections on array access in dot syntax
+
+04/08/2009
+- allow variable object property
+
+04/07/2009
+- changed variable scopes to SMARTY_LOCAL_SCOPE, SMARTY_PARENT_SCOPE, SMARTY_ROOT_SCOPE to avoid possible conflicts with user constants
+- Smarty variable global attribute replaced with scope attribute
+
+04/06/2009
+- variable scopes LOCAL_SCOPE, PARENT_SCOPE, ROOT_SCOPE
+- more getter/setter methods
+
+04/05/2009
+- replaced new array looping syntax {for $foo in $array} with {foreach $foo in $array} to avoid confusion
+- added append array for short form of assign {$foo[]='bar'} and allow assignments to nested arrays {$foo['bla']['blue']='bar'}
+
+04/04/2009
+- make output of template default handlers cachable and save compiled source
+- some fixes on yesterdays update
+
+04/03/2006
+- added registerDefaultTemplateHandler method and functionallity
+- added registerDefaultPluginHandler method and functionallity
+- added {append} tag to extend Smarty array variabled
+
+04/02/2009
+- added setter/getter methods
+- added $foo@first and $foo@last properties at {for} tag
+- added $set_timezone (true/false) property to setup optionally the default time zone
+
+03/31/2009
+- bugfix smarty.class and internal.security_handler
+- added compile_check configuration
+- added setter/getter methods
+
+03/30/2009
+- added all major setter/getter methods
+
+03/28/2009
+- {block} tags can be nested now
+- md5 hash function replace with crc32 for speed optimization
+- file order for exted resource inverted
+- clear_compiled_tpl and clear_cache_all will not touch .svn folder any longer
+
+03/27/2009
+- added extend resource
+
+03/26/2009
+- fixed parser not to create error on `word` in double quoted strings
+- allow PHP array(...)
+- implemented $smarty.block.name.parent to access parent block content
+- fixed smarty.class
+
+
+03/23/2009
+- fixed {foreachelse} and {forelse} tags
+
+03/22/2009
+- fixed possible sources for notice errors
+- rearrange SVN into distribution and development folders
+
+03/21/2009
+- fixed exceptions in function plugins
+- fixed notice error in Smarty.class.php
+- allow chained objects to span multiple lines
+- fixed error in modifiers
+
+03/20/2009
+- moved /plugins folder into /libs folder
+- added noprint modifier
+- autoappend a directory separator if the xxxxx_dir definition have no trailing one
+
+03/19/2009
+- allow array definition as modifier parameter
+- changed modifier to use multi byte string funktions.
+
+03/17/2009
+- bugfix
+
+03/15/2009
+- added {include_php} tag for BC
+- removed @ error suppression
+- bugfix fetch did always repeat output of first call when calling same template several times
+- PHPunit tests extended
+
+03/13/2009
+- changed block syntax to be Smarty like {block:titel} -> {block name=titel}
+- compiling of {block} and {extend} tags rewriten for better performance
+- added special Smarty variable block ($smarty.block.foo} returns the parent definition of block foo
+- optimization of {block} tag compiled code.
+- fixed problem with escaped double quotes in double quoted strings
+
+03/12/2009
+- added support of template inheritance by {extend } and {block } tags.
+- bugfix comments within literals
+- added scope attribuie to {include} tag
+
+03/10/2009
+- couple of bugfixes and improvements
+- PHPunit tests extended
+
+03/09/2009
+- added support for global template vars. {assign_global...} $smarty->assign_global(...)
+- added direct_access_security
+- PHPunit tests extended
+- added missing {if} tag conditions like "is div by" etc.
+
+03/08/2009
+- splitted up the Compiler class to make it easier to use a coustom compiler
+- made default plugins_dir relative to Smarty root and not current working directory
+- some changes to make the lexer parser better configurable
+- implemented {section} tag for Smarty2 BC
+
+03/07/2009
+- fixed problem with comment tags
+- fixed problem with #xxxx in double quoted string
+- new {while} tag implemented
+- made lexer and paser class configurable as $smarty property
+- Smarty method get_template_vars implemented
+- Smarty method get_registered_object implemented
+- Smarty method trigger_error implemented
+- PHPunit tests extended
+
+03/06/2009
+- final changes on config variable handling
+- parser change - unquoted strings will by be converted into single quoted strings
+- PHPunit tests extended
+- some code cleanup
+- fixed problem on catenate strings with expression
+- update of count_words modifier
+- bugfix on comment tags
+
+
+03/05/2009
+- bugfix on <?xml...> tag with caching enabled
+- changes on exception handling (by Monte)
+
+03/04/2009
+- added support for config variables
+- bugfix on <?xml...> tag
+
+03/02/2009
+- fixed unqouted strings within modifier parameter
+- bugfix parsing of mofifier parameter
+
+03/01/2009
+- modifier chaining works now as in Smarty2
+
+02/28/2009
+- changed handling of unqouted strings
+
+02/26/2009
+- bugfix
+- changed $smarty.capture.foo to be global for Smarty2 BC.
+
+02/24/2009
+- bugfix {php} {/php} tags for backward compatibility
+- bugfix for expressions on arrays
+- fixed usage of "null" value
+- added $smarty.foreach.foo.first and $smarty.foreach.foo.last
+
+02/06/2009
+- bugfix for request variables without index for example $smarty.get
+- experimental solution for variable functions in static class
+
+02/05/2009
+- update of popup plugin
+- added config variables to template parser (load config functions still missing)
+- parser bugfix for empty quoted strings
+
+02/03/2009
+- allow array of objects as static class variabales.
+- use htmlentities at source output at template errors.
+
+02/02/2009
+- changed search order on modifiers to look at plugins folder first
+- parser bug fix for modifier on array elements $foo.bar|modifier
+- parser bug fix on single quoted srings
+- internal: splitted up compiler plugin files
+
+02/01/2009
+- allow method chaining on static classes
+- special Smarty variables $smarty.... implemented
+- added {PHP} {/PHP} tags for backward compatibility
+
+01/31/2009
+- added {math} plugin for Smarty2 BC
+- added template_exists method
+- changed Smarty3 method enable_security() to enableSecurity() to follow camelCase standards
+
+01/30/2009
+- bugfix in single quoted strings
+- changed syntax for variable property access from $foo:property to $foo@property because of ambiguous syntax at modifiers
+
+01/29/2009
+- syntax for array definition changed from (1,2,3) to [1,2,3] to remove ambiguous syntax
+- allow {for $foo in [1,2,3]} syntax
+- bugfix in double quoted strings
+- allow <?xml...?> tags in template even if short_tags are enabled
+
+01/28/2009
+- fixed '!==' if condition.
+
+01/28/2009
+- added support of {strip} {/strip} tag.
+
+01/27/2009
+- bug fix on backticks in double quoted strings at objects
+
+01/25/2009
+- Smarty2 modfiers added to SVN
+
+01/25/2009
+- bugfix allow arrays at object properties in Smarty syntax
+- the template object is now passed as additional parameter at plugin calls
+- clear_compiled_tpl method completed
+
+01/20/2009
+- access to class constants implemented ( class::CONSTANT )
+- access to static class variables implemented ( class::$variable )
+- call of static class methods implemented ( class::method() )
+
+01/16/2009
+- reallow leading _ in variable names {$_var}
+- allow array of objects {$array.index->method()} syntax
+- finished work on clear_cache and clear_cache_all methods
+
+01/11/2009
+- added support of {literal} tag
+- added support of {ldelim} and {rdelim} tags
+- make code compatible to run with E_STRICT error setting
+
+01/08/2009
+- moved clear_assign and clear_all_assign to internal.templatebase.php
+- added assign_by_ref, append and append_by_ref methods
+
+01/02/2009
+- added load_filter method
+- fished work on filter handling
+- optimization of plugin loading
+
+12/30/2008
+- added compiler support of registered object
+- added backtick support in doubled quoted strings for backward compatibility
+- some minor bug fixes and improvments
+
+12/23/2008
+- fixed problem of not working "not" operator in if-expressions
+- added handling of compiler function plugins
+- finished work on (un)register_compiler_function method
+- finished work on (un)register_modifier method
+- plugin handling from plugins folder changed for modifier plugins
+ deleted - internal.modifier.php
+- added modifier chaining to parser
+
+12/17/2008
+- finished (un)register_function method
+- finished (un)register_block method
+- added security checking for PHP functions in PHP templates
+- plugin handling from plugins folder rewritten
+ new - internal.plugin_handler.php
+ deleted - internal.block.php
+ deleted - internal.function.php
+- removed plugin checking from security handler
+
+12/16/2008
+
+- new start of this change_log file
new file mode 100644
--- /dev/null
+++ b/library/smarty/composer.json
@@ -0,0 +1,44 @@
+{
+ "name": "smarty/smarty",
+ "type": "library",
+ "description": "Smarty - the compiling PHP template engine",
+ "keywords": [
+ "templating"
+ ],
+ "homepage": "http://www.smarty.net",
+ "license": "LGPL-3.0",
+ "authors": [
+ {
+ "name": "Monte Ohrt",
+ "email": "monte@ohrt.com"
+ },
+ {
+ "name": "Uwe Tews",
+ "email": "uwe.tews@googlemail.com"
+ },
+ {
+ "name": "Rodney Rehm",
+ "email": "rodney.rehm@medialize.de"
+ }
+ ],
+ "support": {
+ "irc": "irc://irc.freenode.org/smarty",
+ "issues": "https://github.com/smarty-php/smarty/issues",
+ "forum": "http://www.smarty.net/forums/"
+ },
+ "require": {
+ "php": ">=5.2"
+ },
+ "autoload": {
+ "classmap": [
+ "libs/Smarty.class.php",
+ "libs/SmartyBC.class.php",
+ "libs/sysplugins/"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.1.x-dev"
+ }
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/demo/configs/test.conf
@@ -0,0 +1,5 @@
+title = Welcome to Smarty!
+cutoff_size = 40
+
+[setup]
+bold = true
new file mode 100644
--- /dev/null
+++ b/library/smarty/demo/index.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Example Application
+ *
+ * @package Example-application
+ */
+
+require '../libs/Smarty.class.php';
+
+$smarty = new Smarty;
+
+//$smarty->force_compile = true;
+$smarty->debugging = true;
+$smarty->caching = true;
+$smarty->cache_lifetime = 120;
+
+$smarty->assign("Name", "Fred Irving Johnathan Bradley Peppergill", true);
+$smarty->assign("FirstName", array("John", "Mary", "James", "Henry"));
+$smarty->assign("LastName", array("Doe", "Smith", "Johnson", "Case"));
+$smarty->assign("Class", array(array("A", "B", "C", "D"), array("E", "F", "G", "H"),
+ array("I", "J", "K", "L"), array("M", "N", "O", "P")));
+
+$smarty->assign("contacts", array(array("phone" => "1", "fax" => "2", "cell" => "3"),
+ array("phone" => "555-4444", "fax" => "555-3333", "cell" => "760-1234")));
+
+$smarty->assign("option_values", array("NY", "NE", "KS", "IA", "OK", "TX"));
+$smarty->assign("option_output", array("New York", "Nebraska", "Kansas", "Iowa", "Oklahoma", "Texas"));
+$smarty->assign("option_selected", "NE");
+
+$smarty->display('index.tpl');
new file mode 100644
--- /dev/null
+++ b/library/smarty/demo/plugins/cacheresource.apc.php
@@ -0,0 +1,77 @@
+<?php
+
+/**
+ * APC CacheResource
+ * CacheResource Implementation based on the KeyValueStore API to use
+ * memcache as the storage resource for Smarty's output caching.
+ * *
+ *
+ * @package CacheResource-examples
+ * @author Uwe Tews
+ */
+class Smarty_CacheResource_Apc extends Smarty_CacheResource_KeyValueStore {
+ public function __construct() {
+ // test if APC is present
+ if (!function_exists('apc_cache_info')) {
+ throw new Exception('APC Template Caching Error: APC is not installed');
+ }
+ }
+
+ /**
+ * Read values for a set of keys from cache
+ *
+ * @param array $keys list of keys to fetch
+ *
+ * @return array list of values with the given keys used as indexes
+ * @return boolean true on success, false on failure
+ */
+ protected function read(array $keys) {
+ $_res = array();
+ $res = apc_fetch($keys);
+ foreach ($res as $k => $v) {
+ $_res[$k] = $v;
+ }
+
+ return $_res;
+ }
+
+ /**
+ * Save values for a set of keys to cache
+ *
+ * @param array $keys list of values to save
+ * @param int $expire expiration time
+ *
+ * @return boolean true on success, false on failure
+ */
+ protected function write(array $keys, $expire = null) {
+ foreach ($keys as $k => $v) {
+ apc_store($k, $v, $expire);
+ }
+
+ return true;
+ }
+
+ /**
+ * Remove values from cache
+ *
+ * @param array $keys list of keys to delete
+ *
+ * @return boolean true on success, false on failure
+ */
+ protected function delete(array $keys) {
+ foreach ($keys as $k) {
+ apc_delete($k);
+ }
+
+ return true;
+ }
+
+ /**
+ * Remove *all* values from cache
+ *
+ * @return boolean true on success, false on failure
+ */
+ protected function purge() {
+ return apc_clear_cache('user');
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/demo/plugins/cacheresource.memcache.php
@@ -0,0 +1,91 @@
+<?php
+
+/**
+ * Memcache CacheResource
+ * CacheResource Implementation based on the KeyValueStore API to use
+ * memcache as the storage resource for Smarty's output caching.
+ * Note that memcache has a limitation of 256 characters per cache-key.
+ * To avoid complications all cache-keys are translated to a sha1 hash.
+ *
+ * @package CacheResource-examples
+ * @author Rodney Rehm
+ */
+class Smarty_CacheResource_Memcache extends Smarty_CacheResource_KeyValueStore {
+ /**
+ * memcache instance
+ *
+ * @var Memcache
+ */
+ protected $memcache = null;
+
+ public function __construct() {
+ $this->memcache = new Memcache();
+ $this->memcache->addServer('127.0.0.1', 11211);
+ }
+
+ /**
+ * Read values for a set of keys from cache
+ *
+ * @param array $keys list of keys to fetch
+ *
+ * @return array list of values with the given keys used as indexes
+ * @return boolean true on success, false on failure
+ */
+ protected function read(array $keys) {
+ $_keys = $lookup = array();
+ foreach ($keys as $k) {
+ $_k = sha1($k);
+ $_keys[] = $_k;
+ $lookup[$_k] = $k;
+ }
+ $_res = array();
+ $res = $this->memcache->get($_keys);
+ foreach ($res as $k => $v) {
+ $_res[$lookup[$k]] = $v;
+ }
+
+ return $_res;
+ }
+
+ /**
+ * Save values for a set of keys to cache
+ *
+ * @param array $keys list of values to save
+ * @param int $expire expiration time
+ *
+ * @return boolean true on success, false on failure
+ */
+ protected function write(array $keys, $expire = null) {
+ foreach ($keys as $k => $v) {
+ $k = sha1($k);
+ $this->memcache->set($k, $v, 0, $expire);
+ }
+
+ return true;
+ }
+
+ /**
+ * Remove values from cache
+ *
+ * @param array $keys list of keys to delete
+ *
+ * @return boolean true on success, false on failure
+ */
+ protected function delete(array $keys) {
+ foreach ($keys as $k) {
+ $k = sha1($k);
+ $this->memcache->delete($k);
+ }
+
+ return true;
+ }
+
+ /**
+ * Remove *all* values from cache
+ *
+ * @return boolean true on success, false on failure
+ */
+ protected function purge() {
+ $this->memcache->flush();
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/demo/plugins/cacheresource.mysql.php
@@ -0,0 +1,155 @@
+<?php
+
+/**
+ * MySQL CacheResource
+ * CacheResource Implementation based on the Custom API to use
+ * MySQL as the storage resource for Smarty's output caching.
+ * Table definition:
+ * <pre>CREATE TABLE IF NOT EXISTS `output_cache` (
+ * `id` CHAR(40) NOT NULL COMMENT 'sha1 hash',
+ * `name` VARCHAR(250) NOT NULL,
+ * `cache_id` VARCHAR(250) NULL DEFAULT NULL,
+ * `compile_id` VARCHAR(250) NULL DEFAULT NULL,
+ * `modified` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ * `content` LONGTEXT NOT NULL,
+ * PRIMARY KEY (`id`),
+ * INDEX(`name`),
+ * INDEX(`cache_id`),
+ * INDEX(`compile_id`),
+ * INDEX(`modified`)
+ * ) ENGINE = InnoDB;</pre>
+ *
+ * @package CacheResource-examples
+ * @author Rodney Rehm
+ */
+class Smarty_CacheResource_Mysql extends Smarty_CacheResource_Custom {
+ // PDO instance
+ protected $db;
+ protected $fetch;
+ protected $fetchTimestamp;
+ protected $save;
+
+ public function __construct() {
+ try {
+ $this->db = new PDO("mysql:dbname=test;host=127.0.0.1", "smarty");
+ } catch (PDOException $e) {
+ throw new SmartyException('Mysql Resource failed: ' . $e->getMessage());
+ }
+ $this->fetch = $this->db->prepare('SELECT modified, content FROM output_cache WHERE id = :id');
+ $this->fetchTimestamp = $this->db->prepare('SELECT modified FROM output_cache WHERE id = :id');
+ $this->save = $this->db->prepare('REPLACE INTO output_cache (id, name, cache_id, compile_id, content)
+ VALUES (:id, :name, :cache_id, :compile_id, :content)');
+ }
+
+ /**
+ * fetch cached content and its modification time from data source
+ *
+ * @param string $id unique cache content identifier
+ * @param string $name template name
+ * @param string $cache_id cache id
+ * @param string $compile_id compile id
+ * @param string $content cached content
+ * @param integer $mtime cache modification timestamp (epoch)
+ *
+ * @return void
+ */
+ protected function fetch($id, $name, $cache_id, $compile_id, &$content, &$mtime) {
+ $this->fetch->execute(array('id' => $id));
+ $row = $this->fetch->fetch();
+ $this->fetch->closeCursor();
+ if ($row) {
+ $content = $row['content'];
+ $mtime = strtotime($row['modified']);
+ } else {
+ $content = null;
+ $mtime = null;
+ }
+ }
+
+ /**
+ * Fetch cached content's modification timestamp from data source
+ *
+ * @note implementing this method is optional. Only implement it if modification times can be accessed faster than loading the complete cached content.
+ *
+ * @param string $id unique cache content identifier
+ * @param string $name template name
+ * @param string $cache_id cache id
+ * @param string $compile_id compile id
+ *
+ * @return integer|boolean timestamp (epoch) the template was modified, or false if not found
+ */
+ protected function fetchTimestamp($id, $name, $cache_id, $compile_id) {
+ $this->fetchTimestamp->execute(array('id' => $id));
+ $mtime = strtotime($this->fetchTimestamp->fetchColumn());
+ $this->fetchTimestamp->closeCursor();
+
+ return $mtime;
+ }
+
+ /**
+ * Save content to cache
+ *
+ * @param string $id unique cache content identifier
+ * @param string $name template name
+ * @param string $cache_id cache id
+ * @param string $compile_id compile id
+ * @param integer|null $exp_time seconds till expiration time in seconds or null
+ * @param string $content content to cache
+ *
+ * @return boolean success
+ */
+ protected function save($id, $name, $cache_id, $compile_id, $exp_time, $content) {
+ $this->save->execute(array(
+ 'id' => $id,
+ 'name' => $name,
+ 'cache_id' => $cache_id,
+ 'compile_id' => $compile_id,
+ 'content' => $content,
+ ));
+
+ return !!$this->save->rowCount();
+ }
+
+ /**
+ * Delete content from cache
+ *
+ * @param string $name template name
+ * @param string $cache_id cache id
+ * @param string $compile_id compile id
+ * @param integer|null $exp_time seconds till expiration or null
+ *
+ * @return integer number of deleted caches
+ */
+ protected function delete($name, $cache_id, $compile_id, $exp_time) {
+ // delete the whole cache
+ if ($name === null && $cache_id === null && $compile_id === null && $exp_time === null) {
+ // returning the number of deleted caches would require a second query to count them
+ $query = $this->db->query('TRUNCATE TABLE output_cache');
+
+ return -1;
+ }
+ // build the filter
+ $where = array();
+ // equal test name
+ if ($name !== null) {
+ $where[] = 'name = ' . $this->db->quote($name);
+ }
+ // equal test compile_id
+ if ($compile_id !== null) {
+ $where[] = 'compile_id = ' . $this->db->quote($compile_id);
+ }
+ // range test expiration time
+ if ($exp_time !== null) {
+ $where[] = 'modified < DATE_SUB(NOW(), INTERVAL ' . intval($exp_time) . ' SECOND)';
+ }
+ // equal test cache_id and match sub-groups
+ if ($cache_id !== null) {
+ $where[] = '(cache_id = ' . $this->db->quote($cache_id)
+ . ' OR cache_id LIKE ' . $this->db->quote($cache_id . '|%') . ')';
+ }
+ // run delete query
+ $query = $this->db->query('DELETE FROM output_cache WHERE ' . join(' AND ', $where));
+
+ return $query->rowCount();
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/demo/plugins/cacheresource.pdo.php
@@ -0,0 +1,312 @@
+<?php
+
+/**
+ * PDO Cache Handler
+ * Allows you to store Smarty Cache files into your db.
+ * Example table :
+ * CREATE TABLE `smarty_cache` (
+ * `id` char(40) NOT NULL COMMENT 'sha1 hash',
+ * `name` varchar(250) NOT NULL,
+ * `cache_id` varchar(250) DEFAULT NULL,
+ * `compile_id` varchar(250) DEFAULT NULL,
+ * `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ * `expire` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
+ * `content` mediumblob NOT NULL,
+ * PRIMARY KEY (`id`),
+ * KEY `name` (`name`),
+ * KEY `cache_id` (`cache_id`),
+ * KEY `compile_id` (`compile_id`),
+ * KEY `modified` (`modified`),
+ * KEY `expire` (`expire`)
+ * ) ENGINE=InnoDB
+ * Example usage :
+ * $cnx = new PDO("mysql:host=localhost;dbname=mydb", "username", "password");
+ * $smarty->setCachingType('pdo');
+ * $smarty->loadPlugin('Smarty_CacheResource_Pdo');
+ * $smarty->registerCacheResource('pdo', new Smarty_CacheResource_Pdo($cnx, 'smarty_cache'));
+ *
+ * @author Beno!t POLASZEK - 2014
+ */
+class Smarty_CacheResource_Pdo extends Smarty_CacheResource_Custom {
+
+ protected $fetchStatements = Array('default' => 'SELECT %2$s
+ FROM %1$s
+ WHERE 1
+ AND id = :id
+ AND cache_id IS NULL
+ AND compile_id IS NULL',
+
+ 'withCacheId' => 'SELECT %2$s
+ FROM %1$s
+ WHERE 1
+ AND id = :id
+ AND cache_id = :cache_id
+ AND compile_id IS NULL',
+
+ 'withCompileId' => 'SELECT %2$s
+ FROM %1$s
+ WHERE 1
+ AND id = :id
+ AND compile_id = :compile_id
+ AND cache_id IS NULL',
+
+ 'withCacheIdAndCompileId' => 'SELECT %2$s
+ FROM %1$s
+ WHERE 1
+ AND id = :id
+ AND cache_id = :cache_id
+ AND compile_id = :compile_id');
+ protected $insertStatement = 'INSERT INTO %s
+
+ SET id = :id,
+ name = :name,
+ cache_id = :cache_id,
+ compile_id = :compile_id,
+ modified = CURRENT_TIMESTAMP,
+ expire = DATE_ADD(CURRENT_TIMESTAMP, INTERVAL :expire SECOND),
+ content = :content
+
+ ON DUPLICATE KEY UPDATE
+ name = :name,
+ cache_id = :cache_id,
+ compile_id = :compile_id,
+ modified = CURRENT_TIMESTAMP,
+ expire = DATE_ADD(CURRENT_TIMESTAMP, INTERVAL :expire SECOND),
+ content = :content';
+
+ protected $deleteStatement = 'DELETE FROM %1$s WHERE %2$s';
+ protected $truncateStatement = 'TRUNCATE TABLE %s';
+
+ protected $fetchColumns = 'modified, content';
+ protected $fetchTimestampColumns = 'modified';
+
+ protected $pdo, $table, $database;
+
+ /*
+ * Constructor
+ *
+ * @param PDO $pdo PDO : active connection
+ * @param string $table : table (or view) name
+ * @param string $database : optionnal - if table is located in another db
+ */
+ public function __construct(PDO $pdo, $table, $database = null) {
+
+ if (is_null($table)) {
+ throw new SmartyException("Table name for caching can't be null");
+ }
+
+ $this->pdo = $pdo;
+ $this->table = $table;
+ $this->database = $database;
+
+ $this->fillStatementsWithTableName();
+ }
+
+ /*
+ * Fills the table name into the statements.
+ *
+ * @return Current Instance
+ * @access protected
+ */
+ protected function fillStatementsWithTableName() {
+
+ foreach ($this->fetchStatements AS &$statement) {
+ $statement = sprintf($statement, $this->getTableName(), '%s');
+ }
+
+ $this->insertStatement = sprintf($this->insertStatement, $this->getTableName());
+ $this->deleteStatement = sprintf($this->deleteStatement, $this->getTableName(), '%s');
+ $this->truncateStatement = sprintf($this->truncateStatement, $this->getTableName());
+
+ return $this;
+ }
+
+ /*
+ * Gets the fetch statement, depending on what you specify
+ *
+ * @param string $columns : the column(s) name(s) you want to retrieve from the database
+ * @param string $id unique cache content identifier
+ * @param string|null $cache_id cache id
+ * @param string|null $compile_id compile id
+ * @access protected
+ */
+ protected function getFetchStatement($columns, $id, $cache_id = null, $compile_id = null) {
+
+ if (!is_null($cache_id) && !is_null($compile_id)) {
+ $query = $this->fetchStatements['withCacheIdAndCompileId'] AND $args = Array('id' => $id, 'cache_id' => $cache_id, 'compile_id' => $compile_id);
+ } elseif (is_null($cache_id) && !is_null($compile_id)) {
+ $query = $this->fetchStatements['withCompileId'] AND $args = Array('id' => $id, 'compile_id' => $compile_id);
+ } elseif (!is_null($cache_id) && is_null($compile_id)) {
+ $query = $this->fetchStatements['withCacheId'] AND $args = Array('id' => $id, 'cache_id' => $cache_id);
+ } else {
+ $query = $this->fetchStatements['default'] AND $args = Array('id' => $id);
+ }
+
+ $query = sprintf($query, $columns);
+
+ $stmt = $this->pdo->prepare($query);
+
+ foreach ($args AS $key => $value) {
+ $stmt->bindValue($key, $value);
+ }
+
+ return $stmt;
+ }
+
+ /**
+ * fetch cached content and its modification time from data source
+ *
+ * @param string $id unique cache content identifier
+ * @param string $name template name
+ * @param string|null $cache_id cache id
+ * @param string|null $compile_id compile id
+ * @param string $content cached content
+ * @param integer $mtime cache modification timestamp (epoch)
+ *
+ * @return void
+ * @access protected
+ */
+ protected function fetch($id, $name, $cache_id = null, $compile_id = null, &$content, &$mtime) {
+
+ $stmt = $this->getFetchStatement($this->fetchColumns, $id, $cache_id, $compile_id);
+ $stmt->execute();
+ $row = $stmt->fetch();
+ $stmt->closeCursor();
+
+ if ($row) {
+ $content = $this->outputContent($row['content']);
+ $mtime = strtotime($row['modified']);
+ } else {
+ $content = null;
+ $mtime = null;
+ }
+ }
+
+ /**
+ * Fetch cached content's modification timestamp from data source
+ * {@internal implementing this method is optional.
+ * Only implement it if modification times can be accessed faster than loading the complete cached content.}}
+ *
+ * @param string $id unique cache content identifier
+ * @param string $name template name
+ * @param string|null $cache_id cache id
+ * @param string|null $compile_id compile id
+ *
+ * @return integer|boolean timestamp (epoch) the template was modified, or false if not found
+ * @access protected
+ */
+ // protected function fetchTimestamp($id, $name, $cache_id = null, $compile_id = null) {
+ // $stmt = $this->getFetchStatement($this->fetchTimestampColumns, $id, $cache_id, $compile_id);
+ // $stmt -> execute();
+ // $mtime = strtotime($stmt->fetchColumn());
+ // $stmt -> closeCursor();
+ // return $mtime;
+ // }
+
+ /**
+ * Save content to cache
+ *
+ * @param string $id unique cache content identifier
+ * @param string $name template name
+ * @param string|null $cache_id cache id
+ * @param string|null $compile_id compile id
+ * @param integer|null $exp_time seconds till expiration time in seconds or null
+ * @param string $content content to cache
+ *
+ * @return boolean success
+ * @access protected
+ */
+ protected function save($id, $name, $cache_id = null, $compile_id = null, $exp_time, $content) {
+
+ $stmt = $this->pdo->prepare($this->insertStatement);
+
+ $stmt->bindValue('id', $id);
+ $stmt->bindValue('name', $name);
+ $stmt->bindValue('cache_id', $cache_id, (is_null($cache_id)) ? PDO::PARAM_NULL : PDO::PARAM_STR);
+ $stmt->bindValue('compile_id', $compile_id, (is_null($compile_id)) ? PDO::PARAM_NULL : PDO::PARAM_STR);
+ $stmt->bindValue('expire', (int)$exp_time, PDO::PARAM_INT);
+ $stmt->bindValue('content', $this->inputContent($content));
+ $stmt->execute();
+
+ return !!$stmt->rowCount();
+ }
+
+ /*
+ * Encodes the content before saving to database
+ *
+ * @param string $content
+ * @return string $content
+ * @access protected
+ */
+ protected function inputContent($content) {
+ return $content;
+ }
+
+ /*
+ * Decodes the content before saving to database
+ *
+ * @param string $content
+ * @return string $content
+ * @access protected
+ */
+ protected function outputContent($content) {
+ return $content;
+ }
+
+ /**
+ * Delete content from cache
+ *
+ * @param string|null $name template name
+ * @param string|null $cache_id cache id
+ * @param string|null $compile_id compile id
+ * @param integer|null|-1 $exp_time seconds till expiration or null
+ *
+ * @return integer number of deleted caches
+ * @access protected
+ */
+ protected function delete($name = null, $cache_id = null, $compile_id = null, $exp_time = null) {
+
+ // delete the whole cache
+ if ($name === null && $cache_id === null && $compile_id === null && $exp_time === null) {
+ // returning the number of deleted caches would require a second query to count them
+ $this->pdo->query($this->truncateStatement);
+ return -1;
+ }
+ // build the filter
+ $where = array();
+ // equal test name
+ if ($name !== null) {
+ $where[] = 'name = ' . $this->pdo->quote($name);
+ }
+ // equal test cache_id and match sub-groups
+ if ($cache_id !== null) {
+ $where[] = '(cache_id = ' . $this->pdo->quote($cache_id)
+ . ' OR cache_id LIKE ' . $this->pdo->quote($cache_id . '|%') . ')';
+ }
+ // equal test compile_id
+ if ($compile_id !== null) {
+ $where[] = 'compile_id = ' . $this->pdo->quote($compile_id);
+ }
+ // for clearing expired caches
+ if ($exp_time === Smarty::CLEAR_EXPIRED) {
+ $where[] = 'expire < CURRENT_TIMESTAMP';
+ } // range test expiration time
+ elseif ($exp_time !== null) {
+ $where[] = 'modified < DATE_SUB(NOW(), INTERVAL ' . intval($exp_time) . ' SECOND)';
+ }
+ // run delete query
+ $query = $this->pdo->query(sprintf($this->deleteStatement, join(' AND ', $where)));
+ return $query->rowCount();
+ }
+
+ /**
+ * Gets the formatted table name
+ *
+ * @return string
+ * @access protected
+ */
+ protected function getTableName() {
+ return (is_null($this->database)) ? "`{$this->table}`" : "`{$this->database}`.`{$this->table}`";
+ }
+}
+
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/library/smarty/demo/plugins/cacheresource.pdo_gzip.php
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * PDO Cache Handler with GZIP support
+ * Example usage :
+ * $cnx = new PDO("mysql:host=localhost;dbname=mydb", "username", "password");
+ * $smarty->setCachingType('pdo_gzip');
+ * $smarty->loadPlugin('Smarty_CacheResource_Pdo_Gzip');
+ * $smarty->registerCacheResource('pdo_gzip', new Smarty_CacheResource_Pdo_Gzip($cnx, 'smarty_cache'));
+ *
+ * @require Smarty_CacheResource_Pdo class
+ * @author Beno!t POLASZEK - 2014
+ */
+require_once 'cacheresource.pdo.php';
+
+class Smarty_CacheResource_Pdo_Gzip extends Smarty_CacheResource_Pdo {
+
+ /*
+ * Encodes the content before saving to database
+ *
+ * @param string $content
+ * @return string $content
+ * @access protected
+ */
+ protected function inputContent($content) {
+ return gzdeflate($content);
+ }
+
+ /*
+ * Decodes the content before saving to database
+ *
+ * @param string $content
+ * @return string $content
+ * @access protected
+ */
+ protected function outputContent($content) {
+ return gzinflate($content);
+ }
+}
+
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/library/smarty/demo/plugins/resource.extendsall.php
@@ -0,0 +1,57 @@
+<?php
+
+/**
+ * Extends All Resource
+ * Resource Implementation modifying the extends-Resource to walk
+ * through the template_dirs and inherit all templates of the same name
+ *
+ * @package Resource-examples
+ * @author Rodney Rehm
+ */
+class Smarty_Resource_Extendsall extends Smarty_Internal_Resource_Extends {
+ /**
+ * populate Source Object with meta data from Resource
+ *
+ * @param Smarty_Template_Source $source source object
+ * @param Smarty_Internal_Template $_template template object
+ *
+ * @return void
+ */
+ public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template = null) {
+ $uid = '';
+ $sources = array();
+ $exists = true;
+ foreach ($_template->smarty->getTemplateDir() as $key => $directory) {
+ try {
+ $s = Smarty_Resource::source(null, $source->smarty, '[' . $key . ']' . $source->name);
+ if (!$s->exists) {
+ continue;
+ }
+ $sources[$s->uid] = $s;
+ $uid .= $s->filepath;
+ } catch (SmartyException $e) {
+ }
+ }
+
+ if (!$sources) {
+ $source->exists = false;
+ $source->template = $_template;
+
+ return;
+ }
+
+ $sources = array_reverse($sources, true);
+ reset($sources);
+ $s = current($sources);
+
+ $source->components = $sources;
+ $source->filepath = $s->filepath;
+ $source->uid = sha1($uid);
+ $source->exists = $exists;
+ if ($_template && $_template->smarty->compile_check) {
+ $source->timestamp = $s->timestamp;
+ }
+ // need the template at getContent()
+ $source->template = $_template;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/demo/plugins/resource.mysql.php
@@ -0,0 +1,76 @@
+<?php
+
+/**
+ * MySQL Resource
+ * Resource Implementation based on the Custom API to use
+ * MySQL as the storage resource for Smarty's templates and configs.
+ * Table definition:
+ * <pre>CREATE TABLE IF NOT EXISTS `templates` (
+ * `name` varchar(100) NOT NULL,
+ * `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ * `source` text,
+ * PRIMARY KEY (`name`)
+ * ) ENGINE=InnoDB DEFAULT CHARSET=utf8;</pre>
+ * Demo data:
+ * <pre>INSERT INTO `templates` (`name`, `modified`, `source`) VALUES ('test.tpl', "2010-12-25 22:00:00", '{$x="hello world"}{$x}');</pre>
+ *
+ * @package Resource-examples
+ * @author Rodney Rehm
+ */
+class Smarty_Resource_Mysql extends Smarty_Resource_Custom {
+ // PDO instance
+ protected $db;
+ // prepared fetch() statement
+ protected $fetch;
+ // prepared fetchTimestamp() statement
+ protected $mtime;
+
+ public function __construct() {
+ try {
+ $this->db = new PDO("mysql:dbname=test;host=127.0.0.1", "smarty");
+ } catch (PDOException $e) {
+ throw new SmartyException('Mysql Resource failed: ' . $e->getMessage());
+ }
+ $this->fetch = $this->db->prepare('SELECT modified, source FROM templates WHERE name = :name');
+ $this->mtime = $this->db->prepare('SELECT modified FROM templates WHERE name = :name');
+ }
+
+ /**
+ * Fetch a template and its modification time from database
+ *
+ * @param string $name template name
+ * @param string $source template source
+ * @param integer $mtime template modification timestamp (epoch)
+ *
+ * @return void
+ */
+ protected function fetch($name, &$source, &$mtime) {
+ $this->fetch->execute(array('name' => $name));
+ $row = $this->fetch->fetch();
+ $this->fetch->closeCursor();
+ if ($row) {
+ $source = $row['source'];
+ $mtime = strtotime($row['modified']);
+ } else {
+ $source = null;
+ $mtime = null;
+ }
+ }
+
+ /**
+ * Fetch a template's modification time from database
+ *
+ * @note implementing this method is optional. Only implement it if modification times can be accessed faster than loading the comple template source.
+ *
+ * @param string $name template name
+ *
+ * @return integer timestamp (epoch) the template was modified
+ */
+ protected function fetchTimestamp($name) {
+ $this->mtime->execute(array('name' => $name));
+ $mtime = $this->mtime->fetchColumn();
+ $this->mtime->closeCursor();
+
+ return strtotime($mtime);
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/demo/plugins/resource.mysqls.php
@@ -0,0 +1,58 @@
+<?php
+
+/**
+ * MySQL Resource
+ * Resource Implementation based on the Custom API to use
+ * MySQL as the storage resource for Smarty's templates and configs.
+ * Note that this MySQL implementation fetches the source and timestamps in
+ * a single database query, instead of two separate like resource.mysql.php does.
+ * Table definition:
+ * <pre>CREATE TABLE IF NOT EXISTS `templates` (
+ * `name` varchar(100) NOT NULL,
+ * `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ * `source` text,
+ * PRIMARY KEY (`name`)
+ * ) ENGINE=InnoDB DEFAULT CHARSET=utf8;</pre>
+ * Demo data:
+ * <pre>INSERT INTO `templates` (`name`, `modified`, `source`) VALUES ('test.tpl', "2010-12-25 22:00:00", '{$x="hello world"}{$x}');</pre>
+ *
+ * @package Resource-examples
+ * @author Rodney Rehm
+ */
+class Smarty_Resource_Mysqls extends Smarty_Resource_Custom {
+ // PDO instance
+ protected $db;
+ // prepared fetch() statement
+ protected $fetch;
+
+ public function __construct() {
+ try {
+ $this->db = new PDO("mysql:dbname=test;host=127.0.0.1", "smarty");
+ } catch (PDOException $e) {
+ throw new SmartyException('Mysql Resource failed: ' . $e->getMessage());
+ }
+ $this->fetch = $this->db->prepare('SELECT modified, source FROM templates WHERE name = :name');
+ }
+
+ /**
+ * Fetch a template and its modification time from database
+ *
+ * @param string $name template name
+ * @param string $source template source
+ * @param integer $mtime template modification timestamp (epoch)
+ *
+ * @return void
+ */
+ protected function fetch($name, &$source, &$mtime) {
+ $this->fetch->execute(array('name' => $name));
+ $row = $this->fetch->fetch();
+ $this->fetch->closeCursor();
+ if ($row) {
+ $source = $row['source'];
+ $mtime = strtotime($row['modified']);
+ } else {
+ $source = null;
+ $mtime = null;
+ }
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/demo/templates/footer.tpl
@@ -0,0 +1,2 @@
+</BODY>
+</HTML>
new file mode 100644
--- /dev/null
+++ b/library/smarty/demo/templates/header.tpl
@@ -0,0 +1,5 @@
+<HTML>
+<HEAD>
+ <TITLE>{$title} - {$Name}</TITLE>
+</HEAD>
+<BODY bgcolor="#ffffff">
new file mode 100644
--- /dev/null
+++ b/library/smarty/demo/templates/index.tpl
@@ -0,0 +1,95 @@
+{config_load file="test.conf" section="setup"}
+{include file="header.tpl" title=foo}
+
+<PRE>
+
+{* bold and title are read from the config file *}
+ {if #bold#}<b>{/if}
+ {* capitalize the first letters of each word of the title *}
+ Title: {#title#|capitalize}
+ {if #bold#}</b>{/if}
+
+ The current date and time is {$smarty.now|date_format:"%Y-%m-%d %H:%M:%S"}
+
+ The value of global assigned variable $SCRIPT_NAME is {$SCRIPT_NAME}
+
+ Example of accessing server environment variable SERVER_NAME: {$smarty.server.SERVER_NAME}
+
+ The value of {ldelim}$Name{rdelim} is <b>{$Name}</b>
+
+variable modifier example of {ldelim}$Name|upper{rdelim}
+
+<b>{$Name|upper}</b>
+
+
+An example of a section loop:
+
+ {section name=outer
+ loop=$FirstName}
+ {if $smarty.section.outer.index is odd by 2}
+ {$smarty.section.outer.rownum} . {$FirstName[outer]} {$LastName[outer]}
+ {else}
+ {$smarty.section.outer.rownum} * {$FirstName[outer]} {$LastName[outer]}
+ {/if}
+ {sectionelse}
+ none
+ {/section}
+
+ An example of section looped key values:
+
+ {section name=sec1 loop=$contacts}
+ phone: {$contacts[sec1].phone}
+ <br>
+
+
+
+ fax: {$contacts[sec1].fax}
+
+
+ <br>
+
+
+
+ cell: {$contacts[sec1].cell}
+
+
+ <br>
+ {/section}
+ <p>
+
+ testing strip tags
+ {strip}
+<table border=0>
+ <tr>
+ <td>
+ <A HREF="{$SCRIPT_NAME}">
+ <font color="red">This is a test </font>
+ </A>
+ </td>
+ </tr>
+</table>
+ {/strip}
+
+</PRE>
+
+This is an example of the html_select_date function:
+
+<form>
+ {html_select_date start_year=1998 end_year=2010}
+</form>
+
+This is an example of the html_select_time function:
+
+<form>
+ {html_select_time use_24_hours=false}
+</form>
+
+This is an example of the html_options function:
+
+<form>
+ <select name=states>
+ {html_options values=$option_values selected=$option_selected output=$option_output}
+ </select>
+</form>
+
+{include file="footer.tpl"}
new file mode 100644
--- /dev/null
+++ b/library/smarty/lexer/smarty_internal_configfilelexer.plex
@@ -0,0 +1,318 @@
+<?php
+/**
+* Smarty Internal Plugin Configfilelexer
+*
+* This is the lexer to break the config file source into tokens
+* @package Smarty
+* @subpackage Config
+* @author Uwe Tews
+*/
+/**
+* Smarty_Internal_Configfilelexer
+*
+* This is the config file lexer.
+* It is generated from the smarty_internal_configfilelexer.plex file
+*
+* @package Smarty
+* @subpackage Compiler
+* @author Uwe Tews
+*/
+class Smarty_Internal_Configfilelexer
+{
+ /**
+ * Source
+ *
+ * @var string
+ */
+ public $data;
+ /**
+ * byte counter
+ *
+ * @var int
+ */
+ public $counter;
+ /**
+ * token number
+ *
+ * @var int
+ */
+ public $token;
+ /**
+ * token value
+ *
+ * @var string
+ */
+ public $value;
+ /**
+ * current line
+ *
+ * @var int
+ */
+ public $line;
+ /**
+ * state number
+ *
+ * @var int
+ */
+ public $state = 1;
+ /**
+ * Smarty object
+ *
+ * @var Smarty
+ */
+ public $smarty = null;
+ /**
+ * compiler object
+ *
+ * @var Smarty_Internal_Config_File_Compiler
+ */
+ private $compiler = null;
+ /**
+ * copy of config_booleanize
+ *
+ * @var bool
+ */
+ private $configBooleanize = false;
+ /**
+ * trace file
+ *
+ * @var resource
+ */
+ public $yyTraceFILE;
+ /**
+ * trace prompt
+ *
+ * @var string
+ */
+ public $yyTracePrompt;
+ /**
+ * state names
+ *
+ * @var array
+ */
+ public $state_name = array(1 => 'START', 2 => 'VALUE', 3 => 'NAKED_STRING_VALUE', 4 => 'COMMENT', 5 => 'SECTION', 6 => 'TRIPPLE');
+
+ /**
+ * storage for assembled token patterns
+ *
+ * @var sring
+ */
+ private $yy_global_pattern1 = null;
+ private $yy_global_pattern2 = null;
+ private $yy_global_pattern3 = null;
+ private $yy_global_pattern4 = null;
+ private $yy_global_pattern5 = null;
+ private $yy_global_pattern6 = null;
+
+ /**
+ * token names
+ *
+ * @var array
+ */
+ public $smarty_token_names = array( // Text for parser error messages
+ );
+
+ /**
+ * constructor
+ *
+ * @param string $data template source
+ * @param Smarty_Internal_Config_File_Compiler $compiler
+ */
+ function __construct($data, Smarty_Internal_Config_File_Compiler $compiler)
+ {
+ // set instance object
+ self::instance($this);
+ $this->data = $data . "\n"; //now all lines are \n-terminated
+ $this->counter = 0;
+ if (preg_match('/^\xEF\xBB\xBF/', $this->data, $match)) {
+ $this->counter += strlen($match[0]);
+ }
+ $this->line = 1;
+ $this->compiler = $compiler;
+ $this->smarty = $compiler->smarty;
+ $this->configBooleanize = $this->smarty->config_booleanize;
+ }
+
+ public static function &instance($new_instance = null)
+ {
+ static $instance = null;
+ if (isset($new_instance) && is_object($new_instance)) {
+ $instance = $new_instance;
+ }
+ return $instance;
+ }
+
+ public function PrintTrace()
+ {
+ $this->yyTraceFILE = fopen('php://output', 'w');
+ $this->yyTracePrompt = '<br>';
+ }
+
+
+/*!lex2php
+%input $this->data
+%counter $this->counter
+%token $this->token
+%value $this->value
+%line $this->line
+commentstart = /#|;/
+openB = /\[/
+closeB = /\]/
+section = /.*?(?=[\.=\[\]\r\n])/
+equal = /=/
+whitespace = /[ \t\r]+/
+dot = /\./
+id = /[0-9]*[a-zA-Z_]\w*/
+newline = /\n/
+single_quoted_string = /'[^'\\]*(?:\\.[^'\\]*)*'(?=[ \t\r]*[\n#;])/
+double_quoted_string = /"[^"\\]*(?:\\.[^"\\]*)*"(?=[ \t\r]*[\n#;])/
+tripple_quotes = /"""/
+tripple_quotes_end = /"""(?=[ \t\r]*[\n#;])/
+text = /[\S\s]/
+float = /\d+\.\d+(?=[ \t\r]*[\n#;])/
+int = /\d+(?=[ \t\r]*[\n#;])/
+maybe_bool = /[a-zA-Z]+(?=[ \t\r]*[\n#;])/
+naked_string = /[^\n]+?(?=[ \t\r]*\n)/
+*/
+
+/*!lex2php
+%statename START
+
+commentstart {
+ $this->token = Smarty_Internal_Configfileparser::TPC_COMMENTSTART;
+ $this->yypushstate(self::COMMENT);
+}
+openB {
+ $this->token = Smarty_Internal_Configfileparser::TPC_OPENB;
+ $this->yypushstate(self::SECTION);
+}
+closeB {
+ $this->token = Smarty_Internal_Configfileparser::TPC_CLOSEB;
+}
+equal {
+ $this->token = Smarty_Internal_Configfileparser::TPC_EQUAL;
+ $this->yypushstate(self::VALUE);
+}
+whitespace {
+ return false;
+}
+newline {
+ $this->token = Smarty_Internal_Configfileparser::TPC_NEWLINE;
+}
+id {
+ $this->token = Smarty_Internal_Configfileparser::TPC_ID;
+}
+text {
+ $this->token = Smarty_Internal_Configfileparser::TPC_OTHER;
+}
+
+*/
+
+/*!lex2php
+%statename VALUE
+
+whitespace {
+ return false;
+}
+float {
+ $this->token = Smarty_Internal_Configfileparser::TPC_FLOAT;
+ $this->yypopstate();
+}
+int {
+ $this->token = Smarty_Internal_Configfileparser::TPC_INT;
+ $this->yypopstate();
+}
+tripple_quotes {
+ $this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_QUOTES;
+ $this->yypushstate(self::TRIPPLE);
+}
+single_quoted_string {
+ $this->token = Smarty_Internal_Configfileparser::TPC_SINGLE_QUOTED_STRING;
+ $this->yypopstate();
+}
+double_quoted_string {
+ $this->token = Smarty_Internal_Configfileparser::TPC_DOUBLE_QUOTED_STRING;
+ $this->yypopstate();
+}
+maybe_bool {
+ if (!$this->configBooleanize || !in_array(strtolower($this->value), Array("true", "false", "on", "off", "yes", "no")) ) {
+ $this->yypopstate();
+ $this->yypushstate(self::NAKED_STRING_VALUE);
+ return true; //reprocess in new state
+ } else {
+ $this->token = Smarty_Internal_Configfileparser::TPC_BOOL;
+ $this->yypopstate();
+ }
+}
+naked_string {
+ $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
+ $this->yypopstate();
+}
+newline {
+ $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
+ $this->value = "";
+ $this->yypopstate();
+}
+
+*/
+
+/*!lex2php
+%statename NAKED_STRING_VALUE
+
+naked_string {
+ $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
+ $this->yypopstate();
+}
+
+*/
+
+/*!lex2php
+%statename COMMENT
+
+whitespace {
+ return false;
+}
+naked_string {
+ $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
+}
+newline {
+ $this->token = Smarty_Internal_Configfileparser::TPC_NEWLINE;
+ $this->yypopstate();
+}
+
+*/
+
+/*!lex2php
+%statename SECTION
+
+dot {
+ $this->token = Smarty_Internal_Configfileparser::TPC_DOT;
+}
+section {
+ $this->token = Smarty_Internal_Configfileparser::TPC_SECTION;
+ $this->yypopstate();
+}
+
+*/
+/*!lex2php
+%statename TRIPPLE
+
+tripple_quotes_end {
+ $this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_QUOTES_END;
+ $this->yypopstate();
+ $this->yypushstate(self::START);
+}
+text {
+ $to = strlen($this->data);
+ preg_match("/\"\"\"[ \t\r]*[\n#;]/",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter);
+ if (isset($match[0][1])) {
+ $to = $match[0][1];
+ } else {
+ $this->compiler->trigger_template_error ("missing or misspelled literal closing tag");
+ }
+ $this->value = substr($this->data,$this->counter,$to-$this->counter);
+ $this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_TEXT;
+}
+*/
+
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/lexer/smarty_internal_configfileparser.y
@@ -0,0 +1,362 @@
+/**
+* Smarty Internal Plugin Configfileparser
+*
+* This is the config file parser
+*
+*
+* @package Smarty
+* @subpackage Config
+* @author Uwe Tews
+*/
+%name TPC_
+%declare_class {
+/**
+* Smarty Internal Plugin Configfileparse
+*
+* This is the config file parser.
+* It is generated from the smarty_internal_configfileparser.y file
+* @package Smarty
+* @subpackage Compiler
+* @author Uwe Tews
+*/
+class Smarty_Internal_Configfileparser
+}
+%include_class
+{
+ /**
+ * result status
+ *
+ * @var bool
+ */
+ public $successful = true;
+ /**
+ * return value
+ *
+ * @var mixed
+ */
+ public $retvalue = 0;
+ /**
+ * @var
+ */
+ public $yymajor;
+ /**
+ * lexer object
+ *
+ * @var Smarty_Internal_Configfilelexer
+ */
+ private $lex;
+ /**
+ * internal error flag
+ *
+ * @var bool
+ */
+ private $internalError = false;
+ /**
+ * compiler object
+ *
+ * @var Smarty_Internal_Config_File_Compiler
+ */
+ public $compiler = null;
+ /**
+ * smarty object
+ *
+ * @var Smarty
+ */
+ public $smarty = null;
+ /**
+ * copy of config_overwrite property
+ *
+ * @var bool
+ */
+ private $configOverwrite = false;
+ /**
+ * copy of config_read_hidden property
+ *
+ * @var bool
+ */
+ private $configReadHidden = false;
+ /**
+ * helper map
+ *
+ * @var array
+ */
+ private static $escapes_single = Array('\\' => '\\',
+ '\'' => '\'');
+
+ /**
+ * constructor
+ *
+ * @param Smarty_Internal_Configfilelexer $lex
+ * @param Smarty_Internal_Config_File_Compiler $compiler
+ */
+ function __construct(Smarty_Internal_Configfilelexer $lex, Smarty_Internal_Config_File_Compiler $compiler)
+ {
+ // set instance object
+ self::instance($this);
+ $this->lex = $lex;
+ $this->smarty = $compiler->smarty;
+ $this->compiler = $compiler;
+ $this->configOverwrite = $this->smarty->config_overwrite;
+ $this->configReadHidden = $this->smarty->config_read_hidden;
+ }
+
+ /**
+ * @param null $new_instance
+ *
+ * @return null
+ */
+ public static function &instance($new_instance = null)
+ {
+ static $instance = null;
+ if (isset($new_instance) && is_object($new_instance)) {
+ $instance = $new_instance;
+ }
+ return $instance;
+ }
+
+ /**
+ * parse optional boolean keywords
+ *
+ * @param string $str
+ *
+ * @return bool
+ */
+ private function parse_bool($str)
+ {
+ $str = strtolower($str);
+ if (in_array($str, array('on', 'yes', 'true'))) {
+ $res = true;
+ } else {
+ $res = false;
+ }
+ return $res;
+ }
+
+ /**
+ * parse single quoted string
+ * remove outer quotes
+ * unescape inner quotes
+ *
+ * @param string $qstr
+ *
+ * @return string
+ */
+ private static function parse_single_quoted_string($qstr)
+ {
+ $escaped_string = substr($qstr, 1, strlen($qstr) - 2); //remove outer quotes
+
+ $ss = preg_split('/(\\\\.)/', $escaped_string, - 1, PREG_SPLIT_DELIM_CAPTURE);
+
+ $str = "";
+ foreach ($ss as $s) {
+ if (strlen($s) === 2 && $s[0] === '\\') {
+ if (isset(self::$escapes_single[$s[1]])) {
+ $s = self::$escapes_single[$s[1]];
+ }
+ }
+ $str .= $s;
+ }
+ return $str;
+ }
+
+ /**
+ * parse double quoted string
+ *
+ * @param string $qstr
+ *
+ * @return string
+ */
+ private static function parse_double_quoted_string($qstr)
+ {
+ $inner_str = substr($qstr, 1, strlen($qstr) - 2);
+ return stripcslashes($inner_str);
+ }
+
+ /**
+ * parse triple quoted string
+ *
+ * @param string $qstr
+ *
+ * @return string
+ */
+ private static function parse_tripple_double_quoted_string($qstr)
+ {
+ return stripcslashes($qstr);
+ }
+
+ /**
+ * set a config variable in target array
+ *
+ * @param array $var
+ * @param array $target_array
+ */
+ private function set_var(Array $var, Array &$target_array)
+ {
+ $key = $var["key"];
+ $value = $var["value"];
+
+ if ($this->configOverwrite || !isset($target_array['vars'][$key])) {
+ $target_array['vars'][$key] = $value;
+ } else {
+ settype($target_array['vars'][$key], 'array');
+ $target_array['vars'][$key][] = $value;
+ }
+ }
+
+ /**
+ * add config variable to global vars
+ *
+ * @param array $vars
+ */
+ private function add_global_vars(Array $vars)
+ {
+ if (!isset($this->compiler->config_data['vars'])) {
+ $this->compiler->config_data['vars'] = Array();
+ }
+ foreach ($vars as $var) {
+ $this->set_var($var, $this->compiler->config_data);
+ }
+ }
+
+ /**
+ * add config variable to section
+ *
+ * @param string $section_name
+ * @param array $vars
+ */
+ private function add_section_vars($section_name, Array $vars)
+ {
+ if (!isset($this->compiler->config_data['sections'][$section_name]['vars'])) {
+ $this->compiler->config_data['sections'][$section_name]['vars'] = Array();
+ }
+ foreach ($vars as $var) {
+ $this->set_var($var, $this->compiler->config_data['sections'][$section_name]);
+ }
+ }
+}
+
+%token_prefix TPC_
+
+%parse_accept
+{
+ $this->successful = !$this->internalError;
+ $this->internalError = false;
+ $this->retvalue = $this->_retvalue;
+}
+
+%syntax_error
+{
+ $this->internalError = true;
+ $this->yymajor = $yymajor;
+ $this->compiler->trigger_config_file_error();
+}
+
+%stack_overflow
+{
+ $this->internalError = true;
+ $this->compiler->trigger_config_file_error("Stack overflow in configfile parser");
+}
+
+// Complete config file
+start(res) ::= global_vars sections. {
+ res = null;
+}
+
+// Global vars
+global_vars(res) ::= var_list(vl). {
+ $this->add_global_vars(vl);
+ res = null;
+}
+
+// Sections
+sections(res) ::= sections section. {
+ res = null;
+}
+
+sections(res) ::= . {
+ res = null;
+}
+
+section(res) ::= OPENB SECTION(i) CLOSEB newline var_list(vars). {
+ $this->add_section_vars(i, vars);
+ res = null;
+}
+
+section(res) ::= OPENB DOT SECTION(i) CLOSEB newline var_list(vars). {
+ if ($this->configReadHidden) {
+ $this->add_section_vars(i, vars);
+ }
+ res = null;
+}
+
+// Var list
+var_list(res) ::= var_list(vl) newline. {
+ res = vl;
+}
+
+var_list(res) ::= var_list(vl) var(v). {
+ res = array_merge(vl, Array(v));
+}
+
+var_list(res) ::= . {
+ res = Array();
+}
+
+
+// Var
+var(res) ::= ID(id) EQUAL value(v). {
+ res = Array("key" => id, "value" => v);
+}
+
+
+value(res) ::= FLOAT(i). {
+ res = (float) i;
+}
+
+value(res) ::= INT(i). {
+ res = (int) i;
+}
+
+value(res) ::= BOOL(i). {
+ res = $this->parse_bool(i);
+}
+
+value(res) ::= SINGLE_QUOTED_STRING(i). {
+ res = self::parse_single_quoted_string(i);
+}
+
+value(res) ::= DOUBLE_QUOTED_STRING(i). {
+ res = self::parse_double_quoted_string(i);
+}
+
+value(res) ::= TRIPPLE_QUOTES(i) TRIPPLE_TEXT(c) TRIPPLE_QUOTES_END(ii). {
+ res = self::parse_tripple_double_quoted_string(c);
+}
+
+value(res) ::= TRIPPLE_QUOTES(i) TRIPPLE_QUOTES_END(ii). {
+ res = '';
+}
+
+value(res) ::= NAKED_STRING(i). {
+ res = i;
+}
+
+// NOTE: this is not a valid rule
+// It is added hier to produce a usefull error message on a missing '=';
+value(res) ::= OTHER(i). {
+ res = i;
+}
+
+
+// Newline and comments
+newline(res) ::= NEWLINE. {
+ res = null;
+}
+
+newline(res) ::= COMMENTSTART NEWLINE. {
+ res = null;
+}
+
+newline(res) ::= COMMENTSTART NAKED_STRING NEWLINE. {
+ res = null;
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/lexer/smarty_internal_templatelexer.plex
@@ -0,0 +1,770 @@
+<?php
+/**
+ * Smarty Internal Plugin Templatelexer
+ * This is the lexer to break the template source into tokens
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty_Internal_Templatelexer
+ * This is the template file lexer.
+ * It is generated from the smarty_internal_templatelexer.plex file
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+class Smarty_Internal_Templatelexer
+{
+ /**
+ * Source
+ *
+ * @var string
+ */
+ public $data;
+ /**
+ * byte counter
+ *
+ * @var int
+ */
+ public $counter;
+ /**
+ * token number
+ *
+ * @var int
+ */
+ public $token;
+ /**
+ * token value
+ *
+ * @var string
+ */
+ public $value;
+ /**
+ * current line
+ *
+ * @var int
+ */
+ public $line;
+ /**
+ * tag start line
+ *
+ * @var
+ */
+ public $taglineno;
+ /**
+ * php code type
+ *
+ * @var string
+ */
+ public $phpType = '';
+ /**
+ * escaped left delimiter
+ *
+ * @var string
+ */
+ public $ldel = '';
+ /**
+ * escaped left delimiter length
+ *
+ * @var int
+ */
+ public $ldel_length = 0;
+ /**
+ * escaped right delimiter
+ *
+ * @var string
+ */
+ public $rdel = '';
+ /**
+ * escaped right delimiter length
+ *
+ * @var int
+ */
+ public $rdel_length = 0;
+ /**
+ * state number
+ *
+ * @var int
+ */
+ public $state = 1;
+ /**
+ * Smarty object
+ *
+ * @var Smarty
+ */
+ public $smarty = null;
+ /**
+ * compiler object
+ *
+ * @var Smarty_Internal_TemplateCompilerBase
+ */
+ public $compiler = null;
+ /**
+ * literal tag nesting level
+ *
+ * @var int
+ */
+ private $literal_cnt = 0;
+
+ /**
+ * PHP start tag string
+ *
+ * @var string
+ */
+
+ /**
+ * trace file
+ *
+ * @var resource
+ */
+ public $yyTraceFILE;
+
+ /**
+ * trace prompt
+ *
+ * @var string
+ */
+ public $yyTracePrompt;
+
+ /**
+ * XML flag true while processing xml
+ *
+ * @var bool
+ */
+ public $is_xml = false;
+
+ /**
+ * state names
+ *
+ * @var array
+ */
+ public $state_name = array(1 => 'TEXT', 2 => 'TAG', 3 => 'TAGBODY', 4 => 'LITERAL', 5 => 'DOUBLEQUOTEDSTRING',
+ 6 => 'CHILDBODY', 7 => 'CHILDBLOCK', 8 => 'CHILDLITERAL');
+
+ /**
+ * storage for assembled token patterns
+ *
+ * @var string
+ */
+ private $yy_global_pattern1 = null;
+
+ private $yy_global_pattern2 = null;
+
+ private $yy_global_pattern3 = null;
+
+ private $yy_global_pattern4 = null;
+
+ private $yy_global_pattern5 = null;
+
+ private $yy_global_pattern6 = null;
+
+ private $yy_global_pattern7 = null;
+
+ private $yy_global_pattern8 = null;
+
+ /**
+ * token names
+ *
+ * @var array
+ */
+ public $smarty_token_names = array( // Text for parser error messages
+ 'NOT' => '(!,not)',
+ 'OPENP' => '(',
+ 'CLOSEP' => ')',
+ 'OPENB' => '[',
+ 'CLOSEB' => ']',
+ 'PTR' => '->',
+ 'APTR' => '=>',
+ 'EQUAL' => '=',
+ 'NUMBER' => 'number',
+ 'UNIMATH' => '+" , "-',
+ 'MATH' => '*" , "/" , "%',
+ 'INCDEC' => '++" , "--',
+ 'SPACE' => ' ',
+ 'DOLLAR' => '$',
+ 'SEMICOLON' => ';',
+ 'COLON' => ':',
+ 'DOUBLECOLON' => '::',
+ 'AT' => '@',
+ 'HATCH' => '#',
+ 'QUOTE' => '"',
+ 'BACKTICK' => '`',
+ 'VERT' => '"|" modifier',
+ 'DOT' => '.',
+ 'COMMA' => '","',
+ 'QMARK' => '"?"',
+ 'ID' => 'id, name',
+ 'TEXT' => 'text',
+ 'LDELSLASH' => '{/..} closing tag',
+ 'LDEL' => '{...} Smarty tag',
+ 'COMMENT' => 'comment',
+ 'AS' => 'as',
+ 'TO' => 'to',
+ 'PHP' => '"<?php", "<%", "{php}" tag',
+ 'LOGOP' => '"<", "==" ... logical operator',
+ 'TLOGOP' => '"lt", "eq" ... logical operator; "is div by" ... if condition',
+ 'SCOND' => '"is even" ... if condition',
+ );
+
+ /**
+ * constructor
+ *
+ * @param string $data template source
+ * @param Smarty_Internal_TemplateCompilerBase $compiler
+ */
+ function __construct($data, Smarty_Internal_TemplateCompilerBase $compiler)
+ {
+ $this->data = $data;
+ $this->counter = 0;
+ if (preg_match('~^\xEF\xBB\xBF~i', $this->data, $match)) {
+ $this->counter += strlen($match[0]);
+ }
+ $this->line = 1;
+ $this->smarty = $compiler->smarty;
+ $this->compiler = $compiler;
+ $this->ldel = preg_quote($this->smarty->left_delimiter, '~');
+ $this->ldel_length = strlen($this->smarty->left_delimiter);
+ $this->rdel = preg_quote($this->smarty->right_delimiter, '~');
+ $this->rdel_length = strlen($this->smarty->right_delimiter);
+ $this->smarty_token_names['LDEL'] = $this->smarty->left_delimiter;
+ $this->smarty_token_names['RDEL'] = $this->smarty->right_delimiter;
+ }
+
+ public function PrintTrace()
+ {
+ $this->yyTraceFILE = fopen('php://output', 'w');
+ $this->yyTracePrompt = '<br>';
+ }
+
+ /*
+ * Check if this tag is autoliteral
+ */
+ public function isAutoLiteral ()
+ {
+ return $this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false;
+ }
+
+ /*!lex2php
+ %input $this->data
+ %counter $this->counter
+ %token $this->token
+ %value $this->value
+ %line $this->line
+ linebreak = ~[\t ]*[\r\n]+[\t ]*~
+ text = ~[\S\s]~
+ textdoublequoted = ~([^"\\]*?)((?:\\.[^"\\]*?)*?)(?=(SMARTYldel|\$|`\$|"))~
+ namespace = ~([0-9]*[a-zA-Z_]\w*)?(\\[0-9]*[a-zA-Z_]\w*)+~
+ all = ~[\S\s]+~
+ emptyjava = ~[{][}]~
+ phpstart = ~(<[?]((php\s+|=)|\s+))|(<[%])|(<[?]xml\s+)|(<script\s+language\s*=\s*["']?\s*php\s*["']?\s*>)|([?][>])|([%][>])|(SMARTYldel\s*php(.*?)SMARTYrdel)|(SMARTYldel\s*[/]phpSMARTYrdel)~
+ slash = ~[/]~
+ ldel = ~SMARTYldel\s*~
+ rdel = ~\s*SMARTYrdel~
+ nocacherdel = ~(\s+nocache)?\s*SMARTYrdel~
+ notblockid = ~(?:(?!block)[0-9]*[a-zA-Z_]\w*)~
+ smartyblockchildparent = ~[\$]smarty\.block\.(child|parent)~
+ integer = ~\d+~
+ hex = ~0[xX][0-9a-fA-F]+~
+ math = ~\s*([*]{1,2}|[%/^&]|[<>]{2})\s*~
+ comment = ~SMARTYldel[*]~
+ incdec = ~([+]|[-]){2}~
+ unimath = ~\s*([+]|[-])\s*~
+ openP = ~\s*[(]\s*~
+ closeP = ~\s*[)]~
+ openB = ~\[\s*~
+ closeB = ~\s*\]~
+ dollar = ~[$]~
+ dot = ~[.]~
+ comma = ~\s*[,]\s*~
+ doublecolon = ~[:]{2}~
+ colon = ~\s*[:]\s*~
+ at = ~[@]~
+ hatch = ~[#]~
+ semicolon = ~\s*[;]\s*~
+ equal = ~\s*[=]\s*~
+ space = ~\s+~
+ ptr = ~\s*[-][>]\s*~
+ aptr = ~\s*[=][>]\s*~
+ singlequotestring = ~'[^'\\]*(?:\\.[^'\\]*)*'~
+ backtick = ~[`]~
+ vert = ~[|]~
+ qmark = ~\s*[?]\s*~
+ constant = ~([_]+[A-Z0-9][0-9A-Z_]*|[A-Z][0-9A-Z_]*)(?![0-9A-Z_]*[a-z])~
+ attr = ~\s+[0-9]*[a-zA-Z_][a-zA-Z0-9_\-:]*\s*[=]\s*~
+ id = ~[0-9]*[a-zA-Z_]\w*~
+ literal = ~literal~
+ strip = ~strip~
+ lop = ~\s*(([!=][=]{1,2})|([<][=>]?)|([>][=]?)|[&|]{2})\s*~
+ tlop = ~\s+(eq|ne|neq|gt|ge|gte|lt|le|lte|mod|and|or|xor|(is\s+(not\s+)?(odd|even|div)\s+by))\s+~
+ scond = ~\s+is\s+(not\s+)?(odd|even)~
+ isin = ~\s+is\s+in\s+~
+ as = ~\s+as\s+~
+ to = ~\s+to\s+~
+ step = ~\s+step\s+~
+ block = ~block~
+ if = ~(if|elseif|else if|while)\s+~
+ for = ~for\s+~
+ foreach = ~foreach(?![^\s])~
+ setfilter = ~setfilter\s+~
+ instanceof = ~\s+instanceof\s+~
+ not = ~([!]\s*)|(not\s+)~
+ typecast = ~[(](int(eger)?|bool(ean)?|float|double|real|string|binary|array|object)[)]\s*~
+ double_quote = ~["]~
+ single_quote = ~[']~
+ */
+ /*!lex2php
+ %statename TEXT
+ emptyjava {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ }
+ comment {
+ preg_match("~[*]{$this->rdel}~",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter);
+ if (isset($match[0][1])) {
+ $to = $match[0][1] + strlen($match[0][0]);
+ } else {
+ $this->compiler->trigger_template_error ("missing or misspelled comment closing tag '*{$this->smarty->right_delimiter}'");
+ }
+ $this->value = substr($this->data,$this->counter,$to-$this->counter);
+ return false;
+ }
+ phpstart {
+ $obj = new Smarty_Internal_Compile_Private_Php();
+ $obj->parsePhp($this);
+ }
+ ldel literal rdel {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_LITERALSTART;
+ $this->yypushstate(self::LITERAL);
+ }
+ }
+ ldel {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->yypushstate(self::TAG);
+ return true;
+ }
+ }
+ rdel {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ }
+ text {
+ $to = strlen($this->data);
+ preg_match("~($this->ldel)|([<]script\s+language\s*=\s*[\"\']?\s*php\s*[\"\']?\s*[>])|([<][?])|([<][%])|([?][>])|([%][>])~i",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter);
+ if (isset($match[0][1])) {
+ $to = $match[0][1];
+ }
+ $this->value = substr($this->data,$this->counter,$to-$this->counter);
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ }
+ */
+ /*!lex2php
+ %statename TAG
+ ldel if {
+ $this->token = Smarty_Internal_Templateparser::TP_LDELIF;
+ $this->yybegin(self::TAGBODY);
+ $this->taglineno = $this->line;
+ }
+ ldel for {
+ $this->token = Smarty_Internal_Templateparser::TP_LDELFOR;
+ $this->yybegin(self::TAGBODY);
+ $this->taglineno = $this->line;
+ }
+ ldel foreach {
+ $this->token = Smarty_Internal_Templateparser::TP_LDELFOREACH;
+ $this->yybegin(self::TAGBODY);
+ $this->taglineno = $this->line;
+ }
+ ldel setfilter {
+ $this->token = Smarty_Internal_Templateparser::TP_LDELSETFILTER;
+ $this->yybegin(self::TAGBODY);
+ $this->taglineno = $this->line;
+ }
+ ldel id nocacherdel {
+ $this->yypopstate();
+ $this->token = Smarty_Internal_Templateparser::TP_SIMPLETAG;
+ $this->taglineno = $this->line;
+ }
+ ldel slash notblockid rdel {
+ $this->yypopstate();
+ $this->token = Smarty_Internal_Templateparser::TP_CLOSETAG;
+ $this->taglineno = $this->line;
+ }
+ ldel dollar id nocacherdel {
+ if ($this->_yy_stack[count($this->_yy_stack)-1] == self::TEXT) {
+ $this->yypopstate();
+ $this->token = Smarty_Internal_Templateparser::TP_SIMPLEOUTPUT;
+ $this->taglineno = $this->line;
+ } else {
+ $this->value = $this->smarty->left_delimiter;
+ $this->token = Smarty_Internal_Templateparser::TP_LDEL;
+ $this->yybegin(self::TAGBODY);
+ $this->taglineno = $this->line;
+ }
+ }
+ ldel slash {
+ $this->token = Smarty_Internal_Templateparser::TP_LDELSLASH;
+ $this->yybegin(self::TAGBODY);
+ $this->taglineno = $this->line;
+ }
+ ldel {
+ $this->token = Smarty_Internal_Templateparser::TP_LDEL;
+ $this->yybegin(self::TAGBODY);
+ $this->taglineno = $this->line;
+ }
+ */
+ /*!lex2php
+ %statename TAGBODY
+ rdel {
+ $this->token = Smarty_Internal_Templateparser::TP_RDEL;
+ $this->yypopstate();
+ }
+ double_quote {
+ $this->token = Smarty_Internal_Templateparser::TP_QUOTE;
+ $this->yypushstate(self::DOUBLEQUOTEDSTRING);
+ }
+ singlequotestring {
+ $this->token = Smarty_Internal_Templateparser::TP_SINGLEQUOTESTRING;
+ }
+ smartyblockchildparent {
+ $this->token = Smarty_Internal_Templateparser::TP_SMARTYBLOCKCHILDPARENT;
+ $this->taglineno = $this->line;
+ }
+ dollar id {
+ $this->token = Smarty_Internal_Templateparser::TP_DOLLARID;
+ }
+ dollar {
+ $this->token = Smarty_Internal_Templateparser::TP_DOLLAR;
+ }
+ isin {
+ $this->token = Smarty_Internal_Templateparser::TP_ISIN;
+ }
+ as {
+ $this->token = Smarty_Internal_Templateparser::TP_AS;
+ }
+ to {
+ $this->token = Smarty_Internal_Templateparser::TP_TO;
+ }
+ step {
+ $this->token = Smarty_Internal_Templateparser::TP_STEP;
+ }
+ instanceof {
+ $this->token = Smarty_Internal_Templateparser::TP_INSTANCEOF;
+ }
+ lop {
+ $this->token = Smarty_Internal_Templateparser::TP_LOGOP;
+ }
+ tlop {
+ $this->token = Smarty_Internal_Templateparser::TP_TLOGOP;
+ }
+ scond {
+ $this->token = Smarty_Internal_Templateparser::TP_SINGLECOND;
+ }
+ not{
+ $this->token = Smarty_Internal_Templateparser::TP_NOT;
+ }
+ typecast {
+ $this->token = Smarty_Internal_Templateparser::TP_TYPECAST;
+ }
+ openP {
+ $this->token = Smarty_Internal_Templateparser::TP_OPENP;
+ }
+ closeP {
+ $this->token = Smarty_Internal_Templateparser::TP_CLOSEP;
+ }
+ openB {
+ $this->token = Smarty_Internal_Templateparser::TP_OPENB;
+ }
+ closeB {
+ $this->token = Smarty_Internal_Templateparser::TP_CLOSEB;
+ }
+ ptr {
+ $this->token = Smarty_Internal_Templateparser::TP_PTR;
+ }
+ aptr {
+ $this->token = Smarty_Internal_Templateparser::TP_APTR;
+ }
+ equal {
+ $this->token = Smarty_Internal_Templateparser::TP_EQUAL;
+ }
+ incdec {
+ $this->token = Smarty_Internal_Templateparser::TP_INCDEC;
+ }
+ unimath {
+ $this->token = Smarty_Internal_Templateparser::TP_UNIMATH;
+ }
+ math {
+ $this->token = Smarty_Internal_Templateparser::TP_MATH;
+ }
+ at {
+ $this->token = Smarty_Internal_Templateparser::TP_AT;
+ }
+ hatch {
+ $this->token = Smarty_Internal_Templateparser::TP_HATCH;
+ }
+ attr {
+ // resolve conflicts with shorttag and right_delimiter starting with '='
+ if (substr($this->data, $this->counter + strlen($this->value) - 1, $this->rdel_length) == $this->smarty->right_delimiter) {
+ preg_match("~\s+~",$this->value,$match);
+ $this->value = $match[0];
+ $this->token = Smarty_Internal_Templateparser::TP_SPACE;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_ATTR;
+ }
+ }
+ namespace {
+ $this->token = Smarty_Internal_Templateparser::TP_NAMESPACE;
+ }
+ id {
+ $this->token = Smarty_Internal_Templateparser::TP_ID;
+ }
+ integer {
+ $this->token = Smarty_Internal_Templateparser::TP_INTEGER;
+ }
+ backtick {
+ $this->token = Smarty_Internal_Templateparser::TP_BACKTICK;
+ $this->yypopstate();
+ }
+ vert {
+ $this->token = Smarty_Internal_Templateparser::TP_VERT;
+ }
+ dot {
+ $this->token = Smarty_Internal_Templateparser::TP_DOT;
+ }
+ comma {
+ $this->token = Smarty_Internal_Templateparser::TP_COMMA;
+ }
+ semicolon {
+ $this->token = Smarty_Internal_Templateparser::TP_SEMICOLON;
+ }
+ doublecolon {
+ $this->token = Smarty_Internal_Templateparser::TP_DOUBLECOLON;
+ }
+ colon {
+ $this->token = Smarty_Internal_Templateparser::TP_COLON;
+ }
+ qmark {
+ $this->token = Smarty_Internal_Templateparser::TP_QMARK;
+ }
+ hex {
+ $this->token = Smarty_Internal_Templateparser::TP_HEX;
+ }
+ space {
+ $this->token = Smarty_Internal_Templateparser::TP_SPACE;
+ }
+ ldel {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->yypushstate(self::TAG);
+ return true;
+ }
+ }
+ text {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ }
+ */
+
+ /*!lex2php
+ %statename LITERAL
+ ldel literal rdel {
+ $this->literal_cnt++;
+ $this->token = Smarty_Internal_Templateparser::TP_LITERAL;
+ }
+ ldel slash literal rdel {
+ if ($this->literal_cnt) {
+ $this->literal_cnt--;
+ $this->token = Smarty_Internal_Templateparser::TP_LITERAL;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_LITERALEND;
+ $this->yypopstate();
+ }
+ }
+ text {
+ $to = strlen($this->data);
+ preg_match("~{$this->ldel}[/]?literal{$this->rdel}~i",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter);
+ if (isset($match[0][1])) {
+ $to = $match[0][1];
+ } else {
+ $this->compiler->trigger_template_error ("missing or misspelled literal closing tag");
+ }
+ $this->value = substr($this->data,$this->counter,$to-$this->counter);
+ $this->token = Smarty_Internal_Templateparser::TP_LITERAL;
+ }
+ */
+ /*!lex2php
+ %statename DOUBLEQUOTEDSTRING
+ ldel literal rdel {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ }
+ ldel slash literal rdel {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ }
+ ldel slash {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->yypushstate(self::TAG);
+ return true;
+ }
+ }
+ ldel id {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->yypushstate(self::TAG);
+ return true;
+ }
+ }
+ ldel {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_LDEL;
+ $this->taglineno = $this->line;
+ $this->yypushstate(self::TAGBODY);
+ }
+ }
+ double_quote {
+ $this->token = Smarty_Internal_Templateparser::TP_QUOTE;
+ $this->yypopstate();
+ }
+ backtick dollar {
+ $this->token = Smarty_Internal_Templateparser::TP_BACKTICK;
+ $this->value = substr($this->value,0,-1);
+ $this->yypushstate(self::TAGBODY);
+ $this->taglineno = $this->line;
+ }
+ dollar id {
+ $this->token = Smarty_Internal_Templateparser::TP_DOLLARID;
+ }
+ dollar {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ }
+ textdoublequoted {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ }
+ text {
+ $to = strlen($this->data);
+ $this->value = substr($this->data,$this->counter,$to-$this->counter);
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ }
+ */
+ /*!lex2php
+ %statename CHILDBODY
+ ldel strip rdel {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ return false;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_STRIPON;
+ }
+ }
+ ldel slash strip rdel {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ return false;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_STRIPOFF;
+ }
+ }
+ ldel block {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ return false;
+ } else {
+ $this->yypopstate();
+ return true;
+ }
+ }
+ text {
+ $to = strlen($this->data);
+ preg_match("~SMARTYldel\s*(([/])?strip\s*SMARTYrdel|block\s+)~i",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter);
+ if (isset($match[0][1])) {
+ $to = $match[0][1];
+ }
+ $this->value = substr($this->data,$this->counter,$to-$this->counter);
+ return false;
+ }
+
+ */
+ /*!lex2php
+ %statename CHILDBLOCK
+ ldel literal rdel {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ $this->yypushstate(self::CHILDLITERAL);
+ }
+ }
+ ldel block {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ } else {
+ $this->yypopstate();
+ return true;
+ }
+ }
+ ldel slash block {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ } else {
+ $this->yypopstate();
+ return true;
+ }
+ }
+ ldel smartyblockchildparent {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ } else {
+ $this->yypopstate();
+ return true;
+ }
+ }
+ text {
+ $to = strlen($this->data);
+ preg_match("~SMARTYldel\s*(literal\s*SMARTYrdel|([/])?block(\s|SMARTYrdel)|[\$]smarty\.block\.(child|parent))~i",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter);
+ if (isset($match[0][1])) {
+ $to = $match[0][1];
+ }
+ $this->value = substr($this->data,$this->counter,$to-$this->counter);
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ }
+ */
+ /*!lex2php
+ %statename CHILDLITERAL
+ ldel literal rdel {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ $this->yypushstate(self::CHILDLITERAL);
+ }
+ }
+ ldel slash literal rdel {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ $this->yypopstate();
+ }
+ }
+ text {
+ $to = strlen($this->data);
+ preg_match("~{$this->ldel}[/]?literal\s*{$this->rdel}~i",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter);
+ if (isset($match[0][1])) {
+ $to = $match[0][1];
+ } else {
+ $this->compiler->trigger_template_error ("missing or misspelled literal closing tag");
+ }
+ $this->value = substr($this->data,$this->counter,$to-$this->counter);
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ }
+ */
+ }
+
+
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/library/smarty/lexer/smarty_internal_templateparser.y
@@ -0,0 +1,1329 @@
+/**
+* Smarty Internal Plugin Templateparser
+*
+* This is the template parser
+*
+*
+* @package Smarty
+* @subpackage Compiler
+* @author Uwe Tews
+*/
+%stack_size 500
+%name TP_
+%declare_class {
+/**
+* Smarty Internal Plugin Templateparser
+*
+* This is the template parser.
+* It is generated from the smarty_internal_templateparser.y file
+* @package Smarty
+* @subpackage Compiler
+* @author Uwe Tews
+*/
+class Smarty_Internal_Templateparser
+}
+%include_class
+{
+ const Err1 = "Security error: Call to private object member not allowed";
+ const Err2 = "Security error: Call to dynamic object member not allowed";
+ const Err3 = "PHP in template not allowed. Use SmartyBC to enable it";
+
+ /**
+ * result status
+ *
+ * @var bool
+ */
+ public $successful = true;
+ /**
+ * return value
+ *
+ * @var mixed
+ */
+ public $retvalue = 0;
+ /**
+ * counter for prefix code
+ *
+ * @var int
+ */
+ public static $prefix_number = 0;
+ /**
+ * @var
+ */
+ public $yymajor;
+ /**
+ * last index of array variable
+ *
+ * @var mixed
+ */
+ public $last_index;
+ /**
+ * last variable name
+ *
+ * @var string
+ */
+ public $last_variable;
+ /**
+ * root parse tree buffer
+ *
+ * @var Smarty_Internal_ParseTree
+ */
+ public $root_buffer;
+ /**
+ * current parse tree object
+ *
+ * @var Smarty_Internal_ParseTree
+ */
+ public $current_buffer;
+ /**
+ * lexer object
+ *
+ * @var Smarty_Internal_Templatelexer
+ */
+ private $lex;
+ /**
+ * internal error flag
+ *
+ * @var bool
+ */
+ private $internalError = false;
+ /**
+ * {strip} status
+ *
+ * @var bool
+ */
+ public $strip = false;
+ /**
+ * compiler object
+ *
+ * @var Smarty_Internal_TemplateCompilerBase
+ */
+ public $compiler = null;
+ /**
+ * smarty object
+ *
+ * @var Smarty
+ */
+ public $smarty = null;
+ /**
+ * template object
+ *
+ * @var Smarty_Internal_Template
+ */
+ public $template = null;
+ /**
+ * block nesting level
+ *
+ * @var int
+ */
+ public $block_nesting_level = 0;
+
+ /**
+ * security object
+ *
+ * @var Smarty_Security
+ */
+ private $security = null;
+
+ /**
+ * constructor
+ *
+ * @param Smarty_Internal_Templatelexer $lex
+ * @param Smarty_Internal_TemplateCompilerBase $compiler
+ */
+ function __construct(Smarty_Internal_Templatelexer $lex, Smarty_Internal_TemplateCompilerBase $compiler)
+ {
+ $this->lex = $lex;
+ $this->compiler = $compiler;
+ $this->template = $this->compiler->template;
+ $this->smarty = $this->template->smarty;
+ $this->security = isset($this->smarty->security_policy) ? $this->smarty->security_policy : false;
+ $this->current_buffer = $this->root_buffer = new Smarty_Internal_ParseTree_Template($this);
+ }
+
+ /**
+ * insert PHP code in current buffer
+ *
+ * @param string $code
+ */
+ public function insertPhpCode($code)
+ {
+ $this->current_buffer->append_subtree(new Smarty_Internal_ParseTree_Tag($this, $code));
+ }
+
+ /**
+ * merge PHP code with prefix code and return parse tree tag object
+ *
+ * @param string $code
+ *
+ * @return Smarty_Internal_ParseTree_Tag
+ */
+ public function mergePrefixCode($code)
+ {
+ $tmp ='';
+ foreach ($this->compiler->prefix_code as $preCode) {
+ $tmp = empty($tmp) ? $preCode : $this->compiler->appendCode($tmp, $preCode);
+ }
+ $this->compiler->prefix_code=array();
+ $tmp = empty($tmp) ? $code : $this->compiler->appendCode($tmp, $code);
+ return new Smarty_Internal_ParseTree_Tag($this, $this->compiler->processNocacheCode($tmp,true));
+ }
+
+}
+
+%token_prefix TP_
+
+%parse_accept
+{
+ $this->successful = !$this->internalError;
+ $this->internalError = false;
+ $this->retvalue = $this->_retvalue;
+}
+
+%syntax_error
+{
+ $this->internalError = true;
+ $this->yymajor = $yymajor;
+ $this->compiler->trigger_template_error();
+}
+
+%stack_overflow
+{
+ $this->internalError = true;
+ $this->compiler->trigger_template_error("Stack overflow in template parser");
+}
+
+%left VERT.
+%left COLON.
+
+ //
+ // complete template
+ //
+start(res) ::= template. {
+ res = $this->root_buffer->to_smarty_php();
+}
+
+ //
+ // loop over template elements
+ //
+ // single template element
+template ::= template_element(e). {
+ if (e != null) {
+ $this->current_buffer->append_subtree(e);
+ }
+}
+
+ // loop of elements
+template ::= template template_element(e). {
+ if (e != null) {
+ // because of possible code injection
+ $this->current_buffer->append_subtree(e);
+ }
+}
+
+ // empty template
+template ::= .
+
+//
+// template elements
+//
+ // Smarty tag
+template_element(res)::= smartytag(st). {
+ if ($this->compiler->has_code) {
+ res = $this->mergePrefixCode(st);
+ } else {
+ res = null;
+ }
+ $this->compiler->has_variable_string = false;
+ $this->block_nesting_level = count($this->compiler->_tag_stack);
+}
+
+ // Literal
+template_element(res) ::= literal(l). {
+ res = new Smarty_Internal_ParseTree_Text($this, l);
+}
+ // php tags
+template_element(res)::= PHP(o). {
+ $code = $this->compiler->compileTag('private_php',array(array('code' => o), array('type' => $this->lex->phpType )),array());
+ if ($this->compiler->has_code && !empty($code)) {
+ $tmp =''; foreach ($this->compiler->prefix_code as $code) {$tmp.=$code;} $this->compiler->prefix_code=array();
+ res = new Smarty_Internal_ParseTree_Tag($this, $this->compiler->processNocacheCode($tmp.$code,true));
+ } else {
+ res = null;
+ }
+}
+
+ // nocache code
+template_element(res)::= NOCACHE(c). {
+ $this->compiler->tag_nocache = true;
+ $save = $this->template->has_nocache_code;
+ res = new Smarty_Internal_ParseTree_Tag($this, $this->compiler->processNocacheCode("<?php echo '{c}';?>\n", $this->compiler, true));
+ $this->template->has_nocache_code = $save;
+}
+ // template text
+template_element(res)::= text_content(t). {
+ res = $this->compiler->processText(t);
+}
+
+text_content(res) ::= TEXT(o). {
+ res = o;
+}
+
+text_content(res) ::= text_content(t) TEXT(o). {
+ res = t . o;
+}
+
+ // strip on
+template_element ::= STRIPON(d). {
+ $this->strip = true;
+}
+ // strip off
+template_element ::= STRIPOFF(d). {
+ $this->strip = false;
+}
+ // process source of inheritance child block
+template_element ::= BLOCKSOURCE(s). {
+ if ($this->strip) {
+ SMARTY_INTERNAL_COMPILE_BLOCK::blockSource($this->compiler, preg_replace('![\t ]*[\r\n]+[\t ]*!', '', s));
+ } else {
+ SMARTY_INTERNAL_COMPILE_BLOCK::blockSource($this->compiler, s);
+ }
+}
+
+ // Litteral
+literal(res) ::= LITERALSTART LITERALEND. {
+ res = '';
+}
+
+literal(res) ::= LITERALSTART literal_elements(l) LITERALEND. {
+ res = l;
+}
+
+literal_elements(res) ::= literal_elements(l1) literal_element(l2). {
+ res = l1.l2;
+}
+
+literal_elements(res) ::= . {
+ res = '';
+}
+
+literal_element(res) ::= literal(l). {
+ res = l;
+}
+
+literal_element(res) ::= LITERAL(l). {
+ res = l;
+}
+
+smartytag(res) ::= tag(t) RDEL. {
+ res = t;
+}
+//
+// output tags start here
+//
+smartytag(res) ::= SIMPLEOUTPUT(i). {
+ $var = trim(substr(i, $this->lex->ldel_length, -$this->lex->rdel_length), ' $');
+ if (preg_match('/^(.*)(\s+nocache)$/', $var, $match)) {
+ res = $this->compiler->compileTag('private_print_expression',array('nocache'),array('value'=>$this->compiler->compileVariable('\''.$match[1].'\'')));
+ } else {
+ res = $this->compiler->compileTag('private_print_expression',array(),array('value'=>$this->compiler->compileVariable('\''.$var.'\'')));
+ }
+}
+
+ // output with optional attributes
+tag(res) ::= LDEL variable(e). {
+ res = $this->compiler->compileTag('private_print_expression',array(),array('value'=>e));
+}
+
+tag(res) ::= LDEL variable(e) attributes(a). {
+ res = $this->compiler->compileTag('private_print_expression',a,array('value'=>e));
+}
+tag(res) ::= LDEL value(e). {
+ res = $this->compiler->compileTag('private_print_expression',array(),array('value'=>e));
+}
+tag(res) ::= LDEL value(e) attributes(a). {
+ res = $this->compiler->compileTag('private_print_expression',a,array('value'=>e));
+}
+
+tag(res) ::= LDEL expr(e). {
+ res = $this->compiler->compileTag('private_print_expression',array(),array('value'=>e));
+}
+
+tag(res) ::= LDEL expr(e) attributes(a). {
+ res = $this->compiler->compileTag('private_print_expression',a,array('value'=>e));
+}
+
+//
+// Smarty tags start here
+//
+
+ // assign new style
+tag(res) ::= LDEL DOLLARID(i) EQUAL value(e). {
+ res = $this->compiler->compileTag('assign',array(array('value'=>e),array('var'=>'\''.substr(i,1).'\'')));
+}
+
+tag(res) ::= LDEL DOLLARID(i) EQUAL expr(e). {
+ res = $this->compiler->compileTag('assign',array(array('value'=>e),array('var'=>'\''.substr(i,1).'\'')));
+}
+
+tag(res) ::= LDEL DOLLARID(i) EQUAL expr(e) attributes(a). {
+ res = $this->compiler->compileTag('assign',array_merge(array(array('value'=>e),array('var'=>'\''.substr(i,1).'\'')),a));
+}
+
+tag(res) ::= LDEL varindexed(vi) EQUAL expr(e) attributes(a). {
+ res = $this->compiler->compileTag('assign',array_merge(array(array('value'=>e),array('var'=>vi['var'])),a),array('smarty_internal_index'=>vi['smarty_internal_index']));
+}
+
+// simple tag like {name}
+smartytag(res)::= SIMPLETAG(t). {
+ $tag = trim(substr(t, $this->lex->ldel_length, -$this->lex->rdel_length));
+ if ($tag == 'strip') {
+ $this->strip = true;
+ res = null;;
+ } else {
+ if (defined($tag)) {
+ if ($this->security) {
+ $this->security->isTrustedConstant($tag, $this->compiler);
+ }
+ res = $this->compiler->compileTag('private_print_expression',array(),array('value'=>$tag));
+ } else {
+ if (preg_match('/^(.*)(\s+nocache)$/', $tag, $match)) {
+ res = $this->compiler->compileTag($match[1],array("'nocache'"));
+ } else {
+ res = $this->compiler->compileTag($tag,array());
+ }
+ }
+ }
+}
+
+ // tag with optional Smarty2 style attributes
+tag(res) ::= LDEL ID(i) attributes(a). {
+ if (defined(i)) {
+ if ($this->security) {
+ $this->security->isTrustedConstant(i, $this->compiler);
+ }
+ res = $this->compiler->compileTag('private_print_expression',a,array('value'=>i));
+ } else {
+ res = $this->compiler->compileTag(i,a);
+ }
+}
+tag(res) ::= LDEL ID(i). {
+ if (defined(i)) {
+ if ($this->security) {
+ $this->security->isTrustedConstant(i, $this->compiler);
+ }
+ res = $this->compiler->compileTag('private_print_expression',array(),array('value'=>i));
+ } else {
+ res = $this->compiler->compileTag(i,array());
+ }
+}
+
+
+ // tag with modifier and optional Smarty2 style attributes
+tag(res) ::= LDEL ID(i) modifierlist(l)attributes(a). {
+ if (defined(i)) {
+ if ($this->security) {
+ $this->security->isTrustedConstant(i, $this->compiler);
+ }
+ res = $this->compiler->compileTag('private_print_expression',a,array('value'=>i, 'modifierlist'=>l));
+ } else {
+ res = '<?php ob_start();?>'.$this->compiler->compileTag(i,a).'<?php echo ';
+ res .= $this->compiler->compileTag('private_modifier',array(),array('modifierlist'=>l,'value'=>'ob_get_clean()')).';?>';
+ }
+}
+
+ // registered object tag
+tag(res) ::= LDEL ID(i) PTR ID(m) attributes(a). {
+ res = $this->compiler->compileTag(i,a,array('object_method'=>m));
+}
+
+ // registered object tag with modifiers
+tag(res) ::= LDEL ID(i) PTR ID(me) modifierlist(l) attributes(a). {
+ res = '<?php ob_start();?>'.$this->compiler->compileTag(i,a,array('object_method'=>me)).'<?php echo ';
+ res .= $this->compiler->compileTag('private_modifier',array(),array('modifierlist'=>l,'value'=>'ob_get_clean()')).';?>';
+}
+
+ // {if}, {elseif} and {while} tag
+tag(res) ::= LDELIF(i) expr(ie). {
+ $tag = trim(substr(i,$this->lex->ldel_length));
+ res = $this->compiler->compileTag(($tag == 'else if')? 'elseif' : $tag,array(),array('if condition'=>ie));
+}
+
+tag(res) ::= LDELIF(i) expr(ie) attributes(a). {
+ $tag = trim(substr(i,$this->lex->ldel_length));
+ res = $this->compiler->compileTag(($tag == 'else if')? 'elseif' : $tag,a,array('if condition'=>ie));
+}
+
+tag(res) ::= LDELIF(i) statement(ie). {
+ $tag = trim(substr(i,$this->lex->ldel_length));
+ res = $this->compiler->compileTag(($tag == 'else if')? 'elseif' : $tag,array(),array('if condition'=>ie));
+}
+
+tag(res) ::= LDELIF(i) statement(ie) attributes(a). {
+ $tag = trim(substr(i,$this->lex->ldel_length));
+ res = $this->compiler->compileTag(($tag == 'else if')? 'elseif' : $tag,a,array('if condition'=>ie));
+}
+
+ // {for} tag
+tag(res) ::= LDELFOR statements(st) SEMICOLON expr(ie) SEMICOLON varindexed(v2) foraction(e2) attributes(a). {
+ res = $this->compiler->compileTag('for',array_merge(a,array(array('start'=>st),array('ifexp'=>ie),array('var'=>v2),array('step'=>e2))),1);
+}
+
+ foraction(res) ::= EQUAL expr(e). {
+ res = '='.e;
+}
+
+ foraction(res) ::= INCDEC(e). {
+ res = e;
+}
+
+tag(res) ::= LDELFOR statement(st) TO expr(v) attributes(a). {
+ res = $this->compiler->compileTag('for',array_merge(a,array(array('start'=>st),array('to'=>v))),0);
+}
+
+tag(res) ::= LDELFOR statement(st) TO expr(v) STEP expr(v2) attributes(a). {
+ res = $this->compiler->compileTag('for',array_merge(a,array(array('start'=>st),array('to'=>v),array('step'=>v2))),0);
+}
+
+ // {foreach} tag
+tag(res) ::= LDELFOREACH attributes(a). {
+ res = $this->compiler->compileTag('foreach',a);
+}
+
+ // {foreach $array as $var} tag
+tag(res) ::= LDELFOREACH SPACE value(v1) AS varvar(v0) attributes(a). {
+ res = $this->compiler->compileTag('foreach',array_merge(a,array(array('from'=>v1),array('item'=>v0))));
+}
+
+tag(res) ::= LDELFOREACH SPACE value(v1) AS varvar(v2) APTR varvar(v0) attributes(a). {
+ res = $this->compiler->compileTag('foreach',array_merge(a,array(array('from'=>v1),array('item'=>v0),array('key'=>v2))));
+}
+
+tag(res) ::= LDELFOREACH SPACE expr(e) AS varvar(v0) attributes(a). {
+ res = $this->compiler->compileTag('foreach',array_merge(a,array(array('from'=>e),array('item'=>v0))));
+}
+
+tag(res) ::= LDELFOREACH SPACE expr(e) AS varvar(v1) APTR varvar(v0) attributes(a). {
+ res = $this->compiler->compileTag('foreach',array_merge(a,array(array('from'=>e),array('item'=>v0),array('key'=>v1))));
+}
+
+ // {setfilter}
+tag(res) ::= LDELSETFILTER ID(m) modparameters(p). {
+ res = $this->compiler->compileTag('setfilter',array(),array('modifier_list'=>array(array_merge(array(m),p))));
+}
+
+tag(res) ::= LDELSETFILTER ID(m) modparameters(p) modifierlist(l). {
+ res = $this->compiler->compileTag('setfilter',array(),array('modifier_list'=>array_merge(array(array_merge(array(m),p)),l)));
+}
+
+ // {$smarty.block.child} or {$smarty.block.parent}
+tag(res) ::= LDEL SMARTYBLOCKCHILDPARENT(i). {
+ $j = strrpos(i,'.');
+ if (i[$j+1] == 'c') {
+ // {$smarty.block.child}
+ res = SMARTY_INTERNAL_COMPILE_BLOCK::compileChildBlock($this->compiler);
+ } else {
+ // {$smarty.block.parent}
+ res = SMARTY_INTERNAL_COMPILE_BLOCK::compileParentBlock($this->compiler);
+ }
+}
+
+
+ // end of block tag {/....}
+smartytag(res)::= CLOSETAG(t). {
+ $tag = trim(substr(t, $this->lex->ldel_length, -$this->lex->rdel_length), ' /');
+ if ($tag == 'strip') {
+ $this->strip = false;
+ res = null;
+ } else {
+ res = $this->compiler->compileTag($tag.'close',array());
+ }
+ }
+tag(res) ::= LDELSLASH ID(i). {
+ res = $this->compiler->compileTag(i.'close',array());
+}
+
+tag(res) ::= LDELSLASH ID(i) modifierlist(l). {
+ res = $this->compiler->compileTag(i.'close',array(),array('modifier_list'=>l));
+}
+
+ // end of block object tag {/....}
+tag(res) ::= LDELSLASH ID(i) PTR ID(m). {
+ res = $this->compiler->compileTag(i.'close',array(),array('object_method'=>m));
+}
+
+tag(res) ::= LDELSLASH ID(i) PTR ID(m) modifierlist(l). {
+ res = $this->compiler->compileTag(i.'close',array(),array('object_method'=>m, 'modifier_list'=>l));
+}
+
+//
+//Attributes of Smarty tags
+//
+ // list of attributes
+attributes(res) ::= attributes(a1) attribute(a2). {
+ res = a1;
+ res[] = a2;
+}
+
+ // single attribute
+attributes(res) ::= attribute(a). {
+ res = array(a);
+}
+
+ // no attributes
+attributes(res) ::= . {
+ res = array();
+}
+
+ // attribute
+attribute(res) ::= SPACE ID(v) EQUAL ID(id). {
+ if (defined(id)) {
+ if ($this->security) {
+ $this->security->isTrustedConstant(id, $this->compiler);
+ }
+ res = array(v=>id);
+ } else {
+ res = array(v=>'\''.id.'\'');
+ }
+}
+
+attribute(res) ::= ATTR(v) expr(e). {
+ res = array(trim(v," =\n\r\t")=>e);
+}
+
+attribute(res) ::= ATTR(v) value(e). {
+ res = array(trim(v," =\n\r\t")=>e);
+}
+
+attribute(res) ::= SPACE ID(v). {
+ res = '\''.v.'\'';
+}
+
+attribute(res) ::= SPACE expr(e). {
+ res = e;
+}
+
+attribute(res) ::= SPACE value(v). {
+ res = v;
+}
+
+attribute(res) ::= SPACE INTEGER(i) EQUAL expr(e). {
+ res = array(i=>e);
+}
+
+
+
+//
+// statement
+//
+statements(res) ::= statement(s). {
+ res = array(s);
+}
+
+statements(res) ::= statements(s1) COMMA statement(s). {
+ s1[]=s;
+ res = s1;
+}
+
+statement(res) ::= DOLLARID(i) EQUAL INTEGER(e). {
+ res = array('var' => '\''.substr(i,1).'\'', 'value'=>e);
+}
+statement(res) ::= DOLLARID(i) EQUAL expr(e). {
+ res = array('var' => '\''.substr(i,1).'\'', 'value'=>e);
+}
+
+statement(res) ::= varindexed(vi) EQUAL expr(e). {
+ res = array('var' => vi, 'value'=>e);
+}
+
+statement(res) ::= OPENP statement(st) CLOSEP. {
+ res = st;
+}
+
+
+//
+// expressions
+//
+
+ // single value
+expr(res) ::= value(v). {
+ res = v;
+}
+
+ // ternary
+expr(res) ::= ternary(v). {
+ res = v;
+}
+
+ // resources/streams
+expr(res) ::= DOLLARID(i) COLON ID(i2). {
+ res = '$_smarty_tpl->getStreamVariable(\''.substr(i,1).'://' . i2 . '\')';
+}
+
+ // arithmetic expression
+expr(res) ::= expr(e) MATH(m) value(v). {
+ res = e . trim(m) . v;
+}
+
+expr(res) ::= expr(e) UNIMATH(m) value(v). {
+ res = e . trim(m) . v;
+}
+
+ // array
+expr(res) ::= array(a). {
+ res = a;
+}
+
+ // modifier
+expr(res) ::= expr(e) modifierlist(l). {
+ res = $this->compiler->compileTag('private_modifier',array(),array('value'=>e,'modifierlist'=>l));
+}
+
+// if expression
+ // simple expression
+expr(res) ::= expr(e1) lop(c) expr(e2). {
+ res = (isset(c['pre']) ? c['pre'] : '') . e1.c['op'].e2 . (isset(c['pre']) ? ')' : '');
+}
+expr(res) ::= expr(e1) scond(c). {
+ res = c . e1 . ')';
+}
+
+expr(res) ::= expr(e1) ISIN array(a). {
+ res = 'in_array('.e1.','.a.')';
+}
+
+expr(res) ::= expr(e1) ISIN value(v). {
+ res = 'in_array('.e1.',(array)'.v.')';
+}
+
+expr(res) ::= variable(v1) INSTANCEOF(i) ns1(v2). {
+ res = v1.i.v2;
+}
+
+
+//
+// ternary
+//
+ternary(res) ::= OPENP expr(v) CLOSEP QMARK DOLLARID(e1) COLON expr(e2). {
+ res = v.' ? '. $this->compiler->compileVariable('\''.substr(e1,1).'\'') . ' : '.e2;
+}
+
+ternary(res) ::= OPENP expr(v) CLOSEP QMARK expr(e1) COLON expr(e2). {
+ res = v.' ? '.e1.' : '.e2;
+}
+
+ // value
+value(res) ::= variable(v). {
+ res = v;
+}
+
+ // +/- value
+value(res) ::= UNIMATH(m) value(v). {
+ res = m.v;
+}
+
+ // logical negation
+value(res) ::= NOT value(v). {
+ res = '!'.v;
+}
+
+value(res) ::= TYPECAST(t) value(v). {
+ res = t.v;
+}
+
+value(res) ::= variable(v) INCDEC(o). {
+ res = v.o;
+}
+
+ // numeric
+value(res) ::= HEX(n). {
+ res = n;
+}
+
+value(res) ::= INTEGER(n). {
+ res = n;
+}
+
+value(res) ::= INTEGER(n1) DOT INTEGER(n2). {
+ res = n1.'.'.n2;
+}
+
+value(res) ::= INTEGER(n1) DOT. {
+ res = n1.'.';
+}
+
+value(res) ::= DOT INTEGER(n1). {
+ res = '.'.n1;
+}
+
+ // ID, true, false, null
+value(res) ::= ID(id). {
+ if (defined(id)) {
+ if ($this->security) {
+ $this->security->isTrustedConstant(id, $this->compiler);
+ }
+ res = id;
+ } else {
+ res = '\''.id.'\'';
+ }
+}
+
+ // function call
+value(res) ::= function(f). {
+ res = f;
+}
+
+ // expression
+value(res) ::= OPENP expr(e) CLOSEP. {
+ res = "(". e .")";
+}
+
+ // singele quoted string
+value(res) ::= SINGLEQUOTESTRING(t). {
+ res = t;
+}
+
+ // double quoted string
+value(res) ::= doublequoted_with_quotes(s). {
+ res = s;
+}
+
+
+value(res) ::= varindexed(vi) DOUBLECOLON static_class_access(r). {
+ self::$prefix_number++;
+ if (vi['var'] == '\'smarty\'') {
+ $this->compiler->prefix_code[] = '<?php $_tmp'.self::$prefix_number.' = '. $this->compiler->compileTag('private_special_variable',array(),vi['smarty_internal_index']).';?>';
+ } else {
+ $this->compiler->prefix_code[] = '<?php $_tmp'.self::$prefix_number.' = '. $this->compiler->compileVariable(vi['var']).vi['smarty_internal_index'].';?>';
+ }
+ res = '$_tmp'.self::$prefix_number.'::'.r[0].r[1];
+}
+
+ // Smarty tag
+value(res) ::= smartytag(st). {
+ self::$prefix_number++;
+ $tmp = $this->compiler->appendCode('<?php ob_start();?>', st);
+ $this->compiler->prefix_code[] = $this->compiler->appendCode($tmp, '<?php $_tmp'.self::$prefix_number.'=ob_get_clean();?>');
+ res = '$_tmp'.self::$prefix_number;
+}
+
+value(res) ::= value(v) modifierlist(l). {
+ res = $this->compiler->compileTag('private_modifier',array(),array('value'=>v,'modifierlist'=>l));
+}
+ // name space constant
+value(res) ::= NAMESPACE(c). {
+ res = c;
+}
+
+
+ // static class access
+value(res) ::= ns1(c)DOUBLECOLON static_class_access(s). {
+ if (!in_array(strtolower(c), array('self', 'parent')) && (!$this->security || $this->security->isTrustedStaticClassAccess(c, s, $this->compiler))) {
+ if (isset($this->smarty->registered_classes[c])) {
+ res = $this->smarty->registered_classes[c].'::'.s[0].s[1];
+ } else {
+ res = c.'::'.s[0].s[1];
+ }
+ } else {
+ $this->compiler->trigger_template_error ("static class '".c."' is undefined or not allowed by security setting");
+ }
+}
+//
+// namespace stuff
+//
+
+ns1(res) ::= ID(i). {
+ res = i;
+}
+
+ns1(res) ::= NAMESPACE(i). {
+ res = i;
+}
+
+//ns1(res) ::= variable(v). {
+// res = v;
+//}
+
+
+
+
+//
+// variables
+//
+ // Smarty variable (optional array)
+variable(res) ::= DOLLARID(i). {
+ res = $this->compiler->compileVariable('\''.substr(i,1).'\'');
+}
+variable(res) ::= varindexed(vi). {
+ if (vi['var'] == '\'smarty\'') {
+ $smarty_var = $this->compiler->compileTag('private_special_variable',array(),vi['smarty_internal_index']);
+ res = $smarty_var;
+ } else {
+ // used for array reset,next,prev,end,current
+ $this->last_variable = vi['var'];
+ $this->last_index = vi['smarty_internal_index'];
+ res = $this->compiler->compileVariable(vi['var']).vi['smarty_internal_index'];
+ }
+}
+
+ // variable with property
+variable(res) ::= varvar(v) AT ID(p). {
+ res = '$_smarty_tpl->tpl_vars['. v .']->'.p;
+}
+
+ // object
+variable(res) ::= object(o). {
+ res = o;
+}
+
+ // config variable
+variable(res) ::= HATCH ID(i) HATCH. {
+ res = '$_smarty_tpl->getConfigVariable( \''. i .'\')';
+}
+
+variable(res) ::= HATCH ID(i) HATCH arrayindex(a). {
+ res = '(is_array($tmp = $_smarty_tpl->getConfigVariable( \''. i .'\')) ? $tmp'.a.' :null)';
+}
+
+variable(res) ::= HATCH variable(v) HATCH. {
+ res = '$_smarty_tpl->getConfigVariable( '. v .')';
+}
+
+variable(res) ::= HATCH variable(v) HATCH arrayindex(a). {
+ res = '(is_array($tmp = $_smarty_tpl->getConfigVariable( '. v .')) ? $tmp'.a.' : null)';
+}
+
+varindexed(res) ::= DOLLARID(i) arrayindex(a). {
+ res = array('var'=>'\''.substr(i,1).'\'', 'smarty_internal_index'=>a);
+}
+varindexed(res) ::= varvar(v) arrayindex(a). {
+ res = array('var'=>v, 'smarty_internal_index'=>a);
+}
+
+//
+// array index
+//
+ // multiple array index
+arrayindex(res) ::= arrayindex(a1) indexdef(a2). {
+ res = a1.a2;
+}
+
+ // no array index
+arrayindex ::= . {
+ return;
+}
+
+// single index definition
+ // Smarty2 style index
+indexdef(res) ::= DOT DOLLARID(i). {
+ res = '['.$this->compiler->compileVariable('\''.substr(i,1).'\'').']';
+}
+indexdef(res) ::= DOT varvar(v). {
+ res = '['.$this->compiler->compileVariable(v).']';
+}
+
+indexdef(res) ::= DOT varvar(v) AT ID(p). {
+ res = '['.$this->compiler->compileVariable(v).'->'.p.']';
+}
+
+indexdef(res) ::= DOT ID(i). {
+ if (defined(i)) {
+ if ($this->security) {
+ $this->security->isTrustedConstant(i, $this->compiler);
+ }
+ res = '['. i .']';
+ } else {
+ res = "['". i ."']";
+ }
+}
+
+indexdef(res) ::= DOT INTEGER(n). {
+ res = '['. n .']';
+}
+
+indexdef(res) ::= DOT LDEL expr(e) RDEL. {
+ res = '['. e .']';
+}
+
+ // section tag index
+indexdef(res) ::= OPENB ID(i)CLOSEB. {
+ res = '['.$this->compiler->compileTag('private_special_variable',array(),'[\'section\'][\''.i.'\'][\'index\']').']';
+}
+
+indexdef(res) ::= OPENB ID(i) DOT ID(i2) CLOSEB. {
+ res = '['.$this->compiler->compileTag('private_special_variable',array(),'[\'section\'][\''.i.'\'][\''.i2.'\']').']';
+}
+indexdef(res) ::= OPENB SINGLEQUOTESTRING(s) CLOSEB. {
+ res = '['.s.']';
+}
+indexdef(res) ::= OPENB INTEGER(n) CLOSEB. {
+ res = '['.n.']';
+}
+indexdef(res) ::= OPENB DOLLARID(i) CLOSEB. {
+ res = '['.$this->compiler->compileVariable('\''.substr(i,1).'\'').']';;
+}
+indexdef(res) ::= OPENB variable(v) CLOSEB. {
+ res = '['.v.']';
+}
+indexdef(res) ::= OPENB value(v) CLOSEB. {
+ res = '['.v.']';
+}
+
+ // PHP style index
+indexdef(res) ::= OPENB expr(e) CLOSEB. {
+ res = '['. e .']';
+}
+
+ // for assign append array
+indexdef(res) ::= OPENB CLOSEB. {
+ res = '[]';
+}
+
+
+//
+// variable variable names
+//
+
+ // singel identifier element
+varvar(res) ::= DOLLARID(i). {
+ res = '\''.substr(i,1).'\'';
+}
+ // single $
+varvar(res) ::= DOLLAR. {
+ res = "''";
+}
+
+ // sequence of identifier elements
+varvar(res) ::= varvar(v1) varvarele(v2). {
+ res = v1.'.'.v2;
+}
+
+ // fix sections of element
+varvarele(res) ::= ID(s). {
+ res = '\''.s.'\'';
+}
+
+ // variable sections of element
+varvarele(res) ::= LDEL expr(e) RDEL. {
+ res = '('.e.')';
+}
+
+//
+// objects
+//
+object(res) ::= varindexed(vi) objectchain(oc). {
+ if (vi['var'] == '\'smarty\'') {
+ res = $this->compiler->compileTag('private_special_variable',array(),vi['smarty_internal_index']).oc;
+ } else {
+ res = $this->compiler->compileVariable(vi['var']).vi['smarty_internal_index'].oc;
+ }
+}
+
+ // single element
+objectchain(res) ::= objectelement(oe). {
+ res = oe;
+}
+
+ // chain of elements
+objectchain(res) ::= objectchain(oc) objectelement(oe). {
+ res = oc.oe;
+}
+
+ // variable
+objectelement(res)::= PTR ID(i) arrayindex(a). {
+ if ($this->security && substr(i,0,1) == '_') {
+ $this->compiler->trigger_template_error (self::Err1);
+ }
+ res = '->'.i.a;
+}
+
+objectelement(res)::= PTR varvar(v) arrayindex(a). {
+ if ($this->security) {
+ $this->compiler->trigger_template_error (self::Err2);
+ }
+ res = '->{'.$this->compiler->compileVariable(v).a.'}';
+}
+
+objectelement(res)::= PTR LDEL expr(e) RDEL arrayindex(a). {
+ if ($this->security) {
+ $this->compiler->trigger_template_error (self::Err2);
+ }
+ res = '->{'.e.a.'}';
+}
+
+objectelement(res)::= PTR ID(ii) LDEL expr(e) RDEL arrayindex(a). {
+ if ($this->security) {
+ $this->compiler->trigger_template_error (self::Err2);
+ }
+ res = '->{\''.ii.'\'.'.e.a.'}';
+}
+
+ // method
+objectelement(res)::= PTR method(f). {
+ res = '->'.f;
+}
+
+
+//
+// function
+//
+function(res) ::= ns1(f) OPENP params(p) CLOSEP. {
+ if (!$this->security || $this->security->isTrustedPhpFunction(f, $this->compiler)) {
+ if (strcasecmp(f,'isset') === 0 || strcasecmp(f,'empty') === 0 || strcasecmp(f,'array') === 0 || is_callable(f)) {
+ $func_name = strtolower(f);
+ if ($func_name == 'isset') {
+ if (count(p) == 0) {
+ $this->compiler->trigger_template_error ('Illegal number of paramer in "isset()"');
+ }
+ $par = implode(',',p);
+ if (strncasecmp($par,'$_smarty_tpl->getConfigVariable',strlen('$_smarty_tpl->getConfigVariable')) === 0) {
+ self::$prefix_number++;
+ $this->compiler->prefix_code[] = '<?php $_tmp'.self::$prefix_number.'='.str_replace(')',', false)',$par).';?>';
+ $isset_par = '$_tmp'.self::$prefix_number;
+ } else {
+ $isset_par=str_replace("')->value","',null,true,false)->value",$par);
+ }
+ res = f . "(". $isset_par .")";
+ } elseif (in_array($func_name,array('empty','reset','current','end','prev','next'))){
+ if (count(p) != 1) {
+ $this->compiler->trigger_template_error ('Illegal number of paramer in "empty()"');
+ }
+ if ($func_name == 'empty') {
+ res = $func_name.'('.str_replace("')->value","',null,true,false)->value",p[0]).')';
+ } else {
+ res = $func_name.'('.p[0].')';
+ }
+ } else {
+ res = f . "(". implode(',',p) .")";
+ }
+ } else {
+ $this->compiler->trigger_template_error ("unknown function \"" . f . "\"");
+ }
+ }
+}
+
+
+//
+// method
+//
+method(res) ::= ID(f) OPENP params(p) CLOSEP. {
+ if ($this->security && substr(f,0,1) == '_') {
+ $this->compiler->trigger_template_error (self::Err1);
+ }
+ res = f . "(". implode(',',p) .")";
+}
+
+method(res) ::= DOLLARID(f) OPENP params(p) CLOSEP. {
+ if ($this->security) {
+ $this->compiler->trigger_template_error (self::Err2);
+ }
+ self::$prefix_number++;
+ $this->compiler->prefix_code[] = '<?php $_tmp'.self::$prefix_number.'='.$this->compiler->compileVariable('\''.substr(f,1).'\'').';?>';
+ res = '$_tmp'.self::$prefix_number.'('. implode(',',p) .')';
+}
+
+// function/method parameter
+ // multiple parameters
+params(res) ::= params(p) COMMA expr(e). {
+ res = array_merge(p,array(e));
+}
+
+ // single parameter
+params(res) ::= expr(e). {
+ res = array(e);
+}
+
+ // kein parameter
+params(res) ::= . {
+ res = array();
+}
+
+//
+// modifier
+//
+modifierlist(res) ::= modifierlist(l) modifier(m) modparameters(p). {
+ res = array_merge(l,array(array_merge(m,p)));
+}
+
+modifierlist(res) ::= modifier(m) modparameters(p). {
+ res = array(array_merge(m,p));
+}
+
+modifier(res) ::= VERT AT ID(m). {
+ res = array(m);
+}
+
+modifier(res) ::= VERT ID(m). {
+ res = array(m);
+}
+
+//
+// modifier parameter
+//
+ // multiple parameter
+modparameters(res) ::= modparameters(mps) modparameter(mp). {
+ res = array_merge(mps,mp);
+}
+
+ // no parameter
+modparameters(res) ::= . {
+ res = array();
+}
+
+ // parameter expression
+modparameter(res) ::= COLON value(mp). {
+ res = array(mp);
+}
+
+modparameter(res) ::= COLON array(mp). {
+ res = array(mp);
+}
+
+ // static class methode call
+static_class_access(res) ::= method(m). {
+ res = array(m, '', 'method');
+}
+
+ // static class methode call with object chainig
+static_class_access(res) ::= method(m) objectchain(oc). {
+ res = array(m, oc, 'method');
+}
+
+ // static class constant
+static_class_access(res) ::= ID(v). {
+ res = array(v, '');
+}
+
+ // static class variables
+static_class_access(res) ::= DOLLARID(v) arrayindex(a). {
+ res = array(v, a, 'property');
+}
+
+ // static class variables with object chain
+static_class_access(res) ::= DOLLARID(v) arrayindex(a) objectchain(oc). {
+ res = array(v, a.oc, 'property');
+}
+
+
+// if conditions and operators
+lop(res) ::= LOGOP(o). {
+ res['op'] = ' '. trim(o) . ' ';
+}
+
+lop(res) ::= TLOGOP(o). {
+ static $lops = array(
+ 'eq' => array('op' => ' == ', 'pre' => null),
+ 'ne' => array('op' => ' != ', 'pre' => null),
+ 'neq' => array('op' => ' != ', 'pre' => null),
+ 'gt' => array('op' => ' > ', 'pre' => null),
+ 'ge' => array('op' => ' >= ', 'pre' => null),
+ 'gte' => array('op' => ' >= ', 'pre' => null),
+ 'lt' => array('op' => ' < ', 'pre' => null),
+ 'le' => array('op' => ' <= ', 'pre' => null),
+ 'lte' => array('op' => ' <= ', 'pre' => null),
+ 'mod' => array('op' => ' % ', 'pre' => null),
+ 'and' => array('op' => ' && ', 'pre' => null),
+ 'or' => array('op' => ' || ', 'pre' => null),
+ 'xor' => array('op' => ' xor ', 'pre' => null),
+ 'isdivby' => array('op' => ' % ', 'pre' => '!('),
+ 'isnotdivby' => array('op' => ' % ', 'pre' => '('),
+ 'isevenby' => array('op' => ' / ', 'pre' => '!(1 & '),
+ 'isnotevenby' => array('op' => ' / ', 'pre' => '(1 & '),
+ 'isoddby' => array('op' => ' / ', 'pre' => '(1 & '),
+ 'isnotoddby' => array('op' => ' / ', 'pre' => '!(1 & '),
+ );
+ $op = strtolower(preg_replace('/\s*/', '', o));
+ res = $lops[$op];
+}
+
+scond(res) ::= SINGLECOND(o). {
+ static $scond = array (
+ 'iseven' => '!(1 & ',
+ 'isnoteven' => '(1 & ',
+ 'isodd' => '(1 & ',
+ 'isnotodd' => '!(1 & ',
+ );
+ $op = strtolower(str_replace(' ', '', o));
+ res = $scond[$op];
+}
+
+//
+// ARRAY element assignment
+//
+array(res) ::= OPENB arrayelements(a) CLOSEB. {
+ res = 'array('.a.')';
+}
+
+arrayelements(res) ::= arrayelement(a). {
+ res = a;
+}
+
+arrayelements(res) ::= arrayelements(a1) COMMA arrayelement(a). {
+ res = a1.','.a;
+}
+
+arrayelements ::= . {
+ return;
+}
+
+arrayelement(res) ::= value(e1) APTR expr(e2). {
+ res = e1.'=>'.e2;
+}
+
+arrayelement(res) ::= ID(i) APTR expr(e2). {
+ res = '\''.i.'\'=>'.e2;
+}
+
+arrayelement(res) ::= expr(e). {
+ res = e;
+}
+
+
+//
+// double qouted strings
+//
+doublequoted_with_quotes(res) ::= QUOTE QUOTE. {
+ res = "''";
+}
+
+doublequoted_with_quotes(res) ::= QUOTE doublequoted(s) QUOTE. {
+ res = s->to_smarty_php();
+}
+
+
+doublequoted(res) ::= doublequoted(o1) doublequotedcontent(o2). {
+ o1->append_subtree(o2);
+ res = o1;
+}
+
+doublequoted(res) ::= doublequotedcontent(o). {
+ res = new Smarty_Internal_ParseTree_Dq($this, o);
+}
+
+doublequotedcontent(res) ::= BACKTICK variable(v) BACKTICK. {
+ res = new Smarty_Internal_ParseTree_Code($this, '(string)'.v);
+}
+
+doublequotedcontent(res) ::= BACKTICK expr(e) BACKTICK. {
+ res = new Smarty_Internal_ParseTree_Code($this, '(string)'.e);
+}
+
+doublequotedcontent(res) ::= DOLLARID(i). {
+ res = new Smarty_Internal_ParseTree_Code($this, '(string)$_smarty_tpl->tpl_vars[\''. substr(i,1) .'\']->value');
+}
+
+doublequotedcontent(res) ::= LDEL variable(v) RDEL. {
+ res = new Smarty_Internal_ParseTree_Code($this, '(string)'.v);
+}
+
+doublequotedcontent(res) ::= LDEL expr(e) RDEL. {
+ res = new Smarty_Internal_ParseTree_Code($this, '(string)('.e.')');
+}
+
+doublequotedcontent(res) ::= smartytag(st). {
+ res = new Smarty_Internal_ParseTree_Tag($this, st);
+}
+
+doublequotedcontent(res) ::= TEXT(o). {
+ res = new Smarty_Internal_ParseTree_DqContent($this, o);
+}
+
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/Autoloader.php
@@ -0,0 +1,154 @@
+<?php
+/**
+ * Smarty Autoloader
+ *
+ * @package Smarty
+ */
+
+/**
+ * Smarty Autoloader
+ *
+ * @package Smarty
+ * @author Uwe Tews
+ * Usage:
+ * require_once '...path/Autoloader.php';
+ * Smarty_Autoloader::register();
+ * $smarty = new Smarty();
+ * Note: This autoloader is not needed if you use Composer.
+ * Composer will automatically add the classes of the Smarty package to it common autoloader.
+ */
+class Smarty_Autoloader {
+ /**
+ * Filepath to Smarty root
+ *
+ * @var string
+ */
+ public static $SMARTY_DIR = '';
+ /**
+ * Filepath to Smarty internal plugins
+ *
+ * @var string
+ */
+ public static $SMARTY_SYSPLUGINS_DIR = '';
+ /**
+ * Array of not existing classes to avoid is_file calls for already tested classes
+ *
+ * @var array
+ */
+ public static $unknown = array();
+ /**
+ * Array with Smarty core classes and their filename
+ *
+ * @var array
+ */
+ public static $rootClasses = array('Smarty' => 'Smarty.class.php',
+ 'SmartyBC' => 'SmartyBC.class.php',
+ );
+
+ private static $syspluginsClasses = array(
+ 'smarty_config_source' => true,
+ 'smarty_security' => true,
+ 'smarty_cacheresource' => true,
+ 'smarty_compiledresource' => true,
+ 'smarty_cacheresource_custom' => true,
+ 'smarty_cacheresource_keyvaluestore' => true,
+ 'smarty_resource' => true,
+ 'smarty_resource_custom' => true,
+ 'smarty_resource_uncompiled' => true,
+ 'smarty_resource_recompiled' => true,
+ 'smarty_template_source' => true,
+ 'smarty_template_compiled' => true,
+ 'smarty_template_cached' => true,
+ 'smarty_template_config' => true,
+ 'smarty_data' => true,
+ 'smarty_variable' => true,
+ 'smarty_undefined_variable' => true,
+ 'smartyexception' => true,
+ 'smartycompilerexception' => true,
+ 'smarty_internal_data' => true,
+ 'smarty_internal_template' => true,
+ 'smarty_internal_templatebase' => true,
+ 'smarty_internal_resource_file' => true,
+ 'smarty_internal_resource_extends' => true,
+ 'smarty_internal_resource_eval' => true,
+ 'smarty_internal_resource_string' => true,
+ 'smarty_internal_resource_registered' => true,
+ 'smarty_internal_extension_codeframe' => true,
+ 'smarty_internal_extension_config' => true,
+ 'smarty_internal_filter_handler' => true,
+ 'smarty_internal_function_call_handler' => true,
+ 'smarty_internal_cacheresource_file' => true,
+ 'smarty_internal_write_file' => true,
+ );
+
+ /**
+ * Registers Smarty_Autoloader backward compatible to older installations.
+ *
+ * @param bool $prepend Whether to prepend the autoloader or not.
+ */
+ public static function registerBC($prepend = false) {
+ /**
+ * register the class autoloader
+ */
+ if (!defined('SMARTY_SPL_AUTOLOAD')) {
+ define('SMARTY_SPL_AUTOLOAD', 0);
+ }
+ if (SMARTY_SPL_AUTOLOAD && set_include_path(get_include_path() . PATH_SEPARATOR . SMARTY_SYSPLUGINS_DIR) !== false) {
+ $registeredAutoLoadFunctions = spl_autoload_functions();
+ if (!isset($registeredAutoLoadFunctions['spl_autoload'])) {
+ spl_autoload_register();
+ }
+ } else {
+ self::register($prepend);
+ }
+ }
+
+ /**
+ * Registers Smarty_Autoloader as an SPL autoloader.
+ *
+ * @param bool $prepend Whether to prepend the autoloader or not.
+ */
+ public static function register($prepend = false) {
+ self::$SMARTY_DIR = defined('SMARTY_DIR') ? SMARTY_DIR : dirname(__FILE__) . '/';
+ self::$SMARTY_SYSPLUGINS_DIR = defined('SMARTY_SYSPLUGINS_DIR') ? SMARTY_SYSPLUGINS_DIR : self::$SMARTY_DIR . 'sysplugins/';
+ if (version_compare(phpversion(), '5.3.0', '>=')) {
+ spl_autoload_register(array(__CLASS__, 'autoload'), true, $prepend);
+ } else {
+ spl_autoload_register(array(__CLASS__, 'autoload'));
+ }
+ }
+
+ /**
+ * Handles autoloading of classes.
+ *
+ * @param string $class A class name.
+ */
+ public static function autoload($class) {
+ // Request for Smarty or already unknown class
+ if (isset(self::$unknown[$class])) {
+ return;
+ }
+ $_class = strtolower($class);
+ if (isset(self::$syspluginsClasses[$_class])) {
+ $_class = (self::$syspluginsClasses[$_class] === true) ? $_class : self::$syspluginsClasses[$_class];
+ $file = self::$SMARTY_SYSPLUGINS_DIR . $_class . '.php';
+ require_once $file;
+ return;
+ } elseif (0 !== strpos($_class, 'smarty_internal_')) {
+ if (isset(self::$rootClasses[$class])) {
+ $file = self::$SMARTY_DIR . self::$rootClasses[$class];
+ require_once $file;
+ return;
+ }
+ self::$unknown[$class] = true;
+ return;
+ }
+ $file = self::$SMARTY_SYSPLUGINS_DIR . $_class . '.php';
+ if (is_file($file)) {
+ require_once $file;
+ return;
+ }
+ self::$unknown[$class] = true;
+ return;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/Smarty.class.php
@@ -0,0 +1,1739 @@
+<?php
+/**
+ * Project: Smarty: the PHP compiling template engine
+ * File: Smarty.class.php
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * For questions, help, comments, discussion, etc., please join the
+ * Smarty mailing list. Send a blank e-mail to
+ * smarty-discussion-subscribe@googlegroups.com
+ *
+ * @link http://www.smarty.net/
+ * @copyright 2015 New Digital Group, Inc.
+ * @copyright 2015 Uwe Tews
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author Uwe Tews
+ * @author Rodney Rehm
+ * @package Smarty
+ * @version 3.1.27
+ */
+
+/**
+ * define shorthand directory separator constant
+ */
+if (!defined('DS')) {
+ define('DS', DIRECTORY_SEPARATOR);
+}
+
+/**
+ * set SMARTY_DIR to absolute path to Smarty library files.
+ * Sets SMARTY_DIR only if user application has not already defined it.
+ */
+if (!defined('SMARTY_DIR')) {
+ define('SMARTY_DIR', dirname(__FILE__) . DS);
+}
+
+/**
+ * set SMARTY_SYSPLUGINS_DIR to absolute path to Smarty internal plugins.
+ * Sets SMARTY_SYSPLUGINS_DIR only if user application has not already defined it.
+ */
+if (!defined('SMARTY_SYSPLUGINS_DIR')) {
+ define('SMARTY_SYSPLUGINS_DIR', SMARTY_DIR . 'sysplugins' . DS);
+}
+if (!defined('SMARTY_PLUGINS_DIR')) {
+ define('SMARTY_PLUGINS_DIR', SMARTY_DIR . 'plugins' . DS);
+}
+if (!defined('SMARTY_MBSTRING')) {
+ define('SMARTY_MBSTRING', function_exists('mb_get_info'));
+}
+if (!defined('SMARTY_RESOURCE_CHAR_SET')) {
+ // UTF-8 can only be done properly when mbstring is available!
+ /**
+ * @deprecated in favor of Smarty::$_CHARSET
+ */
+ define('SMARTY_RESOURCE_CHAR_SET', SMARTY_MBSTRING ? 'UTF-8' : 'ISO-8859-1');
+}
+if (!defined('SMARTY_RESOURCE_DATE_FORMAT')) {
+ /**
+ * @deprecated in favor of Smarty::$_DATE_FORMAT
+ */
+ define('SMARTY_RESOURCE_DATE_FORMAT', '%b %e, %Y');
+}
+
+/**
+ * Try loading the Smarty_Internal_Data class
+ * If we fail we must load Smarty's autoloader.
+ * Otherwise we may have a global autoloader like Composer
+ */
+if (!class_exists('Smarty_Autoloader', false)) {
+ if (!class_exists('Smarty_Internal_Data', true)) {
+ require_once 'Autoloader.php';
+ Smarty_Autoloader::registerBC();
+ }
+}
+
+/**
+ * Load always needed external class files
+ */
+
+if (!class_exists('Smarty_Internal_Data', false)) {
+ require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_data.php';
+}
+require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_templatebase.php';
+require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_template.php';
+require_once SMARTY_SYSPLUGINS_DIR . 'smarty_resource.php';
+require_once SMARTY_SYSPLUGINS_DIR . 'smarty_variable.php';
+require_once SMARTY_SYSPLUGINS_DIR . 'smarty_template_source.php';
+
+/**
+ * This is the main Smarty class
+ *
+ * @package Smarty
+ */
+class Smarty extends Smarty_Internal_TemplateBase {
+ /**#@+
+ * constant definitions
+ */
+
+ /**
+ * smarty version
+ */
+ const SMARTY_VERSION = '3.1.27';
+
+ /**
+ * define variable scopes
+ */
+ const SCOPE_LOCAL = 0;
+
+ const SCOPE_PARENT = 1;
+
+ const SCOPE_ROOT = 2;
+
+ const SCOPE_GLOBAL = 3;
+
+ /**
+ * define caching modes
+ */
+ const CACHING_OFF = 0;
+
+ const CACHING_LIFETIME_CURRENT = 1;
+
+ const CACHING_LIFETIME_SAVED = 2;
+
+ /**
+ * define constant for clearing cache files be saved expiration datees
+ */
+ const CLEAR_EXPIRED = -1;
+
+ /**
+ * define compile check modes
+ */
+ const COMPILECHECK_OFF = 0;
+
+ const COMPILECHECK_ON = 1;
+
+ const COMPILECHECK_CACHEMISS = 2;
+
+ /**
+ * define debug modes
+ */
+ const DEBUG_OFF = 0;
+
+ const DEBUG_ON = 1;
+
+ const DEBUG_INDIVIDUAL = 2;
+
+ /**
+ * modes for handling of "<?php ... ?>" tags in templates.
+ */
+ const PHP_PASSTHRU = 0; //-> print tags as plain text
+
+ const PHP_QUOTE = 1; //-> escape tags as entities
+
+ const PHP_REMOVE = 2; //-> escape tags as entities
+
+ const PHP_ALLOW = 3; //-> escape tags as entities
+
+ /**
+ * filter types
+ */
+ const FILTER_POST = 'post';
+
+ const FILTER_PRE = 'pre';
+
+ const FILTER_OUTPUT = 'output';
+
+ const FILTER_VARIABLE = 'variable';
+
+ /**
+ * plugin types
+ */
+ const PLUGIN_FUNCTION = 'function';
+
+ const PLUGIN_BLOCK = 'block';
+
+ const PLUGIN_COMPILER = 'compiler';
+
+ const PLUGIN_MODIFIER = 'modifier';
+
+ const PLUGIN_MODIFIERCOMPILER = 'modifiercompiler';
+
+ /**#@-*/
+
+ /**
+ * assigned global tpl vars
+ */
+ public static $global_tpl_vars = array();
+
+ /**
+ * error handler returned by set_error_hanlder() in Smarty::muteExpectedErrors()
+ */
+ public static $_previous_error_handler = null;
+
+ /**
+ * contains directories outside of SMARTY_DIR that are to be muted by muteExpectedErrors()
+ */
+ public static $_muted_directories = array('./templates_c/' => null, './cache/' => null);
+
+ /**
+ * Flag denoting if Multibyte String functions are available
+ */
+ public static $_MBSTRING = SMARTY_MBSTRING;
+
+ /**
+ * The character set to adhere to (e.g. "UTF-8")
+ */
+ public static $_CHARSET = SMARTY_RESOURCE_CHAR_SET;
+
+ /**
+ * The date format to be used internally
+ * (accepts date() and strftime())
+ */
+ public static $_DATE_FORMAT = SMARTY_RESOURCE_DATE_FORMAT;
+
+ /**
+ * Flag denoting if PCRE should run in UTF-8 mode
+ */
+ public static $_UTF8_MODIFIER = 'u';
+
+ /**
+ * Flag denoting if operating system is windows
+ */
+ public static $_IS_WINDOWS = false;
+
+ /**#@+
+ * variables
+ */
+
+ /**
+ * auto literal on delimiters with whitspace
+ *
+ * @var boolean
+ */
+ public $auto_literal = true;
+
+ /**
+ * display error on not assigned variables
+ *
+ * @var boolean
+ */
+ public $error_unassigned = false;
+
+ /**
+ * look up relative filepaths in include_path
+ *
+ * @var boolean
+ */
+ public $use_include_path = false;
+
+ /**
+ * template directory
+ *
+ * @var array
+ */
+ private $template_dir = array('./templates/');
+
+ /**
+ * joined template directory string used in cache keys
+ *
+ * @var string
+ */
+ public $joined_template_dir = './templates/';
+
+ /**
+ * joined config directory string used in cache keys
+ *
+ * @var string
+ */
+ public $joined_config_dir = './configs/';
+
+ /**
+ * default template handler
+ *
+ * @var callable
+ */
+ public $default_template_handler_func = null;
+
+ /**
+ * default config handler
+ *
+ * @var callable
+ */
+ public $default_config_handler_func = null;
+
+ /**
+ * default plugin handler
+ *
+ * @var callable
+ */
+ public $default_plugin_handler_func = null;
+
+ /**
+ * compile directory
+ *
+ * @var string
+ */
+ private $compile_dir = './templates_c/';
+
+ /**
+ * plugins directory
+ *
+ * @var array
+ */
+ private $plugins_dir = null;
+
+ /**
+ * cache directory
+ *
+ * @var string
+ */
+ private $cache_dir = './cache/';
+
+ /**
+ * config directory
+ *
+ * @var array
+ */
+ private $config_dir = array('./configs/');
+
+ /**
+ * force template compiling?
+ *
+ * @var boolean
+ */
+ public $force_compile = false;
+
+ /**
+ * check template for modifications?
+ *
+ * @var boolean
+ */
+ public $compile_check = true;
+
+ /**
+ * use sub dirs for compiled/cached files?
+ *
+ * @var boolean
+ */
+ public $use_sub_dirs = false;
+
+ /**
+ * allow ambiguous resources (that are made unique by the resource handler)
+ *
+ * @var boolean
+ */
+ public $allow_ambiguous_resources = false;
+
+ /**
+ * merge compiled includes
+ *
+ * @var boolean
+ */
+ public $merge_compiled_includes = false;
+
+ /**
+ * template inheritance merge compiled includes
+ *
+ * @var boolean
+ */
+ public $inheritance_merge_compiled_includes = true;
+
+ /**
+ * force cache file creation
+ *
+ * @var boolean
+ */
+ public $force_cache = false;
+
+ /**
+ * template left-delimiter
+ *
+ * @var string
+ */
+ public $left_delimiter = "{";
+
+ /**
+ * template right-delimiter
+ *
+ * @var string
+ */
+ public $right_delimiter = "}";
+
+ /**#@+
+ * security
+ */
+ /**
+ * class name
+ * This should be instance of Smarty_Security.
+ *
+ * @var string
+ * @see Smarty_Security
+ */
+ public $security_class = 'Smarty_Security';
+
+ /**
+ * implementation of security class
+ *
+ * @var Smarty_Security
+ */
+ public $security_policy = null;
+
+ /**
+ * controls handling of PHP-blocks
+ *
+ * @var integer
+ */
+ public $php_handling = self::PHP_PASSTHRU;
+
+ /**
+ * controls if the php template file resource is allowed
+ *
+ * @var bool
+ */
+ public $allow_php_templates = false;
+
+ /**
+ * Should compiled-templates be prevented from being called directly?
+ * {@internal
+ * Currently used by Smarty_Internal_Template only.
+ * }}
+ *
+ * @var boolean
+ */
+ public $direct_access_security = true;
+
+ /**#@-*/
+ /**
+ * debug mode
+ * Setting this to true enables the debug-console.
+ *
+ * @var boolean
+ */
+ public $debugging = false;
+
+ /**
+ * This determines if debugging is enable-able from the browser.
+ * <ul>
+ * <li>NONE => no debugging control allowed</li>
+ * <li>URL => enable debugging when SMARTY_DEBUG is found in the URL.</li>
+ * </ul>
+ *
+ * @var string
+ */
+ public $debugging_ctrl = 'NONE';
+
+ /**
+ * Name of debugging URL-param.
+ * Only used when $debugging_ctrl is set to 'URL'.
+ * The name of the URL-parameter that activates debugging.
+ *
+ * @var string
+ */
+ public $smarty_debug_id = 'SMARTY_DEBUG';
+
+ /**
+ * Path of debug template.
+ *
+ * @var string
+ */
+ public $debug_tpl = null;
+
+ /**
+ * When set, smarty uses this value as error_reporting-level.
+ *
+ * @var int
+ */
+ public $error_reporting = null;
+
+ /**
+ * Internal flag for getTags()
+ *
+ * @var boolean
+ */
+ public $get_used_tags = false;
+
+ /**#@+
+ * config var settings
+ */
+
+ /**
+ * Controls whether variables with the same name overwrite each other.
+ *
+ * @var boolean
+ */
+ public $config_overwrite = true;
+
+ /**
+ * Controls whether config values of on/true/yes and off/false/no get converted to boolean.
+ *
+ * @var boolean
+ */
+ public $config_booleanize = true;
+
+ /**
+ * Controls whether hidden config sections/vars are read from the file.
+ *
+ * @var boolean
+ */
+ public $config_read_hidden = false;
+
+ /**#@-*/
+
+ /**#@+
+ * resource locking
+ */
+
+ /**
+ * locking concurrent compiles
+ *
+ * @var boolean
+ */
+ public $compile_locking = true;
+
+ /**
+ * Controls whether cache resources should emply locking mechanism
+ *
+ * @var boolean
+ */
+ public $cache_locking = false;
+
+ /**
+ * seconds to wait for acquiring a lock before ignoring the write lock
+ *
+ * @var float
+ */
+ public $locking_timeout = 10;
+
+ /**#@-*/
+
+ /**
+ * resource type used if none given
+ * Must be an valid key of $registered_resources.
+ *
+ * @var string
+ */
+ public $default_resource_type = 'file';
+
+ /**
+ * caching type
+ * Must be an element of $cache_resource_types.
+ *
+ * @var string
+ */
+ public $caching_type = 'file';
+
+ /**
+ * internal config properties
+ *
+ * @var array
+ */
+ public $properties = array();
+
+ /**
+ * config type
+ *
+ * @var string
+ */
+ public $default_config_type = 'file';
+
+ /**
+ * cached template objects
+ *
+ * @var array
+ */
+ public $source_objects = array();
+
+ /**
+ * cached template objects
+ *
+ * @var array
+ */
+ public $template_objects = array();
+
+ /**
+ * enable resource caching
+ *
+ * @var bool
+ */
+ public $resource_caching = false;
+
+ /**
+ * enable template resource caching
+ *
+ * @var bool
+ */
+ public $template_resource_caching = true;
+
+ /**
+ * check If-Modified-Since headers
+ *
+ * @var boolean
+ */
+ public $cache_modified_check = false;
+
+ /**
+ * registered plugins
+ *
+ * @var array
+ */
+ public $registered_plugins = array();
+
+ /**
+ * plugin search order
+ *
+ * @var array
+ */
+ public $plugin_search_order = array('function', 'block', 'compiler', 'class');
+
+ /**
+ * registered objects
+ *
+ * @var array
+ */
+ public $registered_objects = array();
+
+ /**
+ * registered classes
+ *
+ * @var array
+ */
+ public $registered_classes = array();
+
+ /**
+ * registered filters
+ *
+ * @var array
+ */
+ public $registered_filters = array();
+
+ /**
+ * registered resources
+ *
+ * @var array
+ */
+ public $registered_resources = array();
+
+ /**
+ * resource handler cache
+ *
+ * @var array
+ */
+ public $_resource_handlers = array();
+
+ /**
+ * registered cache resources
+ *
+ * @var array
+ */
+ public $registered_cache_resources = array();
+
+ /**
+ * cache resource handler cache
+ *
+ * @var array
+ */
+ public $_cacheresource_handlers = array();
+
+ /**
+ * autoload filter
+ *
+ * @var array
+ */
+ public $autoload_filters = array();
+
+ /**
+ * default modifier
+ *
+ * @var array
+ */
+ public $default_modifiers = array();
+
+ /**
+ * autoescape variable output
+ *
+ * @var boolean
+ */
+ public $escape_html = false;
+
+ /**
+ * global internal smarty vars
+ *
+ * @var array
+ */
+ public static $_smarty_vars = array();
+
+ /**
+ * start time for execution time calculation
+ *
+ * @var int
+ */
+ public $start_time = 0;
+
+ /**
+ * default file permissions
+ *
+ * @var int
+ */
+ public $_file_perms = 0644;
+
+ /**
+ * default dir permissions
+ *
+ * @var int
+ */
+ public $_dir_perms = 0771;
+
+ /**
+ * block tag hierarchy
+ *
+ * @var array
+ */
+ public $_tag_stack = array();
+
+ /**
+ * required by the compiler for BC
+ *
+ * @var string
+ */
+ public $_current_file = null;
+
+ /**
+ * internal flag to enable parser debugging
+ *
+ * @var bool
+ */
+ public $_parserdebug = false;
+
+ /**
+ * Cache of is_file results of loadPlugin()
+ *
+ * @var array
+ */
+ public $_is_file_cache = array();
+
+ /**#@-*/
+
+ /**
+ * Initialize new Smarty object
+ */
+ public function __construct() {
+ if (is_callable('mb_internal_encoding')) {
+ mb_internal_encoding(Smarty::$_CHARSET);
+ }
+ $this->start_time = microtime(true);
+ // check default dirs for overloading
+ if ($this->template_dir[0] !== './templates/' || isset($this->template_dir[1])) {
+ $this->setTemplateDir($this->template_dir);
+ }
+ if ($this->config_dir[0] !== './configs/' || isset($this->config_dir[1])) {
+ $this->setConfigDir($this->config_dir);
+ }
+ if ($this->compile_dir !== './templates_c/') {
+ unset(self::$_muted_directories['./templates_c/']);
+ $this->setCompileDir($this->compile_dir);
+ }
+ if ($this->cache_dir !== './cache/') {
+ unset(self::$_muted_directories['./cache/']);
+ $this->setCacheDir($this->cache_dir);
+ }
+ if (isset($this->plugins_dir)) {
+ $this->setPluginsDir($this->plugins_dir);
+ } else {
+ $this->setPluginsDir(SMARTY_PLUGINS_DIR);
+ }
+ if (isset($_SERVER['SCRIPT_NAME'])) {
+ Smarty::$global_tpl_vars['SCRIPT_NAME'] = new Smarty_Variable($_SERVER['SCRIPT_NAME']);
+ }
+
+ // Check if we're running on windows
+ Smarty::$_IS_WINDOWS = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
+
+ // let PCRE (preg_*) treat strings as ISO-8859-1 if we're not dealing with UTF-8
+ if (Smarty::$_CHARSET !== 'UTF-8') {
+ Smarty::$_UTF8_MODIFIER = '';
+ }
+ }
+
+ /**
+ * fetches a rendered Smarty template
+ *
+ * @param string $template the resource handle of the template file or template object
+ * @param mixed $cache_id cache id to be used with this template
+ * @param mixed $compile_id compile id to be used with this template
+ * @param object $parent next higher level of Smarty variables
+ * @param bool $display true: display, false: fetch
+ * @param bool $merge_tpl_vars not used - left for BC
+ * @param bool $no_output_filter not used - left for BC
+ *
+ * @throws Exception
+ * @throws SmartyException
+ * @return string rendered template output
+ */
+ public function fetch($template = null, $cache_id = null, $compile_id = null, $parent = null, $display = false, $merge_tpl_vars = true, $no_output_filter = false) {
+ if ($cache_id !== null && is_object($cache_id)) {
+ $parent = $cache_id;
+ $cache_id = null;
+ }
+ if ($parent === null) {
+ $parent = $this;
+ }
+ // get template object
+ $_template = is_object($template) ? $template : $this->createTemplate($template, $cache_id, $compile_id, $parent, false);
+ // set caching in template object
+ $_template->caching = $this->caching;
+ // fetch template content
+ return $_template->render(true, false, $display);
+ }
+
+ /**
+ * displays a Smarty template
+ *
+ * @param string $template the resource handle of the template file or template object
+ * @param mixed $cache_id cache id to be used with this template
+ * @param mixed $compile_id compile id to be used with this template
+ * @param object $parent next higher level of Smarty variables
+ */
+ public function display($template = null, $cache_id = null, $compile_id = null, $parent = null) {
+ // display template
+ $this->fetch($template, $cache_id, $compile_id, $parent, true);
+ }
+
+ /**
+ * Check if a template resource exists
+ *
+ * @param string $resource_name template name
+ *
+ * @return boolean status
+ */
+ public function templateExists($resource_name) {
+ // create template object
+ $save = $this->template_objects;
+ $tpl = new $this->template_class($resource_name, $this);
+ // check if it does exists
+ $result = $tpl->source->exists;
+ $this->template_objects = $save;
+
+ return $result;
+ }
+
+ /**
+ * Returns a single or all global variables
+ *
+ * @param string $varname variable name or null
+ *
+ * @return string variable value or or array of variables
+ */
+ public function getGlobal($varname = null) {
+ if (isset($varname)) {
+ if (isset(self::$global_tpl_vars[$varname])) {
+ return self::$global_tpl_vars[$varname]->value;
+ } else {
+ return '';
+ }
+ } else {
+ $_result = array();
+ foreach (self::$global_tpl_vars AS $key => $var) {
+ $_result[$key] = $var->value;
+ }
+
+ return $_result;
+ }
+ }
+
+ /**
+ * Empty cache folder
+ *
+ * @param integer $exp_time expiration time
+ * @param string $type resource type
+ *
+ * @return integer number of cache files deleted
+ */
+ public function clearAllCache($exp_time = null, $type = null) {
+ // load cache resource and call clearAll
+ $_cache_resource = Smarty_CacheResource::load($this, $type);
+ Smarty_CacheResource::invalidLoadedCache($this);
+
+ return $_cache_resource->clearAll($this, $exp_time);
+ }
+
+ /**
+ * Empty cache for a specific template
+ *
+ * @param string $template_name template name
+ * @param string $cache_id cache id
+ * @param string $compile_id compile id
+ * @param integer $exp_time expiration time
+ * @param string $type resource type
+ *
+ * @return integer number of cache files deleted
+ */
+ public function clearCache($template_name, $cache_id = null, $compile_id = null, $exp_time = null, $type = null) {
+ // load cache resource and call clear
+ $_cache_resource = Smarty_CacheResource::load($this, $type);
+ Smarty_CacheResource::invalidLoadedCache($this);
+
+ return $_cache_resource->clear($this, $template_name, $cache_id, $compile_id, $exp_time);
+ }
+
+ /**
+ * Loads security class and enables security
+ *
+ * @param string|Smarty_Security $security_class if a string is used, it must be class-name
+ *
+ * @return Smarty current Smarty instance for chaining
+ * @throws SmartyException when an invalid class name is provided
+ */
+ public function enableSecurity($security_class = null) {
+ if ($security_class instanceof Smarty_Security) {
+ $this->security_policy = $security_class;
+
+ return $this;
+ } elseif (is_object($security_class)) {
+ throw new SmartyException("Class '" . get_class($security_class) . "' must extend Smarty_Security.");
+ }
+ if ($security_class == null) {
+ $security_class = $this->security_class;
+ }
+ if (!class_exists($security_class)) {
+ throw new SmartyException("Security class '$security_class' is not defined");
+ } elseif ($security_class !== 'Smarty_Security' && !is_subclass_of($security_class, 'Smarty_Security')) {
+ throw new SmartyException("Class '$security_class' must extend Smarty_Security.");
+ } else {
+ $this->security_policy = new $security_class($this);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Disable security
+ *
+ * @return Smarty current Smarty instance for chaining
+ */
+ public function disableSecurity() {
+ $this->security_policy = null;
+
+ return $this;
+ }
+
+ /**
+ * Set template directory
+ *
+ * @param string|array $template_dir directory(s) of template sources
+ *
+ * @return Smarty current Smarty instance for chaining
+ */
+ public function setTemplateDir($template_dir) {
+ $this->template_dir = array();
+ foreach ((array)$template_dir as $k => $v) {
+ $this->template_dir[$k] = rtrim($v, '/\\') . DS;
+ }
+ $this->joined_template_dir = join(' # ', $this->template_dir);
+ return $this;
+ }
+
+ /**
+ * Add template directory(s)
+ *
+ * @param string|array $template_dir directory(s) of template sources
+ * @param string $key of the array element to assign the template dir to
+ *
+ * @return Smarty current Smarty instance for chaining
+ * @throws SmartyException when the given template directory is not valid
+ */
+ public function addTemplateDir($template_dir, $key = null) {
+ $this->_addDir('template_dir', $template_dir, $key);
+ $this->joined_template_dir = join(' # ', $this->template_dir);
+ return $this;
+ }
+
+ /**
+ * Get template directories
+ *
+ * @param mixed $index index of directory to get, null to get all
+ *
+ * @return array|string list of template directories, or directory of $index
+ */
+ public function getTemplateDir($index = null) {
+ if ($index !== null) {
+ return isset($this->template_dir[$index]) ? $this->template_dir[$index] : null;
+ }
+ return (array)$this->template_dir;
+ }
+
+ /**
+ * Set config directory
+ *
+ * @param $config_dir
+ *
+ * @return Smarty current Smarty instance for chaining
+ */
+ public function setConfigDir($config_dir) {
+ $this->config_dir = array();
+ foreach ((array)$config_dir as $k => $v) {
+ $this->config_dir[$k] = rtrim($v, '/\\') . DS;
+ }
+ $this->joined_config_dir = join(' # ', $this->config_dir);
+ return $this;
+ }
+
+ /**
+ * Add config directory(s)
+ *
+ * @param string|array $config_dir directory(s) of config sources
+ * @param mixed $key key of the array element to assign the config dir to
+ *
+ * @return Smarty current Smarty instance for chaining
+ */
+ public function addConfigDir($config_dir, $key = null) {
+ $this->_addDir('config_dir', $config_dir, $key);
+ $this->joined_config_dir = join(' # ', $this->config_dir);
+ return $this;
+ }
+
+ /**
+ * Get config directory
+ *
+ * @param mixed $index index of directory to get, null to get all
+ *
+ * @return array|string configuration directory
+ */
+ public function getConfigDir($index = null) {
+ if ($index !== null) {
+ return isset($this->config_dir[$index]) ? $this->config_dir[$index] : null;
+ }
+ return (array)$this->config_dir;
+ }
+
+ /**
+ * Set plugins directory
+ *
+ * @param string|array $plugins_dir directory(s) of plugins
+ *
+ * @return Smarty current Smarty instance for chaining
+ */
+ public function setPluginsDir($plugins_dir) {
+ $this->plugins_dir = array();
+ $this->addPluginsDir($plugins_dir);
+ return $this;
+ }
+
+ /**
+ * Adds directory of plugin files
+ *
+ * @param $plugins_dir
+ *
+ * @return Smarty current Smarty instance for chaining
+ */
+ public function addPluginsDir($plugins_dir) {
+ // make sure we're dealing with an array
+ $this->plugins_dir = (array)$this->plugins_dir;
+ foreach ((array)$plugins_dir as $v) {
+ $this->plugins_dir[] = rtrim($v, '/\\') . DS;
+ }
+ $this->plugins_dir = array_unique($this->plugins_dir);
+ $this->_is_file_cache = array();
+ return $this;
+ }
+
+ /**
+ * Get plugin directories
+ *
+ * @return array list of plugin directories
+ */
+ public function getPluginsDir() {
+ return (array)$this->plugins_dir;
+ }
+
+ /**
+ * Set compile directory
+ *
+ * @param string $compile_dir directory to store compiled templates in
+ *
+ * @return Smarty current Smarty instance for chaining
+ */
+ public function setCompileDir($compile_dir) {
+ $this->compile_dir = rtrim($compile_dir, '/\\') . DS;
+ if (!isset(Smarty::$_muted_directories[$this->compile_dir])) {
+ Smarty::$_muted_directories[$this->compile_dir] = null;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Get compiled directory
+ *
+ * @return string path to compiled templates
+ */
+ public function getCompileDir() {
+ return $this->compile_dir;
+ }
+
+ /**
+ * Set cache directory
+ *
+ * @param string $cache_dir directory to store cached templates in
+ *
+ * @return Smarty current Smarty instance for chaining
+ */
+ public function setCacheDir($cache_dir) {
+ $this->cache_dir = rtrim($cache_dir, '/\\') . DS;
+ if (!isset(Smarty::$_muted_directories[$this->cache_dir])) {
+ Smarty::$_muted_directories[$this->cache_dir] = null;
+ }
+ return $this;
+ }
+
+ /**
+ * Get cache directory
+ *
+ * @return string path of cache directory
+ */
+ public function getCacheDir() {
+ return $this->cache_dir;
+ }
+
+ /**
+ * add directories to given property name
+ *
+ * @param string $dirName directory property name
+ * @param string|array $dir directory string or array of strings
+ * @param mixed $key optional key
+ */
+ private function _addDir($dirName, $dir, $key = null) {
+ // make sure we're dealing with an array
+ $this->$dirName = (array)$this->$dirName;
+
+ if (is_array($dir)) {
+ foreach ($dir as $k => $v) {
+ if (is_int($k)) {
+ // indexes are not merged but appended
+ $this->{$dirName}[] = rtrim($v, '/\\') . DS;
+ } else {
+ // string indexes are overridden
+ $this->{$dirName}[$k] = rtrim($v, '/\\') . DS;
+ }
+ }
+ } else {
+ if ($key !== null) {
+ // override directory at specified index
+ $this->{$dirName}[$key] = rtrim($dir, '/\\') . DS;
+ } else {
+ // append new directory
+ $this->{$dirName}[] = rtrim($dir, '/\\') . DS;
+ }
+ }
+ }
+
+ /**
+ * Set default modifiers
+ *
+ * @param array|string $modifiers modifier or list of modifiers to set
+ *
+ * @return Smarty current Smarty instance for chaining
+ */
+ public function setDefaultModifiers($modifiers) {
+ $this->default_modifiers = (array)$modifiers;
+
+ return $this;
+ }
+
+ /**
+ * Add default modifiers
+ *
+ * @param array|string $modifiers modifier or list of modifiers to add
+ *
+ * @return Smarty current Smarty instance for chaining
+ */
+ public function addDefaultModifiers($modifiers) {
+ if (is_array($modifiers)) {
+ $this->default_modifiers = array_merge($this->default_modifiers, $modifiers);
+ } else {
+ $this->default_modifiers[] = $modifiers;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Get default modifiers
+ *
+ * @return array list of default modifiers
+ */
+ public function getDefaultModifiers() {
+ return $this->default_modifiers;
+ }
+
+ /**
+ * Set autoload filters
+ *
+ * @param array $filters filters to load automatically
+ * @param string $type "pre", "output", … specify the filter type to set. Defaults to none treating $filters'
+ * keys as the appropriate types
+ *
+ * @return Smarty current Smarty instance for chaining
+ */
+ public function setAutoloadFilters($filters, $type = null) {
+ if ($type !== null) {
+ $this->autoload_filters[$type] = (array)$filters;
+ } else {
+ $this->autoload_filters = (array)$filters;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Add autoload filters
+ *
+ * @param array $filters filters to load automatically
+ * @param string $type "pre", "output", … specify the filter type to set. Defaults to none treating $filters'
+ * keys as the appropriate types
+ *
+ * @return Smarty current Smarty instance for chaining
+ */
+ public function addAutoloadFilters($filters, $type = null) {
+ if ($type !== null) {
+ if (!empty($this->autoload_filters[$type])) {
+ $this->autoload_filters[$type] = array_merge($this->autoload_filters[$type], (array)$filters);
+ } else {
+ $this->autoload_filters[$type] = (array)$filters;
+ }
+ } else {
+ foreach ((array)$filters as $key => $value) {
+ if (!empty($this->autoload_filters[$key])) {
+ $this->autoload_filters[$key] = array_merge($this->autoload_filters[$key], (array)$value);
+ } else {
+ $this->autoload_filters[$key] = (array)$value;
+ }
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Get autoload filters
+ *
+ * @param string $type type of filter to get autoloads for. Defaults to all autoload filters
+ *
+ * @return array array( 'type1' => array( 'filter1', 'filter2', … ) ) or array( 'filter1', 'filter2', …) if $type
+ * was specified
+ */
+ public function getAutoloadFilters($type = null) {
+ if ($type !== null) {
+ return isset($this->autoload_filters[$type]) ? $this->autoload_filters[$type] : array();
+ }
+
+ return $this->autoload_filters;
+ }
+
+ /**
+ * return name of debugging template
+ *
+ * @return string
+ */
+ public function getDebugTemplate() {
+ return $this->debug_tpl;
+ }
+
+ /**
+ * set the debug template
+ *
+ * @param string $tpl_name
+ *
+ * @return Smarty current Smarty instance for chaining
+ * @throws SmartyException if file is not readable
+ */
+ public function setDebugTemplate($tpl_name) {
+ if (!is_readable($tpl_name)) {
+ throw new SmartyException("Unknown file '{$tpl_name}'");
+ }
+ $this->debug_tpl = $tpl_name;
+
+ return $this;
+ }
+
+ /**
+ * creates a template object
+ *
+ * @param string $template the resource handle of the template file
+ * @param mixed $cache_id cache id to be used with this template
+ * @param mixed $compile_id compile id to be used with this template
+ * @param object $parent next higher level of Smarty variables
+ * @param boolean $do_clone flag is Smarty object shall be cloned
+ *
+ * @return object template object
+ */
+ public function createTemplate($template, $cache_id = null, $compile_id = null, $parent = null, $do_clone = true) {
+ if ($cache_id !== null && (is_object($cache_id) || is_array($cache_id))) {
+ $parent = $cache_id;
+ $cache_id = null;
+ }
+ if ($parent !== null && is_array($parent)) {
+ $data = $parent;
+ $parent = null;
+ } else {
+ $data = null;
+ }
+ $_templateId = $this->getTemplateId($template, $cache_id, $compile_id);
+ if (isset($this->template_objects[$_templateId])) {
+ if ($do_clone) {
+ $tpl = clone $this->template_objects[$_templateId];
+ $tpl->smarty = clone $tpl->smarty;
+ } else {
+ $tpl = $this->template_objects[$_templateId];
+ }
+ $tpl->parent = $parent;
+ $tpl->tpl_vars = array();
+ $tpl->config_vars = array();
+ } else {
+ $tpl = new $this->template_class($template, $this, $parent, $cache_id, $compile_id);
+ if ($do_clone) {
+ $tpl->smarty = clone $tpl->smarty;
+ }
+ $tpl->templateId = $_templateId;
+ }
+ // fill data if present
+ if (!empty($data) && is_array($data)) {
+ // set up variable values
+ foreach ($data as $_key => $_val) {
+ $tpl->tpl_vars[$_key] = new Smarty_Variable($_val);
+ }
+ }
+ if ($this->debugging) {
+ Smarty_Internal_Debug::register_template($tpl);
+ }
+ return $tpl;
+ }
+
+ /**
+ * Takes unknown classes and loads plugin files for them
+ * class name format: Smarty_PluginType_PluginName
+ * plugin filename format: plugintype.pluginname.php
+ *
+ * @param string $plugin_name class plugin name to load
+ * @param bool $check check if already loaded
+ *
+ * @throws SmartyException
+ * @return string |boolean filepath of loaded file or false
+ */
+ public function loadPlugin($plugin_name, $check = true) {
+ // if function or class exists, exit silently (already loaded)
+ if ($check && (is_callable($plugin_name) || class_exists($plugin_name, false))) {
+ return true;
+ }
+ // Plugin name is expected to be: Smarty_[Type]_[Name]
+ $_name_parts = explode('_', $plugin_name, 3);
+ // class name must have three parts to be valid plugin
+ // count($_name_parts) < 3 === !isset($_name_parts[2])
+ if (!isset($_name_parts[2]) || strtolower($_name_parts[0]) !== 'smarty') {
+ throw new SmartyException("plugin {$plugin_name} is not a valid name format");
+ }
+ // if type is "internal", get plugin from sysplugins
+ if (strtolower($_name_parts[1]) == 'internal') {
+ $file = SMARTY_SYSPLUGINS_DIR . strtolower($plugin_name) . '.php';
+ if (isset($this->_is_file_cache[$file]) ? $this->_is_file_cache[$file] : $this->_is_file_cache[$file] = is_file($file)) {
+ require_once($file);
+ return $file;
+ } else {
+ return false;
+ }
+ }
+ // plugin filename is expected to be: [type].[name].php
+ $_plugin_filename = "{$_name_parts[1]}.{$_name_parts[2]}.php";
+
+ $_stream_resolve_include_path = function_exists('stream_resolve_include_path');
+
+ // loop through plugin dirs and find the plugin
+ foreach ($this->getPluginsDir() as $_plugin_dir) {
+ $names = array($_plugin_dir . $_plugin_filename, $_plugin_dir . strtolower($_plugin_filename),);
+ foreach ($names as $file) {
+ if (isset($this->_is_file_cache[$file]) ? $this->_is_file_cache[$file] : $this->_is_file_cache[$file] = is_file($file)) {
+ require_once($file);
+ return $file;
+ }
+ if ($this->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_plugin_dir)) {
+ // try PHP include_path
+ if ($_stream_resolve_include_path) {
+ $file = stream_resolve_include_path($file);
+ } else {
+ $file = Smarty_Internal_Get_Include_Path::getIncludePath($file);
+ }
+
+ if ($file !== false) {
+ require_once($file);
+
+ return $file;
+ }
+ }
+ }
+ }
+ // no plugin loaded
+ return false;
+ }
+
+ /**
+ * Compile all template files
+ *
+ * @param string $extension file extension
+ * @param bool $force_compile force all to recompile
+ * @param int $time_limit
+ * @param int $max_errors
+ *
+ * @return integer number of template files recompiled
+ */
+ public function compileAllTemplates($extension = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null) {
+ return Smarty_Internal_Utility::compileAllTemplates($extension, $force_compile, $time_limit, $max_errors, $this);
+ }
+
+ /**
+ * Compile all config files
+ *
+ * @param string $extension file extension
+ * @param bool $force_compile force all to recompile
+ * @param int $time_limit
+ * @param int $max_errors
+ *
+ * @return integer number of template files recompiled
+ */
+ public function compileAllConfig($extension = '.conf', $force_compile = false, $time_limit = 0, $max_errors = null) {
+ return Smarty_Internal_Utility::compileAllConfig($extension, $force_compile, $time_limit, $max_errors, $this);
+ }
+
+ /**
+ * Delete compiled template file
+ *
+ * @param string $resource_name template name
+ * @param string $compile_id compile id
+ * @param integer $exp_time expiration time
+ *
+ * @return integer number of template files deleted
+ */
+ public function clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null) {
+ return Smarty_Internal_Utility::clearCompiledTemplate($resource_name, $compile_id, $exp_time, $this);
+ }
+
+ /**
+ * Return array of tag/attributes of all tags used by an template
+ *
+ * @param Smarty_Internal_Template $template
+ *
+ * @return array of tag/attributes
+ */
+ public function getTags(Smarty_Internal_Template $template) {
+ return Smarty_Internal_Utility::getTags($template);
+ }
+
+ /**
+ * Run installation test
+ *
+ * @param array $errors Array to write errors into, rather than outputting them
+ *
+ * @return boolean true if setup is fine, false if something is wrong
+ */
+ public function testInstall(&$errors = null) {
+ return Smarty_Internal_TestInstall::testInstall($this, $errors);
+ }
+
+ /**
+ * @param boolean $compile_check
+ */
+ public function setCompileCheck($compile_check) {
+ $this->compile_check = $compile_check;
+ }
+
+ /**
+ * @param boolean $use_sub_dirs
+ */
+ public function setUseSubDirs($use_sub_dirs) {
+ $this->use_sub_dirs = $use_sub_dirs;
+ }
+
+ /**
+ * @param boolean $caching
+ */
+ public function setCaching($caching) {
+ $this->caching = $caching;
+ }
+
+ /**
+ * @param int $cache_lifetime
+ */
+ public function setCacheLifetime($cache_lifetime) {
+ $this->cache_lifetime = $cache_lifetime;
+ }
+
+ /**
+ * @param string $compile_id
+ */
+ public function setCompileId($compile_id) {
+ $this->compile_id = $compile_id;
+ }
+
+ /**
+ * @param string $cache_id
+ */
+ public function setCacheId($cache_id) {
+ $this->cache_id = $cache_id;
+ }
+
+ /**
+ * @param int $error_reporting
+ */
+ public function setErrorReporting($error_reporting) {
+ $this->error_reporting = $error_reporting;
+ }
+
+ /**
+ * @param boolean $escape_html
+ */
+ public function setEscapeHtml($escape_html) {
+ $this->escape_html = $escape_html;
+ }
+
+ /**
+ * @param boolean $auto_literal
+ */
+ public function setAutoLiteral($auto_literal) {
+ $this->auto_literal = $auto_literal;
+ }
+
+ /**
+ * @param boolean $force_compile
+ */
+ public function setForceCompile($force_compile) {
+ $this->force_compile = $force_compile;
+ }
+
+ /**
+ * @param boolean $merge_compiled_includes
+ */
+ public function setMergeCompiledIncludes($merge_compiled_includes) {
+ $this->merge_compiled_includes = $merge_compiled_includes;
+ }
+
+ /**
+ * @param string $left_delimiter
+ */
+ public function setLeftDelimiter($left_delimiter) {
+ $this->left_delimiter = $left_delimiter;
+ }
+
+ /**
+ * @param string $right_delimiter
+ */
+ public function setRightDelimiter($right_delimiter) {
+ $this->right_delimiter = $right_delimiter;
+ }
+
+ /**
+ * @param boolean $debugging
+ */
+ public function setDebugging($debugging) {
+ $this->debugging = $debugging;
+ }
+
+ /**
+ * @param boolean $config_overwrite
+ */
+ public function setConfigOverwrite($config_overwrite) {
+ $this->config_overwrite = $config_overwrite;
+ }
+
+ /**
+ * @param boolean $config_booleanize
+ */
+ public function setConfigBooleanize($config_booleanize) {
+ $this->config_booleanize = $config_booleanize;
+ }
+
+ /**
+ * @param boolean $config_read_hidden
+ */
+ public function setConfigReadHidden($config_read_hidden) {
+ $this->config_read_hidden = $config_read_hidden;
+ }
+
+ /**
+ * @param boolean $compile_locking
+ */
+ public function setCompileLocking($compile_locking) {
+ $this->compile_locking = $compile_locking;
+ }
+
+ /**
+ * Class destructor
+ */
+ public function __destruct() {
+ // intentionally left blank
+ }
+
+ /**
+ * <<magic>> Generic getter.
+ * Calls the appropriate getter function.
+ * Issues an E_USER_NOTICE if no valid getter is found.
+ *
+ * @param string $name property name
+ *
+ * @return mixed
+ */
+ public function __get($name) {
+ $allowed = array('template_dir' => 'getTemplateDir', 'config_dir' => 'getConfigDir',
+ 'plugins_dir' => 'getPluginsDir', 'compile_dir' => 'getCompileDir',
+ 'cache_dir' => 'getCacheDir',);
+
+ if (isset($allowed[$name])) {
+ return $this->{$allowed[$name]}();
+ } else {
+ trigger_error('Undefined property: ' . get_class($this) . '::$' . $name, E_USER_NOTICE);
+ }
+ }
+
+ /**
+ * <<magic>> Generic setter.
+ * Calls the appropriate setter function.
+ * Issues an E_USER_NOTICE if no valid setter is found.
+ *
+ * @param string $name property name
+ * @param mixed $value parameter passed to setter
+ */
+ public function __set($name, $value) {
+ $allowed = array('template_dir' => 'setTemplateDir', 'config_dir' => 'setConfigDir',
+ 'plugins_dir' => 'setPluginsDir', 'compile_dir' => 'setCompileDir',
+ 'cache_dir' => 'setCacheDir',);
+
+ if (isset($allowed[$name])) {
+ $this->{$allowed[$name]}($value);
+ } else {
+ trigger_error('Undefined property: ' . get_class($this) . '::$' . $name, E_USER_NOTICE);
+ }
+ }
+
+ /**
+ * Error Handler to mute expected messages
+ *
+ * @link http://php.net/set_error_handler
+ *
+ * @param integer $errno Error level
+ * @param $errstr
+ * @param $errfile
+ * @param $errline
+ * @param $errcontext
+ *
+ * @return boolean
+ */
+ public static function mutingErrorHandler($errno, $errstr, $errfile, $errline, $errcontext) {
+ $_is_muted_directory = false;
+
+ // add the SMARTY_DIR to the list of muted directories
+ if (!isset(Smarty::$_muted_directories[SMARTY_DIR])) {
+ $smarty_dir = realpath(SMARTY_DIR);
+ if ($smarty_dir !== false) {
+ Smarty::$_muted_directories[SMARTY_DIR] = array('file' => $smarty_dir,
+ 'length' => strlen($smarty_dir),);
+ }
+ }
+
+ // walk the muted directories and test against $errfile
+ foreach (Smarty::$_muted_directories as $key => &$dir) {
+ if (!$dir) {
+ // resolve directory and length for speedy comparisons
+ $file = realpath($key);
+ if ($file === false) {
+ // this directory does not exist, remove and skip it
+ unset(Smarty::$_muted_directories[$key]);
+ continue;
+ }
+ $dir = array('file' => $file, 'length' => strlen($file),);
+ }
+ if (!strncmp($errfile, $dir['file'], $dir['length'])) {
+ $_is_muted_directory = true;
+ break;
+ }
+ }
+
+ // pass to next error handler if this error did not occur inside SMARTY_DIR
+ // or the error was within smarty but masked to be ignored
+ if (!$_is_muted_directory || ($errno && $errno & error_reporting())) {
+ if (Smarty::$_previous_error_handler) {
+ return call_user_func(Smarty::$_previous_error_handler, $errno, $errstr, $errfile, $errline, $errcontext);
+ } else {
+ return false;
+ }
+ }
+ }
+
+ /**
+ * Enable error handler to mute expected messages
+ *
+ * @return void
+ */
+ public static function muteExpectedErrors() {
+ /*
+ error muting is done because some people implemented custom error_handlers using
+ http://php.net/set_error_handler and for some reason did not understand the following paragraph:
+
+ It is important to remember that the standard PHP error handler is completely bypassed for the
+ error types specified by error_types unless the callback function returns FALSE.
+ error_reporting() settings will have no effect and your error handler will be called regardless -
+ however you are still able to read the current value of error_reporting and act appropriately.
+ Of particular note is that this value will be 0 if the statement that caused the error was
+ prepended by the @ error-control operator.
+
+ Smarty deliberately uses @filemtime() over file_exists() and filemtime() in some places. Reasons include
+ - @filemtime() is almost twice as fast as using an additional file_exists()
+ - between file_exists() and filemtime() a possible race condition is opened,
+ which does not exist using the simple @filemtime() approach.
+ */
+ $error_handler = array('Smarty', 'mutingErrorHandler');
+ $previous = set_error_handler($error_handler);
+
+ // avoid dead loops
+ if ($previous !== $error_handler) {
+ Smarty::$_previous_error_handler = $previous;
+ }
+ }
+
+ /**
+ * Disable error handler muting expected messages
+ *
+ * @return void
+ */
+ public static function unmuteExpectedErrors() {
+ restore_error_handler();
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/SmartyBC.class.php
@@ -0,0 +1,412 @@
+<?php
+/**
+ * Project: Smarty: the PHP compiling template engine
+ * File: SmartyBC.class.php
+ * SVN: $Id: $
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * For questions, help, comments, discussion, etc., please join the
+ * Smarty mailing list. Send a blank e-mail to
+ * smarty-discussion-subscribe@googlegroups.com
+ *
+ * @link http://www.smarty.net/
+ * @copyright 2008 New Digital Group, Inc.
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author Uwe Tews
+ * @author Rodney Rehm
+ * @package Smarty
+ */
+/**
+ * @ignore
+ */
+require_once(dirname(__FILE__) . '/Smarty.class.php');
+
+/**
+ * Smarty Backward Compatability Wrapper Class
+ *
+ * @package Smarty
+ */
+class SmartyBC extends Smarty {
+ /**
+ * Smarty 2 BC
+ *
+ * @var string
+ */
+ public $_version = self::SMARTY_VERSION;
+
+ /**
+ * Initialize new SmartyBC object
+ *
+ * @param array $options options to set during initialization, e.g. array( 'forceCompile' => false )
+ */
+ public function __construct(array $options = array()) {
+ parent::__construct($options);
+ }
+
+ /**
+ * wrapper for assign_by_ref
+ *
+ * @param string $tpl_var the template variable name
+ * @param mixed &$value the referenced value to assign
+ */
+ public function assign_by_ref($tpl_var, &$value) {
+ $this->assignByRef($tpl_var, $value);
+ }
+
+ /**
+ * wrapper for append_by_ref
+ *
+ * @param string $tpl_var the template variable name
+ * @param mixed &$value the referenced value to append
+ * @param boolean $merge flag if array elements shall be merged
+ */
+ public function append_by_ref($tpl_var, &$value, $merge = false) {
+ $this->appendByRef($tpl_var, $value, $merge);
+ }
+
+ /**
+ * clear the given assigned template variable.
+ *
+ * @param string $tpl_var the template variable to clear
+ */
+ public function clear_assign($tpl_var) {
+ $this->clearAssign($tpl_var);
+ }
+
+ /**
+ * Registers custom function to be used in templates
+ *
+ * @param string $function the name of the template function
+ * @param string $function_impl the name of the PHP function to register
+ * @param bool $cacheable
+ * @param mixed $cache_attrs
+ */
+ public function register_function($function, $function_impl, $cacheable = true, $cache_attrs = null) {
+ $this->registerPlugin('function', $function, $function_impl, $cacheable, $cache_attrs);
+ }
+
+ /**
+ * Unregisters custom function
+ *
+ * @param string $function name of template function
+ */
+ public function unregister_function($function) {
+ $this->unregisterPlugin('function', $function);
+ }
+
+ /**
+ * Registers object to be used in templates
+ *
+ * @param string $object name of template object
+ * @param object $object_impl the referenced PHP object to register
+ * @param array $allowed list of allowed methods (empty = all)
+ * @param boolean $smarty_args smarty argument format, else traditional
+ * @param array $block_methods list of methods that are block format
+ *
+ * @throws SmartyException
+ * @internal param array $block_functs list of methods that are block format
+ */
+ public function register_object($object, $object_impl, $allowed = array(), $smarty_args = true, $block_methods = array()) {
+ settype($allowed, 'array');
+ settype($smarty_args, 'boolean');
+ $this->registerObject($object, $object_impl, $allowed, $smarty_args, $block_methods);
+ }
+
+ /**
+ * Unregisters object
+ *
+ * @param string $object name of template object
+ */
+ public function unregister_object($object) {
+ $this->unregisterObject($object);
+ }
+
+ /**
+ * Registers block function to be used in templates
+ *
+ * @param string $block name of template block
+ * @param string $block_impl PHP function to register
+ * @param bool $cacheable
+ * @param mixed $cache_attrs
+ */
+ public function register_block($block, $block_impl, $cacheable = true, $cache_attrs = null) {
+ $this->registerPlugin('block', $block, $block_impl, $cacheable, $cache_attrs);
+ }
+
+ /**
+ * Unregisters block function
+ *
+ * @param string $block name of template function
+ */
+ public function unregister_block($block) {
+ $this->unregisterPlugin('block', $block);
+ }
+
+ /**
+ * Registers compiler function
+ *
+ * @param string $function name of template function
+ * @param string $function_impl name of PHP function to register
+ * @param bool $cacheable
+ */
+ public function register_compiler_function($function, $function_impl, $cacheable = true) {
+ $this->registerPlugin('compiler', $function, $function_impl, $cacheable);
+ }
+
+ /**
+ * Unregisters compiler function
+ *
+ * @param string $function name of template function
+ */
+ public function unregister_compiler_function($function) {
+ $this->unregisterPlugin('compiler', $function);
+ }
+
+ /**
+ * Registers modifier to be used in templates
+ *
+ * @param string $modifier name of template modifier
+ * @param string $modifier_impl name of PHP function to register
+ */
+ public function register_modifier($modifier, $modifier_impl) {
+ $this->registerPlugin('modifier', $modifier, $modifier_impl);
+ }
+
+ /**
+ * Unregisters modifier
+ *
+ * @param string $modifier name of template modifier
+ */
+ public function unregister_modifier($modifier) {
+ $this->unregisterPlugin('modifier', $modifier);
+ }
+
+ /**
+ * Registers a resource to fetch a template
+ *
+ * @param string $type name of resource
+ * @param array $functions array of functions to handle resource
+ */
+ public function register_resource($type, $functions) {
+ $this->registerResource($type, $functions);
+ }
+
+ /**
+ * Unregisters a resource
+ *
+ * @param string $type name of resource
+ */
+ public function unregister_resource($type) {
+ $this->unregisterResource($type);
+ }
+
+ /**
+ * Registers a prefilter function to apply
+ * to a template before compiling
+ *
+ * @param callable $function
+ */
+ public function register_prefilter($function) {
+ $this->registerFilter('pre', $function);
+ }
+
+ /**
+ * Unregisters a prefilter function
+ *
+ * @param callable $function
+ */
+ public function unregister_prefilter($function) {
+ $this->unregisterFilter('pre', $function);
+ }
+
+ /**
+ * Registers a postfilter function to apply
+ * to a compiled template after compilation
+ *
+ * @param callable $function
+ */
+ public function register_postfilter($function) {
+ $this->registerFilter('post', $function);
+ }
+
+ /**
+ * Unregisters a postfilter function
+ *
+ * @param callable $function
+ */
+ public function unregister_postfilter($function) {
+ $this->unregisterFilter('post', $function);
+ }
+
+ /**
+ * Registers an output filter function to apply
+ * to a template output
+ *
+ * @param callable $function
+ */
+ public function register_outputfilter($function) {
+ $this->registerFilter('output', $function);
+ }
+
+ /**
+ * Unregisters an outputfilter function
+ *
+ * @param callable $function
+ */
+ public function unregister_outputfilter($function) {
+ $this->unregisterFilter('output', $function);
+ }
+
+ /**
+ * load a filter of specified type and name
+ *
+ * @param string $type filter type
+ * @param string $name filter name
+ */
+ public function load_filter($type, $name) {
+ $this->loadFilter($type, $name);
+ }
+
+ /**
+ * clear cached content for the given template and cache id
+ *
+ * @param string $tpl_file name of template file
+ * @param string $cache_id name of cache_id
+ * @param string $compile_id name of compile_id
+ * @param string $exp_time expiration time
+ *
+ * @return boolean
+ */
+ public function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null) {
+ return $this->clearCache($tpl_file, $cache_id, $compile_id, $exp_time);
+ }
+
+ /**
+ * clear the entire contents of cache (all templates)
+ *
+ * @param string $exp_time expire time
+ *
+ * @return boolean
+ */
+ public function clear_all_cache($exp_time = null) {
+ return $this->clearCache(null, null, null, $exp_time);
+ }
+
+ /**
+ * test to see if valid cache exists for this template
+ *
+ * @param string $tpl_file name of template file
+ * @param string $cache_id
+ * @param string $compile_id
+ *
+ * @return boolean
+ */
+ public function is_cached($tpl_file, $cache_id = null, $compile_id = null) {
+ return $this->isCached($tpl_file, $cache_id, $compile_id);
+ }
+
+ /**
+ * clear all the assigned template variables.
+ */
+ public function clear_all_assign() {
+ $this->clearAllAssign();
+ }
+
+ /**
+ * clears compiled version of specified template resource,
+ * or all compiled template files if one is not specified.
+ * This function is for advanced use only, not normally needed.
+ *
+ * @param string $tpl_file
+ * @param string $compile_id
+ * @param string $exp_time
+ *
+ * @return boolean results of {@link smarty_core_rm_auto()}
+ */
+ public function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null) {
+ return $this->clearCompiledTemplate($tpl_file, $compile_id, $exp_time);
+ }
+
+ /**
+ * Checks whether requested template exists.
+ *
+ * @param string $tpl_file
+ *
+ * @return boolean
+ */
+ public function template_exists($tpl_file) {
+ return $this->templateExists($tpl_file);
+ }
+
+ /**
+ * Returns an array containing template variables
+ *
+ * @param string $name
+ *
+ * @return array
+ */
+ public function get_template_vars($name = null) {
+ return $this->getTemplateVars($name);
+ }
+
+ /**
+ * Returns an array containing config variables
+ *
+ * @param string $name
+ *
+ * @return array
+ */
+ public function get_config_vars($name = null) {
+ return $this->getConfigVars($name);
+ }
+
+ /**
+ * load configuration values
+ *
+ * @param string $file
+ * @param string $section
+ * @param string $scope
+ */
+ public function config_load($file, $section = null, $scope = 'global') {
+ $this->ConfigLoad($file, $section, $scope);
+ }
+
+ /**
+ * return a reference to a registered object
+ *
+ * @param string $name
+ *
+ * @return object
+ */
+ public function get_registered_object($name) {
+ return $this->getRegisteredObject($name);
+ }
+
+ /**
+ * clear configuration values
+ *
+ * @param string $var
+ */
+ public function clear_config($var = null) {
+ $this->clearConfig($var);
+ }
+
+ /**
+ * trigger Smarty error
+ *
+ * @param string $error_msg
+ * @param integer $error_type
+ */
+ public function trigger_error($error_msg, $error_type = E_USER_WARNING) {
+ trigger_error("Smarty error: $error_msg", $error_type);
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/debug.tpl
@@ -0,0 +1,167 @@
+{capture name='_smarty_debug' assign=debug_output}
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+ <head>
+ <title>Smarty Debug Console</title>
+ <style type="text/css">
+ {literal}
+ body, h1, h2, h3, td, th, p {
+ font-family: sans-serif;
+ font-weight: normal;
+ font-size: 0.9em;
+ margin: 1px;
+ padding: 0;
+ }
+
+ h1 {
+ margin: 0;
+ text-align: left;
+ padding: 2px;
+ background-color: #f0c040;
+ color: black;
+ font-weight: bold;
+ font-size: 1.2em;
+ }
+
+ h2 {
+ background-color: #9B410E;
+ color: white;
+ text-align: left;
+ font-weight: bold;
+ padding: 2px;
+ border-top: 1px solid black;
+ }
+
+ h3 {
+ text-align: left;
+ font-weight: bold;
+ color: black;
+ font-size: 0.7em;
+ padding: 2px;
+ }
+
+ body {
+ background: black;
+ }
+
+ p, table, div {
+ background: #f0ead8;
+ }
+
+ p {
+ margin: 0;
+ font-style: italic;
+ text-align: center;
+ }
+
+ table {
+ width: 100%;
+ }
+
+ th, td {
+ font-family: monospace;
+ vertical-align: top;
+ text-align: left;
+ }
+
+ td {
+ color: green;
+ }
+
+ .odd {
+ background-color: #eeeeee;
+ }
+
+ .even {
+ background-color: #fafafa;
+ }
+
+ .exectime {
+ font-size: 0.8em;
+ font-style: italic;
+ }
+
+ #bold div {
+ color: black;
+ font-weight: bold;
+ }
+
+ #blue h3 {
+ color: blue;
+ }
+
+ #normal div {
+ color: black;
+ font-weight: normal;
+ }
+
+ #table_assigned_vars th {
+ color: blue;
+ font-weight: bold;
+ }
+
+ #table_config_vars th {
+ color: maroon;
+ }
+
+ {/literal}
+ </style>
+ </head>
+ <body>
+
+ <h1>Smarty {Smarty::SMARTY_VERSION} Debug Console
+ - {if isset($template_name)}{$template_name|debug_print_var nofilter} {/if}{if !empty($template_data)}Total Time {$execution_time|string_format:"%.5f"}{/if}</h1>
+
+ {if !empty($template_data)}
+ <h2>included templates & config files (load time in seconds)</h2>
+ <div>
+ {foreach $template_data as $template}
+ <font color=brown>{$template.name}</font>
+ <br>
+
+ <span class="exectime">
+ (compile {$template['compile_time']|string_format:"%.5f"}) (render {$template['render_time']|string_format:"%.5f"}
+ ) (cache {$template['cache_time']|string_format:"%.5f"})
+ </span>
+ <br>
+ {/foreach}
+ </div>
+ {/if}
+
+ <h2>assigned template variables</h2>
+
+ <table id="table_assigned_vars">
+ {foreach $assigned_vars as $vars}
+ <tr class="{if $vars@iteration % 2 eq 0}odd{else}even{/if}">
+ <td><h3><font color=blue>${$vars@key}</font></h3>
+ {if isset($vars['nocache'])}<b>Nocache</b></br>{/if}
+ {if isset($vars['scope'])}<b>Origin:</b>{$vars['scope']|debug_print_var:10:80 nofilter}{/if}
+ </td>
+ <td><h3>Value</h3>{$vars['value']|debug_print_var:10:80 nofilter}</td>
+ <td>{if isset($vars['attributes'])}<h3>Attributes</h3>{$vars['attributes']|debug_print_var nofilter} {/if}</td>
+ {/foreach}
+ </table>
+
+ <h2>assigned config file variables</h2>
+
+ <table id="table_config_vars">
+ {foreach $config_vars as $vars}
+ <tr class="{if $vars@iteration % 2 eq 0}odd{else}even{/if}">
+ <td><h3><font color=blue>#{$vars@key}#</font></h3>
+ {if isset($vars['scope'])}<b>Origin:</b>{$vars['scope']|debug_print_var:10:80 nofilter}{/if}
+ </td>
+ <td>{$vars['value']|debug_print_var:10:80 nofilter}</td>
+ </tr>
+ {/foreach}
+
+ </table>
+ </body>
+ </html>
+{/capture}
+<script type="text/javascript">
+ {$id = ''}
+ {if $display_mode}{$id = "$offset$template_name"|md5}{/if}
+ _smarty_console = window.open("", "console{$id}", "width=680,height=600,left={$offset},top={$offset},resizable,scrollbars=yes");
+ _smarty_console.document.write("{$debug_output|escape:'javascript' nofilter}");
+ _smarty_console.document.close();
+</script>
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/block.textformat.php
@@ -0,0 +1,109 @@
+<?php
+/**
+ * Smarty plugin to format text blocks
+ *
+ * @package Smarty
+ * @subpackage PluginsBlock
+ */
+
+/**
+ * Smarty {textformat}{/textformat} block plugin
+ * Type: block function<br>
+ * Name: textformat<br>
+ * Purpose: format text a certain way with preset styles
+ * or custom wrap/indent settings<br>
+ * Params:
+ * <pre>
+ * - style - string (email)
+ * - indent - integer (0)
+ * - wrap - integer (80)
+ * - wrap_char - string ("\n")
+ * - indent_char - string (" ")
+ * - wrap_boundary - boolean (true)
+ * </pre>
+ *
+ * @link http://www.smarty.net/manual/en/language.function.textformat.php {textformat}
+ * (Smarty online manual)
+ *
+ * @param array $params parameters
+ * @param string $content contents of the block
+ * @param Smarty_Internal_Template $template template object
+ * @param boolean &$repeat repeat flag
+ *
+ * @return string content re-formatted
+ * @author Monte Ohrt <monte at ohrt dot com>
+ */
+function smarty_block_textformat($params, $content, $template, &$repeat) {
+ if (is_null($content)) {
+ return;
+ }
+
+ $style = null;
+ $indent = 0;
+ $indent_first = 0;
+ $indent_char = ' ';
+ $wrap = 80;
+ $wrap_char = "\n";
+ $wrap_cut = false;
+ $assign = null;
+
+ foreach ($params as $_key => $_val) {
+ switch ($_key) {
+ case 'style':
+ case 'indent_char':
+ case 'wrap_char':
+ case 'assign':
+ $$_key = (string)$_val;
+ break;
+
+ case 'indent':
+ case 'indent_first':
+ case 'wrap':
+ $$_key = (int)$_val;
+ break;
+
+ case 'wrap_cut':
+ $$_key = (bool)$_val;
+ break;
+
+ default:
+ trigger_error("textformat: unknown attribute '$_key'");
+ }
+ }
+
+ if ($style == 'email') {
+ $wrap = 72;
+ }
+ // split into paragraphs
+ $_paragraphs = preg_split('![\r\n]{2}!', $content);
+
+ foreach ($_paragraphs as &$_paragraph) {
+ if (!$_paragraph) {
+ continue;
+ }
+ // convert mult. spaces & special chars to single space
+ $_paragraph = preg_replace(array('!\s+!' . Smarty::$_UTF8_MODIFIER, '!(^\s+)|(\s+$)!' . Smarty::$_UTF8_MODIFIER), array(' ', ''), $_paragraph);
+ // indent first line
+ if ($indent_first > 0) {
+ $_paragraph = str_repeat($indent_char, $indent_first) . $_paragraph;
+ }
+ // wordwrap sentences
+ if (Smarty::$_MBSTRING) {
+ require_once(SMARTY_PLUGINS_DIR . 'shared.mb_wordwrap.php');
+ $_paragraph = smarty_mb_wordwrap($_paragraph, $wrap - $indent, $wrap_char, $wrap_cut);
+ } else {
+ $_paragraph = wordwrap($_paragraph, $wrap - $indent, $wrap_char, $wrap_cut);
+ }
+ // indent lines
+ if ($indent > 0) {
+ $_paragraph = preg_replace('!^!m', str_repeat($indent_char, $indent), $_paragraph);
+ }
+ }
+ $_output = implode($wrap_char . $wrap_char, $_paragraphs);
+
+ if ($assign) {
+ $template->assign($assign, $_output);
+ } else {
+ return $_output;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/function.counter.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsFunction
+ */
+
+/**
+ * Smarty {counter} function plugin
+ * Type: function<br>
+ * Name: counter<br>
+ * Purpose: print out a counter value
+ *
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @link http://www.smarty.net/manual/en/language.function.counter.php {counter}
+ * (Smarty online manual)
+ *
+ * @param array $params parameters
+ * @param Smarty_Internal_Template $template template object
+ *
+ * @return string|null
+ */
+function smarty_function_counter($params, $template) {
+ static $counters = array();
+
+ $name = (isset($params['name'])) ? $params['name'] : 'default';
+ if (!isset($counters[$name])) {
+ $counters[$name] = array(
+ 'start' => 1,
+ 'skip' => 1,
+ 'direction' => 'up',
+ 'count' => 1
+ );
+ }
+ $counter =& $counters[$name];
+
+ if (isset($params['start'])) {
+ $counter['start'] = $counter['count'] = (int)$params['start'];
+ }
+
+ if (!empty($params['assign'])) {
+ $counter['assign'] = $params['assign'];
+ }
+
+ if (isset($counter['assign'])) {
+ $template->assign($counter['assign'], $counter['count']);
+ }
+
+ if (isset($params['print'])) {
+ $print = (bool)$params['print'];
+ } else {
+ $print = empty($counter['assign']);
+ }
+
+ if ($print) {
+ $retval = $counter['count'];
+ } else {
+ $retval = null;
+ }
+
+ if (isset($params['skip'])) {
+ $counter['skip'] = $params['skip'];
+ }
+
+ if (isset($params['direction'])) {
+ $counter['direction'] = $params['direction'];
+ }
+
+ if ($counter['direction'] == "down") {
+ $counter['count'] -= $counter['skip'];
+ } else {
+ $counter['count'] += $counter['skip'];
+ }
+
+ return $retval;
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/function.cycle.php
@@ -0,0 +1,106 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsFunction
+ */
+
+/**
+ * Smarty {cycle} function plugin
+ * Type: function<br>
+ * Name: cycle<br>
+ * Date: May 3, 2002<br>
+ * Purpose: cycle through given values<br>
+ * Params:
+ * <pre>
+ * - name - name of cycle (optional)
+ * - values - comma separated list of values to cycle, or an array of values to cycle
+ * (this can be left out for subsequent calls)
+ * - reset - boolean - resets given var to true
+ * - print - boolean - print var or not. default is true
+ * - advance - boolean - whether or not to advance the cycle
+ * - delimiter - the value delimiter, default is ","
+ * - assign - boolean, assigns to template var instead of printed.
+ * </pre>
+ * Examples:<br>
+ * <pre>
+ * {cycle values="#eeeeee,#d0d0d0d"}
+ * {cycle name=row values="one,two,three" reset=true}
+ * {cycle name=row}
+ * </pre>
+ *
+ * @link http://www.smarty.net/manual/en/language.function.cycle.php {cycle}
+ * (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author credit to Mark Priatel <mpriatel@rogers.com>
+ * @author credit to Gerard <gerard@interfold.com>
+ * @author credit to Jason Sweat <jsweat_php@yahoo.com>
+ * @version 1.3
+ *
+ * @param array $params parameters
+ * @param Smarty_Internal_Template $template template object
+ *
+ * @return string|null
+ */
+
+function smarty_function_cycle($params, $template) {
+ static $cycle_vars;
+
+ $name = (empty($params['name'])) ? 'default' : $params['name'];
+ $print = (isset($params['print'])) ? (bool)$params['print'] : true;
+ $advance = (isset($params['advance'])) ? (bool)$params['advance'] : true;
+ $reset = (isset($params['reset'])) ? (bool)$params['reset'] : false;
+
+ if (!isset($params['values'])) {
+ if (!isset($cycle_vars[$name]['values'])) {
+ trigger_error("cycle: missing 'values' parameter");
+
+ return;
+ }
+ } else {
+ if (isset($cycle_vars[$name]['values'])
+ && $cycle_vars[$name]['values'] != $params['values']
+ ) {
+ $cycle_vars[$name]['index'] = 0;
+ }
+ $cycle_vars[$name]['values'] = $params['values'];
+ }
+
+ if (isset($params['delimiter'])) {
+ $cycle_vars[$name]['delimiter'] = $params['delimiter'];
+ } elseif (!isset($cycle_vars[$name]['delimiter'])) {
+ $cycle_vars[$name]['delimiter'] = ',';
+ }
+
+ if (is_array($cycle_vars[$name]['values'])) {
+ $cycle_array = $cycle_vars[$name]['values'];
+ } else {
+ $cycle_array = explode($cycle_vars[$name]['delimiter'], $cycle_vars[$name]['values']);
+ }
+
+ if (!isset($cycle_vars[$name]['index']) || $reset) {
+ $cycle_vars[$name]['index'] = 0;
+ }
+
+ if (isset($params['assign'])) {
+ $print = false;
+ $template->assign($params['assign'], $cycle_array[$cycle_vars[$name]['index']]);
+ }
+
+ if ($print) {
+ $retval = $cycle_array[$cycle_vars[$name]['index']];
+ } else {
+ $retval = null;
+ }
+
+ if ($advance) {
+ if ($cycle_vars[$name]['index'] >= count($cycle_array) - 1) {
+ $cycle_vars[$name]['index'] = 0;
+ } else {
+ $cycle_vars[$name]['index']++;
+ }
+ }
+
+ return $retval;
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/function.fetch.php
@@ -0,0 +1,220 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsFunction
+ */
+
+/**
+ * Smarty {fetch} plugin
+ * Type: function<br>
+ * Name: fetch<br>
+ * Purpose: fetch file, web or ftp data and display results
+ *
+ * @link http://www.smarty.net/manual/en/language.function.fetch.php {fetch}
+ * (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ *
+ * @param array $params parameters
+ * @param Smarty_Internal_Template $template template object
+ *
+ * @throws SmartyException
+ * @return string|null if the assign parameter is passed, Smarty assigns the result to a template variable
+ */
+function smarty_function_fetch($params, $template) {
+ if (empty($params['file'])) {
+ trigger_error("[plugin] fetch parameter 'file' cannot be empty", E_USER_NOTICE);
+
+ return;
+ }
+
+ // strip file protocol
+ if (stripos($params['file'], 'file://') === 0) {
+ $params['file'] = substr($params['file'], 7);
+ }
+
+ $protocol = strpos($params['file'], '://');
+ if ($protocol !== false) {
+ $protocol = strtolower(substr($params['file'], 0, $protocol));
+ }
+
+ if (isset($template->smarty->security_policy)) {
+ if ($protocol) {
+ // remote resource (or php stream, …)
+ if (!$template->smarty->security_policy->isTrustedUri($params['file'])) {
+ return;
+ }
+ } else {
+ // local file
+ if (!$template->smarty->security_policy->isTrustedResourceDir($params['file'])) {
+ return;
+ }
+ }
+ }
+
+ $content = '';
+ if ($protocol == 'http') {
+ // http fetch
+ if ($uri_parts = parse_url($params['file'])) {
+ // set defaults
+ $host = $server_name = $uri_parts['host'];
+ $timeout = 30;
+ $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*";
+ $agent = "Smarty Template Engine " . Smarty::SMARTY_VERSION;
+ $referer = "";
+ $uri = !empty($uri_parts['path']) ? $uri_parts['path'] : '/';
+ $uri .= !empty($uri_parts['query']) ? '?' . $uri_parts['query'] : '';
+ $_is_proxy = false;
+ if (empty($uri_parts['port'])) {
+ $port = 80;
+ } else {
+ $port = $uri_parts['port'];
+ }
+ if (!empty($uri_parts['user'])) {
+ $user = $uri_parts['user'];
+ }
+ if (!empty($uri_parts['pass'])) {
+ $pass = $uri_parts['pass'];
+ }
+ // loop through parameters, setup headers
+ foreach ($params as $param_key => $param_value) {
+ switch ($param_key) {
+ case "file":
+ case "assign":
+ case "assign_headers":
+ break;
+ case "user":
+ if (!empty($param_value)) {
+ $user = $param_value;
+ }
+ break;
+ case "pass":
+ if (!empty($param_value)) {
+ $pass = $param_value;
+ }
+ break;
+ case "accept":
+ if (!empty($param_value)) {
+ $accept = $param_value;
+ }
+ break;
+ case "header":
+ if (!empty($param_value)) {
+ if (!preg_match('![\w\d-]+: .+!', $param_value)) {
+ trigger_error("[plugin] invalid header format '" . $param_value . "'", E_USER_NOTICE);
+
+ return;
+ } else {
+ $extra_headers[] = $param_value;
+ }
+ }
+ break;
+ case "proxy_host":
+ if (!empty($param_value)) {
+ $proxy_host = $param_value;
+ }
+ break;
+ case "proxy_port":
+ if (!preg_match('!\D!', $param_value)) {
+ $proxy_port = (int)$param_value;
+ } else {
+ trigger_error("[plugin] invalid value for attribute '" . $param_key . "'", E_USER_NOTICE);
+
+ return;
+ }
+ break;
+ case "agent":
+ if (!empty($param_value)) {
+ $agent = $param_value;
+ }
+ break;
+ case "referer":
+ if (!empty($param_value)) {
+ $referer = $param_value;
+ }
+ break;
+ case "timeout":
+ if (!preg_match('!\D!', $param_value)) {
+ $timeout = (int)$param_value;
+ } else {
+ trigger_error("[plugin] invalid value for attribute '" . $param_key . "'", E_USER_NOTICE);
+
+ return;
+ }
+ break;
+ default:
+ trigger_error("[plugin] unrecognized attribute '" . $param_key . "'", E_USER_NOTICE);
+
+ return;
+ }
+ }
+ if (!empty($proxy_host) && !empty($proxy_port)) {
+ $_is_proxy = true;
+ $fp = fsockopen($proxy_host, $proxy_port, $errno, $errstr, $timeout);
+ } else {
+ $fp = fsockopen($server_name, $port, $errno, $errstr, $timeout);
+ }
+
+ if (!$fp) {
+ trigger_error("[plugin] unable to fetch: $errstr ($errno)", E_USER_NOTICE);
+
+ return;
+ } else {
+ if ($_is_proxy) {
+ fputs($fp, 'GET ' . $params['file'] . " HTTP/1.0\r\n");
+ } else {
+ fputs($fp, "GET $uri HTTP/1.0\r\n");
+ }
+ if (!empty($host)) {
+ fputs($fp, "Host: $host\r\n");
+ }
+ if (!empty($accept)) {
+ fputs($fp, "Accept: $accept\r\n");
+ }
+ if (!empty($agent)) {
+ fputs($fp, "User-Agent: $agent\r\n");
+ }
+ if (!empty($referer)) {
+ fputs($fp, "Referer: $referer\r\n");
+ }
+ if (isset($extra_headers) && is_array($extra_headers)) {
+ foreach ($extra_headers as $curr_header) {
+ fputs($fp, $curr_header . "\r\n");
+ }
+ }
+ if (!empty($user) && !empty($pass)) {
+ fputs($fp, "Authorization: BASIC " . base64_encode("$user:$pass") . "\r\n");
+ }
+
+ fputs($fp, "\r\n");
+ while (!feof($fp)) {
+ $content .= fgets($fp, 4096);
+ }
+ fclose($fp);
+ $csplit = preg_split("!\r\n\r\n!", $content, 2);
+
+ $content = $csplit[1];
+
+ if (!empty($params['assign_headers'])) {
+ $template->assign($params['assign_headers'], preg_split("!\r\n!", $csplit[0]));
+ }
+ }
+ } else {
+ trigger_error("[plugin fetch] unable to parse URL, check syntax", E_USER_NOTICE);
+
+ return;
+ }
+ } else {
+ $content = @file_get_contents($params['file']);
+ if ($content === false) {
+ throw new SmartyException("{fetch} cannot read resource '" . $params['file'] . "'");
+ }
+ }
+
+ if (!empty($params['assign'])) {
+ $template->assign($params['assign'], $content);
+ } else {
+ return $content;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/function.html_checkboxes.php
@@ -0,0 +1,235 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsFunction
+ */
+
+/**
+ * Smarty {html_checkboxes} function plugin
+ * File: function.html_checkboxes.php<br>
+ * Type: function<br>
+ * Name: html_checkboxes<br>
+ * Date: 24.Feb.2003<br>
+ * Purpose: Prints out a list of checkbox input types<br>
+ * Examples:
+ * <pre>
+ * {html_checkboxes values=$ids output=$names}
+ * {html_checkboxes values=$ids name='box' separator='<br>' output=$names}
+ * {html_checkboxes values=$ids checked=$checked separator='<br>' output=$names}
+ * </pre>
+ * Params:
+ * <pre>
+ * - name (optional) - string default "checkbox"
+ * - values (required) - array
+ * - options (optional) - associative array
+ * - checked (optional) - array default not set
+ * - separator (optional) - ie <br> or
+ * - output (optional) - the output next to each checkbox
+ * - assign (optional) - assign the output as an array to this variable
+ * - escape (optional) - escape the content (not value), defaults to true
+ * </pre>
+ *
+ * @link http://www.smarty.net/manual/en/language.function.html.checkboxes.php {html_checkboxes}
+ * (Smarty online manual)
+ * @author Christopher Kvarme <christopher.kvarme@flashjab.com>
+ * @author credits to Monte Ohrt <monte at ohrt dot com>
+ * @version 1.0
+ *
+ * @param array $params parameters
+ * @param object $template template object
+ *
+ * @return string
+ * @uses smarty_function_escape_special_chars()
+ */
+function smarty_function_html_checkboxes($params, $template) {
+ require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
+
+ $name = 'checkbox';
+ $values = null;
+ $options = null;
+ $selected = array();
+ $separator = '';
+ $escape = true;
+ $labels = true;
+ $label_ids = false;
+ $output = null;
+
+ $extra = '';
+
+ foreach ($params as $_key => $_val) {
+ switch ($_key) {
+ case 'name':
+ case 'separator':
+ $$_key = (string)$_val;
+ break;
+
+ case 'escape':
+ case 'labels':
+ case 'label_ids':
+ $$_key = (bool)$_val;
+ break;
+
+ case 'options':
+ $$_key = (array)$_val;
+ break;
+
+ case 'values':
+ case 'output':
+ $$_key = array_values((array)$_val);
+ break;
+
+ case 'checked':
+ case 'selected':
+ if (is_array($_val)) {
+ $selected = array();
+ foreach ($_val as $_sel) {
+ if (is_object($_sel)) {
+ if (method_exists($_sel, "__toString")) {
+ $_sel = smarty_function_escape_special_chars((string)$_sel->__toString());
+ } else {
+ trigger_error("html_checkboxes: selected attribute contains an object of class '" . get_class($_sel) . "' without __toString() method", E_USER_NOTICE);
+ continue;
+ }
+ } else {
+ $_sel = smarty_function_escape_special_chars((string)$_sel);
+ }
+ $selected[$_sel] = true;
+ }
+ } elseif (is_object($_val)) {
+ if (method_exists($_val, "__toString")) {
+ $selected = smarty_function_escape_special_chars((string)$_val->__toString());
+ } else {
+ trigger_error("html_checkboxes: selected attribute is an object of class '" . get_class($_val) . "' without __toString() method", E_USER_NOTICE);
+ }
+ } else {
+ $selected = smarty_function_escape_special_chars((string)$_val);
+ }
+ break;
+
+ case 'checkboxes':
+ trigger_error('html_checkboxes: the use of the "checkboxes" attribute is deprecated, use "options" instead', E_USER_WARNING);
+ $options = (array)$_val;
+ break;
+
+ case 'assign':
+ break;
+
+ case 'strict':
+ break;
+
+ case 'disabled':
+ case 'readonly':
+ if (!empty($params['strict'])) {
+ if (!is_scalar($_val)) {
+ trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute", E_USER_NOTICE);
+ }
+
+ if ($_val === true || $_val === $_key) {
+ $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"';
+ }
+
+ break;
+ }
+ // omit break; to fall through!
+
+ default:
+ if (!is_array($_val)) {
+ $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
+ } else {
+ trigger_error("html_checkboxes: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+ }
+ break;
+ }
+ }
+
+ if (!isset($options) && !isset($values)) {
+ return '';
+ } /* raise error here? */
+
+ $_html_result = array();
+
+ if (isset($options)) {
+ foreach ($options as $_key => $_val) {
+ $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape);
+ }
+ } else {
+ foreach ($values as $_i => $_key) {
+ $_val = isset($output[$_i]) ? $output[$_i] : '';
+ $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape);
+ }
+ }
+
+ if (!empty($params['assign'])) {
+ $template->assign($params['assign'], $_html_result);
+ } else {
+ return implode("\n", $_html_result);
+ }
+}
+
+function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids, $escape = true) {
+ $_output = '';
+
+ if (is_object($value)) {
+ if (method_exists($value, "__toString")) {
+ $value = (string)$value->__toString();
+ } else {
+ trigger_error("html_options: value is an object of class '" . get_class($value) . "' without __toString() method", E_USER_NOTICE);
+
+ return '';
+ }
+ } else {
+ $value = (string)$value;
+ }
+
+ if (is_object($output)) {
+ if (method_exists($output, "__toString")) {
+ $output = (string)$output->__toString();
+ } else {
+ trigger_error("html_options: output is an object of class '" . get_class($output) . "' without __toString() method", E_USER_NOTICE);
+
+ return '';
+ }
+ } else {
+ $output = (string)$output;
+ }
+
+ if ($labels) {
+ if ($label_ids) {
+ $_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!' . Smarty::$_UTF8_MODIFIER, '_', $name . '_' . $value));
+ $_output .= '<label for="' . $_id . '">';
+ } else {
+ $_output .= '<label>';
+ }
+ }
+
+ $name = smarty_function_escape_special_chars($name);
+ $value = smarty_function_escape_special_chars($value);
+ if ($escape) {
+ $output = smarty_function_escape_special_chars($output);
+ }
+
+ $_output .= '<input type="checkbox" name="' . $name . '[]" value="' . $value . '"';
+
+ if ($labels && $label_ids) {
+ $_output .= ' id="' . $_id . '"';
+ }
+
+ if (is_array($selected)) {
+ if (isset($selected[$value])) {
+ $_output .= ' checked="checked"';
+ }
+ } elseif ($value === $selected) {
+ $_output .= ' checked="checked"';
+ }
+
+ $_output .= $extra . ' />' . $output;
+ if ($labels) {
+ $_output .= '</label>';
+ }
+
+ $_output .= $separator;
+
+ return $_output;
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/function.html_image.php
@@ -0,0 +1,162 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsFunction
+ */
+
+/**
+ * Smarty {html_image} function plugin
+ * Type: function<br>
+ * Name: html_image<br>
+ * Date: Feb 24, 2003<br>
+ * Purpose: format HTML tags for the image<br>
+ * Examples: {html_image file="/images/masthead.gif"}<br>
+ * Output: <img src="/images/masthead.gif" width=400 height=23><br>
+ * Params:
+ * <pre>
+ * - file - (required) - file (and path) of image
+ * - height - (optional) - image height (default actual height)
+ * - width - (optional) - image width (default actual width)
+ * - basedir - (optional) - base directory for absolute paths, default is environment variable DOCUMENT_ROOT
+ * - path_prefix - prefix for path output (optional, default empty)
+ * </pre>
+ *
+ * @link http://www.smarty.net/manual/en/language.function.html.image.php {html_image}
+ * (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author credits to Duda <duda@big.hu>
+ * @version 1.0
+ *
+ * @param array $params parameters
+ * @param Smarty_Internal_Template $template template object
+ *
+ * @throws SmartyException
+ * @return string
+ * @uses smarty_function_escape_special_chars()
+ */
+function smarty_function_html_image($params, $template) {
+ require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
+
+ $alt = '';
+ $file = '';
+ $height = '';
+ $width = '';
+ $extra = '';
+ $prefix = '';
+ $suffix = '';
+ $path_prefix = '';
+ $basedir = isset($_SERVER['DOCUMENT_ROOT']) ? $_SERVER['DOCUMENT_ROOT'] : '';
+ foreach ($params as $_key => $_val) {
+ switch ($_key) {
+ case 'file':
+ case 'height':
+ case 'width':
+ case 'dpi':
+ case 'path_prefix':
+ case 'basedir':
+ $$_key = $_val;
+ break;
+
+ case 'alt':
+ if (!is_array($_val)) {
+ $$_key = smarty_function_escape_special_chars($_val);
+ } else {
+ throw new SmartyException ("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+ }
+ break;
+
+ case 'link':
+ case 'href':
+ $prefix = '<a href="' . $_val . '">';
+ $suffix = '</a>';
+ break;
+
+ default:
+ if (!is_array($_val)) {
+ $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
+ } else {
+ throw new SmartyException ("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+ }
+ break;
+ }
+ }
+
+ if (empty($file)) {
+ trigger_error("html_image: missing 'file' parameter", E_USER_NOTICE);
+
+ return;
+ }
+
+ if ($file[0] == '/') {
+ $_image_path = $basedir . $file;
+ } else {
+ $_image_path = $file;
+ }
+
+ // strip file protocol
+ if (stripos($params['file'], 'file://') === 0) {
+ $params['file'] = substr($params['file'], 7);
+ }
+
+ $protocol = strpos($params['file'], '://');
+ if ($protocol !== false) {
+ $protocol = strtolower(substr($params['file'], 0, $protocol));
+ }
+
+ if (isset($template->smarty->security_policy)) {
+ if ($protocol) {
+ // remote resource (or php stream, …)
+ if (!$template->smarty->security_policy->isTrustedUri($params['file'])) {
+ return;
+ }
+ } else {
+ // local file
+ if (!$template->smarty->security_policy->isTrustedResourceDir($_image_path)) {
+ return;
+ }
+ }
+ }
+
+ if (!isset($params['width']) || !isset($params['height'])) {
+ // FIXME: (rodneyrehm) getimagesize() loads the complete file off a remote resource, use custom [jpg,png,gif]header reader!
+ if (!$_image_data = @getimagesize($_image_path)) {
+ if (!file_exists($_image_path)) {
+ trigger_error("html_image: unable to find '$_image_path'", E_USER_NOTICE);
+
+ return;
+ } elseif (!is_readable($_image_path)) {
+ trigger_error("html_image: unable to read '$_image_path'", E_USER_NOTICE);
+
+ return;
+ } else {
+ trigger_error("html_image: '$_image_path' is not a valid image file", E_USER_NOTICE);
+
+ return;
+ }
+ }
+
+ if (!isset($params['width'])) {
+ $width = $_image_data[0];
+ }
+ if (!isset($params['height'])) {
+ $height = $_image_data[1];
+ }
+ }
+
+ if (isset($params['dpi'])) {
+ if (strstr($_SERVER['HTTP_USER_AGENT'], 'Mac')) {
+ // FIXME: (rodneyrehm) wrong dpi assumption
+ // don't know who thought this up… even if it was true in 1998, it's definitely wrong in 2011.
+ $dpi_default = 72;
+ } else {
+ $dpi_default = 96;
+ }
+ $_resize = $dpi_default / $params['dpi'];
+ $width = round($width * $_resize);
+ $height = round($height * $_resize);
+ }
+
+ return $prefix . '<img src="' . $path_prefix . $file . '" alt="' . $alt . '" width="' . $width . '" height="' . $height . '"' . $extra . ' />' . $suffix;
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/function.html_options.php
@@ -0,0 +1,193 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsFunction
+ */
+
+/**
+ * Smarty {html_options} function plugin
+ * Type: function<br>
+ * Name: html_options<br>
+ * Purpose: Prints the list of <option> tags generated from
+ * the passed parameters<br>
+ * Params:
+ * <pre>
+ * - name (optional) - string default "select"
+ * - values (required) - if no options supplied) - array
+ * - options (required) - if no values supplied) - associative array
+ * - selected (optional) - string default not set
+ * - output (required) - if not options supplied) - array
+ * - id (optional) - string default not set
+ * - class (optional) - string default not set
+ * </pre>
+ *
+ * @link http://www.smarty.net/manual/en/language.function.html.options.php {html_image}
+ * (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author Ralf Strehle (minor optimization) <ralf dot strehle at yahoo dot de>
+ *
+ * @param array $params parameters
+ *
+ * @return string
+ * @uses smarty_function_escape_special_chars()
+ */
+function smarty_function_html_options($params) {
+ require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
+
+ $name = null;
+ $values = null;
+ $options = null;
+ $selected = null;
+ $output = null;
+ $id = null;
+ $class = null;
+
+ $extra = '';
+
+ foreach ($params as $_key => $_val) {
+ switch ($_key) {
+ case 'name':
+ case 'class':
+ case 'id':
+ $$_key = (string)$_val;
+ break;
+
+ case 'options':
+ $options = (array)$_val;
+ break;
+
+ case 'values':
+ case 'output':
+ $$_key = array_values((array)$_val);
+ break;
+
+ case 'selected':
+ if (is_array($_val)) {
+ $selected = array();
+ foreach ($_val as $_sel) {
+ if (is_object($_sel)) {
+ if (method_exists($_sel, "__toString")) {
+ $_sel = smarty_function_escape_special_chars((string)$_sel->__toString());
+ } else {
+ trigger_error("html_options: selected attribute contains an object of class '" . get_class($_sel) . "' without __toString() method", E_USER_NOTICE);
+ continue;
+ }
+ } else {
+ $_sel = smarty_function_escape_special_chars((string)$_sel);
+ }
+ $selected[$_sel] = true;
+ }
+ } elseif (is_object($_val)) {
+ if (method_exists($_val, "__toString")) {
+ $selected = smarty_function_escape_special_chars((string)$_val->__toString());
+ } else {
+ trigger_error("html_options: selected attribute is an object of class '" . get_class($_val) . "' without __toString() method", E_USER_NOTICE);
+ }
+ } else {
+ $selected = smarty_function_escape_special_chars((string)$_val);
+ }
+ break;
+
+ case 'strict':
+ break;
+
+ case 'disabled':
+ case 'readonly':
+ if (!empty($params['strict'])) {
+ if (!is_scalar($_val)) {
+ trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute", E_USER_NOTICE);
+ }
+
+ if ($_val === true || $_val === $_key) {
+ $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"';
+ }
+
+ break;
+ }
+ // omit break; to fall through!
+
+ default:
+ if (!is_array($_val)) {
+ $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
+ } else {
+ trigger_error("html_options: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+ }
+ break;
+ }
+ }
+
+ if (!isset($options) && !isset($values)) {
+ /* raise error here? */
+
+ return '';
+ }
+
+ $_html_result = '';
+ $_idx = 0;
+
+ if (isset($options)) {
+ foreach ($options as $_key => $_val) {
+ $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected, $id, $class, $_idx);
+ }
+ } else {
+ foreach ($values as $_i => $_key) {
+ $_val = isset($output[$_i]) ? $output[$_i] : '';
+ $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected, $id, $class, $_idx);
+ }
+ }
+
+ if (!empty($name)) {
+ $_html_class = !empty($class) ? ' class="' . $class . '"' : '';
+ $_html_id = !empty($id) ? ' id="' . $id . '"' : '';
+ $_html_result = '<select name="' . $name . '"' . $_html_class . $_html_id . $extra . '>' . "\n" . $_html_result . '</select>' . "\n";
+ }
+
+ return $_html_result;
+}
+
+function smarty_function_html_options_optoutput($key, $value, $selected, $id, $class, &$idx) {
+ if (!is_array($value)) {
+ $_key = smarty_function_escape_special_chars($key);
+ $_html_result = '<option value="' . $_key . '"';
+ if (is_array($selected)) {
+ if (isset($selected[$_key])) {
+ $_html_result .= ' selected="selected"';
+ }
+ } elseif ($_key === $selected) {
+ $_html_result .= ' selected="selected"';
+ }
+ $_html_class = !empty($class) ? ' class="' . $class . ' option"' : '';
+ $_html_id = !empty($id) ? ' id="' . $id . '-' . $idx . '"' : '';
+ if (is_object($value)) {
+ if (method_exists($value, "__toString")) {
+ $value = smarty_function_escape_special_chars((string)$value->__toString());
+ } else {
+ trigger_error("html_options: value is an object of class '" . get_class($value) . "' without __toString() method", E_USER_NOTICE);
+
+ return '';
+ }
+ } else {
+ $value = smarty_function_escape_special_chars((string)$value);
+ }
+ $_html_result .= $_html_class . $_html_id . '>' . $value . '</option>' . "\n";
+ $idx++;
+ } else {
+ $_idx = 0;
+ $_html_result = smarty_function_html_options_optgroup($key, $value, $selected, !empty($id) ? ($id . '-' . $idx) : null, $class, $_idx);
+ $idx++;
+ }
+
+ return $_html_result;
+}
+
+function smarty_function_html_options_optgroup($key, $values, $selected, $id, $class, &$idx) {
+ $optgroup_html = '<optgroup label="' . smarty_function_escape_special_chars($key) . '">' . "\n";
+ foreach ($values as $key => $value) {
+ $optgroup_html .= smarty_function_html_options_optoutput($key, $value, $selected, $id, $class, $idx);
+ }
+ $optgroup_html .= "</optgroup>\n";
+
+ return $optgroup_html;
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/function.html_radios.php
@@ -0,0 +1,219 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsFunction
+ */
+
+/**
+ * Smarty {html_radios} function plugin
+ * File: function.html_radios.php<br>
+ * Type: function<br>
+ * Name: html_radios<br>
+ * Date: 24.Feb.2003<br>
+ * Purpose: Prints out a list of radio input types<br>
+ * Params:
+ * <pre>
+ * - name (optional) - string default "radio"
+ * - values (required) - array
+ * - options (required) - associative array
+ * - checked (optional) - array default not set
+ * - separator (optional) - ie <br> or
+ * - output (optional) - the output next to each radio button
+ * - assign (optional) - assign the output as an array to this variable
+ * - escape (optional) - escape the content (not value), defaults to true
+ * </pre>
+ * Examples:
+ * <pre>
+ * {html_radios values=$ids output=$names}
+ * {html_radios values=$ids name='box' separator='<br>' output=$names}
+ * {html_radios values=$ids checked=$checked separator='<br>' output=$names}
+ * </pre>
+ *
+ * @link http://smarty.php.net/manual/en/language.function.html.radios.php {html_radios}
+ * (Smarty online manual)
+ * @author Christopher Kvarme <christopher.kvarme@flashjab.com>
+ * @author credits to Monte Ohrt <monte at ohrt dot com>
+ * @version 1.0
+ *
+ * @param array $params parameters
+ * @param Smarty_Internal_Template $template template object
+ *
+ * @return string
+ * @uses smarty_function_escape_special_chars()
+ */
+function smarty_function_html_radios($params, $template) {
+ require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
+
+ $name = 'radio';
+ $values = null;
+ $options = null;
+ $selected = null;
+ $separator = '';
+ $escape = true;
+ $labels = true;
+ $label_ids = false;
+ $output = null;
+ $extra = '';
+
+ foreach ($params as $_key => $_val) {
+ switch ($_key) {
+ case 'name':
+ case 'separator':
+ $$_key = (string)$_val;
+ break;
+
+ case 'checked':
+ case 'selected':
+ if (is_array($_val)) {
+ trigger_error('html_radios: the "' . $_key . '" attribute cannot be an array', E_USER_WARNING);
+ } elseif (is_object($_val)) {
+ if (method_exists($_val, "__toString")) {
+ $selected = smarty_function_escape_special_chars((string)$_val->__toString());
+ } else {
+ trigger_error("html_radios: selected attribute is an object of class '" . get_class($_val) . "' without __toString() method", E_USER_NOTICE);
+ }
+ } else {
+ $selected = (string)$_val;
+ }
+ break;
+
+ case 'escape':
+ case 'labels':
+ case 'label_ids':
+ $$_key = (bool)$_val;
+ break;
+
+ case 'options':
+ $$_key = (array)$_val;
+ break;
+
+ case 'values':
+ case 'output':
+ $$_key = array_values((array)$_val);
+ break;
+
+ case 'radios':
+ trigger_error('html_radios: the use of the "radios" attribute is deprecated, use "options" instead', E_USER_WARNING);
+ $options = (array)$_val;
+ break;
+
+ case 'assign':
+ break;
+
+ case 'strict':
+ break;
+
+ case 'disabled':
+ case 'readonly':
+ if (!empty($params['strict'])) {
+ if (!is_scalar($_val)) {
+ trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute", E_USER_NOTICE);
+ }
+
+ if ($_val === true || $_val === $_key) {
+ $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"';
+ }
+
+ break;
+ }
+ // omit break; to fall through!
+
+ default:
+ if (!is_array($_val)) {
+ $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
+ } else {
+ trigger_error("html_radios: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+ }
+ break;
+ }
+ }
+
+ if (!isset($options) && !isset($values)) {
+ /* raise error here? */
+
+ return '';
+ }
+
+ $_html_result = array();
+
+ if (isset($options)) {
+ foreach ($options as $_key => $_val) {
+ $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape);
+ }
+ } else {
+ foreach ($values as $_i => $_key) {
+ $_val = isset($output[$_i]) ? $output[$_i] : '';
+ $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape);
+ }
+ }
+
+ if (!empty($params['assign'])) {
+ $template->assign($params['assign'], $_html_result);
+ } else {
+ return implode("\n", $_html_result);
+ }
+}
+
+function smarty_function_html_radios_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids, $escape) {
+ $_output = '';
+
+ if (is_object($value)) {
+ if (method_exists($value, "__toString")) {
+ $value = (string)$value->__toString();
+ } else {
+ trigger_error("html_options: value is an object of class '" . get_class($value) . "' without __toString() method", E_USER_NOTICE);
+
+ return '';
+ }
+ } else {
+ $value = (string)$value;
+ }
+
+ if (is_object($output)) {
+ if (method_exists($output, "__toString")) {
+ $output = (string)$output->__toString();
+ } else {
+ trigger_error("html_options: output is an object of class '" . get_class($output) . "' without __toString() method", E_USER_NOTICE);
+
+ return '';
+ }
+ } else {
+ $output = (string)$output;
+ }
+
+ if ($labels) {
+ if ($label_ids) {
+ $_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!' . Smarty::$_UTF8_MODIFIER, '_', $name . '_' . $value));
+ $_output .= '<label for="' . $_id . '">';
+ } else {
+ $_output .= '<label>';
+ }
+ }
+
+ $name = smarty_function_escape_special_chars($name);
+ $value = smarty_function_escape_special_chars($value);
+ if ($escape) {
+ $output = smarty_function_escape_special_chars($output);
+ }
+
+ $_output .= '<input type="radio" name="' . $name . '" value="' . $value . '"';
+
+ if ($labels && $label_ids) {
+ $_output .= ' id="' . $_id . '"';
+ }
+
+ if ($value === $selected) {
+ $_output .= ' checked="checked"';
+ }
+
+ $_output .= $extra . ' />' . $output;
+ if ($labels) {
+ $_output .= '</label>';
+ }
+
+ $_output .= $separator;
+
+ return $_output;
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/function.html_select_date.php
@@ -0,0 +1,386 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsFunction
+ */
+
+/**
+ * @ignore
+ */
+require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
+/**
+ * @ignore
+ */
+require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php');
+
+/**
+ * Smarty {html_select_date} plugin
+ * Type: function<br>
+ * Name: html_select_date<br>
+ * Purpose: Prints the dropdowns for date selection.
+ * ChangeLog:
+ * <pre>
+ * - 1.0 initial release
+ * - 1.1 added support for +/- N syntax for begin
+ * and end year values. (Monte)
+ * - 1.2 added support for yyyy-mm-dd syntax for
+ * time value. (Jan Rosier)
+ * - 1.3 added support for choosing format for
+ * month values (Gary Loescher)
+ * - 1.3.1 added support for choosing format for
+ * day values (Marcus Bointon)
+ * - 1.3.2 support negative timestamps, force year
+ * dropdown to include given date unless explicitly set (Monte)
+ * - 1.3.4 fix behaviour of 0000-00-00 00:00:00 dates to match that
+ * of 0000-00-00 dates (cybot, boots)
+ * - 2.0 complete rewrite for performance,
+ * added attributes month_names, *_id
+ * </pre>
+ *
+ * @link http://www.smarty.net/manual/en/language.function.html.select.date.php {html_select_date}
+ * (Smarty online manual)
+ * @version 2.0
+ * @author Andrei Zmievski
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author Rodney Rehm
+ *
+ * @param array $params parameters
+ *
+ * @return string
+ */
+function smarty_function_html_select_date($params) {
+ // generate timestamps used for month names only
+ static $_month_timestamps = null;
+ static $_current_year = null;
+ if ($_month_timestamps === null) {
+ $_current_year = date('Y');
+ $_month_timestamps = array();
+ for ($i = 1; $i <= 12; $i++) {
+ $_month_timestamps[$i] = mktime(0, 0, 0, $i, 1, 2000);
+ }
+ }
+
+ /* Default values. */
+ $prefix = "Date_";
+ $start_year = null;
+ $end_year = null;
+ $display_days = true;
+ $display_months = true;
+ $display_years = true;
+ $month_format = "%B";
+ /* Write months as numbers by default GL */
+ $month_value_format = "%m";
+ $day_format = "%02d";
+ /* Write day values using this format MB */
+ $day_value_format = "%d";
+ $year_as_text = false;
+ /* Display years in reverse order? Ie. 2000,1999,.... */
+ $reverse_years = false;
+ /* Should the select boxes be part of an array when returned from PHP?
+ e.g. setting it to "birthday", would create "birthday[Day]",
+ "birthday[Month]" & "birthday[Year]". Can be combined with prefix */
+ $field_array = null;
+ /* <select size>'s of the different <select> tags.
+ If not set, uses default dropdown. */
+ $day_size = null;
+ $month_size = null;
+ $year_size = null;
+ /* Unparsed attributes common to *ALL* the <select>/<input> tags.
+ An example might be in the template: all_extra ='class ="foo"'. */
+ $all_extra = null;
+ /* Separate attributes for the tags. */
+ $day_extra = null;
+ $month_extra = null;
+ $year_extra = null;
+ /* Order in which to display the fields.
+ "D" -> day, "M" -> month, "Y" -> year. */
+ $field_order = 'MDY';
+ /* String printed between the different fields. */
+ $field_separator = "\n";
+ $option_separator = "\n";
+ $time = null;
+ // $all_empty = null;
+ // $day_empty = null;
+ // $month_empty = null;
+ // $year_empty = null;
+ $extra_attrs = '';
+ $all_id = null;
+ $day_id = null;
+ $month_id = null;
+ $year_id = null;
+
+ foreach ($params as $_key => $_value) {
+ switch ($_key) {
+ case 'time':
+ if (!is_array($_value) && $_value !== null) {
+ $time = smarty_make_timestamp($_value);
+ }
+ break;
+
+ case 'month_names':
+ if (is_array($_value) && count($_value) == 12) {
+ $$_key = $_value;
+ } else {
+ trigger_error("html_select_date: month_names must be an array of 12 strings", E_USER_NOTICE);
+ }
+ break;
+
+ case 'prefix':
+ case 'field_array':
+ case 'start_year':
+ case 'end_year':
+ case 'day_format':
+ case 'day_value_format':
+ case 'month_format':
+ case 'month_value_format':
+ case 'day_size':
+ case 'month_size':
+ case 'year_size':
+ case 'all_extra':
+ case 'day_extra':
+ case 'month_extra':
+ case 'year_extra':
+ case 'field_order':
+ case 'field_separator':
+ case 'option_separator':
+ case 'all_empty':
+ case 'month_empty':
+ case 'day_empty':
+ case 'year_empty':
+ case 'all_id':
+ case 'month_id':
+ case 'day_id':
+ case 'year_id':
+ $$_key = (string)$_value;
+ break;
+
+ case 'display_days':
+ case 'display_months':
+ case 'display_years':
+ case 'year_as_text':
+ case 'reverse_years':
+ $$_key = (bool)$_value;
+ break;
+
+ default:
+ if (!is_array($_value)) {
+ $extra_attrs .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_value) . '"';
+ } else {
+ trigger_error("html_select_date: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+ }
+ break;
+ }
+ }
+
+ // Note: date() is faster than strftime()
+ // Note: explode(date()) is faster than date() date() date()
+ if (isset($params['time']) && is_array($params['time'])) {
+ if (isset($params['time'][$prefix . 'Year'])) {
+ // $_REQUEST[$field_array] given
+ foreach (array('Y' => 'Year', 'm' => 'Month', 'd' => 'Day') as $_elementKey => $_elementName) {
+ $_variableName = '_' . strtolower($_elementName);
+ $$_variableName = isset($params['time'][$prefix . $_elementName])
+ ? $params['time'][$prefix . $_elementName]
+ : date($_elementKey);
+ }
+ } elseif (isset($params['time'][$field_array][$prefix . 'Year'])) {
+ // $_REQUEST given
+ foreach (array('Y' => 'Year', 'm' => 'Month', 'd' => 'Day') as $_elementKey => $_elementName) {
+ $_variableName = '_' . strtolower($_elementName);
+ $$_variableName = isset($params['time'][$field_array][$prefix . $_elementName])
+ ? $params['time'][$field_array][$prefix . $_elementName]
+ : date($_elementKey);
+ }
+ } else {
+ // no date found, use NOW
+ list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d'));
+ }
+ } elseif ($time === null) {
+ if (array_key_exists('time', $params)) {
+ $_year = $_month = $_day = $time = null;
+ } else {
+ list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d'));
+ }
+ } else {
+ list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d', $time));
+ }
+
+ // make syntax "+N" or "-N" work with $start_year and $end_year
+ // Note preg_match('!^(\+|\-)\s*(\d+)$!', $end_year, $match) is slower than trim+substr
+ foreach (array('start', 'end') as $key) {
+ $key .= '_year';
+ $t = $$key;
+ if ($t === null) {
+ $$key = (int)$_current_year;
+ } elseif ($t[0] == '+') {
+ $$key = (int)($_current_year + (int)trim(substr($t, 1)));
+ } elseif ($t[0] == '-') {
+ $$key = (int)($_current_year - (int)trim(substr($t, 1)));
+ } else {
+ $$key = (int)$$key;
+ }
+ }
+
+ // flip for ascending or descending
+ if (($start_year > $end_year && !$reverse_years) || ($start_year < $end_year && $reverse_years)) {
+ $t = $end_year;
+ $end_year = $start_year;
+ $start_year = $t;
+ }
+
+ // generate year <select> or <input>
+ if ($display_years) {
+ $_extra = '';
+ $_name = $field_array ? ($field_array . '[' . $prefix . 'Year]') : ($prefix . 'Year');
+ if ($all_extra) {
+ $_extra .= ' ' . $all_extra;
+ }
+ if ($year_extra) {
+ $_extra .= ' ' . $year_extra;
+ }
+
+ if ($year_as_text) {
+ $_html_years = '<input type="text" name="' . $_name . '" value="' . $_year . '" size="4" maxlength="4"' . $_extra . $extra_attrs . ' />';
+ } else {
+ $_html_years = '<select name="' . $_name . '"';
+ if ($year_id !== null || $all_id !== null) {
+ $_html_years .= ' id="' . smarty_function_escape_special_chars(
+ $year_id !== null ? ($year_id ? $year_id : $_name) : ($all_id ? ($all_id . $_name) : $_name)
+ ) . '"';
+ }
+ if ($year_size) {
+ $_html_years .= ' size="' . $year_size . '"';
+ }
+ $_html_years .= $_extra . $extra_attrs . '>' . $option_separator;
+
+ if (isset($year_empty) || isset($all_empty)) {
+ $_html_years .= '<option value="">' . (isset($year_empty) ? $year_empty : $all_empty) . '</option>' . $option_separator;
+ }
+
+ $op = $start_year > $end_year ? -1 : 1;
+ for ($i = $start_year; $op > 0 ? $i <= $end_year : $i >= $end_year; $i += $op) {
+ $_html_years .= '<option value="' . $i . '"'
+ . ($_year == $i ? ' selected="selected"' : '')
+ . '>' . $i . '</option>' . $option_separator;
+ }
+
+ $_html_years .= '</select>';
+ }
+ }
+
+ // generate month <select> or <input>
+ if ($display_months) {
+ $_extra = '';
+ $_name = $field_array ? ($field_array . '[' . $prefix . 'Month]') : ($prefix . 'Month');
+ if ($all_extra) {
+ $_extra .= ' ' . $all_extra;
+ }
+ if ($month_extra) {
+ $_extra .= ' ' . $month_extra;
+ }
+
+ $_html_months = '<select name="' . $_name . '"';
+ if ($month_id !== null || $all_id !== null) {
+ $_html_months .= ' id="' . smarty_function_escape_special_chars(
+ $month_id !== null ? ($month_id ? $month_id : $_name) : ($all_id ? ($all_id . $_name) : $_name)
+ ) . '"';
+ }
+ if ($month_size) {
+ $_html_months .= ' size="' . $month_size . '"';
+ }
+ $_html_months .= $_extra . $extra_attrs . '>' . $option_separator;
+
+ if (isset($month_empty) || isset($all_empty)) {
+ $_html_months .= '<option value="">' . (isset($month_empty) ? $month_empty : $all_empty) . '</option>' . $option_separator;
+ }
+
+ for ($i = 1; $i <= 12; $i++) {
+ $_val = sprintf('%02d', $i);
+ $_text = isset($month_names) ? smarty_function_escape_special_chars($month_names[$i]) : ($month_format == "%m" ? $_val : strftime($month_format, $_month_timestamps[$i]));
+ $_value = $month_value_format == "%m" ? $_val : strftime($month_value_format, $_month_timestamps[$i]);
+ $_html_months .= '<option value="' . $_value . '"'
+ . ($_val == $_month ? ' selected="selected"' : '')
+ . '>' . $_text . '</option>' . $option_separator;
+ }
+
+ $_html_months .= '</select>';
+ }
+
+ // generate day <select> or <input>
+ if ($display_days) {
+ $_extra = '';
+ $_name = $field_array ? ($field_array . '[' . $prefix . 'Day]') : ($prefix . 'Day');
+ if ($all_extra) {
+ $_extra .= ' ' . $all_extra;
+ }
+ if ($day_extra) {
+ $_extra .= ' ' . $day_extra;
+ }
+
+ $_html_days = '<select name="' . $_name . '"';
+ if ($day_id !== null || $all_id !== null) {
+ $_html_days .= ' id="' . smarty_function_escape_special_chars(
+ $day_id !== null ? ($day_id ? $day_id : $_name) : ($all_id ? ($all_id . $_name) : $_name)
+ ) . '"';
+ }
+ if ($day_size) {
+ $_html_days .= ' size="' . $day_size . '"';
+ }
+ $_html_days .= $_extra . $extra_attrs . '>' . $option_separator;
+
+ if (isset($day_empty) || isset($all_empty)) {
+ $_html_days .= '<option value="">' . (isset($day_empty) ? $day_empty : $all_empty) . '</option>' . $option_separator;
+ }
+
+ for ($i = 1; $i <= 31; $i++) {
+ $_val = sprintf('%02d', $i);
+ $_text = $day_format == '%02d' ? $_val : sprintf($day_format, $i);
+ $_value = $day_value_format == '%02d' ? $_val : sprintf($day_value_format, $i);
+ $_html_days .= '<option value="' . $_value . '"'
+ . ($_val == $_day ? ' selected="selected"' : '')
+ . '>' . $_text . '</option>' . $option_separator;
+ }
+
+ $_html_days .= '</select>';
+ }
+
+ // order the fields for output
+ $_html = '';
+ for ($i = 0; $i <= 2; $i++) {
+ switch ($field_order[$i]) {
+ case 'Y':
+ case 'y':
+ if (isset($_html_years)) {
+ if ($_html) {
+ $_html .= $field_separator;
+ }
+ $_html .= $_html_years;
+ }
+ break;
+
+ case 'm':
+ case 'M':
+ if (isset($_html_months)) {
+ if ($_html) {
+ $_html .= $field_separator;
+ }
+ $_html .= $_html_months;
+ }
+ break;
+
+ case 'd':
+ case 'D':
+ if (isset($_html_days)) {
+ if ($_html) {
+ $_html .= $field_separator;
+ }
+ $_html .= $_html_days;
+ }
+ break;
+ }
+ }
+
+ return $_html;
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/function.html_select_time.php
@@ -0,0 +1,363 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsFunction
+ */
+
+/**
+ * @ignore
+ */
+require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
+/**
+ * @ignore
+ */
+require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php');
+
+/**
+ * Smarty {html_select_time} function plugin
+ * Type: function<br>
+ * Name: html_select_time<br>
+ * Purpose: Prints the dropdowns for time selection
+ *
+ * @link http://www.smarty.net/manual/en/language.function.html.select.time.php {html_select_time}
+ * (Smarty online manual)
+ * @author Roberto Berto <roberto@berto.net>
+ * @author Monte Ohrt <monte AT ohrt DOT com>
+ *
+ * @param array $params parameters
+ *
+ * @return string
+ * @uses smarty_make_timestamp()
+ */
+function smarty_function_html_select_time($params) {
+ $prefix = "Time_";
+ $field_array = null;
+ $field_separator = "\n";
+ $option_separator = "\n";
+ $time = null;
+
+ $display_hours = true;
+ $display_minutes = true;
+ $display_seconds = true;
+ $display_meridian = true;
+
+ $hour_format = '%02d';
+ $hour_value_format = '%02d';
+ $minute_format = '%02d';
+ $minute_value_format = '%02d';
+ $second_format = '%02d';
+ $second_value_format = '%02d';
+
+ $hour_size = null;
+ $minute_size = null;
+ $second_size = null;
+ $meridian_size = null;
+
+ $all_empty = null;
+ $hour_empty = null;
+ $minute_empty = null;
+ $second_empty = null;
+ $meridian_empty = null;
+
+ $all_id = null;
+ $hour_id = null;
+ $minute_id = null;
+ $second_id = null;
+ $meridian_id = null;
+
+ $use_24_hours = true;
+ $minute_interval = 1;
+ $second_interval = 1;
+
+ $extra_attrs = '';
+ $all_extra = null;
+ $hour_extra = null;
+ $minute_extra = null;
+ $second_extra = null;
+ $meridian_extra = null;
+
+ foreach ($params as $_key => $_value) {
+ switch ($_key) {
+ case 'time':
+ if (!is_array($_value) && $_value !== null) {
+ $time = smarty_make_timestamp($_value);
+ }
+ break;
+
+ case 'prefix':
+ case 'field_array':
+
+ case 'field_separator':
+ case 'option_separator':
+
+ case 'all_extra':
+ case 'hour_extra':
+ case 'minute_extra':
+ case 'second_extra':
+ case 'meridian_extra':
+
+ case 'all_empty':
+ case 'hour_empty':
+ case 'minute_empty':
+ case 'second_empty':
+ case 'meridian_empty':
+
+ case 'all_id':
+ case 'hour_id':
+ case 'minute_id':
+ case 'second_id':
+ case 'meridian_id':
+
+ case 'hour_format':
+ case 'hour_value_format':
+ case 'minute_format':
+ case 'minute_value_format':
+ case 'second_format':
+ case 'second_value_format':
+ $$_key = (string)$_value;
+ break;
+
+ case 'display_hours':
+ case 'display_minutes':
+ case 'display_seconds':
+ case 'display_meridian':
+ case 'use_24_hours':
+ $$_key = (bool)$_value;
+ break;
+
+ case 'minute_interval':
+ case 'second_interval':
+
+ case 'hour_size':
+ case 'minute_size':
+ case 'second_size':
+ case 'meridian_size':
+ $$_key = (int)$_value;
+ break;
+
+ default:
+ if (!is_array($_value)) {
+ $extra_attrs .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_value) . '"';
+ } else {
+ trigger_error("html_select_date: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+ }
+ break;
+ }
+ }
+
+ if (isset($params['time']) && is_array($params['time'])) {
+ if (isset($params['time'][$prefix . 'Hour'])) {
+ // $_REQUEST[$field_array] given
+ foreach (array('H' => 'Hour', 'i' => 'Minute', 's' => 'Second') as $_elementKey => $_elementName) {
+ $_variableName = '_' . strtolower($_elementName);
+ $$_variableName = isset($params['time'][$prefix . $_elementName])
+ ? $params['time'][$prefix . $_elementName]
+ : date($_elementKey);
+ }
+ $_meridian = isset($params['time'][$prefix . 'Meridian'])
+ ? (' ' . $params['time'][$prefix . 'Meridian'])
+ : '';
+ $time = strtotime($_hour . ':' . $_minute . ':' . $_second . $_meridian);
+ list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s', $time));
+ } elseif (isset($params['time'][$field_array][$prefix . 'Hour'])) {
+ // $_REQUEST given
+ foreach (array('H' => 'Hour', 'i' => 'Minute', 's' => 'Second') as $_elementKey => $_elementName) {
+ $_variableName = '_' . strtolower($_elementName);
+ $$_variableName = isset($params['time'][$field_array][$prefix . $_elementName])
+ ? $params['time'][$field_array][$prefix . $_elementName]
+ : date($_elementKey);
+ }
+ $_meridian = isset($params['time'][$field_array][$prefix . 'Meridian'])
+ ? (' ' . $params['time'][$field_array][$prefix . 'Meridian'])
+ : '';
+ $time = strtotime($_hour . ':' . $_minute . ':' . $_second . $_meridian);
+ list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s', $time));
+ } else {
+ // no date found, use NOW
+ list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d'));
+ }
+ } elseif ($time === null) {
+ if (array_key_exists('time', $params)) {
+ $_hour = $_minute = $_second = $time = null;
+ } else {
+ list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s'));
+ }
+ } else {
+ list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s', $time));
+ }
+
+ // generate hour <select>
+ if ($display_hours) {
+ $_html_hours = '';
+ $_extra = '';
+ $_name = $field_array ? ($field_array . '[' . $prefix . 'Hour]') : ($prefix . 'Hour');
+ if ($all_extra) {
+ $_extra .= ' ' . $all_extra;
+ }
+ if ($hour_extra) {
+ $_extra .= ' ' . $hour_extra;
+ }
+
+ $_html_hours = '<select name="' . $_name . '"';
+ if ($hour_id !== null || $all_id !== null) {
+ $_html_hours .= ' id="' . smarty_function_escape_special_chars(
+ $hour_id !== null ? ($hour_id ? $hour_id : $_name) : ($all_id ? ($all_id . $_name) : $_name)
+ ) . '"';
+ }
+ if ($hour_size) {
+ $_html_hours .= ' size="' . $hour_size . '"';
+ }
+ $_html_hours .= $_extra . $extra_attrs . '>' . $option_separator;
+
+ if (isset($hour_empty) || isset($all_empty)) {
+ $_html_hours .= '<option value="">' . (isset($hour_empty) ? $hour_empty : $all_empty) . '</option>' . $option_separator;
+ }
+
+ $start = $use_24_hours ? 0 : 1;
+ $end = $use_24_hours ? 23 : 12;
+ for ($i = $start; $i <= $end; $i++) {
+ $_val = sprintf('%02d', $i);
+ $_text = $hour_format == '%02d' ? $_val : sprintf($hour_format, $i);
+ $_value = $hour_value_format == '%02d' ? $_val : sprintf($hour_value_format, $i);
+
+ if (!$use_24_hours) {
+ $_hour12 = $_hour == 0
+ ? 12
+ : ($_hour <= 12 ? $_hour : $_hour - 12);
+ }
+
+ $selected = $_hour !== null ? ($use_24_hours ? $_hour == $_val : $_hour12 == $_val) : null;
+ $_html_hours .= '<option value="' . $_value . '"'
+ . ($selected ? ' selected="selected"' : '')
+ . '>' . $_text . '</option>' . $option_separator;
+ }
+
+ $_html_hours .= '</select>';
+ }
+
+ // generate minute <select>
+ if ($display_minutes) {
+ $_html_minutes = '';
+ $_extra = '';
+ $_name = $field_array ? ($field_array . '[' . $prefix . 'Minute]') : ($prefix . 'Minute');
+ if ($all_extra) {
+ $_extra .= ' ' . $all_extra;
+ }
+ if ($minute_extra) {
+ $_extra .= ' ' . $minute_extra;
+ }
+
+ $_html_minutes = '<select name="' . $_name . '"';
+ if ($minute_id !== null || $all_id !== null) {
+ $_html_minutes .= ' id="' . smarty_function_escape_special_chars(
+ $minute_id !== null ? ($minute_id ? $minute_id : $_name) : ($all_id ? ($all_id . $_name) : $_name)
+ ) . '"';
+ }
+ if ($minute_size) {
+ $_html_minutes .= ' size="' . $minute_size . '"';
+ }
+ $_html_minutes .= $_extra . $extra_attrs . '>' . $option_separator;
+
+ if (isset($minute_empty) || isset($all_empty)) {
+ $_html_minutes .= '<option value="">' . (isset($minute_empty) ? $minute_empty : $all_empty) . '</option>' . $option_separator;
+ }
+
+ $selected = $_minute !== null ? ($_minute - $_minute % $minute_interval) : null;
+ for ($i = 0; $i <= 59; $i += $minute_interval) {
+ $_val = sprintf('%02d', $i);
+ $_text = $minute_format == '%02d' ? $_val : sprintf($minute_format, $i);
+ $_value = $minute_value_format == '%02d' ? $_val : sprintf($minute_value_format, $i);
+ $_html_minutes .= '<option value="' . $_value . '"'
+ . ($selected === $i ? ' selected="selected"' : '')
+ . '>' . $_text . '</option>' . $option_separator;
+ }
+
+ $_html_minutes .= '</select>';
+ }
+
+ // generate second <select>
+ if ($display_seconds) {
+ $_html_seconds = '';
+ $_extra = '';
+ $_name = $field_array ? ($field_array . '[' . $prefix . 'Second]') : ($prefix . 'Second');
+ if ($all_extra) {
+ $_extra .= ' ' . $all_extra;
+ }
+ if ($second_extra) {
+ $_extra .= ' ' . $second_extra;
+ }
+
+ $_html_seconds = '<select name="' . $_name . '"';
+ if ($second_id !== null || $all_id !== null) {
+ $_html_seconds .= ' id="' . smarty_function_escape_special_chars(
+ $second_id !== null ? ($second_id ? $second_id : $_name) : ($all_id ? ($all_id . $_name) : $_name)
+ ) . '"';
+ }
+ if ($second_size) {
+ $_html_seconds .= ' size="' . $second_size . '"';
+ }
+ $_html_seconds .= $_extra . $extra_attrs . '>' . $option_separator;
+
+ if (isset($second_empty) || isset($all_empty)) {
+ $_html_seconds .= '<option value="">' . (isset($second_empty) ? $second_empty : $all_empty) . '</option>' . $option_separator;
+ }
+
+ $selected = $_second !== null ? ($_second - $_second % $second_interval) : null;
+ for ($i = 0; $i <= 59; $i += $second_interval) {
+ $_val = sprintf('%02d', $i);
+ $_text = $second_format == '%02d' ? $_val : sprintf($second_format, $i);
+ $_value = $second_value_format == '%02d' ? $_val : sprintf($second_value_format, $i);
+ $_html_seconds .= '<option value="' . $_value . '"'
+ . ($selected === $i ? ' selected="selected"' : '')
+ . '>' . $_text . '</option>' . $option_separator;
+ }
+
+ $_html_seconds .= '</select>';
+ }
+
+ // generate meridian <select>
+ if ($display_meridian && !$use_24_hours) {
+ $_html_meridian = '';
+ $_extra = '';
+ $_name = $field_array ? ($field_array . '[' . $prefix . 'Meridian]') : ($prefix . 'Meridian');
+ if ($all_extra) {
+ $_extra .= ' ' . $all_extra;
+ }
+ if ($meridian_extra) {
+ $_extra .= ' ' . $meridian_extra;
+ }
+
+ $_html_meridian = '<select name="' . $_name . '"';
+ if ($meridian_id !== null || $all_id !== null) {
+ $_html_meridian .= ' id="' . smarty_function_escape_special_chars(
+ $meridian_id !== null ? ($meridian_id ? $meridian_id : $_name) : ($all_id ? ($all_id . $_name) : $_name)
+ ) . '"';
+ }
+ if ($meridian_size) {
+ $_html_meridian .= ' size="' . $meridian_size . '"';
+ }
+ $_html_meridian .= $_extra . $extra_attrs . '>' . $option_separator;
+
+ if (isset($meridian_empty) || isset($all_empty)) {
+ $_html_meridian .= '<option value="">' . (isset($meridian_empty) ? $meridian_empty : $all_empty) . '</option>' . $option_separator;
+ }
+
+ $_html_meridian .= '<option value="am"' . ($_hour > 0 && $_hour < 12 ? ' selected="selected"' : '') . '>AM</option>' . $option_separator
+ . '<option value="pm"' . ($_hour < 12 ? '' : ' selected="selected"') . '>PM</option>' . $option_separator
+ . '</select>';
+ }
+
+ $_html = '';
+ foreach (array('_html_hours', '_html_minutes', '_html_seconds', '_html_meridian') as $k) {
+ if (isset($$k)) {
+ if ($_html) {
+ $_html .= $field_separator;
+ }
+ $_html .= $$k;
+ }
+ }
+
+ return $_html;
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/function.html_table.php
@@ -0,0 +1,174 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsFunction
+ */
+
+/**
+ * Smarty {html_table} function plugin
+ * Type: function<br>
+ * Name: html_table<br>
+ * Date: Feb 17, 2003<br>
+ * Purpose: make an html table from an array of data<br>
+ * Params:
+ * <pre>
+ * - loop - array to loop through
+ * - cols - number of columns, comma separated list of column names
+ * or array of column names
+ * - rows - number of rows
+ * - table_attr - table attributes
+ * - th_attr - table heading attributes (arrays are cycled)
+ * - tr_attr - table row attributes (arrays are cycled)
+ * - td_attr - table cell attributes (arrays are cycled)
+ * - trailpad - value to pad trailing cells with
+ * - caption - text for caption element
+ * - vdir - vertical direction (default: "down", means top-to-bottom)
+ * - hdir - horizontal direction (default: "right", means left-to-right)
+ * - inner - inner loop (default "cols": print $loop line by line,
+ * $loop will be printed column by column otherwise)
+ * </pre>
+ * Examples:
+ * <pre>
+ * {table loop=$data}
+ * {table loop=$data cols=4 tr_attr='"bgcolor=red"'}
+ * {table loop=$data cols="first,second,third" tr_attr=$colors}
+ * </pre>
+ *
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author credit to Messju Mohr <messju at lammfellpuschen dot de>
+ * @author credit to boots <boots dot smarty at yahoo dot com>
+ * @version 1.1
+ * @link http://www.smarty.net/manual/en/language.function.html.table.php {html_table}
+ * (Smarty online manual)
+ *
+ * @param array $params parameters
+ *
+ * @return string
+ */
+function smarty_function_html_table($params) {
+ $table_attr = 'border="1"';
+ $tr_attr = '';
+ $th_attr = '';
+ $td_attr = '';
+ $cols = $cols_count = 3;
+ $rows = 3;
+ $trailpad = ' ';
+ $vdir = 'down';
+ $hdir = 'right';
+ $inner = 'cols';
+ $caption = '';
+ $loop = null;
+
+ if (!isset($params['loop'])) {
+ trigger_error("html_table: missing 'loop' parameter", E_USER_WARNING);
+
+ return;
+ }
+
+ foreach ($params as $_key => $_value) {
+ switch ($_key) {
+ case 'loop':
+ $$_key = (array)$_value;
+ break;
+
+ case 'cols':
+ if (is_array($_value) && !empty($_value)) {
+ $cols = $_value;
+ $cols_count = count($_value);
+ } elseif (!is_numeric($_value) && is_string($_value) && !empty($_value)) {
+ $cols = explode(',', $_value);
+ $cols_count = count($cols);
+ } elseif (!empty($_value)) {
+ $cols_count = (int)$_value;
+ } else {
+ $cols_count = $cols;
+ }
+ break;
+
+ case 'rows':
+ $$_key = (int)$_value;
+ break;
+
+ case 'table_attr':
+ case 'trailpad':
+ case 'hdir':
+ case 'vdir':
+ case 'inner':
+ case 'caption':
+ $$_key = (string)$_value;
+ break;
+
+ case 'tr_attr':
+ case 'td_attr':
+ case 'th_attr':
+ $$_key = $_value;
+ break;
+ }
+ }
+
+ $loop_count = count($loop);
+ if (empty($params['rows'])) {
+ /* no rows specified */
+ $rows = ceil($loop_count / $cols_count);
+ } elseif (empty($params['cols'])) {
+ if (!empty($params['rows'])) {
+ /* no cols specified, but rows */
+ $cols_count = ceil($loop_count / $rows);
+ }
+ }
+
+ $output = "<table $table_attr>\n";
+
+ if (!empty($caption)) {
+ $output .= '<caption>' . $caption . "</caption>\n";
+ }
+
+ if (is_array($cols)) {
+ $cols = ($hdir == 'right') ? $cols : array_reverse($cols);
+ $output .= "<thead><tr>\n";
+
+ for ($r = 0; $r < $cols_count; $r++) {
+ $output .= '<th' . smarty_function_html_table_cycle('th', $th_attr, $r) . '>';
+ $output .= $cols[$r];
+ $output .= "</th>\n";
+ }
+ $output .= "</tr></thead>\n";
+ }
+
+ $output .= "<tbody>\n";
+ for ($r = 0; $r < $rows; $r++) {
+ $output .= "<tr" . smarty_function_html_table_cycle('tr', $tr_attr, $r) . ">\n";
+ $rx = ($vdir == 'down') ? $r * $cols_count : ($rows - 1 - $r) * $cols_count;
+
+ for ($c = 0; $c < $cols_count; $c++) {
+ $x = ($hdir == 'right') ? $rx + $c : $rx + $cols_count - 1 - $c;
+ if ($inner != 'cols') {
+ /* shuffle x to loop over rows*/
+ $x = floor($x / $cols_count) + ($x % $cols_count) * $rows;
+ }
+
+ if ($x < $loop_count) {
+ $output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">" . $loop[$x] . "</td>\n";
+ } else {
+ $output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">$trailpad</td>\n";
+ }
+ }
+ $output .= "</tr>\n";
+ }
+ $output .= "</tbody>\n";
+ $output .= "</table>\n";
+
+ return $output;
+}
+
+function smarty_function_html_table_cycle($name, $var, $no) {
+ if (!is_array($var)) {
+ $ret = $var;
+ } else {
+ $ret = $var[$no % count($var)];
+ }
+
+ return ($ret) ? ' ' . $ret : '';
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/function.mailto.php
@@ -0,0 +1,154 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsFunction
+ */
+
+/**
+ * Smarty {mailto} function plugin
+ * Type: function<br>
+ * Name: mailto<br>
+ * Date: May 21, 2002
+ * Purpose: automate mailto address link creation, and optionally encode them.<br>
+ * Params:
+ * <pre>
+ * - address - (required) - e-mail address
+ * - text - (optional) - text to display, default is address
+ * - encode - (optional) - can be one of:
+ * * none : no encoding (default)
+ * * javascript : encode with javascript
+ * * javascript_charcode : encode with javascript charcode
+ * * hex : encode with hexidecimal (no javascript)
+ * - cc - (optional) - address(es) to carbon copy
+ * - bcc - (optional) - address(es) to blind carbon copy
+ * - subject - (optional) - e-mail subject
+ * - newsgroups - (optional) - newsgroup(s) to post to
+ * - followupto - (optional) - address(es) to follow up to
+ * - extra - (optional) - extra tags for the href link
+ * </pre>
+ * Examples:
+ * <pre>
+ * {mailto address="me@domain.com"}
+ * {mailto address="me@domain.com" encode="javascript"}
+ * {mailto address="me@domain.com" encode="hex"}
+ * {mailto address="me@domain.com" subject="Hello to you!"}
+ * {mailto address="me@domain.com" cc="you@domain.com,they@domain.com"}
+ * {mailto address="me@domain.com" extra='class="mailto"'}
+ * </pre>
+ *
+ * @link http://www.smarty.net/manual/en/language.function.mailto.php {mailto}
+ * (Smarty online manual)
+ * @version 1.2
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author credits to Jason Sweat (added cc, bcc and subject functionality)
+ *
+ * @param array $params parameters
+ *
+ * @return string
+ */
+function smarty_function_mailto($params) {
+ static $_allowed_encoding = array('javascript' => true, 'javascript_charcode' => true, 'hex' => true, 'none' => true);
+ $extra = '';
+
+ if (empty($params['address'])) {
+ trigger_error("mailto: missing 'address' parameter", E_USER_WARNING);
+
+ return;
+ } else {
+ $address = $params['address'];
+ }
+
+ $text = $address;
+ // netscape and mozilla do not decode %40 (@) in BCC field (bug?)
+ // so, don't encode it.
+ $search = array('%40', '%2C');
+ $replace = array('@', ',');
+ $mail_parms = array();
+ foreach ($params as $var => $value) {
+ switch ($var) {
+ case 'cc':
+ case 'bcc':
+ case 'followupto':
+ if (!empty($value)) {
+ $mail_parms[] = $var . '=' . str_replace($search, $replace, rawurlencode($value));
+ }
+ break;
+
+ case 'subject':
+ case 'newsgroups':
+ $mail_parms[] = $var . '=' . rawurlencode($value);
+ break;
+
+ case 'extra':
+ case 'text':
+ $$var = $value;
+
+ default:
+ }
+ }
+
+ if ($mail_parms) {
+ $address .= '?' . join('&', $mail_parms);
+ }
+
+ $encode = (empty($params['encode'])) ? 'none' : $params['encode'];
+ if (!isset($_allowed_encoding[$encode])) {
+ trigger_error("mailto: 'encode' parameter must be none, javascript, javascript_charcode or hex", E_USER_WARNING);
+
+ return;
+ }
+ // FIXME: (rodneyrehm) document.write() excues me what? 1998 has passed!
+ if ($encode == 'javascript') {
+ $string = 'document.write(\'<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>\');';
+
+ $js_encode = '';
+ for ($x = 0, $_length = strlen($string); $x < $_length; $x++) {
+ $js_encode .= '%' . bin2hex($string[$x]);
+ }
+
+ return '<script type="text/javascript">eval(unescape(\'' . $js_encode . '\'))</script>';
+ } elseif ($encode == 'javascript_charcode') {
+ $string = '<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>';
+
+ for ($x = 0, $y = strlen($string); $x < $y; $x++) {
+ $ord[] = ord($string[$x]);
+ }
+
+ $_ret = "<script type=\"text/javascript\" language=\"javascript\">\n"
+ . "{document.write(String.fromCharCode("
+ . implode(',', $ord)
+ . "))"
+ . "}\n"
+ . "</script>\n";
+
+ return $_ret;
+ } elseif ($encode == 'hex') {
+ preg_match('!^(.*)(\?.*)$!', $address, $match);
+ if (!empty($match[2])) {
+ trigger_error("mailto: hex encoding does not work with extra attributes. Try javascript.", E_USER_WARNING);
+
+ return;
+ }
+ $address_encode = '';
+ for ($x = 0, $_length = strlen($address); $x < $_length; $x++) {
+ if (preg_match('!\w!' . Smarty::$_UTF8_MODIFIER, $address[$x])) {
+ $address_encode .= '%' . bin2hex($address[$x]);
+ } else {
+ $address_encode .= $address[$x];
+ }
+ }
+ $text_encode = '';
+ for ($x = 0, $_length = strlen($text); $x < $_length; $x++) {
+ $text_encode .= '&#x' . bin2hex($text[$x]) . ';';
+ }
+
+ $mailto = "mailto:";
+
+ return '<a href="' . $mailto . $address_encode . '" ' . $extra . '>' . $text_encode . '</a>';
+ } else {
+ // no encoding
+ return '<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>';
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/function.math.php
@@ -0,0 +1,90 @@
+<?php
+/**
+ * Smarty plugin
+ * This plugin is only for Smarty2 BC
+ *
+ * @package Smarty
+ * @subpackage PluginsFunction
+ */
+
+/**
+ * Smarty {math} function plugin
+ * Type: function<br>
+ * Name: math<br>
+ * Purpose: handle math computations in template
+ *
+ * @link http://www.smarty.net/manual/en/language.function.math.php {math}
+ * (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ *
+ * @param array $params parameters
+ * @param Smarty_Internal_Template $template template object
+ *
+ * @return string|null
+ */
+function smarty_function_math($params, $template) {
+ static $_allowed_funcs = array(
+ 'int' => true, 'abs' => true, 'ceil' => true, 'cos' => true, 'exp' => true, 'floor' => true,
+ 'log' => true, 'log10' => true, 'max' => true, 'min' => true, 'pi' => true, 'pow' => true,
+ 'rand' => true, 'round' => true, 'sin' => true, 'sqrt' => true, 'srand' => true, 'tan' => true
+ );
+ // be sure equation parameter is present
+ if (empty($params['equation'])) {
+ trigger_error("math: missing equation parameter", E_USER_WARNING);
+
+ return;
+ }
+
+ $equation = $params['equation'];
+
+ // make sure parenthesis are balanced
+ if (substr_count($equation, "(") != substr_count($equation, ")")) {
+ trigger_error("math: unbalanced parenthesis", E_USER_WARNING);
+
+ return;
+ }
+
+ // match all vars in equation, make sure all are passed
+ preg_match_all("!(?:0x[a-fA-F0-9]+)|([a-zA-Z][a-zA-Z0-9_]*)!", $equation, $match);
+
+ foreach ($match[1] as $curr_var) {
+ if ($curr_var && !isset($params[$curr_var]) && !isset($_allowed_funcs[$curr_var])) {
+ trigger_error("math: function call $curr_var not allowed", E_USER_WARNING);
+
+ return;
+ }
+ }
+
+ foreach ($params as $key => $val) {
+ if ($key != "equation" && $key != "format" && $key != "assign") {
+ // make sure value is not empty
+ if (strlen($val) == 0) {
+ trigger_error("math: parameter $key is empty", E_USER_WARNING);
+
+ return;
+ }
+ if (!is_numeric($val)) {
+ trigger_error("math: parameter $key: is not numeric", E_USER_WARNING);
+
+ return;
+ }
+ $equation = preg_replace("/\b$key\b/", " \$params['$key'] ", $equation);
+ }
+ }
+ $smarty_math_result = null;
+ eval("\$smarty_math_result = " . $equation . ";");
+
+ if (empty($params['format'])) {
+ if (empty($params['assign'])) {
+ return $smarty_math_result;
+ } else {
+ $template->assign($params['assign'], $smarty_math_result);
+ }
+ } else {
+ if (empty($params['assign'])) {
+ printf($params['format'], $smarty_math_result);
+ } else {
+ $template->assign($params['assign'], sprintf($params['format'], $smarty_math_result));
+ }
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/modifier.capitalize.php
@@ -0,0 +1,85 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifier
+ */
+
+/**
+ * Smarty capitalize modifier plugin
+ * Type: modifier<br>
+ * Name: capitalize<br>
+ * Purpose: capitalize words in the string
+ * {@internal {$string|capitalize:true:true} is the fastest option for MBString enabled systems }}
+ *
+ * @param string $string string to capitalize
+ * @param boolean $uc_digits also capitalize "x123" to "X123"
+ * @param boolean $lc_rest capitalize first letters, lowercase all following letters "aAa" to "Aaa"
+ *
+ * @return string capitalized string
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author Rodney Rehm
+ */
+function smarty_modifier_capitalize($string, $uc_digits = false, $lc_rest = false) {
+ if (Smarty::$_MBSTRING) {
+ if ($lc_rest) {
+ // uppercase (including hyphenated words)
+ $upper_string = mb_convert_case($string, MB_CASE_TITLE, Smarty::$_CHARSET);
+ } else {
+ // uppercase word breaks
+ $upper_string = preg_replace_callback("!(^|[^\p{L}'])([\p{Ll}])!S" . Smarty::$_UTF8_MODIFIER, 'smarty_mod_cap_mbconvert_cb', $string);
+ }
+ // check uc_digits case
+ if (!$uc_digits) {
+ if (preg_match_all("!\b([\p{L}]*[\p{N}]+[\p{L}]*)\b!" . Smarty::$_UTF8_MODIFIER, $string, $matches, PREG_OFFSET_CAPTURE)) {
+ foreach ($matches[1] as $match) {
+ $upper_string = substr_replace($upper_string, mb_strtolower($match[0], Smarty::$_CHARSET), $match[1], strlen($match[0]));
+ }
+ }
+ }
+ $upper_string = preg_replace_callback("!((^|\s)['\"])(\w)!" . Smarty::$_UTF8_MODIFIER, 'smarty_mod_cap_mbconvert2_cb', $upper_string);
+ return $upper_string;
+ }
+
+ // lowercase first
+ if ($lc_rest) {
+ $string = strtolower($string);
+ }
+ // uppercase (including hyphenated words)
+ $upper_string = preg_replace_callback("!(^|[^\p{L}'])([\p{Ll}])!S" . Smarty::$_UTF8_MODIFIER, 'smarty_mod_cap_ucfirst_cb', $string);
+ // check uc_digits case
+ if (!$uc_digits) {
+ if (preg_match_all("!\b([\p{L}]*[\p{N}]+[\p{L}]*)\b!" . Smarty::$_UTF8_MODIFIER, $string, $matches, PREG_OFFSET_CAPTURE)) {
+ foreach ($matches[1] as $match) {
+ $upper_string = substr_replace($upper_string, strtolower($match[0]), $match[1], strlen($match[0]));
+ }
+ }
+ }
+ $upper_string = preg_replace_callback("!((^|\s)['\"])(\w)!" . Smarty::$_UTF8_MODIFIER, 'smarty_mod_cap_ucfirst2_cb', $upper_string);
+ return $upper_string;
+}
+
+/*
+ *
+ * Bug: create_function() use exhausts memory when used in long loops
+ * Fix: use declared functions for callbacks instead of using create_function()
+ * Note: This can be fixed using anonymous functions instead, but that requires PHP >= 5.3
+ *
+ * @author Kyle Renfrow
+ */
+function smarty_mod_cap_mbconvert_cb($matches) {
+ return stripslashes($matches[1]) . mb_convert_case(stripslashes($matches[2]), MB_CASE_UPPER, Smarty::$_CHARSET);
+}
+
+function smarty_mod_cap_mbconvert2_cb($matches) {
+ return stripslashes($matches[1]) . mb_convert_case(stripslashes($matches[3]), MB_CASE_UPPER, Smarty::$_CHARSET);
+}
+
+function smarty_mod_cap_ucfirst_cb($matches) {
+ return stripslashes($matches[1]) . ucfirst(stripslashes($matches[2]));
+}
+
+function smarty_mod_cap_ucfirst2_cb($matches) {
+ return stripslashes($matches[1]) . ucfirst(stripslashes($matches[3]));
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/modifier.date_format.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifier
+ */
+
+/**
+ * Smarty date_format modifier plugin
+ * Type: modifier<br>
+ * Name: date_format<br>
+ * Purpose: format datestamps via strftime<br>
+ * Input:<br>
+ * - string: input date string
+ * - format: strftime format for output
+ * - default_date: default date if $string is empty
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.date.format.php date_format (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ *
+ * @param string $string input date string
+ * @param string $format strftime format for output
+ * @param string $default_date default date if $string is empty
+ * @param string $formatter either 'strftime' or 'auto'
+ *
+ * @return string |void
+ * @uses smarty_make_timestamp()
+ */
+function smarty_modifier_date_format($string, $format = null, $default_date = '', $formatter = 'auto') {
+ if ($format === null) {
+ $format = Smarty::$_DATE_FORMAT;
+ }
+ /**
+ * require_once the {@link shared.make_timestamp.php} plugin
+ */
+ require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php');
+ if ($string != '' && $string != '0000-00-00' && $string != '0000-00-00 00:00:00') {
+ $timestamp = smarty_make_timestamp($string);
+ } elseif ($default_date != '') {
+ $timestamp = smarty_make_timestamp($default_date);
+ } else {
+ return;
+ }
+ if ($formatter == 'strftime' || ($formatter == 'auto' && strpos($format, '%') !== false)) {
+ if (DS == '\\') {
+ $_win_from = array('%D', '%h', '%n', '%r', '%R', '%t', '%T');
+ $_win_to = array('%m/%d/%y', '%b', "\n", '%I:%M:%S %p', '%H:%M', "\t", '%H:%M:%S');
+ if (strpos($format, '%e') !== false) {
+ $_win_from[] = '%e';
+ $_win_to[] = sprintf('%\' 2d', date('j', $timestamp));
+ }
+ if (strpos($format, '%l') !== false) {
+ $_win_from[] = '%l';
+ $_win_to[] = sprintf('%\' 2d', date('h', $timestamp));
+ }
+ $format = str_replace($_win_from, $_win_to, $format);
+ }
+
+ return strftime($format, $timestamp);
+ } else {
+ return date($format, $timestamp);
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/modifier.debug_print_var.php
@@ -0,0 +1,115 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage Debug
+ */
+
+/**
+ * Smarty debug_print_var modifier plugin
+ * Type: modifier<br>
+ * Name: debug_print_var<br>
+ * Purpose: formats variable contents for display in the console
+ *
+ * @author Monte Ohrt <monte at ohrt dot com>
+ *
+ * @param array|object $var variable to be formatted
+ * @param int $max maximum recursion depth if $var is an array or object
+ * @param int $length maximum string length if $var is a string
+ * @param int $depth actual recursion depth
+ * @param array $objects processed objects in actual depth to prevent recursive object processing
+ *
+ * @return string
+ */
+function smarty_modifier_debug_print_var($var, $max = 10, $length = 40, $depth = 0, $objects = array()) {
+ $_replace = array("\n" => '<i>\n</i>',
+ "\r" => '<i>\r</i>',
+ "\t" => '<i>\t</i>'
+ );
+ switch (gettype($var)) {
+ case 'array' :
+ $results = '<b>Array (' . count($var) . ')</b>';
+ if ($depth == $max) {
+ break;
+ }
+ foreach ($var as $curr_key => $curr_val) {
+ $results .= '<br>' . str_repeat(' ', $depth * 2)
+ . '<b>' . strtr($curr_key, $_replace) . '</b> => '
+ . smarty_modifier_debug_print_var($curr_val, $max, $length, ++$depth, $objects);
+ $depth--;
+ }
+ break;
+
+ case 'object' :
+ $object_vars = get_object_vars($var);
+ $results = '<b>' . get_class($var) . ' Object (' . count($object_vars) . ')</b>';
+ if (in_array($var, $objects)) {
+ $results .= ' called recursive';
+ break;
+ }
+ if ($depth == $max) {
+ break;
+ }
+ $objects[] = $var;
+ foreach ($object_vars as $curr_key => $curr_val) {
+ $results .= '<br>' . str_repeat(' ', $depth * 2)
+ . '<b> ->' . strtr($curr_key, $_replace) . '</b> = '
+ . smarty_modifier_debug_print_var($curr_val, $max, $length, ++$depth, $objects);
+ $depth--;
+ }
+ break;
+
+ case 'boolean' :
+ case 'NULL' :
+ case 'resource' :
+ if (true === $var) {
+ $results = 'true';
+ } elseif (false === $var) {
+ $results = 'false';
+ } elseif (null === $var) {
+ $results = 'null';
+ } else {
+ $results = htmlspecialchars((string)$var);
+ }
+ $results = '<i>' . $results . '</i>';
+ break;
+
+ case 'integer' :
+ case 'float' :
+ $results = htmlspecialchars((string)$var);
+ break;
+
+ case 'string' :
+ $results = strtr($var, $_replace);
+ if (Smarty::$_MBSTRING) {
+ if (mb_strlen($var, Smarty::$_CHARSET) > $length) {
+ $results = mb_substr($var, 0, $length - 3, Smarty::$_CHARSET) . '...';
+ }
+ } else {
+ if (isset($var[$length])) {
+ $results = substr($var, 0, $length - 3) . '...';
+ }
+ }
+
+ $results = htmlspecialchars('"' . $results . '"');
+ break;
+
+ case 'unknown type' :
+ default :
+ $results = strtr((string)$var, $_replace);
+ if (Smarty::$_MBSTRING) {
+ if (mb_strlen($results, Smarty::$_CHARSET) > $length) {
+ $results = mb_substr($results, 0, $length - 3, Smarty::$_CHARSET) . '...';
+ }
+ } else {
+ if (strlen($results) > $length) {
+ $results = substr($results, 0, $length - 3) . '...';
+ }
+ }
+
+ $results = htmlspecialchars($results);
+ }
+
+ return $results;
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/modifier.escape.php
@@ -0,0 +1,197 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifier
+ */
+
+/**
+ * Smarty escape modifier plugin
+ * Type: modifier<br>
+ * Name: escape<br>
+ * Purpose: escape string for output
+ *
+ * @link http://www.smarty.net/docs/en/language.modifier.escape
+ * @author Monte Ohrt <monte at ohrt dot com>
+ *
+ * @param string $string input string
+ * @param string $esc_type escape type
+ * @param string $char_set character set, used for htmlspecialchars() or htmlentities()
+ * @param boolean $double_encode encode already encoded entitites again, used for htmlspecialchars() or htmlentities()
+ *
+ * @return string escaped input string
+ */
+function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $double_encode = true) {
+ static $_double_encode = null;
+ if ($_double_encode === null) {
+ $_double_encode = version_compare(PHP_VERSION, '5.2.3', '>=');
+ }
+
+ if (!$char_set) {
+ $char_set = Smarty::$_CHARSET;
+ }
+
+ switch ($esc_type) {
+ case 'html':
+ if ($_double_encode) {
+ // php >=5.3.2 - go native
+ return htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode);
+ } else {
+ if ($double_encode) {
+ // php <5.2.3 - only handle double encoding
+ return htmlspecialchars($string, ENT_QUOTES, $char_set);
+ } else {
+ // php <5.2.3 - prevent double encoding
+ $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
+ $string = htmlspecialchars($string, ENT_QUOTES, $char_set);
+ $string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string);
+
+ return $string;
+ }
+ }
+
+ case 'htmlall':
+ if (Smarty::$_MBSTRING) {
+ // mb_convert_encoding ignores htmlspecialchars()
+ if ($_double_encode) {
+ // php >=5.3.2 - go native
+ $string = htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode);
+ } else {
+ if ($double_encode) {
+ // php <5.2.3 - only handle double encoding
+ $string = htmlspecialchars($string, ENT_QUOTES, $char_set);
+ } else {
+ // php <5.2.3 - prevent double encoding
+ $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
+ $string = htmlspecialchars($string, ENT_QUOTES, $char_set);
+ $string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string);
+
+ return $string;
+ }
+ }
+
+ // htmlentities() won't convert everything, so use mb_convert_encoding
+ return mb_convert_encoding($string, 'HTML-ENTITIES', $char_set);
+ }
+
+ // no MBString fallback
+ if ($_double_encode) {
+ return htmlentities($string, ENT_QUOTES, $char_set, $double_encode);
+ } else {
+ if ($double_encode) {
+ return htmlentities($string, ENT_QUOTES, $char_set);
+ } else {
+ $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
+ $string = htmlentities($string, ENT_QUOTES, $char_set);
+ $string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string);
+
+ return $string;
+ }
+ }
+
+ case 'url':
+ return rawurlencode($string);
+
+ case 'urlpathinfo':
+ return str_replace('%2F', '/', rawurlencode($string));
+
+ case 'quotes':
+ // escape unescaped single quotes
+ return preg_replace("%(?<!\\\\)'%", "\\'", $string);
+
+ case 'hex':
+ // escape every byte into hex
+ // Note that the UTF-8 encoded character ä will be represented as %c3%a4
+ $return = '';
+ $_length = strlen($string);
+ for ($x = 0; $x < $_length; $x++) {
+ $return .= '%' . bin2hex($string[$x]);
+ }
+
+ return $return;
+
+ case 'hexentity':
+ $return = '';
+ if (Smarty::$_MBSTRING) {
+ require_once(SMARTY_PLUGINS_DIR . 'shared.mb_unicode.php');
+ $return = '';
+ foreach (smarty_mb_to_unicode($string, Smarty::$_CHARSET) as $unicode) {
+ $return .= '&#x' . strtoupper(dechex($unicode)) . ';';
+ }
+
+ return $return;
+ }
+ // no MBString fallback
+ $_length = strlen($string);
+ for ($x = 0; $x < $_length; $x++) {
+ $return .= '&#x' . bin2hex($string[$x]) . ';';
+ }
+
+ return $return;
+
+ case 'decentity':
+ $return = '';
+ if (Smarty::$_MBSTRING) {
+ require_once(SMARTY_PLUGINS_DIR . 'shared.mb_unicode.php');
+ $return = '';
+ foreach (smarty_mb_to_unicode($string, Smarty::$_CHARSET) as $unicode) {
+ $return .= '&#' . $unicode . ';';
+ }
+
+ return $return;
+ }
+ // no MBString fallback
+ $_length = strlen($string);
+ for ($x = 0; $x < $_length; $x++) {
+ $return .= '&#' . ord($string[$x]) . ';';
+ }
+
+ return $return;
+
+ case 'javascript':
+ // escape quotes and backslashes, newlines, etc.
+ return strtr($string, array('\\' => '\\\\', "'" => "\\'", '"' => '\\"', "\r" => '\\r', "\n" => '\\n', '</' => '<\/'));
+
+ case 'mail':
+ if (Smarty::$_MBSTRING) {
+ require_once(SMARTY_PLUGINS_DIR . 'shared.mb_str_replace.php');
+
+ return smarty_mb_str_replace(array('@', '.'), array(' [AT] ', ' [DOT] '), $string);
+ }
+ // no MBString fallback
+ return str_replace(array('@', '.'), array(' [AT] ', ' [DOT] '), $string);
+
+ case 'nonstd':
+ // escape non-standard chars, such as ms document quotes
+ $return = '';
+ if (Smarty::$_MBSTRING) {
+ require_once(SMARTY_PLUGINS_DIR . 'shared.mb_unicode.php');
+ foreach (smarty_mb_to_unicode($string, Smarty::$_CHARSET) as $unicode) {
+ if ($unicode >= 126) {
+ $return .= '&#' . $unicode . ';';
+ } else {
+ $return .= chr($unicode);
+ }
+ }
+
+ return $return;
+ }
+
+ $_length = strlen($string);
+ for ($_i = 0; $_i < $_length; $_i++) {
+ $_ord = ord(substr($string, $_i, 1));
+ // non-standard char, escape it
+ if ($_ord >= 126) {
+ $return .= '&#' . $_ord . ';';
+ } else {
+ $return .= substr($string, $_i, 1);
+ }
+ }
+
+ return $return;
+
+ default:
+ return $string;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/modifier.regex_replace.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifier
+ */
+
+/**
+ * Smarty regex_replace modifier plugin
+ * Type: modifier<br>
+ * Name: regex_replace<br>
+ * Purpose: regular expression search/replace
+ *
+ * @link http://smarty.php.net/manual/en/language.modifier.regex.replace.php
+ * regex_replace (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ *
+ * @param string $string input string
+ * @param string|array $search regular expression(s) to search for
+ * @param string|array $replace string(s) that should be replaced
+ *
+ * @return string
+ */
+function smarty_modifier_regex_replace($string, $search, $replace) {
+ if (is_array($search)) {
+ foreach ($search as $idx => $s) {
+ $search[$idx] = _smarty_regex_replace_check($s);
+ }
+ } else {
+ $search = _smarty_regex_replace_check($search);
+ }
+
+ return preg_replace($search, $replace, $string);
+}
+
+/**
+ * @param string $search string(s) that should be replaced
+ *
+ * @return string
+ * @ignore
+ */
+function _smarty_regex_replace_check($search) {
+ // null-byte injection detection
+ // anything behind the first null-byte is ignored
+ if (($pos = strpos($search, "\0")) !== false) {
+ $search = substr($search, 0, $pos);
+ }
+ // remove eval-modifier from $search
+ if (preg_match('!([a-zA-Z\s]+)$!s', $search, $match) && (strpos($match[1], 'e') !== false)) {
+ $search = substr($search, 0, -strlen($match[1])) . preg_replace('![e\s]+!', '', $match[1]);
+ }
+
+ return $search;
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/modifier.replace.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifier
+ */
+
+/**
+ * Smarty replace modifier plugin
+ * Type: modifier<br>
+ * Name: replace<br>
+ * Purpose: simple search/replace
+ *
+ * @link http://smarty.php.net/manual/en/language.modifier.replace.php replace (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author Uwe Tews
+ *
+ * @param string $string input string
+ * @param string $search text to search for
+ * @param string $replace replacement text
+ *
+ * @return string
+ */
+function smarty_modifier_replace($string, $search, $replace) {
+ if (Smarty::$_MBSTRING) {
+ require_once(SMARTY_PLUGINS_DIR . 'shared.mb_str_replace.php');
+
+ return smarty_mb_str_replace($search, $replace, $string);
+ }
+
+ return str_replace($search, $replace, $string);
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/modifier.spacify.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifier
+ */
+
+/**
+ * Smarty spacify modifier plugin
+ * Type: modifier<br>
+ * Name: spacify<br>
+ * Purpose: add spaces between characters in a string
+ *
+ * @link http://smarty.php.net/manual/en/language.modifier.spacify.php spacify (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ *
+ * @param string $string input string
+ * @param string $spacify_char string to insert between characters.
+ *
+ * @return string
+ */
+function smarty_modifier_spacify($string, $spacify_char = ' ') {
+ // well… what about charsets besides latin and UTF-8?
+ return implode($spacify_char, preg_split('//' . Smarty::$_UTF8_MODIFIER, $string, -1, PREG_SPLIT_NO_EMPTY));
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/modifier.truncate.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifier
+ */
+
+/**
+ * Smarty truncate modifier plugin
+ * Type: modifier<br>
+ * Name: truncate<br>
+ * Purpose: Truncate a string to a certain length if necessary,
+ * optionally splitting in the middle of a word, and
+ * appending the $etc string or inserting $etc into the middle.
+ *
+ * @link http://smarty.php.net/manual/en/language.modifier.truncate.php truncate (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ *
+ * @param string $string input string
+ * @param integer $length length of truncated text
+ * @param string $etc end string
+ * @param boolean $break_words truncate at word boundary
+ * @param boolean $middle truncate in the middle of text
+ *
+ * @return string truncated string
+ */
+function smarty_modifier_truncate($string, $length = 80, $etc = '...', $break_words = false, $middle = false) {
+ if ($length == 0) {
+ return '';
+ }
+
+ if (Smarty::$_MBSTRING) {
+ if (mb_strlen($string, Smarty::$_CHARSET) > $length) {
+ $length -= min($length, mb_strlen($etc, Smarty::$_CHARSET));
+ if (!$break_words && !$middle) {
+ $string = preg_replace('/\s+?(\S+)?$/' . Smarty::$_UTF8_MODIFIER, '', mb_substr($string, 0, $length + 1, Smarty::$_CHARSET));
+ }
+ if (!$middle) {
+ return mb_substr($string, 0, $length, Smarty::$_CHARSET) . $etc;
+ }
+
+ return mb_substr($string, 0, $length / 2, Smarty::$_CHARSET) . $etc . mb_substr($string, -$length / 2, $length, Smarty::$_CHARSET);
+ }
+
+ return $string;
+ }
+
+ // no MBString fallback
+ if (isset($string[$length])) {
+ $length -= min($length, strlen($etc));
+ if (!$break_words && !$middle) {
+ $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length + 1));
+ }
+ if (!$middle) {
+ return substr($string, 0, $length) . $etc;
+ }
+
+ return substr($string, 0, $length / 2) . $etc . substr($string, -$length / 2);
+ }
+
+ return $string;
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/modifiercompiler.cat.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty cat modifier plugin
+ * Type: modifier<br>
+ * Name: cat<br>
+ * Date: Feb 24, 2003<br>
+ * Purpose: catenate a value to a variable<br>
+ * Input: string to catenate<br>
+ * Example: {$var|cat:"foo"}
+ *
+ * @link http://smarty.php.net/manual/en/language.modifier.cat.php cat
+ * (Smarty online manual)
+ * @author Uwe Tews
+ *
+ * @param array $params parameters
+ *
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_cat($params) {
+ return '(' . implode(').(', $params) . ')';
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/modifiercompiler.count_characters.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty count_characters modifier plugin
+ * Type: modifier<br>
+ * Name: count_characteres<br>
+ * Purpose: count the number of characters in a text
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.count.characters.php count_characters (Smarty online manual)
+ * @author Uwe Tews
+ *
+ * @param array $params parameters
+ *
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_count_characters($params) {
+ if (!isset($params[1]) || $params[1] != 'true') {
+ return 'preg_match_all(\'/[^\s]/' . Smarty::$_UTF8_MODIFIER . '\',' . $params[0] . ', $tmp)';
+ }
+ if (Smarty::$_MBSTRING) {
+ return 'mb_strlen(' . $params[0] . ', \'' . addslashes(Smarty::$_CHARSET) . '\')';
+ }
+ // no MBString fallback
+ return 'strlen(' . $params[0] . ')';
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/modifiercompiler.count_paragraphs.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty count_paragraphs modifier plugin
+ * Type: modifier<br>
+ * Name: count_paragraphs<br>
+ * Purpose: count the number of paragraphs in a text
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.count.paragraphs.php
+ * count_paragraphs (Smarty online manual)
+ * @author Uwe Tews
+ *
+ * @param array $params parameters
+ *
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_count_paragraphs($params) {
+ // count \r or \n characters
+ return '(preg_match_all(\'#[\r\n]+#\', ' . $params[0] . ', $tmp)+1)';
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/modifiercompiler.count_sentences.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty count_sentences modifier plugin
+ * Type: modifier<br>
+ * Name: count_sentences
+ * Purpose: count the number of sentences in a text
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.count.paragraphs.php
+ * count_sentences (Smarty online manual)
+ * @author Uwe Tews
+ *
+ * @param array $params parameters
+ *
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_count_sentences($params) {
+ // find periods, question marks, exclamation marks with a word before but not after.
+ return 'preg_match_all("#\w[\.\?\!](\W|$)#S' . Smarty::$_UTF8_MODIFIER . '", ' . $params[0] . ', $tmp)';
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/modifiercompiler.count_words.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty count_words modifier plugin
+ * Type: modifier<br>
+ * Name: count_words<br>
+ * Purpose: count the number of words in a text
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.count.words.php count_words (Smarty online manual)
+ * @author Uwe Tews
+ *
+ * @param array $params parameters
+ *
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_count_words($params) {
+ if (Smarty::$_MBSTRING) {
+ // return 'preg_match_all(\'#[\w\pL]+#' . Smarty::$_UTF8_MODIFIER . '\', ' . $params[0] . ', $tmp)';
+ // expression taken from http://de.php.net/manual/en/function.str-word-count.php#85592
+ return 'preg_match_all(\'/\p{L}[\p{L}\p{Mn}\p{Pd}\\\'\x{2019}]*/' . Smarty::$_UTF8_MODIFIER . '\', ' . $params[0] . ', $tmp)';
+ }
+ // no MBString fallback
+ return 'str_word_count(' . $params[0] . ')';
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/modifiercompiler.default.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty default modifier plugin
+ * Type: modifier<br>
+ * Name: default<br>
+ * Purpose: designate default value for empty variables
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.default.php default (Smarty online manual)
+ * @author Uwe Tews
+ *
+ * @param array $params parameters
+ *
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_default($params) {
+ $output = $params[0];
+ if (!isset($params[1])) {
+ $params[1] = "''";
+ }
+
+ array_shift($params);
+ foreach ($params as $param) {
+ $output = '(($tmp = @' . $output . ')===null||$tmp===\'\' ? ' . $param . ' : $tmp)';
+ }
+
+ return $output;
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/modifiercompiler.escape.php
@@ -0,0 +1,124 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * @ignore
+ */
+require_once(SMARTY_PLUGINS_DIR . 'shared.literal_compiler_param.php');
+
+/**
+ * Smarty escape modifier plugin
+ * Type: modifier<br>
+ * Name: escape<br>
+ * Purpose: escape string for output
+ *
+ * @link http://www.smarty.net/docsv2/en/language.modifier.escape count_characters (Smarty online manual)
+ * @author Rodney Rehm
+ *
+ * @param array $params parameters
+ * @param $compiler
+ *
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_escape($params, $compiler) {
+ static $_double_encode = null;
+ if ($_double_encode === null) {
+ $_double_encode = version_compare(PHP_VERSION, '5.2.3', '>=');
+ }
+
+ try {
+ $esc_type = smarty_literal_compiler_param($params, 1, 'html');
+ $char_set = smarty_literal_compiler_param($params, 2, Smarty::$_CHARSET);
+ $double_encode = smarty_literal_compiler_param($params, 3, true);
+
+ if (!$char_set) {
+ $char_set = Smarty::$_CHARSET;
+ }
+
+ switch ($esc_type) {
+ case 'html':
+ if ($_double_encode) {
+ return 'htmlspecialchars('
+ . $params[0] . ', ENT_QUOTES, '
+ . var_export($char_set, true) . ', '
+ . var_export($double_encode, true) . ')';
+ } elseif ($double_encode) {
+ return 'htmlspecialchars('
+ . $params[0] . ', ENT_QUOTES, '
+ . var_export($char_set, true) . ')';
+ } else {
+ // fall back to modifier.escape.php
+ }
+
+ case 'htmlall':
+ if (Smarty::$_MBSTRING) {
+ if ($_double_encode) {
+ // php >=5.2.3 - go native
+ return 'mb_convert_encoding(htmlspecialchars('
+ . $params[0] . ', ENT_QUOTES, '
+ . var_export($char_set, true) . ', '
+ . var_export($double_encode, true)
+ . '), "HTML-ENTITIES", '
+ . var_export($char_set, true) . ')';
+ } elseif ($double_encode) {
+ // php <5.2.3 - only handle double encoding
+ return 'mb_convert_encoding(htmlspecialchars('
+ . $params[0] . ', ENT_QUOTES, '
+ . var_export($char_set, true)
+ . '), "HTML-ENTITIES", '
+ . var_export($char_set, true) . ')';
+ } else {
+ // fall back to modifier.escape.php
+ }
+ }
+
+ // no MBString fallback
+ if ($_double_encode) {
+ // php >=5.2.3 - go native
+ return 'htmlentities('
+ . $params[0] . ', ENT_QUOTES, '
+ . var_export($char_set, true) . ', '
+ . var_export($double_encode, true) . ')';
+ } elseif ($double_encode) {
+ // php <5.2.3 - only handle double encoding
+ return 'htmlentities('
+ . $params[0] . ', ENT_QUOTES, '
+ . var_export($char_set, true) . ')';
+ } else {
+ // fall back to modifier.escape.php
+ }
+
+ case 'url':
+ return 'rawurlencode(' . $params[0] . ')';
+
+ case 'urlpathinfo':
+ return 'str_replace("%2F", "/", rawurlencode(' . $params[0] . '))';
+
+ case 'quotes':
+ // escape unescaped single quotes
+ return 'preg_replace("%(?<!\\\\\\\\)\'%", "\\\'",' . $params[0] . ')';
+
+ case 'javascript':
+ // escape quotes and backslashes, newlines, etc.
+ return 'strtr(' . $params[0] . ', array("\\\\" => "\\\\\\\\", "\'" => "\\\\\'", "\"" => "\\\\\"", "\\r" => "\\\\r", "\\n" => "\\\n", "</" => "<\/" ))';
+ }
+ } catch (SmartyException $e) {
+ // pass through to regular plugin fallback
+ }
+
+ // could not optimize |escape call, so fallback to regular plugin
+ if ($compiler->template->caching && ($compiler->tag_nocache | $compiler->nocache)) {
+ $compiler->template->required_plugins['nocache']['escape']['modifier']['file'] = SMARTY_PLUGINS_DIR . 'modifier.escape.php';
+ $compiler->template->required_plugins['nocache']['escape']['modifier']['function'] = 'smarty_modifier_escape';
+ } else {
+ $compiler->template->required_plugins['compiled']['escape']['modifier']['file'] = SMARTY_PLUGINS_DIR . 'modifier.escape.php';
+ $compiler->template->required_plugins['compiled']['escape']['modifier']['function'] = 'smarty_modifier_escape';
+ }
+
+ return 'smarty_modifier_escape(' . join(', ', $params) . ')';
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/modifiercompiler.from_charset.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty from_charset modifier plugin
+ * Type: modifier<br>
+ * Name: from_charset<br>
+ * Purpose: convert character encoding from $charset to internal encoding
+ *
+ * @author Rodney Rehm
+ *
+ * @param array $params parameters
+ *
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_from_charset($params) {
+ if (!Smarty::$_MBSTRING) {
+ // FIXME: (rodneyrehm) shouldn't this throw an error?
+ return $params[0];
+ }
+
+ if (!isset($params[1])) {
+ $params[1] = '"ISO-8859-1"';
+ }
+
+ return 'mb_convert_encoding(' . $params[0] . ', "' . addslashes(Smarty::$_CHARSET) . '", ' . $params[1] . ')';
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/modifiercompiler.indent.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty indent modifier plugin
+ * Type: modifier<br>
+ * Name: indent<br>
+ * Purpose: indent lines of text
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.indent.php indent (Smarty online manual)
+ * @author Uwe Tews
+ *
+ * @param array $params parameters
+ *
+ * @return string with compiled code
+ */
+
+function smarty_modifiercompiler_indent($params) {
+ if (!isset($params[1])) {
+ $params[1] = 4;
+ }
+ if (!isset($params[2])) {
+ $params[2] = "' '";
+ }
+
+ return 'preg_replace(\'!^!m\',str_repeat(' . $params[2] . ',' . $params[1] . '),' . $params[0] . ')';
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/modifiercompiler.lower.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty lower modifier plugin
+ * Type: modifier<br>
+ * Name: lower<br>
+ * Purpose: convert string to lowercase
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.lower.php lower (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author Uwe Tews
+ *
+ * @param array $params parameters
+ *
+ * @return string with compiled code
+ */
+
+function smarty_modifiercompiler_lower($params) {
+ if (Smarty::$_MBSTRING) {
+ return 'mb_strtolower(' . $params[0] . ', \'' . addslashes(Smarty::$_CHARSET) . '\')';
+ }
+ // no MBString fallback
+ return 'strtolower(' . $params[0] . ')';
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/modifiercompiler.noprint.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty noprint modifier plugin
+ * Type: modifier<br>
+ * Name: noprint<br>
+ * Purpose: return an empty string
+ *
+ * @author Uwe Tews
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_noprint() {
+ return "''";
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/modifiercompiler.string_format.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty string_format modifier plugin
+ * Type: modifier<br>
+ * Name: string_format<br>
+ * Purpose: format strings via sprintf
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.string.format.php string_format (Smarty online manual)
+ * @author Uwe Tews
+ *
+ * @param array $params parameters
+ *
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_string_format($params) {
+ return 'sprintf(' . $params[1] . ',' . $params[0] . ')';
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/modifiercompiler.strip.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty strip modifier plugin
+ * Type: modifier<br>
+ * Name: strip<br>
+ * Purpose: Replace all repeated spaces, newlines, tabs
+ * with a single space or supplied replacement string.<br>
+ * Example: {$var|strip} {$var|strip:" "}<br>
+ * Date: September 25th, 2002
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.strip.php strip (Smarty online manual)
+ * @author Uwe Tews
+ *
+ * @param array $params parameters
+ *
+ * @return string with compiled code
+ */
+
+function smarty_modifiercompiler_strip($params) {
+ if (!isset($params[1])) {
+ $params[1] = "' '";
+ }
+
+ return "preg_replace('!\s+!" . Smarty::$_UTF8_MODIFIER . "', {$params[1]},{$params[0]})";
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/modifiercompiler.strip_tags.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty strip_tags modifier plugin
+ * Type: modifier<br>
+ * Name: strip_tags<br>
+ * Purpose: strip html tags from text
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.strip.tags.php strip_tags (Smarty online manual)
+ * @author Uwe Tews
+ *
+ * @param array $params parameters
+ *
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_strip_tags($params) {
+ if (!isset($params[1]) || $params[1] === true || trim($params[1], '"') == 'true') {
+ return "preg_replace('!<[^>]*?>!', ' ', {$params[0]})";
+ } else {
+ return 'strip_tags(' . $params[0] . ')';
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/modifiercompiler.to_charset.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty to_charset modifier plugin
+ * Type: modifier<br>
+ * Name: to_charset<br>
+ * Purpose: convert character encoding from internal encoding to $charset
+ *
+ * @author Rodney Rehm
+ *
+ * @param array $params parameters
+ *
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_to_charset($params) {
+ if (!Smarty::$_MBSTRING) {
+ // FIXME: (rodneyrehm) shouldn't this throw an error?
+ return $params[0];
+ }
+
+ if (!isset($params[1])) {
+ $params[1] = '"ISO-8859-1"';
+ }
+
+ return 'mb_convert_encoding(' . $params[0] . ', ' . $params[1] . ', "' . addslashes(Smarty::$_CHARSET) . '")';
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/modifiercompiler.unescape.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty unescape modifier plugin
+ * Type: modifier<br>
+ * Name: unescape<br>
+ * Purpose: unescape html entities
+ *
+ * @author Rodney Rehm
+ *
+ * @param array $params parameters
+ *
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_unescape($params) {
+ if (!isset($params[1])) {
+ $params[1] = 'html';
+ }
+ if (!isset($params[2])) {
+ $params[2] = '\'' . addslashes(Smarty::$_CHARSET) . '\'';
+ } else {
+ $params[2] = "'" . $params[2] . "'";
+ }
+
+ switch (trim($params[1], '"\'')) {
+ case 'entity':
+ case 'htmlall':
+ if (Smarty::$_MBSTRING) {
+ return 'mb_convert_encoding(' . $params[0] . ', ' . $params[2] . ', \'HTML-ENTITIES\')';
+ }
+
+ return 'html_entity_decode(' . $params[0] . ', ENT_NOQUOTES, ' . $params[2] . ')';
+
+ case 'html':
+ return 'htmlspecialchars_decode(' . $params[0] . ', ENT_QUOTES)';
+
+ case 'url':
+ return 'rawurldecode(' . $params[0] . ')';
+
+ default:
+ return $params[0];
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/modifiercompiler.upper.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty upper modifier plugin
+ * Type: modifier<br>
+ * Name: lower<br>
+ * Purpose: convert string to uppercase
+ *
+ * @link http://smarty.php.net/manual/en/language.modifier.upper.php lower (Smarty online manual)
+ * @author Uwe Tews
+ *
+ * @param array $params parameters
+ *
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_upper($params) {
+ if (Smarty::$_MBSTRING) {
+ return 'mb_strtoupper(' . $params[0] . ', \'' . addslashes(Smarty::$_CHARSET) . '\')';
+ }
+ // no MBString fallback
+ return 'strtoupper(' . $params[0] . ')';
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/modifiercompiler.wordwrap.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty wordwrap modifier plugin
+ * Type: modifier<br>
+ * Name: wordwrap<br>
+ * Purpose: wrap a string of text at a given length
+ *
+ * @link http://smarty.php.net/manual/en/language.modifier.wordwrap.php wordwrap (Smarty online manual)
+ * @author Uwe Tews
+ *
+ * @param array $params parameters
+ * @param $compiler
+ *
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_wordwrap($params, $compiler) {
+ if (!isset($params[1])) {
+ $params[1] = 80;
+ }
+ if (!isset($params[2])) {
+ $params[2] = '"\n"';
+ }
+ if (!isset($params[3])) {
+ $params[3] = 'false';
+ }
+ $function = 'wordwrap';
+ if (Smarty::$_MBSTRING) {
+ if ($compiler->template->caching && ($compiler->tag_nocache | $compiler->nocache)) {
+ $compiler->template->required_plugins['nocache']['wordwrap']['modifier']['file'] = SMARTY_PLUGINS_DIR . 'shared.mb_wordwrap.php';
+ $compiler->template->required_plugins['nocache']['wordwrap']['modifier']['function'] = 'smarty_mb_wordwrap';
+ } else {
+ $compiler->template->required_plugins['compiled']['wordwrap']['modifier']['file'] = SMARTY_PLUGINS_DIR . 'shared.mb_wordwrap.php';
+ $compiler->template->required_plugins['compiled']['wordwrap']['modifier']['function'] = 'smarty_mb_wordwrap';
+ }
+ $function = 'smarty_mb_wordwrap';
+ }
+
+ return $function . '(' . $params[0] . ',' . $params[1] . ',' . $params[2] . ',' . $params[3] . ')';
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/outputfilter.trimwhitespace.php
@@ -0,0 +1,89 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsFilter
+ */
+
+/**
+ * Smarty trimwhitespace outputfilter plugin
+ * Trim unnecessary whitespace from HTML markup.
+ *
+ * @author Rodney Rehm
+ *
+ * @param string $source input string
+ *
+ * @return string filtered output
+ * @todo substr_replace() is not overloaded by mbstring.func_overload - so this function might fail!
+ */
+function smarty_outputfilter_trimwhitespace($source) {
+ $store = array();
+ $_store = 0;
+ $_offset = 0;
+
+ // Unify Line-Breaks to \n
+ $source = preg_replace("/\015\012|\015|\012/", "\n", $source);
+
+ // capture Internet Explorer Conditional Comments
+ if (preg_match_all('#<!--\[[^\]]+\]>.*?<!\[[^\]]+\]-->#is', $source, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
+ foreach ($matches as $match) {
+ $store[] = $match[0][0];
+ $_length = strlen($match[0][0]);
+ $replace = '@!@SMARTY:' . $_store . ':SMARTY@!@';
+ $source = substr_replace($source, $replace, $match[0][1] - $_offset, $_length);
+
+ $_offset += $_length - strlen($replace);
+ $_store++;
+ }
+ }
+
+ // Strip all HTML-Comments
+ // yes, even the ones in <script> - see http://stackoverflow.com/a/808850/515124
+ $source = preg_replace('#<!--.*?-->#ms', '', $source);
+
+ // capture html elements not to be messed with
+ $_offset = 0;
+ if (preg_match_all('#(<script[^>]*>.*?</script[^>]*>)|(<textarea[^>]*>.*?</textarea[^>]*>)|(<pre[^>]*>.*?</pre[^>]*>)#is', $source, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
+ foreach ($matches as $match) {
+ $store[] = $match[0][0];
+ $_length = strlen($match[0][0]);
+ $replace = '@!@SMARTY:' . $_store . ':SMARTY@!@';
+ $source = substr_replace($source, $replace, $match[0][1] - $_offset, $_length);
+
+ $_offset += $_length - strlen($replace);
+ $_store++;
+ }
+ }
+
+ $expressions = array(
+ // replace multiple spaces between tags by a single space
+ // can't remove them entirely, becaue that might break poorly implemented CSS display:inline-block elements
+ '#(:SMARTY@!@|>)\s+(?=@!@SMARTY:|<)#s' => '\1 \2',
+ // remove spaces between attributes (but not in attribute values!)
+ '#(([a-z0-9]\s*=\s*("[^"]*?")|(\'[^\']*?\'))|<[a-z0-9_]+)\s+([a-z/>])#is' => '\1 \5',
+ // note: for some very weird reason trim() seems to remove spaces inside attributes.
+ // maybe a \0 byte or something is interfering?
+ '#^\s+<#Ss' => '<',
+ '#>\s+$#Ss' => '>',
+ );
+
+ $source = preg_replace(array_keys($expressions), array_values($expressions), $source);
+ // note: for some very weird reason trim() seems to remove spaces inside attributes.
+ // maybe a \0 byte or something is interfering?
+ // $source = trim( $source );
+
+ $_offset = 0;
+ if (preg_match_all('#@!@SMARTY:([0-9]+):SMARTY@!@#is', $source, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
+ foreach ($matches as $match) {
+ $_length = strlen($match[0][0]);
+ $replace = $store[$match[1][0]];
+ $source = substr_replace($source, $replace, $match[0][1] + $_offset, $_length);
+
+ $_offset += strlen($replace) - $_length;
+ $_store++;
+ }
+ }
+
+ return $source;
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/shared.escape_special_chars.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Smarty shared plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsShared
+ */
+
+if (version_compare(PHP_VERSION, '5.2.3', '>=')) {
+ /**
+ * escape_special_chars common function
+ * Function: smarty_function_escape_special_chars<br>
+ * Purpose: used by other smarty functions to escape
+ * special chars except for already escaped ones
+ *
+ * @author Monte Ohrt <monte at ohrt dot com>
+ *
+ * @param string $string text that should by escaped
+ *
+ * @return string
+ */
+ function smarty_function_escape_special_chars($string) {
+ if (!is_array($string)) {
+ $string = htmlspecialchars($string, ENT_COMPAT, Smarty::$_CHARSET, false);
+ }
+
+ return $string;
+ }
+} else {
+ /**
+ * escape_special_chars common function
+ * Function: smarty_function_escape_special_chars<br>
+ * Purpose: used by other smarty functions to escape
+ * special chars except for already escaped ones
+ *
+ * @author Monte Ohrt <monte at ohrt dot com>
+ *
+ * @param string $string text that should by escaped
+ *
+ * @return string
+ */
+ function smarty_function_escape_special_chars($string) {
+ if (!is_array($string)) {
+ $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
+ $string = htmlspecialchars($string);
+ $string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string);
+ }
+
+ return $string;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/shared.literal_compiler_param.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsShared
+ */
+
+/**
+ * evaluate compiler parameter
+ *
+ * @param array $params parameter array as given to the compiler function
+ * @param integer $index array index of the parameter to convert
+ * @param mixed $default value to be returned if the parameter is not present
+ *
+ * @return mixed evaluated value of parameter or $default
+ * @throws SmartyException if parameter is not a literal (but an expression, variable, …)
+ * @author Rodney Rehm
+ */
+function smarty_literal_compiler_param($params, $index, $default = null) {
+ // not set, go default
+ if (!isset($params[$index])) {
+ return $default;
+ }
+ // test if param is a literal
+ if (!preg_match('/^([\'"]?)[a-zA-Z0-9-]+(\\1)$/', $params[$index])) {
+ throw new SmartyException('$param[' . $index . '] is not a literal and is thus not evaluatable at compile time');
+ }
+
+ $t = null;
+ eval("\$t = " . $params[$index] . ";");
+
+ return $t;
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/shared.make_timestamp.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Smarty shared plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsShared
+ */
+
+/**
+ * Function: smarty_make_timestamp<br>
+ * Purpose: used by other smarty functions to make a timestamp from a string.
+ *
+ * @author Monte Ohrt <monte at ohrt dot com>
+ *
+ * @param DateTime|int|string $string date object, timestamp or string that can be converted using strtotime()
+ *
+ * @return int
+ */
+function smarty_make_timestamp($string) {
+ if (empty($string)) {
+ // use "now":
+ return time();
+ } elseif ($string instanceof DateTime) {
+ return $string->getTimestamp();
+ } elseif (strlen($string) == 14 && ctype_digit($string)) {
+ // it is mysql timestamp format of YYYYMMDDHHMMSS?
+ return mktime(substr($string, 8, 2), substr($string, 10, 2), substr($string, 12, 2),
+ substr($string, 4, 2), substr($string, 6, 2), substr($string, 0, 4));
+ } elseif (is_numeric($string)) {
+ // it is a numeric string, we handle it as timestamp
+ return (int)$string;
+ } else {
+ // strtotime should handle it
+ $time = strtotime($string);
+ if ($time == -1 || $time === false) {
+ // strtotime() was not able to parse $string, use "now":
+ return time();
+ }
+
+ return $time;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/shared.mb_str_replace.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Smarty shared plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsShared
+ */
+if (!function_exists('smarty_mb_str_replace')) {
+
+ /**
+ * Multibyte string replace
+ *
+ * @param string $search the string to be searched
+ * @param string $replace the replacement string
+ * @param string $subject the source string
+ * @param int &$count number of matches found
+ *
+ * @return string replaced string
+ * @author Rodney Rehm
+ */
+ function smarty_mb_str_replace($search, $replace, $subject, &$count = 0) {
+ if (!is_array($search) && is_array($replace)) {
+ return false;
+ }
+ if (is_array($subject)) {
+ // call mb_replace for each single string in $subject
+ foreach ($subject as &$string) {
+ $string = &smarty_mb_str_replace($search, $replace, $string, $c);
+ $count += $c;
+ }
+ } elseif (is_array($search)) {
+ if (!is_array($replace)) {
+ foreach ($search as &$string) {
+ $subject = smarty_mb_str_replace($string, $replace, $subject, $c);
+ $count += $c;
+ }
+ } else {
+ $n = max(count($search), count($replace));
+ while ($n--) {
+ $subject = smarty_mb_str_replace(current($search), current($replace), $subject, $c);
+ $count += $c;
+ next($search);
+ next($replace);
+ }
+ }
+ } else {
+ $parts = mb_split(preg_quote($search), $subject);
+ $count = count($parts) - 1;
+ $subject = implode($replace, $parts);
+ }
+
+ return $subject;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/shared.mb_unicode.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Smarty shared plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsShared
+ */
+
+/**
+ * convert characters to their decimal unicode equivalents
+ *
+ * @link http://www.ibm.com/developerworks/library/os-php-unicode/index.html#listing3 for inspiration
+ *
+ * @param string $string characters to calculate unicode of
+ * @param string $encoding encoding of $string, if null mb_internal_encoding() is used
+ *
+ * @return array sequence of unicodes
+ * @author Rodney Rehm
+ */
+function smarty_mb_to_unicode($string, $encoding = null) {
+ if ($encoding) {
+ $expanded = mb_convert_encoding($string, "UTF-32BE", $encoding);
+ } else {
+ $expanded = mb_convert_encoding($string, "UTF-32BE");
+ }
+
+ return unpack("N*", $expanded);
+}
+
+/**
+ * convert unicodes to the character of given encoding
+ *
+ * @link http://www.ibm.com/developerworks/library/os-php-unicode/index.html#listing3 for inspiration
+ *
+ * @param integer|array $unicode single unicode or list of unicodes to convert
+ * @param string $encoding encoding of returned string, if null mb_internal_encoding() is used
+ *
+ * @return string unicode as character sequence in given $encoding
+ * @author Rodney Rehm
+ */
+function smarty_mb_from_unicode($unicode, $encoding = null) {
+ $t = '';
+ if (!$encoding) {
+ $encoding = mb_internal_encoding();
+ }
+ foreach ((array)$unicode as $utf32be) {
+ $character = pack("N*", $utf32be);
+ $t .= mb_convert_encoding($character, $encoding, "UTF-32BE");
+ }
+
+ return $t;
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/shared.mb_wordwrap.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ * Smarty shared plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsShared
+ */
+
+if (!function_exists('smarty_mb_wordwrap')) {
+
+ /**
+ * Wrap a string to a given number of characters
+ *
+ * @link http://php.net/manual/en/function.wordwrap.php for similarity
+ *
+ * @param string $str the string to wrap
+ * @param int $width the width of the output
+ * @param string $break the character used to break the line
+ * @param boolean $cut ignored parameter, just for the sake of
+ *
+ * @return string wrapped string
+ * @author Rodney Rehm
+ */
+ function smarty_mb_wordwrap($str, $width = 75, $break = "\n", $cut = false) {
+ // break words into tokens using white space as a delimiter
+ $tokens = preg_split('!(\s)!S' . Smarty::$_UTF8_MODIFIER, $str, -1, PREG_SPLIT_NO_EMPTY + PREG_SPLIT_DELIM_CAPTURE);
+ $length = 0;
+ $t = '';
+ $_previous = false;
+ $_space = false;
+
+ foreach ($tokens as $_token) {
+ $token_length = mb_strlen($_token, Smarty::$_CHARSET);
+ $_tokens = array($_token);
+ if ($token_length > $width) {
+ if ($cut) {
+ $_tokens = preg_split('!(.{' . $width . '})!S' . Smarty::$_UTF8_MODIFIER, $_token, -1, PREG_SPLIT_NO_EMPTY + PREG_SPLIT_DELIM_CAPTURE);
+ }
+ }
+
+ foreach ($_tokens as $token) {
+ $_space = !!preg_match('!^\s$!S' . Smarty::$_UTF8_MODIFIER, $token);
+ $token_length = mb_strlen($token, Smarty::$_CHARSET);
+ $length += $token_length;
+
+ if ($length > $width) {
+ // remove space before inserted break
+ if ($_previous) {
+ $t = mb_substr($t, 0, -1, Smarty::$_CHARSET);
+ }
+
+ if (!$_space) {
+ // add the break before the token
+ if (!empty($t)) {
+ $t .= $break;
+ }
+ $length = $token_length;
+ }
+ } elseif ($token == "\n") {
+ // hard break must reset counters
+ $_previous = 0;
+ $length = 0;
+ }
+ $_previous = $_space;
+ // add the token
+ $t .= $token;
+ }
+ }
+
+ return $t;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/plugins/variablefilter.htmlspecialchars.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsFilter
+ */
+
+/**
+ * Smarty htmlspecialchars variablefilter plugin
+ *
+ * @param string $source input string
+ *
+ * @return string filtered output
+ */
+function smarty_variablefilter_htmlspecialchars($source) {
+ return htmlspecialchars($source, ENT_QUOTES, Smarty::$_CHARSET);
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_cacheresource.php
@@ -0,0 +1,221 @@
+<?php
+/**
+ * Smarty Internal Plugin
+ *
+ * @package Smarty
+ * @subpackage Cacher
+ */
+
+/**
+ * Cache Handler API
+ *
+ * @package Smarty
+ * @subpackage Cacher
+ * @author Rodney Rehm
+ */
+abstract class Smarty_CacheResource {
+ /**
+ * resource types provided by the core
+ *
+ * @var array
+ */
+ protected static $sysplugins = array(
+ 'file' => 'smarty_internal_cacheresource_file.php',
+ );
+
+ /**
+ * populate Cached Object with meta data from Resource
+ *
+ * @param Smarty_Template_Cached $cached cached object
+ * @param Smarty_Internal_Template $_template template object
+ *
+ * @return void
+ */
+ abstract public function populate(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template);
+
+ /**
+ * populate Cached Object with timestamp and exists from Resource
+ *
+ * @param Smarty_Template_Cached $cached
+ *
+ * @return void
+ */
+ abstract public function populateTimestamp(Smarty_Template_Cached $cached);
+
+ /**
+ * Read the cached template and process header
+ *
+ * @param Smarty_Internal_Template $_template template object
+ * @param Smarty_Template_Cached $cached cached object
+ *
+ * @return boolean true or false if the cached content does not exist
+ */
+ abstract public function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached = null);
+
+ /**
+ * Write the rendered template output to cache
+ *
+ * @param Smarty_Internal_Template $_template template object
+ * @param string $content content to cache
+ *
+ * @return boolean success
+ */
+ abstract public function writeCachedContent(Smarty_Internal_Template $_template, $content);
+
+ /**
+ * Return cached content
+ *
+ * @param Smarty_Internal_Template $_template template object
+ *
+ * @return null|string
+ */
+ public function getCachedContent(Smarty_Internal_Template $_template) {
+ if ($_template->cached->handler->process($_template)) {
+ ob_start();
+ $_template->properties['unifunc']($_template);
+
+ return ob_get_clean();
+ }
+
+ return null;
+ }
+
+ /**
+ * Empty cache
+ *
+ * @param Smarty $smarty Smarty object
+ * @param integer $exp_time expiration time (number of seconds, not timestamp)
+ *
+ * @return integer number of cache files deleted
+ */
+ abstract public function clearAll(Smarty $smarty, $exp_time = null);
+
+ /**
+ * Empty cache for a specific template
+ *
+ * @param Smarty $smarty Smarty object
+ * @param string $resource_name template name
+ * @param string $cache_id cache id
+ * @param string $compile_id compile id
+ * @param integer $exp_time expiration time (number of seconds, not timestamp)
+ *
+ * @return integer number of cache files deleted
+ */
+ abstract public function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time);
+
+ /**
+ * @param Smarty $smarty
+ * @param Smarty_Template_Cached $cached
+ *
+ * @return bool|null
+ */
+ public function locked(Smarty $smarty, Smarty_Template_Cached $cached) {
+ // theoretically locking_timeout should be checked against time_limit (max_execution_time)
+ $start = microtime(true);
+ $hadLock = null;
+ while ($this->hasLock($smarty, $cached)) {
+ $hadLock = true;
+ if (microtime(true) - $start > $smarty->locking_timeout) {
+ // abort waiting for lock release
+ return false;
+ }
+ sleep(1);
+ }
+
+ return $hadLock;
+ }
+
+ /**
+ * Check is cache is locked for this template
+ *
+ * @param Smarty $smarty
+ * @param Smarty_Template_Cached $cached
+ *
+ * @return bool
+ */
+ public function hasLock(Smarty $smarty, Smarty_Template_Cached $cached) {
+ // check if lock exists
+ return false;
+ }
+
+ /**
+ * Lock cache for this template
+ *
+ * @param Smarty $smarty
+ * @param Smarty_Template_Cached $cached
+ *
+ * @return bool
+ */
+ public function acquireLock(Smarty $smarty, Smarty_Template_Cached $cached) {
+ // create lock
+ return true;
+ }
+
+ /**
+ * Unlock cache for this template
+ *
+ * @param Smarty $smarty
+ * @param Smarty_Template_Cached $cached
+ *
+ * @return bool
+ */
+ public function releaseLock(Smarty $smarty, Smarty_Template_Cached $cached) {
+ // release lock
+ return true;
+ }
+
+ /**
+ * Load Cache Resource Handler
+ *
+ * @param Smarty $smarty Smarty object
+ * @param string $type name of the cache resource
+ *
+ * @throws SmartyException
+ * @return Smarty_CacheResource Cache Resource Handler
+ */
+ public static function load(Smarty $smarty, $type = null) {
+ if (!isset($type)) {
+ $type = $smarty->caching_type;
+ }
+
+ // try smarty's cache
+ if (isset($smarty->_cacheresource_handlers[$type])) {
+ return $smarty->_cacheresource_handlers[$type];
+ }
+
+ // try registered resource
+ if (isset($smarty->registered_cache_resources[$type])) {
+ // do not cache these instances as they may vary from instance to instance
+ return $smarty->_cacheresource_handlers[$type] = $smarty->registered_cache_resources[$type];
+ }
+ // try sysplugins dir
+ if (isset(self::$sysplugins[$type])) {
+ $cache_resource_class = 'Smarty_Internal_CacheResource_' . ucfirst($type);
+ if (!class_exists($cache_resource_class, false)) {
+ require SMARTY_SYSPLUGINS_DIR . self::$sysplugins[$type];
+ }
+ return $smarty->_cacheresource_handlers[$type] = new $cache_resource_class();
+ }
+ // try plugins dir
+ $cache_resource_class = 'Smarty_CacheResource_' . ucfirst($type);
+ if ($smarty->loadPlugin($cache_resource_class)) {
+ return $smarty->_cacheresource_handlers[$type] = new $cache_resource_class();
+ }
+ // give up
+ throw new SmartyException("Unable to load cache resource '{$type}'");
+ }
+
+ /**
+ * Invalid Loaded Cache Files
+ *
+ * @param Smarty $smarty Smarty object
+ */
+ public static function invalidLoadedCache(Smarty $smarty) {
+ foreach ($smarty->template_objects as $tpl) {
+ if (isset($tpl->cached)) {
+ $tpl->cached->valid = false;
+ $tpl->cached->processed = false;
+ }
+ }
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_cacheresource_custom.php
@@ -0,0 +1,300 @@
+<?php
+/**
+ * Smarty Internal Plugin
+ *
+ * @package Smarty
+ * @subpackage Cacher
+ */
+
+/**
+ * Cache Handler API
+ *
+ * @package Smarty
+ * @subpackage Cacher
+ * @author Rodney Rehm
+ */
+abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource {
+ /**
+ * fetch cached content and its modification time from data source
+ *
+ * @param string $id unique cache content identifier
+ * @param string $name template name
+ * @param string $cache_id cache id
+ * @param string $compile_id compile id
+ * @param string $content cached content
+ * @param integer $mtime cache modification timestamp (epoch)
+ *
+ * @return void
+ */
+ abstract protected function fetch($id, $name, $cache_id, $compile_id, &$content, &$mtime);
+
+ /**
+ * Fetch cached content's modification timestamp from data source
+ * {@internal implementing this method is optional.
+ * Only implement it if modification times can be accessed faster than loading the complete cached content.}}
+ *
+ * @param string $id unique cache content identifier
+ * @param string $name template name
+ * @param string $cache_id cache id
+ * @param string $compile_id compile id
+ *
+ * @return integer|boolean timestamp (epoch) the template was modified, or false if not found
+ */
+ protected function fetchTimestamp($id, $name, $cache_id, $compile_id) {
+ return null;
+ }
+
+ /**
+ * Save content to cache
+ *
+ * @param string $id unique cache content identifier
+ * @param string $name template name
+ * @param string $cache_id cache id
+ * @param string $compile_id compile id
+ * @param integer|null $exp_time seconds till expiration or null
+ * @param string $content content to cache
+ *
+ * @return boolean success
+ */
+ abstract protected function save($id, $name, $cache_id, $compile_id, $exp_time, $content);
+
+ /**
+ * Delete content from cache
+ *
+ * @param string $name template name
+ * @param string $cache_id cache id
+ * @param string $compile_id compile id
+ * @param integer|null $exp_time seconds till expiration time in seconds or null
+ *
+ * @return integer number of deleted caches
+ */
+ abstract protected function delete($name, $cache_id, $compile_id, $exp_time);
+
+ /**
+ * populate Cached Object with meta data from Resource
+ *
+ * @param Smarty_Template_Cached $cached cached object
+ * @param Smarty_Internal_Template $_template template object
+ *
+ * @return void
+ */
+ public function populate(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template) {
+ $_cache_id = isset($cached->cache_id) ? preg_replace('![^\w\|]+!', '_', $cached->cache_id) : null;
+ $_compile_id = isset($cached->compile_id) ? preg_replace('![^\w\|]+!', '_', $cached->compile_id) : null;
+ $path = $cached->source->filepath . $_cache_id . $_compile_id;
+ $cached->filepath = sha1($path);
+ if ($_template->smarty->cache_locking) {
+ $cached->lock_id = sha1('lock.' . $path);
+ }
+ $this->populateTimestamp($cached);
+ }
+
+ /**
+ * populate Cached Object with timestamp and exists from Resource
+ *
+ * @param Smarty_Template_Cached $cached
+ *
+ * @return void
+ */
+ public function populateTimestamp(Smarty_Template_Cached $cached) {
+ $mtime = $this->fetchTimestamp($cached->filepath, $cached->source->name, $cached->cache_id, $cached->compile_id);
+ if ($mtime !== null) {
+ $cached->timestamp = $mtime;
+ $cached->exists = !!$cached->timestamp;
+
+ return;
+ }
+ $timestamp = null;
+ $this->fetch($cached->filepath, $cached->source->name, $cached->cache_id, $cached->compile_id, $cached->content, $timestamp);
+ $cached->timestamp = isset($timestamp) ? $timestamp : false;
+ $cached->exists = !!$cached->timestamp;
+ }
+
+ /**
+ * Read the cached template and process the header
+ *
+ * @param Smarty_Internal_Template $_template template object
+ * @param Smarty_Template_Cached $cached cached object
+ *
+ * @return boolean true or false if the cached content does not exist
+ */
+ public function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached = null) {
+ if (!$cached) {
+ $cached = $_template->cached;
+ }
+ $content = $cached->content ? $cached->content : null;
+ $timestamp = $cached->timestamp ? $cached->timestamp : null;
+ if ($content === null || !$timestamp) {
+ $this->fetch(
+ $_template->cached->filepath,
+ $_template->source->name,
+ $_template->cache_id,
+ $_template->compile_id,
+ $content,
+ $timestamp
+ );
+ }
+ if (isset($content)) {
+ /** @var Smarty_Internal_Template $_smarty_tpl
+ * used in evaluated code
+ */
+ $_smarty_tpl = $_template;
+ eval("?>" . $content);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Write the rendered template output to cache
+ *
+ * @param Smarty_Internal_Template $_template template object
+ * @param string $content content to cache
+ *
+ * @return boolean success
+ */
+ public function writeCachedContent(Smarty_Internal_Template $_template, $content) {
+ return $this->save(
+ $_template->cached->filepath,
+ $_template->source->name,
+ $_template->cache_id,
+ $_template->compile_id,
+ $_template->properties['cache_lifetime'],
+ $content
+ );
+ }
+
+ /**
+ * Read cached template from cache
+ *
+ * @param Smarty_Internal_Template $_template template object
+ *
+ * @return string content
+ */
+ public function readCachedContent(Smarty_Internal_Template $_template) {
+ $content = $_template->cached->content ? $_template->cached->content : null;
+ $timestamp = null;
+ if ($content === null) {
+ $timestamp = null;
+ $this->fetch(
+ $_template->cached->filepath,
+ $_template->source->name,
+ $_template->cache_id,
+ $_template->compile_id,
+ $content,
+ $timestamp
+ );
+ }
+ if (isset($content)) {
+ return $content;
+ }
+ return false;
+ }
+
+ /**
+ * Empty cache
+ *
+ * @param Smarty $smarty Smarty object
+ * @param integer $exp_time expiration time (number of seconds, not timestamp)
+ *
+ * @return integer number of cache files deleted
+ */
+ public function clearAll(Smarty $smarty, $exp_time = null) {
+ $this->cache = array();
+
+ return $this->delete(null, null, null, $exp_time);
+ }
+
+ /**
+ * Empty cache for a specific template
+ *
+ * @param Smarty $smarty Smarty object
+ * @param string $resource_name template name
+ * @param string $cache_id cache id
+ * @param string $compile_id compile id
+ * @param integer $exp_time expiration time (number of seconds, not timestamp)
+ *
+ * @return integer number of cache files deleted
+ */
+ public function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time) {
+ $this->cache = array();
+ $cache_name = null;
+
+ if (isset($resource_name)) {
+ $_save_stat = $smarty->caching;
+ $smarty->caching = true;
+ $tpl = new $smarty->template_class($resource_name, $smarty);
+ $smarty->caching = $_save_stat;
+
+ if ($tpl->source->exists) {
+ $cache_name = $tpl->source->name;
+ } else {
+ return 0;
+ }
+ // remove from template cache
+ if ($smarty->allow_ambiguous_resources) {
+ $_templateId = $tpl->source->unique_resource . $tpl->cache_id . $tpl->compile_id;
+ } else {
+ $_templateId = $smarty->joined_template_dir . '#' . $resource_name . $tpl->cache_id . $tpl->compile_id;
+ }
+ if (isset($_templateId[150])) {
+ $_templateId = sha1($_templateId);
+ }
+ unset($smarty->template_objects[$_templateId]);
+ // template object no longer needed
+ unset($tpl);
+ }
+
+ return $this->delete($cache_name, $cache_id, $compile_id, $exp_time);
+ }
+
+ /**
+ * Check is cache is locked for this template
+ *
+ * @param Smarty $smarty Smarty object
+ * @param Smarty_Template_Cached $cached cached object
+ *
+ * @return boolean true or false if cache is locked
+ */
+ public function hasLock(Smarty $smarty, Smarty_Template_Cached $cached) {
+ $id = $cached->lock_id;
+ $name = $cached->source->name . '.lock';
+
+ $mtime = $this->fetchTimestamp($id, $name, $cached->cache_id, $cached->compile_id);
+ if ($mtime === null) {
+ $this->fetch($id, $name, $cached->cache_id, $cached->compile_id, $content, $mtime);
+ }
+ return $mtime && ($t = time()) - $mtime < $smarty->locking_timeout;
+ }
+
+ /**
+ * Lock cache for this template
+ *
+ * @param Smarty $smarty Smarty object
+ * @param Smarty_Template_Cached $cached cached object
+ *
+ * @return bool|void
+ */
+ public function acquireLock(Smarty $smarty, Smarty_Template_Cached $cached) {
+ $cached->is_locked = true;
+ $id = $cached->lock_id;
+ $name = $cached->source->name . '.lock';
+ $this->save($id, $name, $cached->cache_id, $cached->compile_id, $smarty->locking_timeout, '');
+ }
+
+ /**
+ * Unlock cache for this template
+ *
+ * @param Smarty $smarty Smarty object
+ * @param Smarty_Template_Cached $cached cached object
+ *
+ * @return bool|void
+ */
+ public function releaseLock(Smarty $smarty, Smarty_Template_Cached $cached) {
+ $cached->is_locked = false;
+ $name = $cached->source->name . '.lock';
+ $this->delete($name, $cached->cache_id, $cached->compile_id, null);
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_cacheresource_keyvaluestore.php
@@ -0,0 +1,490 @@
+<?php
+/**
+ * Smarty Internal Plugin
+ *
+ * @package Smarty
+ * @subpackage Cacher
+ */
+
+/**
+ * Smarty Cache Handler Base for Key/Value Storage Implementations
+ * This class implements the functionality required to use simple key/value stores
+ * for hierarchical cache groups. key/value stores like memcache or APC do not support
+ * wildcards in keys, therefore a cache group cannot be cleared like "a|*" - which
+ * is no problem to filesystem and RDBMS implementations.
+ * This implementation is based on the concept of invalidation. While one specific cache
+ * can be identified and cleared, any range of caches cannot be identified. For this reason
+ * each level of the cache group hierarchy can have its own value in the store. These values
+ * are nothing but microtimes, telling us when a particular cache group was cleared for the
+ * last time. These keys are evaluated for every cache read to determine if the cache has
+ * been invalidated since it was created and should hence be treated as inexistent.
+ * Although deep hierarchies are possible, they are not recommended. Try to keep your
+ * cache groups as shallow as possible. Anything up 3-5 parents should be ok. So
+ * »a|b|c« is a good depth where »a|b|c|d|e|f|g|h|i|j|k« isn't. Try to join correlating
+ * cache groups: if your cache groups look somewhat like »a|b|$page|$items|$whatever«
+ * consider using »a|b|c|$page-$items-$whatever« instead.
+ *
+ * @package Smarty
+ * @subpackage Cacher
+ * @author Rodney Rehm
+ */
+abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource {
+ /**
+ * cache for contents
+ *
+ * @var array
+ */
+ protected $contents = array();
+
+ /**
+ * cache for timestamps
+ *
+ * @var array
+ */
+ protected $timestamps = array();
+
+ /**
+ * populate Cached Object with meta data from Resource
+ *
+ * @param Smarty_Template_Cached $cached cached object
+ * @param Smarty_Internal_Template $_template template object
+ *
+ * @return void
+ */
+ public function populate(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template) {
+ $cached->filepath = $_template->source->uid . '#' . $this->sanitize($cached->source->resource) . '#' . $this->sanitize($cached->cache_id) . '#' . $this->sanitize($cached->compile_id);
+
+ $this->populateTimestamp($cached);
+ }
+
+ /**
+ * populate Cached Object with timestamp and exists from Resource
+ *
+ * @param Smarty_Template_Cached $cached cached object
+ *
+ * @return void
+ */
+ public function populateTimestamp(Smarty_Template_Cached $cached) {
+ if (!$this->fetch($cached->filepath, $cached->source->name, $cached->cache_id, $cached->compile_id, $content, $timestamp, $cached->source->uid)) {
+ return;
+ }
+ $cached->content = $content;
+ $cached->timestamp = (int)$timestamp;
+ $cached->exists = $cached->timestamp;
+ }
+
+ /**
+ * Read the cached template and process the header
+ *
+ * @param Smarty_Internal_Template $_template template object
+ * @param Smarty_Template_Cached $cached cached object
+ *
+ * @return boolean true or false if the cached content does not exist
+ */
+ public function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached = null) {
+ if (!$cached) {
+ $cached = $_template->cached;
+ }
+ $content = $cached->content ? $cached->content : null;
+ $timestamp = $cached->timestamp ? $cached->timestamp : null;
+ if ($content === null || !$timestamp) {
+ if (!$this->fetch($_template->cached->filepath, $_template->source->name, $_template->cache_id, $_template->compile_id, $content, $timestamp, $_template->source->uid)) {
+ return false;
+ }
+ }
+ if (isset($content)) {
+ /** @var Smarty_Internal_Template $_smarty_tpl
+ * used in evaluated code
+ */
+ $_smarty_tpl = $_template;
+ eval("?>" . $content);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Write the rendered template output to cache
+ *
+ * @param Smarty_Internal_Template $_template template object
+ * @param string $content content to cache
+ *
+ * @return boolean success
+ */
+ public function writeCachedContent(Smarty_Internal_Template $_template, $content) {
+ $this->addMetaTimestamp($content);
+
+ return $this->write(array($_template->cached->filepath => $content), $_template->properties['cache_lifetime']);
+ }
+
+ /**
+ * Read cached template from cache
+ *
+ * @param Smarty_Internal_Template $_template template object
+ *
+ * @return string content
+ */
+ public function readCachedContent(Smarty_Internal_Template $_template) {
+ $content = $_template->cached->content ? $_template->cached->content : null;
+ $timestamp = null;
+ if ($content === null) {
+ if (!$this->fetch($_template->cached->filepath, $_template->source->name, $_template->cache_id, $_template->compile_id, $content, $timestamp, $_template->source->uid)) {
+ return false;
+ }
+ }
+ if (isset($content)) {
+ return $content;
+ }
+ return false;
+ }
+
+ /**
+ * Empty cache
+ * {@internal the $exp_time argument is ignored altogether }}
+ *
+ * @param Smarty $smarty Smarty object
+ * @param integer $exp_time expiration time [being ignored]
+ *
+ * @return integer number of cache files deleted [always -1]
+ * @uses purge() to clear the whole store
+ * @uses invalidate() to mark everything outdated if purge() is inapplicable
+ */
+ public function clearAll(Smarty $smarty, $exp_time = null) {
+ if (!$this->purge()) {
+ $this->invalidate(null);
+ }
+
+ return -1;
+ }
+
+ /**
+ * Empty cache for a specific template
+ * {@internal the $exp_time argument is ignored altogether}}
+ *
+ * @param Smarty $smarty Smarty object
+ * @param string $resource_name template name
+ * @param string $cache_id cache id
+ * @param string $compile_id compile id
+ * @param integer $exp_time expiration time [being ignored]
+ *
+ * @return integer number of cache files deleted [always -1]
+ * @uses buildCachedFilepath() to generate the CacheID
+ * @uses invalidate() to mark CacheIDs parent chain as outdated
+ * @uses delete() to remove CacheID from cache
+ */
+ public function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time) {
+ $uid = $this->getTemplateUid($smarty, $resource_name, $cache_id, $compile_id);
+ $cid = $uid . '#' . $this->sanitize($resource_name) . '#' . $this->sanitize($cache_id) . '#' . $this->sanitize($compile_id);
+ $this->delete(array($cid));
+ $this->invalidate($cid, $resource_name, $cache_id, $compile_id, $uid);
+
+ return -1;
+ }
+
+ /**
+ * Get template's unique ID
+ *
+ * @param Smarty $smarty Smarty object
+ * @param string $resource_name template name
+ * @param string $cache_id cache id
+ * @param string $compile_id compile id
+ *
+ * @return string filepath of cache file
+ */
+ protected function getTemplateUid(Smarty $smarty, $resource_name, $cache_id, $compile_id) {
+ $uid = '';
+ if (isset($resource_name)) {
+ $tpl = new $smarty->template_class($resource_name, $smarty);
+ if ($tpl->source->exists) {
+ $uid = $tpl->source->uid;
+ }
+
+ // remove from template cache
+ if ($smarty->allow_ambiguous_resources) {
+ $_templateId = $tpl->source->unique_resource . $tpl->cache_id . $tpl->compile_id;
+ } else {
+ $_templateId = $smarty->joined_template_dir . '#' . $resource_name . $tpl->cache_id . $tpl->compile_id;
+ }
+ if (isset($_templateId[150])) {
+ $_templateId = sha1($_templateId);
+ }
+ unset($smarty->template_objects[$_templateId]);
+ }
+
+ return $uid;
+ }
+
+ /**
+ * Sanitize CacheID components
+ *
+ * @param string $string CacheID component to sanitize
+ *
+ * @return string sanitized CacheID component
+ */
+ protected function sanitize($string) {
+ // some poeple smoke bad weed
+ $string = trim($string, '|');
+ if (!$string) {
+ return null;
+ }
+
+ return preg_replace('#[^\w\|]+#S', '_', $string);
+ }
+
+ /**
+ * Fetch and prepare a cache object.
+ *
+ * @param string $cid CacheID to fetch
+ * @param string $resource_name template name
+ * @param string $cache_id cache id
+ * @param string $compile_id compile id
+ * @param string $content cached content
+ * @param integer &$timestamp cached timestamp (epoch)
+ * @param string $resource_uid resource's uid
+ *
+ * @return boolean success
+ */
+ protected function fetch($cid, $resource_name = null, $cache_id = null, $compile_id = null, &$content = null, &$timestamp = null, $resource_uid = null) {
+ $t = $this->read(array($cid));
+ $content = !empty($t[$cid]) ? $t[$cid] : null;
+ $timestamp = null;
+
+ if ($content && ($timestamp = $this->getMetaTimestamp($content))) {
+ $invalidated = $this->getLatestInvalidationTimestamp($cid, $resource_name, $cache_id, $compile_id, $resource_uid);
+ if ($invalidated > $timestamp) {
+ $timestamp = null;
+ $content = null;
+ }
+ }
+
+ return !!$content;
+ }
+
+ /**
+ * Add current microtime to the beginning of $cache_content
+ * {@internal the header uses 8 Bytes, the first 4 Bytes are the seconds, the second 4 Bytes are the microseconds}}
+ *
+ * @param string &$content the content to be cached
+ */
+ protected function addMetaTimestamp(&$content) {
+ $mt = explode(" ", microtime());
+ $ts = pack("NN", $mt[1], (int)($mt[0] * 100000000));
+ $content = $ts . $content;
+ }
+
+ /**
+ * Extract the timestamp the $content was cached
+ *
+ * @param string &$content the cached content
+ *
+ * @return float the microtime the content was cached
+ */
+ protected function getMetaTimestamp(&$content) {
+ extract(unpack('N1s/N1m/a*content', $content));
+ return $s + ($m / 100000000);
+ }
+
+ /**
+ * Invalidate CacheID
+ *
+ * @param string $cid CacheID
+ * @param string $resource_name template name
+ * @param string $cache_id cache id
+ * @param string $compile_id compile id
+ * @param string $resource_uid source's uid
+ *
+ * @return void
+ */
+ protected function invalidate($cid = null, $resource_name = null, $cache_id = null, $compile_id = null, $resource_uid = null) {
+ $now = microtime(true);
+ $key = null;
+ // invalidate everything
+ if (!$resource_name && !$cache_id && !$compile_id) {
+ $key = 'IVK#ALL';
+ } // invalidate all caches by template
+ else {
+ if ($resource_name && !$cache_id && !$compile_id) {
+ $key = 'IVK#TEMPLATE#' . $resource_uid . '#' . $this->sanitize($resource_name);
+ } // invalidate all caches by cache group
+ else {
+ if (!$resource_name && $cache_id && !$compile_id) {
+ $key = 'IVK#CACHE#' . $this->sanitize($cache_id);
+ } // invalidate all caches by compile id
+ else {
+ if (!$resource_name && !$cache_id && $compile_id) {
+ $key = 'IVK#COMPILE#' . $this->sanitize($compile_id);
+ } // invalidate by combination
+ else {
+ $key = 'IVK#CID#' . $cid;
+ }
+ }
+ }
+ }
+ $this->write(array($key => $now));
+ }
+
+ /**
+ * Determine the latest timestamp known to the invalidation chain
+ *
+ * @param string $cid CacheID to determine latest invalidation timestamp of
+ * @param string $resource_name template name
+ * @param string $cache_id cache id
+ * @param string $compile_id compile id
+ * @param string $resource_uid source's filepath
+ *
+ * @return float the microtime the CacheID was invalidated
+ */
+ protected function getLatestInvalidationTimestamp($cid, $resource_name = null, $cache_id = null, $compile_id = null, $resource_uid = null) {
+ // abort if there is no CacheID
+ if (false && !$cid) {
+ return 0;
+ }
+ // abort if there are no InvalidationKeys to check
+ if (!($_cid = $this->listInvalidationKeys($cid, $resource_name, $cache_id, $compile_id, $resource_uid))) {
+ return 0;
+ }
+
+ // there are no InValidationKeys
+ if (!($values = $this->read($_cid))) {
+ return 0;
+ }
+ // make sure we're dealing with floats
+ $values = array_map('floatval', $values);
+
+ return max($values);
+ }
+
+ /**
+ * Translate a CacheID into the list of applicable InvalidationKeys.
+ * Splits "some|chain|into|an|array" into array( '#clearAll#', 'some', 'some|chain', 'some|chain|into', ... )
+ *
+ * @param string $cid CacheID to translate
+ * @param string $resource_name template name
+ * @param string $cache_id cache id
+ * @param string $compile_id compile id
+ * @param string $resource_uid source's filepath
+ *
+ * @return array list of InvalidationKeys
+ * @uses $invalidationKeyPrefix to prepend to each InvalidationKey
+ */
+ protected function listInvalidationKeys($cid, $resource_name = null, $cache_id = null, $compile_id = null, $resource_uid = null) {
+ $t = array('IVK#ALL');
+ $_name = $_compile = '#';
+ if ($resource_name) {
+ $_name .= $resource_uid . '#' . $this->sanitize($resource_name);
+ $t[] = 'IVK#TEMPLATE' . $_name;
+ }
+ if ($compile_id) {
+ $_compile .= $this->sanitize($compile_id);
+ $t[] = 'IVK#COMPILE' . $_compile;
+ }
+ $_name .= '#';
+ // some poeple smoke bad weed
+ $cid = trim($cache_id, '|');
+ if (!$cid) {
+ return $t;
+ }
+ $i = 0;
+ while (true) {
+ // determine next delimiter position
+ $i = strpos($cid, '|', $i);
+ // add complete CacheID if there are no more delimiters
+ if ($i === false) {
+ $t[] = 'IVK#CACHE#' . $cid;
+ $t[] = 'IVK#CID' . $_name . $cid . $_compile;
+ $t[] = 'IVK#CID' . $_name . $_compile;
+ break;
+ }
+ $part = substr($cid, 0, $i);
+ // add slice to list
+ $t[] = 'IVK#CACHE#' . $part;
+ $t[] = 'IVK#CID' . $_name . $part . $_compile;
+ // skip past delimiter position
+ $i++;
+ }
+
+ return $t;
+ }
+
+ /**
+ * Check is cache is locked for this template
+ *
+ * @param Smarty $smarty Smarty object
+ * @param Smarty_Template_Cached $cached cached object
+ *
+ * @return boolean true or false if cache is locked
+ */
+ public function hasLock(Smarty $smarty, Smarty_Template_Cached $cached) {
+ $key = 'LOCK#' . $cached->filepath;
+ $data = $this->read(array($key));
+
+ return $data && time() - $data[$key] < $smarty->locking_timeout;
+ }
+
+ /**
+ * Lock cache for this template
+ *
+ * @param Smarty $smarty Smarty object
+ * @param Smarty_Template_Cached $cached cached object
+ *
+ * @return bool|void
+ */
+ public function acquireLock(Smarty $smarty, Smarty_Template_Cached $cached) {
+ $cached->is_locked = true;
+ $key = 'LOCK#' . $cached->filepath;
+ $this->write(array($key => time()), $smarty->locking_timeout);
+ }
+
+ /**
+ * Unlock cache for this template
+ *
+ * @param Smarty $smarty Smarty object
+ * @param Smarty_Template_Cached $cached cached object
+ *
+ * @return bool|void
+ */
+ public function releaseLock(Smarty $smarty, Smarty_Template_Cached $cached) {
+ $cached->is_locked = false;
+ $key = 'LOCK#' . $cached->filepath;
+ $this->delete(array($key));
+ }
+
+ /**
+ * Read values for a set of keys from cache
+ *
+ * @param array $keys list of keys to fetch
+ *
+ * @return array list of values with the given keys used as indexes
+ */
+ abstract protected function read(array $keys);
+
+ /**
+ * Save values for a set of keys to cache
+ *
+ * @param array $keys list of values to save
+ * @param int $expire expiration time
+ *
+ * @return boolean true on success, false on failure
+ */
+ abstract protected function write(array $keys, $expire = null);
+
+ /**
+ * Remove values from cache
+ *
+ * @param array $keys list of keys to delete
+ *
+ * @return boolean true on success, false on failure
+ */
+ abstract protected function delete(array $keys);
+
+ /**
+ * Remove *all* values from cache
+ *
+ * @return boolean true on success, false on failure
+ */
+ protected function purge() {
+ return false;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_data.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Smarty Plugin Data
+ * This file contains the data object
+ *
+ * @package Smarty
+ * @subpackage Template
+ * @author Uwe Tews
+ */
+
+/**
+ * class for the Smarty data object
+ * The Smarty data object will hold Smarty variables in the current scope
+ *
+ * @package Smarty
+ * @subpackage Template
+ */
+class Smarty_Data extends Smarty_Internal_Data {
+ /**
+ * Counter
+ *
+ * @var int
+ */
+ static $count = 0;
+
+ /**
+ * Data block name
+ *
+ * @var string
+ */
+ public $dataObjectName = '';
+ /**
+ * Smarty object
+ *
+ * @var Smarty
+ */
+ public $smarty = null;
+
+ /**
+ * create Smarty data object
+ *
+ * @param Smarty|array $_parent parent template
+ * @param Smarty|Smarty_Internal_Template $smarty global smarty instance
+ * @param string $name optional data block name
+ *
+ * @throws SmartyException
+ */
+ public function __construct($_parent = null, $smarty = null, $name = null) {
+ self::$count++;
+ $this->dataObjectName = 'Data_object ' . (isset($name) ? "'{$name}'" : self::$count);
+ $this->smarty = $smarty;
+ if (is_object($_parent)) {
+ // when object set up back pointer
+ $this->parent = $_parent;
+ } elseif (is_array($_parent)) {
+ // set up variable values
+ foreach ($_parent as $_key => $_val) {
+ $this->tpl_vars[$_key] = new Smarty_Variable($_val);
+ }
+ } elseif ($_parent != null) {
+ throw new SmartyException("Wrong type for template variables");
+ }
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_cacheresource_file.php
@@ -0,0 +1,309 @@
+<?php
+/**
+ * Smarty Internal Plugin CacheResource File
+ *
+ * @package Smarty
+ * @subpackage Cacher
+ * @author Uwe Tews
+ * @author Rodney Rehm
+ */
+
+/**
+ * This class does contain all necessary methods for the HTML cache on file system
+ * Implements the file system as resource for the HTML cache Version ussing nocache inserts.
+ *
+ * @package Smarty
+ * @subpackage Cacher
+ */
+class Smarty_Internal_CacheResource_File extends Smarty_CacheResource {
+ /**
+ * populate Cached Object with meta data from Resource
+ *
+ * @param Smarty_Template_Cached $cached cached object
+ * @param Smarty_Internal_Template $_template template object
+ *
+ * @return void
+ */
+ public function populate(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template) {
+ $_source_file_path = str_replace(':', '.', $_template->source->filepath);
+ $_cache_id = isset($_template->cache_id) ? preg_replace('![^\w\|]+!', '_', $_template->cache_id) : null;
+ $_compile_id = isset($_template->compile_id) ? preg_replace('![^\w\|]+!', '_', $_template->compile_id) : null;
+ $_filepath = $_template->source->uid;
+ // if use_sub_dirs, break file into directories
+ if ($_template->smarty->use_sub_dirs) {
+ $_filepath = substr($_filepath, 0, 2) . DS
+ . substr($_filepath, 2, 2) . DS
+ . substr($_filepath, 4, 2) . DS
+ . $_filepath;
+ }
+ $_compile_dir_sep = $_template->smarty->use_sub_dirs ? DS : '^';
+ if (isset($_cache_id)) {
+ $_cache_id = str_replace('|', $_compile_dir_sep, $_cache_id) . $_compile_dir_sep;
+ } else {
+ $_cache_id = '';
+ }
+ if (isset($_compile_id)) {
+ $_compile_id = $_compile_id . $_compile_dir_sep;
+ } else {
+ $_compile_id = '';
+ }
+ $_cache_dir = $_template->smarty->getCacheDir();
+ if ($_template->smarty->cache_locking) {
+ // create locking file name
+ // relative file name?
+ if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_cache_dir)) {
+ $_lock_dir = rtrim(getcwd(), '/\\') . DS . $_cache_dir;
+ } else {
+ $_lock_dir = $_cache_dir;
+ }
+ $cached->lock_id = $_lock_dir . sha1($_cache_id . $_compile_id . $_template->source->uid) . '.lock';
+ }
+ $cached->filepath = $_cache_dir . $_cache_id . $_compile_id . $_filepath . '.' . basename($_source_file_path) . '.php';
+ $cached->timestamp = $cached->exists = is_file($cached->filepath);
+ if ($cached->exists) {
+ $cached->timestamp = filemtime($cached->filepath);
+ }
+ }
+
+ /**
+ * populate Cached Object with timestamp and exists from Resource
+ *
+ * @param Smarty_Template_Cached $cached cached object
+ *
+ * @return void
+ */
+ public function populateTimestamp(Smarty_Template_Cached $cached) {
+ $cached->timestamp = $cached->exists = is_file($cached->filepath);
+ if ($cached->exists) {
+ $cached->timestamp = filemtime($cached->filepath);
+ }
+ }
+
+ /**
+ * Read the cached template and process its header
+ *
+ * @param Smarty_Internal_Template $_template template object
+ * @param Smarty_Template_Cached $cached cached object
+ *
+ * @return booleantrue or false if the cached content does not exist
+ */
+ public function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached = null) {
+ /** @var Smarty_Internal_Template $_smarty_tpl
+ * used in included file
+ */
+ $_smarty_tpl = $_template;
+
+ return @include $_template->cached->filepath;
+ }
+
+ /**
+ * Write the rendered template output to cache
+ *
+ * @param Smarty_Internal_Template $_template template object
+ * @param string $content content to cache
+ *
+ * @return boolean success
+ */
+ public function writeCachedContent(Smarty_Internal_Template $_template, $content) {
+ $obj = new Smarty_Internal_Write_File();
+ if ($obj->writeFile($_template->cached->filepath, $content, $_template->smarty) === true) {
+ $cached = $_template->cached;
+ $cached->timestamp = $cached->exists = is_file($cached->filepath);
+ if ($cached->exists) {
+ $cached->timestamp = filemtime($cached->filepath);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Read cached template from cache
+ *
+ * @param Smarty_Internal_Template $_template template object
+ *
+ * @return string content
+ */
+ public function readCachedContent(Smarty_Internal_Template $_template) {
+ if (is_file($_template->cached->filepath)) {
+ return file_get_contents($_template->cached->filepath);
+ }
+ return false;
+ }
+
+ /**
+ * Empty cache
+ *
+ * @param Smarty $smarty
+ * @param integer $exp_time expiration time (number of seconds, not timestamp)
+ *
+ * @return integer number of cache files deleted
+ */
+ public function clearAll(Smarty $smarty, $exp_time = null) {
+ return $this->clear($smarty, null, null, null, $exp_time);
+ }
+
+ /**
+ * Empty cache for a specific template
+ *
+ * @param Smarty $smarty
+ * @param string $resource_name template name
+ * @param string $cache_id cache id
+ * @param string $compile_id compile id
+ * @param integer $exp_time expiration time (number of seconds, not timestamp)
+ *
+ * @return integer number of cache files deleted
+ */
+ public function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time) {
+ $_cache_id = isset($cache_id) ? preg_replace('![^\w\|]+!', '_', $cache_id) : null;
+ $_compile_id = isset($compile_id) ? preg_replace('![^\w\|]+!', '_', $compile_id) : null;
+ $_dir_sep = $smarty->use_sub_dirs ? '/' : '^';
+ $_compile_id_offset = $smarty->use_sub_dirs ? 3 : 0;
+ $_dir = realpath($smarty->getCacheDir()) . '/';
+ if ($_dir == '/') { //We should never want to delete this!
+ return 0;
+ }
+ $_dir_length = strlen($_dir);
+ if (isset($_cache_id)) {
+ $_cache_id_parts = explode('|', $_cache_id);
+ $_cache_id_parts_count = count($_cache_id_parts);
+ if ($smarty->use_sub_dirs) {
+ foreach ($_cache_id_parts as $id_part) {
+ $_dir .= $id_part . DS;
+ }
+ }
+ }
+ if (isset($resource_name)) {
+ $_save_stat = $smarty->caching;
+ $smarty->caching = true;
+ $tpl = new $smarty->template_class($resource_name, $smarty);
+ $smarty->caching = $_save_stat;
+
+ // remove from template cache
+ $tpl->source; // have the template registered before unset()
+ if ($smarty->allow_ambiguous_resources) {
+ $_templateId = $tpl->source->unique_resource . $tpl->cache_id . $tpl->compile_id;
+ } else {
+ $_templateId = $smarty->joined_template_dir . '#' . $resource_name . $tpl->cache_id . $tpl->compile_id;
+ }
+ if (isset($_templateId[150])) {
+ $_templateId = sha1($_templateId);
+ }
+ unset($smarty->template_objects[$_templateId]);
+
+ if ($tpl->source->exists) {
+ $_resourcename_parts = basename(str_replace('^', '/', $tpl->cached->filepath));
+ } else {
+ return 0;
+ }
+ }
+ $_count = 0;
+ $_time = time();
+ if (file_exists($_dir)) {
+ $_cacheDirs = new RecursiveDirectoryIterator($_dir);
+ $_cache = new RecursiveIteratorIterator($_cacheDirs, RecursiveIteratorIterator::CHILD_FIRST);
+ foreach ($_cache as $_file) {
+ if (substr(basename($_file->getPathname()), 0, 1) == '.' || strpos($_file, '.svn') !== false) {
+ continue;
+ }
+ // directory ?
+ if ($_file->isDir()) {
+ if (!$_cache->isDot()) {
+ // delete folder if empty
+ @rmdir($_file->getPathname());
+ }
+ } else {
+ $_parts = explode($_dir_sep, str_replace('\\', '/', substr((string)$_file, $_dir_length)));
+ $_parts_count = count($_parts);
+ // check name
+ if (isset($resource_name)) {
+ if ($_parts[$_parts_count - 1] != $_resourcename_parts) {
+ continue;
+ }
+ }
+ // check compile id
+ if (isset($_compile_id) && (!isset($_parts[$_parts_count - 2 - $_compile_id_offset]) || $_parts[$_parts_count - 2 - $_compile_id_offset] != $_compile_id)) {
+ continue;
+ }
+ // check cache id
+ if (isset($_cache_id)) {
+ // count of cache id parts
+ $_parts_count = (isset($_compile_id)) ? $_parts_count - 2 - $_compile_id_offset : $_parts_count - 1 - $_compile_id_offset;
+ if ($_parts_count < $_cache_id_parts_count) {
+ continue;
+ }
+ for ($i = 0; $i < $_cache_id_parts_count; $i++) {
+ if ($_parts[$i] != $_cache_id_parts[$i]) {
+ continue 2;
+ }
+ }
+ }
+ // expired ?
+ if (isset($exp_time)) {
+ if ($exp_time < 0) {
+ preg_match('#\'cache_lifetime\' =>\s*(\d*)#', file_get_contents($_file), $match);
+ if ($_time < (@filemtime($_file) + $match[1])) {
+ continue;
+ }
+ } else {
+ if ($_time - @filemtime($_file) < $exp_time) {
+ continue;
+ }
+ }
+ }
+ $_count += @unlink((string)$_file) ? 1 : 0;
+ }
+ }
+ }
+
+ return $_count;
+ }
+
+ /**
+ * Check is cache is locked for this template
+ *
+ * @param Smarty $smarty Smarty object
+ * @param Smarty_Template_Cached $cached cached object
+ *
+ * @return boolean true or false if cache is locked
+ */
+ public function hasLock(Smarty $smarty, Smarty_Template_Cached $cached) {
+ if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
+ clearstatcache(true, $cached->lock_id);
+ } else {
+ clearstatcache();
+ }
+ if (is_file($cached->lock_id)) {
+ $t = @filemtime($cached->lock_id);
+ return $t && (time() - $t < $smarty->locking_timeout);
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Lock cache for this template
+ *
+ * @param Smarty $smarty Smarty object
+ * @param Smarty_Template_Cached $cached cached object
+ *
+ * @return bool|void
+ */
+ public function acquireLock(Smarty $smarty, Smarty_Template_Cached $cached) {
+ $cached->is_locked = true;
+ touch($cached->lock_id);
+ }
+
+ /**
+ * Unlock cache for this template
+ *
+ * @param Smarty $smarty Smarty object
+ * @param Smarty_Template_Cached $cached cached object
+ *
+ * @return bool|void
+ */
+ public function releaseLock(Smarty $smarty, Smarty_Template_Cached $cached) {
+ $cached->is_locked = false;
+ @unlink($cached->lock_id);
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_append.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Append
+ * Compiles the {append} tag
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Append Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Append extends Smarty_Internal_Compile_Assign {
+ /**
+ * Compiles code for the {append} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter) {
+ // the following must be assigned at runtime because it will be overwritten in parent class
+ $this->required_attributes = array('var', 'value');
+ $this->shorttag_order = array('var', 'value');
+ $this->optional_attributes = array('scope', 'index');
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+ // map to compile assign attributes
+ if (isset($_attr['index'])) {
+ $_params['smarty_internal_index'] = '[' . $_attr['index'] . ']';
+ unset($_attr['index']);
+ } else {
+ $_params['smarty_internal_index'] = '[]';
+ }
+ $_new_attr = array();
+ foreach ($_attr as $key => $value) {
+ $_new_attr[] = array($key => $value);
+ }
+ // call compile assign
+ return parent::compile($_new_attr, $compiler, $_params);
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_assign.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Assign
+ * Compiles the {assign} tag
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Assign Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Assign extends Smarty_Internal_CompileBase {
+ /**
+ * Compiles code for the {assign} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter) {
+ // the following must be assigned at runtime because it will be overwritten in Smarty_Internal_Compile_Append
+ $this->required_attributes = array('var', 'value');
+ $this->shorttag_order = array('var', 'value');
+ $this->optional_attributes = array('scope');
+ $_nocache = 'null';
+ $_scope = Smarty::SCOPE_LOCAL;
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+ // nocache ?
+ if ($compiler->tag_nocache || $compiler->nocache) {
+ $_nocache = 'true';
+ // create nocache var to make it know for further compiling
+ if (isset($compiler->template->tpl_vars[trim($_attr['var'], "'")])) {
+ $compiler->template->tpl_vars[trim($_attr['var'], "'")]->nocache = true;
+ } else {
+ $compiler->template->tpl_vars[trim($_attr['var'], "'")] = new Smarty_Variable(null, true);
+ }
+ }
+ // scope setup
+ if (isset($_attr['scope'])) {
+ $_attr['scope'] = trim($_attr['scope'], "'\"");
+ if ($_attr['scope'] == 'parent') {
+ $_scope = Smarty::SCOPE_PARENT;
+ } elseif ($_attr['scope'] == 'root') {
+ $_scope = Smarty::SCOPE_ROOT;
+ } elseif ($_attr['scope'] == 'global') {
+ $_scope = Smarty::SCOPE_GLOBAL;
+ } else {
+ $compiler->trigger_template_error('illegal value for "scope" attribute', $compiler->lex->taglineno);
+ }
+ }
+ // compiled output
+ if (isset($parameter['smarty_internal_index'])) {
+ $output = "<?php \$_smarty_tpl->createLocalArrayVariable($_attr[var], $_nocache, $_scope);\n\$_smarty_tpl->tpl_vars[$_attr[var]]->value$parameter[smarty_internal_index] = $_attr[value];";
+ } else {
+ // implement Smarty2's behaviour of variables assigned by reference
+ if ($compiler->template->smarty instanceof SmartyBC) {
+ $output = "<?php if (isset(\$_smarty_tpl->tpl_vars[$_attr[var]])) {\$_smarty_tpl->tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]];";
+ $output .= "\n\$_smarty_tpl->tpl_vars[$_attr[var]]->value = $_attr[value]; \$_smarty_tpl->tpl_vars[$_attr[var]]->nocache = $_nocache; \$_smarty_tpl->tpl_vars[$_attr[var]]->scope = $_scope;";
+ $output .= "\n} else \$_smarty_tpl->tpl_vars[$_attr[var]] = new Smarty_Variable($_attr[value], $_nocache, $_scope);";
+ } else {
+ $output = "<?php \$_smarty_tpl->tpl_vars[$_attr[var]] = new Smarty_Variable($_attr[value], $_nocache, $_scope);";
+ }
+ }
+ if ($_scope == Smarty::SCOPE_PARENT) {
+ $output .= "\nif (\$_smarty_tpl->parent != null) \$_smarty_tpl->parent->tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]];";
+ } elseif ($_scope == Smarty::SCOPE_ROOT || $_scope == Smarty::SCOPE_GLOBAL) {
+ $output .= "\n\$_ptr = \$_smarty_tpl->parent; while (\$_ptr != null) {\$_ptr->tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]]; \$_ptr = \$_ptr->parent; }";
+ }
+ if ($_scope == Smarty::SCOPE_GLOBAL) {
+ $output .= "\nSmarty::\$global_tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]];";
+ }
+ $output .= '?>';
+
+ return $output;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_block.php
@@ -0,0 +1,432 @@
+<?php
+
+/**
+ * Smarty Internal Plugin Compile Block
+ * Compiles the {block}{/block} tags
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Block Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
+
+ const parent = '____SMARTY_BLOCK_PARENT____';
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $required_attributes = array('name');
+
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $shorttag_order = array('name');
+
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $option_flags = array('hide', 'append', 'prepend', 'nocache');
+
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $optional_attributes = array('internal_file', 'internal_uid', 'internal_line');
+ /**
+ * nested child block names
+ *
+ * @var array
+ */
+ public static $nested_block_names = array();
+
+ /**
+ * child block source buffer
+ *
+ * @var array
+ */
+ public static $block_data = array();
+
+ /**
+ * Compiles code for the {block} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ *
+ * @return boolean true
+ */
+ public function compile($args, $compiler) {
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+ $_name = trim($_attr['name'], "\"'");
+
+ // existing child must override parent settings
+ if (isset($compiler->template->block_data[$_name]) && $compiler->template->block_data[$_name]['mode'] == 'replace') {
+ $_attr['append'] = false;
+ $_attr['prepend'] = false;
+ }
+
+ // check if we process an inheritance child template
+ if ($compiler->inheritance_child) {
+ array_unshift(self::$nested_block_names, $_name);
+ // build {block} for child block
+ self::$block_data[$_name]['source'] =
+ "{$compiler->smarty->left_delimiter}private_child_block name={$_attr['name']} file='{$compiler->template->source->filepath}' type='{$compiler->template->source->type}' resource='{$compiler->template->template_resource}'" .
+ " uid='{$compiler->template->source->uid}' line={$compiler->lex->line}";
+ if ($_attr['nocache']) {
+ self::$block_data[$_name]['source'] .= ' nocache';
+ }
+ self::$block_data[$_name]['source'] .= $compiler->smarty->right_delimiter;
+
+ $save = array($_attr, $compiler->inheritance);
+ $this->openTag($compiler, 'block', $save);
+ // set flag for {block} tag
+ $compiler->inheritance = true;
+ $compiler->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBLOCK);
+ $compiler->has_code = false;
+ return;
+ }
+ // must merge includes
+ if ($_attr['nocache'] == true) {
+ $compiler->tag_nocache = true;
+ }
+ $save = array($_attr, $compiler->inheritance, $compiler->parser->current_buffer, $compiler->nocache);
+ $this->openTag($compiler, 'block', $save);
+ $compiler->inheritance = true;
+ $compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
+
+ $compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template($compiler->parser);
+ $compiler->has_code = false;
+
+ return true;
+ }
+
+ /**
+ * Compile saved child block source
+ *
+ * @param object $compiler compiler object
+ * @param string $_name optional name of child block
+ *
+ * @return string compiled code of child block
+ */
+ static function compileChildBlock($compiler, $_name = null) {
+ if ($compiler->inheritance_child) {
+ $name1 = Smarty_Internal_Compile_Block::$nested_block_names[0];
+ if (isset($compiler->template->block_data[$name1])) {
+ // replace inner block name with generic
+ Smarty_Internal_Compile_Block::$block_data[$name1]['source'] .= $compiler->template->block_data[$name1]['source'];
+ Smarty_Internal_Compile_Block::$block_data[$name1]['child'] = true;
+ }
+ $compiler->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBLOCK);
+ $compiler->has_code = false;
+ return;
+ }
+ // if called by {$smarty.block.child} we must search the name of enclosing {block}
+ if ($_name == null) {
+ $stack_count = count($compiler->_tag_stack);
+ while (--$stack_count >= 0) {
+ if ($compiler->_tag_stack[$stack_count][0] == 'block') {
+ $_name = trim($compiler->_tag_stack[$stack_count][1][0]['name'], "\"'");
+ break;
+ }
+ }
+ }
+ if ($_name == null) {
+ $compiler->trigger_template_error(' tag {$smarty.block.child} used outside {block} tags ', $compiler->lex->taglineno);
+ }
+ // undefined child?
+ if (!isset($compiler->template->block_data[$_name]['source'])) {
+ $compiler->popTrace();
+ return '';
+ }
+ // flag that child is already compile by {$smarty.block.child} inclusion
+ $compiler->template->block_data[$_name]['compiled'] = true;
+ $_tpl = new Smarty_Internal_template('string:' . $compiler->template->block_data[$_name]['source'], $compiler->smarty, $compiler->template, $compiler->template->cache_id,
+ $compiler->template->compile_id, $compiler->template->caching, $compiler->template->cache_lifetime);
+ if ($compiler->smarty->debugging) {
+ Smarty_Internal_Debug::ignore($_tpl);
+ }
+ $_tpl->tpl_vars = $compiler->template->tpl_vars;
+ $_tpl->variable_filters = $compiler->template->variable_filters;
+ $_tpl->properties['nocache_hash'] = $compiler->template->properties['nocache_hash'];
+ $_tpl->allow_relative_path = true;
+ $_tpl->compiler->inheritance = true;
+ $_tpl->compiler->suppressHeader = true;
+ $_tpl->compiler->suppressFilter = true;
+ $_tpl->compiler->suppressTemplatePropertyHeader = true;
+ $nocache = $compiler->nocache || $compiler->tag_nocache;
+ if (strpos($compiler->template->block_data[$_name]['source'], self::parent) !== false) {
+ $_output = str_replace(self::parent, $compiler->parser->current_buffer->to_smarty_php(), $_tpl->compiler->compileTemplate($_tpl, $nocache, $compiler->parent_compiler));
+ } elseif ($compiler->template->block_data[$_name]['mode'] == 'prepend') {
+ $_output = $_tpl->compiler->compileTemplate($_tpl, $nocache, $compiler->parent_compiler) . $compiler->parser->current_buffer->to_smarty_php();
+ } elseif ($compiler->template->block_data[$_name]['mode'] == 'append') {
+ $_output = $compiler->parser->current_buffer->to_smarty_php() . $_tpl->compiler->compileTemplate($_tpl, $nocache, $compiler->parent_compiler);
+ } elseif (!empty($compiler->template->block_data[$_name])) {
+ $_output = $_tpl->compiler->compileTemplate($_tpl, $nocache, $compiler->parent_compiler);
+ }
+ $compiler->template->properties['file_dependency'] = array_merge($compiler->template->properties['file_dependency'], $_tpl->properties['file_dependency']);
+ $compiler->template->properties['tpl_function'] = array_merge($compiler->template->properties['tpl_function'], $_tpl->properties['tpl_function']);
+ $compiler->template->variable_filters = $_tpl->variable_filters;
+ if ($_tpl->has_nocache_code) {
+ $compiler->template->has_nocache_code = true;
+ }
+ foreach ($_tpl->required_plugins as $key => $tmp1) {
+ if ($compiler->nocache && $compiler->template->caching) {
+ $code = 'nocache';
+ } else {
+ $code = $key;
+ }
+ foreach ($tmp1 as $name => $tmp) {
+ foreach ($tmp as $type => $data) {
+ $compiler->template->required_plugins[$code][$name][$type] = $data;
+ }
+ }
+ }
+ unset($_tpl);
+ $compiler->has_code = true;
+ return $_output;
+ }
+
+ /**
+ * Compile $smarty.block.parent
+ *
+ * @param object $compiler compiler object
+ * @param string $_name optional name of child block
+ *
+ * @return string compiled code of child block
+ */
+ static function compileParentBlock($compiler, $_name = null) {
+ // if called by {$smarty.block.parent} we must search the name of enclosing {block}
+ if ($_name == null) {
+ $stack_count = count($compiler->_tag_stack);
+ while (--$stack_count >= 0) {
+ if ($compiler->_tag_stack[$stack_count][0] == 'block') {
+ $_name = trim($compiler->_tag_stack[$stack_count][1][0]['name'], "\"'");
+ break;
+ }
+ }
+ }
+ if ($_name == null) {
+ $compiler->trigger_template_error(' tag {$smarty.block.parent} used outside {block} tags ', $compiler->lex->taglineno);
+ }
+ if (empty(Smarty_Internal_Compile_Block::$nested_block_names)) {
+ $compiler->trigger_template_error(' illegal {$smarty.block.parent} in parent template ', $compiler->lex->taglineno);
+ }
+ Smarty_Internal_Compile_Block::$block_data[Smarty_Internal_Compile_Block::$nested_block_names[0]]['source'] .= Smarty_Internal_Compile_Block::parent;
+ $compiler->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBLOCK);
+ $compiler->has_code = false;
+ return;
+ }
+
+ /**
+ * Process block source
+ *
+ * @param $compiler
+ * @param string $source source text
+ */
+ static function blockSource($compiler, $source) {
+ Smarty_Internal_Compile_Block::$block_data[Smarty_Internal_Compile_Block::$nested_block_names[0]]['source'] .= $source;
+ }
+}
+
+/**
+ * Smarty Internal Plugin Compile BlockClose Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase {
+ /**
+ * Compiles code for the {/block} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler) {
+ $compiler->has_code = true;
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+ $saved_data = $this->closeTag($compiler, array('block'));
+ $_name = trim($saved_data[0]['name'], "\"'");
+ // reset flag for {block} tag
+ $compiler->inheritance = $saved_data[1];
+ // check if we process an inheritance child template
+ if ($compiler->inheritance_child) {
+ $name1 = Smarty_Internal_Compile_Block::$nested_block_names[0];
+ Smarty_Internal_Compile_Block::$block_data[$name1]['source'] .= "{$compiler->smarty->left_delimiter}/private_child_block{$compiler->smarty->right_delimiter}";
+ array_shift(Smarty_Internal_Compile_Block::$nested_block_names);
+ if (!empty(Smarty_Internal_Compile_Block::$nested_block_names)) {
+ $name2 = Smarty_Internal_Compile_Block::$nested_block_names[0];
+ if (isset($compiler->template->block_data[$name1]) || !$saved_data[0]['hide']) {
+ if (isset(Smarty_Internal_Compile_Block::$block_data[$name1]['child']) || !isset($compiler->template->block_data[$name1])) {
+ Smarty_Internal_Compile_Block::$block_data[$name2]['source'] .= Smarty_Internal_Compile_Block::$block_data[$name1]['source'];
+ } else {
+ if ($compiler->template->block_data[$name1]['mode'] == 'append') {
+ Smarty_Internal_Compile_Block::$block_data[$name2]['source'] .= Smarty_Internal_Compile_Block::$block_data[$name1]['source'] . $compiler->template->block_data[$name1]['source'];
+ } elseif ($compiler->template->block_data[$name1]['mode'] == 'prepend') {
+ Smarty_Internal_Compile_Block::$block_data[$name2]['source'] .= $compiler->template->block_data[$name1]['source'] . Smarty_Internal_Compile_Block::$block_data[$name1]['source'];
+ } else {
+ Smarty_Internal_Compile_Block::$block_data[$name2]['source'] .= $compiler->template->block_data[$name1]['source'];
+ }
+ }
+ }
+ unset(Smarty_Internal_Compile_Block::$block_data[$name1]);
+ $compiler->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBLOCK);
+ } else {
+ if (isset($compiler->template->block_data[$name1]) || !$saved_data[0]['hide']) {
+ if (isset($compiler->template->block_data[$name1]) && !isset(Smarty_Internal_Compile_Block::$block_data[$name1]['child'])) {
+ if (strpos($compiler->template->block_data[$name1]['source'], Smarty_Internal_Compile_Block::parent) !== false) {
+ $compiler->template->block_data[$name1]['source'] =
+ str_replace(Smarty_Internal_Compile_Block::parent, Smarty_Internal_Compile_Block::$block_data[$name1]['source'], $compiler->template->block_data[$name1]['source']);
+ } elseif ($compiler->template->block_data[$name1]['mode'] == 'prepend') {
+ $compiler->template->block_data[$name1]['source'] .= Smarty_Internal_Compile_Block::$block_data[$name1]['source'];
+ } elseif ($compiler->template->block_data[$name1]['mode'] == 'append') {
+ $compiler->template->block_data[$name1]['source'] = Smarty_Internal_Compile_Block::$block_data[$name1]['source'] . $compiler->template->block_data[$name1]['source'];
+ }
+ } else {
+ $compiler->template->block_data[$name1]['source'] = Smarty_Internal_Compile_Block::$block_data[$name1]['source'];
+ }
+ $compiler->template->block_data[$name1]['mode'] = 'replace';
+ if ($saved_data[0]['append']) {
+ $compiler->template->block_data[$name1]['mode'] = 'append';
+ }
+ if ($saved_data[0]['prepend']) {
+ $compiler->template->block_data[$name1]['mode'] = 'prepend';
+ }
+ }
+ unset(Smarty_Internal_Compile_Block::$block_data[$name1]);
+ $compiler->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBODY);
+ }
+ $compiler->has_code = false;
+ return;
+ }
+ if (isset($compiler->template->block_data[$_name]) && !isset($compiler->template->block_data[$_name]['compiled'])) {
+ $_output = Smarty_Internal_Compile_Block::compileChildBlock($compiler, $_name);
+ } else {
+ if ($saved_data[0]['hide'] && !isset($compiler->template->block_data[$_name]['source'])) {
+ $_output = '';
+ } else {
+ $_output = $compiler->parser->current_buffer->to_smarty_php();
+ }
+ }
+ if (isset($compiler->template->block_data[$_name]['compiled'])) {
+ unset($compiler->template->block_data[$_name]['compiled']);
+ }
+ // reset flags
+ $compiler->parser->current_buffer = $saved_data[2];
+ if ($compiler->nocache) {
+ $compiler->tag_nocache = true;
+ }
+ $compiler->nocache = $saved_data[3];
+ // $_output content has already nocache code processed
+ $compiler->suppressNocacheProcessing = true;
+
+ return $_output;
+ }
+}
+
+/**
+ * Smarty Internal Plugin Compile Child Block Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Private_Child_Block extends Smarty_Internal_CompileBase {
+
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $required_attributes = array('name', 'file', 'uid', 'line', 'type', 'resource');
+
+ /**
+ * Compiles code for the {private_child_block} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ *
+ * @return boolean true
+ */
+ public function compile($args, $compiler) {
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+
+ // update template with original template resource of {block}
+ if (trim($_attr['type'], "'") == 'file') {
+ $compiler->template->template_resource = 'file:' . realpath(trim($_attr['file'], "'"));
+ } else {
+ $compiler->template->template_resource = trim($_attr['resource'], "'");
+ }
+ // source object
+ unset ($compiler->template->source);
+ $exists = $compiler->template->source->exists;
+
+ // must merge includes
+ if ($_attr['nocache'] == true) {
+ $compiler->tag_nocache = true;
+ }
+ $save = array($_attr, $compiler->nocache);
+
+ // set trace back to child block
+ $compiler->pushTrace(trim($_attr['file'], "\"'"), trim($_attr['uid'], "\"'"), $_attr['line'] - $compiler->lex->line);
+
+ $this->openTag($compiler, 'private_child_block', $save);
+
+ $compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
+ $compiler->has_code = false;
+
+ return true;
+ }
+}
+
+/**
+ * Smarty Internal Plugin Compile Child Block Close Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Private_Child_Blockclose extends Smarty_Internal_CompileBase {
+
+ /**
+ * Compiles code for the {/private_child_block} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ *
+ * @return boolean true
+ */
+ public function compile($args, $compiler) {
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+
+ $saved_data = $this->closeTag($compiler, array('private_child_block'));
+
+ // end of child block
+ $compiler->popTrace();
+
+ $compiler->nocache = $saved_data[1];
+ $compiler->has_code = false;
+
+ return true;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_break.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Break
+ * Compiles the {break} tag
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Break Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Break extends Smarty_Internal_CompileBase {
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $optional_attributes = array('levels');
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $shorttag_order = array('levels');
+
+ /**
+ * Compiles code for the {break} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter) {
+ static $_is_loopy = array('for' => true, 'foreach' => true, 'while' => true, 'section' => true);
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+
+ if ($_attr['nocache'] === true) {
+ $compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
+ }
+
+ if (isset($_attr['levels'])) {
+ if (!is_numeric($_attr['levels'])) {
+ $compiler->trigger_template_error('level attribute must be a numeric constant', $compiler->lex->taglineno);
+ }
+ $_levels = $_attr['levels'];
+ } else {
+ $_levels = 1;
+ }
+ $level_count = $_levels;
+ $stack_count = count($compiler->_tag_stack) - 1;
+ while ($level_count > 0 && $stack_count >= 0) {
+ if (isset($_is_loopy[$compiler->_tag_stack[$stack_count][0]])) {
+ $level_count--;
+ }
+ $stack_count--;
+ }
+ if ($level_count != 0) {
+ $compiler->trigger_template_error("cannot break {$_levels} level(s)", $compiler->lex->taglineno);
+ }
+
+ return "<?php break {$_levels};?>";
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_call.php
@@ -0,0 +1,83 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Function_Call
+ * Compiles the calls of user defined tags defined by {function}
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Function_Call Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Call extends Smarty_Internal_CompileBase {
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $required_attributes = array('name');
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $shorttag_order = array('name');
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $optional_attributes = array('_any');
+
+ /**
+ * Compiles the calls of user defined tags defined by {function}
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler) {
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+ // save possible attributes
+ if (isset($_attr['assign'])) {
+ // output will be stored in a smarty variable instead of being displayed
+ $_assign = $_attr['assign'];
+ }
+ //$_name = trim($_attr['name'], "'\"");
+ $_name = $_attr['name'];
+ unset($_attr['name'], $_attr['assign'], $_attr['nocache']);
+ // set flag (compiled code of {function} must be included in cache file
+ if (!$compiler->template->caching || $compiler->nocache || $compiler->tag_nocache) {
+ $_nocache = 'true';
+ } else {
+ $_nocache = 'false';
+ }
+ $_paramsArray = array();
+ foreach ($_attr as $_key => $_value) {
+ if (is_int($_key)) {
+ $_paramsArray[] = "$_key=>$_value";
+ } else {
+ $_paramsArray[] = "'$_key'=>$_value";
+ }
+ }
+ $_params = 'array(' . implode(",", $_paramsArray) . ')';
+ //$compiler->suppressNocacheProcessing = true;
+ // was there an assign attribute
+ if (isset($_assign)) {
+ $_output = "<?php ob_start();\$_smarty_tpl->callTemplateFunction ({$_name}, \$_smarty_tpl, {$_params}, {$_nocache}); \$_smarty_tpl->assign({$_assign}, ob_get_clean());?>\n";
+ } else {
+ $_output = "<?php \$_smarty_tpl->callTemplateFunction ({$_name}, \$_smarty_tpl, {$_params}, {$_nocache});?>\n";
+ }
+ return $_output;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_capture.php
@@ -0,0 +1,92 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Capture
+ * Compiles the {capture} tag
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Capture Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Capture extends Smarty_Internal_CompileBase {
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $shorttag_order = array('name');
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $optional_attributes = array('name', 'assign', 'append');
+
+ /**
+ * Compiles code for the {capture} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler) {
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+
+ $buffer = isset($_attr['name']) ? $_attr['name'] : "'default'";
+ $assign = isset($_attr['assign']) ? $_attr['assign'] : 'null';
+ $append = isset($_attr['append']) ? $_attr['append'] : 'null';
+
+ $compiler->_capture_stack[0][] = array($buffer, $assign, $append, $compiler->nocache);
+ // maybe nocache because of nocache variables
+ $compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
+ $_output = "<?php \$_smarty_tpl->_capture_stack[0][] = array($buffer, $assign, $append); ob_start(); ?>";
+
+ return $_output;
+ }
+}
+
+/**
+ * Smarty Internal Plugin Compile Captureclose Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_CaptureClose extends Smarty_Internal_CompileBase {
+ /**
+ * Compiles code for the {/capture} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler) {
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+ // must endblock be nocache?
+ if ($compiler->nocache) {
+ $compiler->tag_nocache = true;
+ }
+
+ list($buffer, $assign, $append, $compiler->nocache) = array_pop($compiler->_capture_stack[0]);
+
+ $_output = "<?php list(\$_capture_buffer, \$_capture_assign, \$_capture_append) = array_pop(\$_smarty_tpl->_capture_stack[0]);\n";
+ $_output .= "if (!empty(\$_capture_buffer)) {\n";
+ $_output .= " if (isset(\$_capture_assign)) \$_smarty_tpl->assign(\$_capture_assign, ob_get_contents());\n";
+ $_output .= " if (isset( \$_capture_append)) \$_smarty_tpl->append( \$_capture_append, ob_get_contents());\n";
+ $_output .= " Smarty::\$_smarty_vars['capture'][\$_capture_buffer]=ob_get_clean();\n";
+ $_output .= "} else \$_smarty_tpl->capture_error();?>";
+
+ return $_output;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_config_load.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Config Load
+ * Compiles the {config load} tag
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Config Load Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Config_Load extends Smarty_Internal_CompileBase {
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $required_attributes = array('file');
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $shorttag_order = array('file', 'section');
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $optional_attributes = array('section', 'scope');
+
+ /**
+ * Compiles code for the {config_load} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler) {
+ static $_is_legal_scope = array('local' => true, 'parent' => true, 'root' => true, 'global' => true);
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+
+ if ($_attr['nocache'] === true) {
+ $compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
+ }
+
+ // save possible attributes
+ $conf_file = $_attr['file'];
+ if (isset($_attr['section'])) {
+ $section = $_attr['section'];
+ } else {
+ $section = 'null';
+ }
+ $scope = 'local';
+ // scope setup
+ if (isset($_attr['scope'])) {
+ $_attr['scope'] = trim($_attr['scope'], "'\"");
+ if (isset($_is_legal_scope[$_attr['scope']])) {
+ $scope = $_attr['scope'];
+ } else {
+ $compiler->trigger_template_error('illegal value for "scope" attribute', $compiler->lex->taglineno);
+ }
+ }
+ // create config object
+ $_output = "<?php Smarty_Internal_Extension_Config::configLoad(\$_smarty_tpl, $conf_file, $section, '$scope');?>";
+
+ return $_output;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_continue.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Continue
+ * Compiles the {continue} tag
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Continue Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Continue extends Smarty_Internal_CompileBase {
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $optional_attributes = array('levels');
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $shorttag_order = array('levels');
+
+ /**
+ * Compiles code for the {continue} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter) {
+ static $_is_loopy = array('for' => true, 'foreach' => true, 'while' => true, 'section' => true);
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+
+ if ($_attr['nocache'] === true) {
+ $compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
+ }
+
+ if (isset($_attr['levels'])) {
+ if (!is_numeric($_attr['levels'])) {
+ $compiler->trigger_template_error('level attribute must be a numeric constant', $compiler->lex->taglineno);
+ }
+ $_levels = $_attr['levels'];
+ } else {
+ $_levels = 1;
+ }
+ $level_count = $_levels;
+ $stack_count = count($compiler->_tag_stack) - 1;
+ while ($level_count > 0 && $stack_count >= 0) {
+ if (isset($_is_loopy[$compiler->_tag_stack[$stack_count][0]])) {
+ $level_count--;
+ }
+ $stack_count--;
+ }
+ if ($level_count != 0) {
+ $compiler->trigger_template_error("cannot continue {$_levels} level(s)", $compiler->lex->taglineno);
+ }
+
+ return "<?php continue {$_levels};?>";
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_debug.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Debug
+ * Compiles the {debug} tag.
+ * It opens a window the the Smarty Debugging Console.
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Debug Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Debug extends Smarty_Internal_CompileBase {
+ /**
+ * Compiles code for the {debug} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler) {
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+
+ // compile always as nocache
+ $compiler->tag_nocache = true;
+
+ // display debug template
+ $_output = "<?php \$_smarty_tpl->smarty->loadPlugin('Smarty_Internal_Debug'); Smarty_Internal_Debug::display_debug(\$_smarty_tpl); ?>";
+
+ return $_output;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_eval.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Eval
+ * Compiles the {eval} tag.
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Eval Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Eval extends Smarty_Internal_CompileBase {
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $required_attributes = array('var');
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $optional_attributes = array('assign');
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $shorttag_order = array('var', 'assign');
+
+ /**
+ * Compiles code for the {eval} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler) {
+ $this->required_attributes = array('var');
+ $this->optional_attributes = array('assign');
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+ if (isset($_attr['assign'])) {
+ // output will be stored in a smarty variable instead of being displayed
+ $_assign = $_attr['assign'];
+ }
+
+ // create template object
+ $_output = "\$_template = new {$compiler->smarty->template_class}('eval:'." . $_attr['var'] . ", \$_smarty_tpl->smarty, \$_smarty_tpl);";
+ //was there an assign attribute?
+ if (isset($_assign)) {
+ $_output .= "\$_smarty_tpl->assign($_assign,\$_template->fetch());";
+ } else {
+ $_output .= "echo \$_template->fetch();";
+ }
+
+ return "<?php $_output ?>";
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_extends.php
@@ -0,0 +1,83 @@
+<?php
+
+/**
+ * Smarty Internal Plugin Compile extend
+ * Compiles the {extends} tag
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile extend Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Extends extends Smarty_Internal_CompileBase {
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $required_attributes = array('file');
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $shorttag_order = array('file');
+
+ /**
+ * Compiles code for the {extends} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler) {
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+ if ($_attr['nocache'] === true) {
+ $compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
+ }
+ if (strpos($_attr['file'], '$_tmp') !== false) {
+ $compiler->trigger_template_error('illegal value for file attribute', $compiler->lex->taglineno);
+ }
+
+ $name = $_attr['file'];
+ /** @var Smarty_Internal_Template $_smarty_tpl
+ * used in evaluated code
+ */
+ $_smarty_tpl = $compiler->template;
+ eval("\$tpl_name = $name;");
+ // create template object
+ $_template = new $compiler->smarty->template_class($tpl_name, $compiler->smarty, $compiler->template);
+ // check for recursion
+ $uid = $_template->source->uid;
+ if (isset($compiler->extends_uid[$uid])) {
+ $compiler->trigger_template_error("illegal recursive call of \"$include_file\"", $compiler->lex->line - 1);
+ }
+ $compiler->extends_uid[$uid] = true;
+ if (empty($_template->source->components)) {
+ array_unshift($compiler->sources, $_template->source);
+ } else {
+ foreach ($_template->source->components as $source) {
+ array_unshift($compiler->sources, $source);
+ $uid = $source->uid;
+ if (isset($compiler->extends_uid[$uid])) {
+ $compiler->trigger_template_error("illegal recursive call of \"{$source->filepath}\"", $compiler->lex->line - 1);
+ }
+ $compiler->extends_uid[$uid] = true;
+ }
+ }
+ unset ($_template);
+ $compiler->inheritance_child = true;
+ $compiler->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBODY);
+ return '';
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_for.php
@@ -0,0 +1,160 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile For
+ * Compiles the {for} {forelse} {/for} tags
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile For Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_For extends Smarty_Internal_CompileBase {
+ /**
+ * Compiles code for the {for} tag
+ * Smarty 3 does implement two different syntax's:
+ * - {for $var in $array}
+ * For looping over arrays or iterators
+ * - {for $x=0; $x<$y; $x++}
+ * For general loops
+ * The parser is generating different sets of attribute by which this compiler can
+ * determine which syntax is used.
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter) {
+ if ($parameter == 0) {
+ $this->required_attributes = array('start', 'to');
+ $this->optional_attributes = array('max', 'step');
+ } else {
+ $this->required_attributes = array('start', 'ifexp', 'var', 'step');
+ $this->optional_attributes = array();
+ }
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+
+ $output = "<?php ";
+ if ($parameter == 1) {
+ foreach ($_attr['start'] as $_statement) {
+ if (is_array($_statement['var'])) {
+ $var = $_statement['var']['var'];
+ $index = $_statement['var']['smarty_internal_index'];
+ } else {
+ $var = $_statement['var'];
+ $index = '';
+ }
+ $output .= " \$_smarty_tpl->tpl_vars[$var] = new Smarty_Variable;";
+ $output .= " \$_smarty_tpl->tpl_vars[$var]->value{$index} = $_statement[value];\n";
+ }
+ if (is_array($_attr['var'])) {
+ $var = $_attr['var']['var'];
+ $index = $_attr['var']['smarty_internal_index'];
+ } else {
+ $var = $_attr['var'];
+ $index = '';
+ }
+ $output .= " if ($_attr[ifexp]) { for (\$_foo=true;$_attr[ifexp]; \$_smarty_tpl->tpl_vars[$var]->value{$index}$_attr[step]) {\n";
+ } else {
+ $_statement = $_attr['start'];
+ if (is_array($_statement['var'])) {
+ $var = $_statement['var']['var'];
+ $index = $_statement['var']['smarty_internal_index'];
+ } else {
+ $var = $_statement['var'];
+ $index = '';
+ }
+ $output .= "\$_smarty_tpl->tpl_vars[$var] = new Smarty_Variable;";
+ if (isset($_attr['step'])) {
+ $output .= "\$_smarty_tpl->tpl_vars[$var]->step = $_attr[step];";
+ } else {
+ $output .= "\$_smarty_tpl->tpl_vars[$var]->step = 1;";
+ }
+ if (isset($_attr['max'])) {
+ $output .= "\$_smarty_tpl->tpl_vars[$var]->total = (int) min(ceil((\$_smarty_tpl->tpl_vars[$var]->step > 0 ? $_attr[to]+1 - ($_statement[value]) : $_statement[value]-($_attr[to])+1)/abs(\$_smarty_tpl->tpl_vars[$var]->step)),$_attr[max]);\n";
+ } else {
+ $output .= "\$_smarty_tpl->tpl_vars[$var]->total = (int) ceil((\$_smarty_tpl->tpl_vars[$var]->step > 0 ? $_attr[to]+1 - ($_statement[value]) : $_statement[value]-($_attr[to])+1)/abs(\$_smarty_tpl->tpl_vars[$var]->step));\n";
+ }
+ $output .= "if (\$_smarty_tpl->tpl_vars[$var]->total > 0) {\n";
+ $output .= "for (\$_smarty_tpl->tpl_vars[$var]->value{$index} = $_statement[value], \$_smarty_tpl->tpl_vars[$var]->iteration = 1;\$_smarty_tpl->tpl_vars[$var]->iteration <= \$_smarty_tpl->tpl_vars[$var]->total;\$_smarty_tpl->tpl_vars[$var]->value{$index} += \$_smarty_tpl->tpl_vars[$var]->step, \$_smarty_tpl->tpl_vars[$var]->iteration++) {\n";
+ $output .= "\$_smarty_tpl->tpl_vars[$var]->first = \$_smarty_tpl->tpl_vars[$var]->iteration == 1;";
+ $output .= "\$_smarty_tpl->tpl_vars[$var]->last = \$_smarty_tpl->tpl_vars[$var]->iteration == \$_smarty_tpl->tpl_vars[$var]->total;";
+ }
+ $output .= "?>";
+
+ $this->openTag($compiler, 'for', array('for', $compiler->nocache));
+ // maybe nocache because of nocache variables
+ $compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
+ // return compiled code
+ return $output;
+ }
+}
+
+/**
+ * Smarty Internal Plugin Compile Forelse Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Forelse extends Smarty_Internal_CompileBase {
+ /**
+ * Compiles code for the {forelse} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter) {
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+
+ list($openTag, $nocache) = $this->closeTag($compiler, array('for'));
+ $this->openTag($compiler, 'forelse', array('forelse', $nocache));
+
+ return "<?php }} else { ?>";
+ }
+}
+
+/**
+ * Smarty Internal Plugin Compile Forclose Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Forclose extends Smarty_Internal_CompileBase {
+ /**
+ * Compiles code for the {/for} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter) {
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+ // must endblock be nocache?
+ if ($compiler->nocache) {
+ $compiler->tag_nocache = true;
+ }
+
+ list($openTag, $compiler->nocache) = $this->closeTag($compiler, array('for', 'forelse'));
+
+ if ($openTag == 'forelse') {
+ return "<?php } ?>";
+ } else {
+ return "<?php }} ?>";
+ }
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_foreach.php
@@ -0,0 +1,282 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Foreach
+ * Compiles the {foreach} {foreachelse} {/foreach} tags
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Foreach Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Foreach extends Smarty_Internal_CompileBase {
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $required_attributes = array('from', 'item');
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $optional_attributes = array('name', 'key');
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $shorttag_order = array('from', 'item', 'key', 'name');
+
+ /**
+ * Compiles code for the {foreach} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter) {
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+
+ $from = $_attr['from'];
+ $item = $_attr['item'];
+ if (!strncmp("\$_smarty_tpl->tpl_vars[$item]", $from, strlen($item) + 24)) {
+ $compiler->trigger_template_error("item variable {$item} may not be the same variable as at 'from'", $compiler->lex->taglineno);
+ }
+
+ if (isset($_attr['key'])) {
+ $key = $_attr['key'];
+ } else {
+ $key = null;
+ }
+
+ $this->openTag($compiler, 'foreach', array('foreach', $compiler->nocache, $item, $key, true));
+ // maybe nocache because of nocache variables
+ $compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
+
+ if (isset($_attr['name'])) {
+ $name = trim($_attr['name'], '\'"');
+ $has_name = true;
+ $SmartyVarName = "\$smarty.foreach.{$name}.";
+ } else {
+ $has_name = false;
+ }
+ $ItemVarName = '$' . trim($item, '\'"') . '@';
+ // evaluates which Smarty variables and properties have to be computed
+
+ if ($has_name) {
+ $useSmartyForeach = $usesSmartyFirst = strpos($compiler->lex->data, $SmartyVarName . 'first') !== false;
+ $useSmartyForeach = ($usesSmartyLast = strpos($compiler->lex->data, $SmartyVarName . 'last') !== false) || $useSmartyForeach;
+ $useSmartyForeach = ($usesSmartyIndex = strpos($compiler->lex->data, $SmartyVarName . 'index') !== false) || $useSmartyForeach;
+ $useSmartyForeach = ($usesSmartyIteration = (!$usesSmartyIndex && ($usesSmartyFirst || $usesSmartyLast)) || strpos($compiler->lex->data, $SmartyVarName . 'iteration') !== false) || $useSmartyForeach;
+ $useSmartyForeach = ($usesSmartyShow = strpos($compiler->lex->data, $SmartyVarName . 'show') !== false) || $useSmartyForeach;
+ $useSmartyForeach = ($usesSmartyTotal = $usesSmartyLast || strpos($compiler->lex->data, $SmartyVarName . 'total') !== false) || $useSmartyForeach;
+ } else {
+ $usesSmartyFirst = false;
+ $usesSmartyLast = false;
+ $usesSmartyTotal = false;
+ $usesSmartyShow = false;
+ $useSmartyForeach = false;
+ }
+
+ $usesPropKey = strpos($compiler->lex->data, $ItemVarName . 'key') !== false;
+ $usesPropFirst = strpos($compiler->lex->data, $ItemVarName . 'first') !== false;
+ $usesPropLast = strpos($compiler->lex->data, $ItemVarName . 'last') !== false;
+ $usesPropIndex = strpos($compiler->lex->data, $ItemVarName . 'index') !== false;
+ $usesPropIteration = (!$usesPropIndex && ($usesPropFirst || $usesPropLast)) || strpos($compiler->lex->data, $ItemVarName . 'iteration') !== false;
+ $usesPropShow = strpos($compiler->lex->data, $ItemVarName . 'show') !== false;
+ $usesPropTotal = $usesPropLast || strpos($compiler->lex->data, $ItemVarName . 'total') !== false;
+
+ $keyTerm = '';
+ if ($usesPropKey) {
+ $keyTerm = "\$_smarty_tpl->tpl_vars[$item]->key => ";
+ } elseif ($key != null) {
+ $keyTerm = "\$_smarty_tpl->tpl_vars[$key]->value => ";
+ }
+ // generate output code
+ $output = "<?php\n";
+ $output .= "\$_from = $from;\n";
+ $output .= "if (!is_array(\$_from) && !is_object(\$_from)) {\n";
+ $output .= "settype(\$_from, 'array');\n";
+ $output .= "}\n";
+ $output .= "\$_smarty_tpl->tpl_vars[$item] = new Smarty_Variable;\n";
+ $output .= "\$_smarty_tpl->tpl_vars[$item]->_loop = false;\n";
+ if ($key != null) {
+ $output .= "\$_smarty_tpl->tpl_vars[$key] = new Smarty_Variable;\n";
+ }
+ if ($usesPropTotal) {
+ $output .= "\$_smarty_tpl->tpl_vars[$item]->total= \$_smarty_tpl->_count(\$_from);\n";
+ }
+ if ($usesPropIteration) {
+ $output .= "\$_smarty_tpl->tpl_vars[$item]->iteration=0;\n";
+ }
+ if ($usesPropIndex) {
+ $output .= "\$_smarty_tpl->tpl_vars[$item]->index=-1;\n";
+ }
+ if ($usesPropShow) {
+ if ($usesPropTotal) {
+ $output .= "\$_smarty_tpl->tpl_vars[$item]->show = (\$_smarty_tpl->tpl_vars[$item]->total > 0);\n";
+ } else {
+ $output .= "\$_smarty_tpl->tpl_vars[$item]->show = (\$_smarty_tpl->_count(\$_from) > 0);\n";
+ }
+ }
+ if ($has_name) {
+ $prop = array();
+ if ($usesSmartyTotal) {
+ $prop['total'] = "'total' => ";
+ $prop['total'] .= $usesSmartyShow ? '$total = ' : '';
+ $prop['total'] .= '$_smarty_tpl->_count($_from)';
+ }
+ if ($usesSmartyIteration) {
+ $prop['iteration'] = "'iteration' => 0";
+ }
+ if ($usesSmartyIndex) {
+ $prop['index'] = "'index' => -1";
+ }
+ if ($usesSmartyShow) {
+ $prop['show'] = "'show' => ";
+ if ($usesSmartyTotal) {
+ $prop['show'] .= "(\$total > 0)";
+ } else {
+ $prop['show'] .= "(\$_smarty_tpl->_count(\$_from) > 0)";
+ }
+ }
+ if ($useSmartyForeach) {
+ $_vars = 'array(' . join(', ', $prop) . ')';
+ $foreachVar = "'__foreach_{$name}'";
+ $output .= "\$_smarty_tpl->tpl_vars[$foreachVar] = new Smarty_Variable({$_vars});\n";
+ }
+ }
+ $output .= "foreach (\$_from as {$keyTerm}\$_smarty_tpl->tpl_vars[$item]->value) {\n";
+ $output .= "\$_smarty_tpl->tpl_vars[$item]->_loop = true;\n";
+ if ($key != null && $usesPropKey) {
+ $output .= "\$_smarty_tpl->tpl_vars[$key]->value = \$_smarty_tpl->tpl_vars[$item]->key;\n";
+ }
+ if ($usesPropIteration) {
+ $output .= "\$_smarty_tpl->tpl_vars[$item]->iteration++;\n";
+ }
+ if ($usesPropIndex) {
+ $output .= "\$_smarty_tpl->tpl_vars[$item]->index++;\n";
+ }
+ if ($usesPropFirst) {
+ if ($usesPropIndex) {
+ $output .= "\$_smarty_tpl->tpl_vars[$item]->first = \$_smarty_tpl->tpl_vars[$item]->index == 0;\n";
+ } else {
+ $output .= "\$_smarty_tpl->tpl_vars[$item]->first = \$_smarty_tpl->tpl_vars[$item]->iteration == 1;\n";
+ }
+ }
+ if ($usesPropLast) {
+ if ($usesPropIndex) {
+ $output .= "\$_smarty_tpl->tpl_vars[$item]->last = \$_smarty_tpl->tpl_vars[$item]->index + 1 == \$_smarty_tpl->tpl_vars[$item]->total;\n";
+ } else {
+ $output .= "\$_smarty_tpl->tpl_vars[$item]->last = \$_smarty_tpl->tpl_vars[$item]->iteration == \$_smarty_tpl->tpl_vars[$item]->total;\n";
+ }
+ }
+ if ($has_name) {
+ if ($usesSmartyIteration) {
+ $output .= "\$_smarty_tpl->tpl_vars[$foreachVar]->value['iteration']++;\n";
+ }
+ if ($usesSmartyIndex) {
+ $output .= "\$_smarty_tpl->tpl_vars[$foreachVar]->value['index']++;\n";
+ }
+ if ($usesSmartyFirst) {
+ if ($usesSmartyIndex) {
+ $output .= "\$_smarty_tpl->tpl_vars[$foreachVar]->value['first'] = \$_smarty_tpl->tpl_vars[$foreachVar]->value['index'] == 0;\n";
+ } else {
+ $output .= "\$_smarty_tpl->tpl_vars[$foreachVar]->value['first'] = \$_smarty_tpl->tpl_vars[$foreachVar]->value['iteration'] == 1;\n";
+ }
+ }
+ if ($usesSmartyLast) {
+ if ($usesSmartyIndex) {
+ $output .= "\$_smarty_tpl->tpl_vars[$foreachVar]->value['last'] = \$_smarty_tpl->tpl_vars[$foreachVar]->value['index'] + 1 == \$_smarty_tpl->tpl_vars[$foreachVar]->value['total'];\n";
+ } else {
+ $output .= "\$_smarty_tpl->tpl_vars[$foreachVar]->value['last'] = \$_smarty_tpl->tpl_vars[$foreachVar]->value['iteration'] == \$_smarty_tpl->tpl_vars[$foreachVar]->value['total'];\n";
+ }
+ }
+ }
+ $itemName = trim($item, "'\"");
+ $output .= "\$foreach_{$itemName}_Sav = \$_smarty_tpl->tpl_vars[$item];\n";
+ $output .= "?>";
+
+ return $output;
+ }
+}
+
+/**
+ * Smarty Internal Plugin Compile Foreachelse Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Foreachelse extends Smarty_Internal_CompileBase {
+ /**
+ * Compiles code for the {foreachelse} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter) {
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+
+ list($openTag, $nocache, $item, $key, $foo) = $this->closeTag($compiler, array('foreach'));
+ $this->openTag($compiler, 'foreachelse', array('foreachelse', $nocache, $item, $key, false));
+ $itemName = trim($item, "'\"");
+ $output = "<?php\n";
+ $output .= "\$_smarty_tpl->tpl_vars[$item] = \$foreach_{$itemName}_Sav;\n";
+ $output .= "}\n";
+ $output .= "if (!\$_smarty_tpl->tpl_vars[$item]->_loop) {\n?>";
+ return $output;
+ }
+}
+
+/**
+ * Smarty Internal Plugin Compile Foreachclose Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Foreachclose extends Smarty_Internal_CompileBase {
+ /**
+ * Compiles code for the {/foreach} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter) {
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+ // must endblock be nocache?
+ if ($compiler->nocache) {
+ $compiler->tag_nocache = true;
+ }
+
+ list($openTag, $compiler->nocache, $item, $key, $restore) = $this->closeTag($compiler, array('foreach', 'foreachelse'));
+ $itemName = trim($item, "'\"");
+ $output = "<?php\n";
+ if ($restore) {
+ $output .= "\$_smarty_tpl->tpl_vars[$item] = \$foreach_{$itemName}_Sav;\n";
+ }
+ $output .= "}\n?>";
+
+ return $output;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_function.php
@@ -0,0 +1,225 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Function
+ * Compiles the {function} {/function} tags
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Function Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Function extends Smarty_Internal_CompileBase {
+
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $required_attributes = array('name');
+
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $shorttag_order = array('name');
+
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $optional_attributes = array('_any');
+
+ /**
+ * Compiles code for the {function} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ *
+ * @return boolean true
+ */
+ public function compile($args, $compiler, $parameter) {
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+
+ if ($_attr['nocache'] === true) {
+ $compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
+ }
+ unset($_attr['nocache']);
+ $_name = trim($_attr['name'], "'\"");
+ $compiler->parent_compiler->templateProperties['tpl_function'][$_name] = array();
+ $save = array($_attr, $compiler->parser->current_buffer, $compiler->template->has_nocache_code, $compiler->template->required_plugins, $compiler->template->caching);
+ $this->openTag($compiler, 'function', $save);
+ // set flag that we are compiling a template function
+ $compiler->compiles_template_function = true;
+ // Init temporary context
+ $compiler->template->required_plugins = array('compiled' => array(), 'nocache' => array());
+ $compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template($compiler->parser);
+ $compiler->template->has_nocache_code = false;
+ $compiler->template->caching = true;
+ return true;
+ }
+}
+
+/**
+ * Smarty Internal Plugin Compile Functionclose Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Functionclose extends Smarty_Internal_CompileBase {
+
+ /**
+ * Compiler object
+ *
+ * @var object
+ */
+ private $compiler = null;
+
+ /**
+ * Compiles code for the {/function} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object|\Smarty_Internal_TemplateCompilerBase $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ *
+ * @return bool true
+ */
+ public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter) {
+ $this->compiler = $compiler;
+ $saved_data = $this->closeTag($compiler, array('function'));
+ $_attr = $saved_data[0];
+ $_name = trim($_attr['name'], "'\"");
+ // reset flag that we are compiling a template function
+ $compiler->compiles_template_function = false;
+ $compiler->parent_compiler->templateProperties['tpl_function'][$_name]['called_functions'] = $compiler->called_functions;
+ $compiler->parent_compiler->templateProperties['tpl_function'][$_name]['compiled_filepath'] = $compiler->parent_compiler->template->compiled->filepath;
+ $compiler->parent_compiler->templateProperties['tpl_function'][$_name]['uid'] = $compiler->template->source->uid;
+ $compiler->called_functions = array();
+ $_parameter = $_attr;
+ unset($_parameter['name']);
+ // default parameter
+ $_paramsArray = array();
+ foreach ($_parameter as $_key => $_value) {
+ if (is_int($_key)) {
+ $_paramsArray[] = "$_key=>$_value";
+ } else {
+ $_paramsArray[] = "'$_key'=>$_value";
+ }
+ }
+ if (!empty($_paramsArray)) {
+ $_params = 'array(' . implode(",", $_paramsArray) . ')';
+ $_paramsCode = "\$params = array_merge($_params, \$params);\n";
+ } else {
+ $_paramsCode = '';
+ }
+ $_functionCode = $compiler->parser->current_buffer;
+ // setup buffer for template function code
+ $compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template($compiler->parser);
+
+ $_funcName = "smarty_template_function_{$_name}_{$compiler->template->properties['nocache_hash']}";
+ $_funcNameCaching = $_funcName . '_nocache';
+ if ($compiler->template->has_nocache_code) {
+ $compiler->parent_compiler->templateProperties['tpl_function'][$_name]['call_name_caching'] = $_funcNameCaching;
+ $output = "<?php\n";
+ $output .= "/* {$_funcNameCaching} */\n";
+ $output .= "if (!function_exists('{$_funcNameCaching}')) {\n";
+ $output .= "function {$_funcNameCaching} (\$_smarty_tpl,\$params) {\n";
+ // build plugin include code
+ if (!empty($compiler->template->required_plugins['compiled'])) {
+ foreach ($compiler->template->required_plugins['compiled'] as $tmp) {
+ foreach ($tmp as $data) {
+ $output .= "if (!is_callable('{$data['function']}')) require_once '{$data['file']}';\n";
+ }
+ }
+ }
+ if (!empty($compiler->template->required_plugins['nocache'])) {
+ $output .= "echo '/*%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%*/<?php ";
+ foreach ($compiler->template->required_plugins['nocache'] as $tmp) {
+ foreach ($tmp as $data) {
+ $output .= "if (!is_callable(\'{$data['function']}\')) require_once \'{$data['file']}\';\n";
+ }
+ }
+ $output .= "?>/*/%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%*/';\n";
+ }
+ $output .= "ob_start();\n";
+ $output .= $_paramsCode;
+ $output .= "\$_smarty_tpl->properties['saved_tpl_vars'][] = \$_smarty_tpl->tpl_vars;\n";
+ $output .= "foreach (\$params as \$key => \$value) {\n\$_smarty_tpl->tpl_vars[\$key] = new Smarty_Variable(\$value);\n}";
+ $output .= "\$params = var_export(\$params, true);\n";
+ $output .= "echo \"/*%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%*/<?php ";
+ $output .= "\\\$saved_tpl_vars = \\\$_smarty_tpl->tpl_vars;\nforeach (\$params as \\\$key => \\\$value) {\n\\\$_smarty_tpl->tpl_vars[\\\$key] = new Smarty_Variable(\\\$value);\n}\n?>";
+ $output .= "/*/%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%*/\n\";?>";
+ $compiler->parser->current_buffer->append_subtree(new Smarty_Internal_ParseTree_Tag($compiler->parser, $output));
+ $compiler->parser->current_buffer->append_subtree($_functionCode);
+ $output = "<?php echo \"/*%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%*/<?php ";
+ $output .= "foreach (Smarty::\\\$global_tpl_vars as \\\$key => \\\$value){\n";
+ $output .= "if (\\\$_smarty_tpl->tpl_vars[\\\$key] === \\\$value) \\\$saved_tpl_vars[\\\$key] = \\\$value;\n}\n";
+ $output .= "\\\$_smarty_tpl->tpl_vars = \\\$saved_tpl_vars;?>\n";
+ $output .= "/*/%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%*/\";\n?>";
+ $output .= "<?php echo str_replace('{$compiler->template->properties['nocache_hash']}', \$_smarty_tpl->properties['nocache_hash'], ob_get_clean());\n";
+ $output .= "\$_smarty_tpl->tpl_vars = array_pop(\$_smarty_tpl->properties['saved_tpl_vars']);\n}\n}\n";
+ $output .= "/*/ {$_funcName}_nocache */\n\n";
+ $output .= "?>\n";
+ $compiler->parser->current_buffer->append_subtree(new Smarty_Internal_ParseTree_Tag($compiler->parser, $output));
+ $_functionCode = new Smarty_Internal_ParseTree_Tag($compiler->parser, preg_replace_callback("/((<\?php )?echo '\/\*%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%\*\/([\S\s]*?)\/\*\/%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%\*\/';(\?>\n)?)/", array($this, 'removeNocache'), $_functionCode->to_smarty_php()));
+ }
+ $compiler->parent_compiler->templateProperties['tpl_function'][$_name]['call_name'] = $_funcName;
+ $output = "<?php\n";
+ $output .= "/* {$_funcName} */\n";
+ $output .= "if (!function_exists('{$_funcName}')) {\n";
+ $output .= "function {$_funcName}(\$_smarty_tpl,\$params) {\n";
+ // build plugin include code
+ if (!empty($compiler->template->required_plugins['nocache'])) {
+ $compiler->template->required_plugins['compiled'] = array_merge($compiler->template->required_plugins['compiled'], $compiler->template->required_plugins['nocache']);
+ }
+ if (!empty($compiler->template->required_plugins['compiled'])) {
+ foreach ($compiler->template->required_plugins['compiled'] as $tmp) {
+ foreach ($tmp as $data) {
+ $output .= "if (!is_callable('{$data['function']}')) require_once '{$data['file']}';\n";
+ }
+ }
+ }
+ $output .= "\$saved_tpl_vars = \$_smarty_tpl->tpl_vars;\n";
+ $output .= $_paramsCode;
+ $output .= "foreach (\$params as \$key => \$value) {\n\$_smarty_tpl->tpl_vars[\$key] = new Smarty_Variable(\$value);\n}?>";
+ $compiler->parser->current_buffer->append_subtree(new Smarty_Internal_ParseTree_Tag($compiler->parser, $output));
+ $compiler->parser->current_buffer->append_subtree($_functionCode);
+ $output = "<?php foreach (Smarty::\$global_tpl_vars as \$key => \$value){\n";
+ $output .= "if (\$_smarty_tpl->tpl_vars[\$key] === \$value) \$saved_tpl_vars[\$key] = \$value;\n}\n";
+ $output .= "\$_smarty_tpl->tpl_vars = \$saved_tpl_vars;\n}\n}\n";
+ $output .= "/*/ {$_funcName} */\n\n";
+ $output .= "?>\n";
+ $compiler->parser->current_buffer->append_subtree(new Smarty_Internal_ParseTree_Tag($compiler->parser, $output));
+ $compiler->parent_compiler->templateFunctionCode .= $compiler->parser->current_buffer->to_smarty_php();
+ // restore old buffer
+ $compiler->parser->current_buffer = $saved_data[1];
+ // restore old status
+ $compiler->template->has_nocache_code = $saved_data[2];
+ $compiler->template->required_plugins = $saved_data[3];
+ $compiler->template->caching = $saved_data[4];
+ return true;
+ }
+
+ /**
+ * @param $match
+ *
+ * @return mixed
+ */
+ function removeNocache($match) {
+ $code = preg_replace("/((<\?php )?echo '\/\*%%SmartyNocache:{$this->compiler->template->properties['nocache_hash']}%%\*\/)|(\/\*\/%%SmartyNocache:{$this->compiler->template->properties['nocache_hash']}%%\*\/';(\?>\n)?)/", '', $match[0]);
+ $code = str_replace(array('\\\'', '\\\\\''), array('\'', '\\\''), $code);
+ return $code;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_if.php
@@ -0,0 +1,213 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile If
+ * Compiles the {if} {else} {elseif} {/if} tags
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile If Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_If extends Smarty_Internal_CompileBase {
+ /**
+ * Compiles code for the {if} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter) {
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+ $this->openTag($compiler, 'if', array(1, $compiler->nocache));
+ // must whole block be nocache ?
+ $compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
+
+ if (!array_key_exists("if condition", $parameter)) {
+ $compiler->trigger_template_error("missing if condition", $compiler->lex->taglineno);
+ }
+
+ if (is_array($parameter['if condition'])) {
+ if ($compiler->nocache) {
+ $_nocache = ',true';
+ // create nocache var to make it know for further compiling
+ if (is_array($parameter['if condition']['var'])) {
+ $var = trim($parameter['if condition']['var']['var'], "'");
+ } else {
+ $var = trim($parameter['if condition']['var'], "'");
+ }
+ if (isset($compiler->template->tpl_vars[$var])) {
+ $compiler->template->tpl_vars[$var]->nocache = true;
+ } else {
+ $compiler->template->tpl_vars[$var] = new Smarty_Variable(null, true);
+ }
+ } else {
+ $_nocache = '';
+ }
+ if (is_array($parameter['if condition']['var'])) {
+ $_output = "<?php if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]) || !is_array(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value)) \$_smarty_tpl->createLocalArrayVariable(" . $parameter['if condition']['var']['var'] . "$_nocache);\n";
+ $_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value" . $parameter['if condition']['var']['smarty_internal_index'] . " = " . $parameter['if condition']['value'] . ") {?>";
+ } else {
+ $_output = "<?php if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "])) \$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "] = new Smarty_Variable(null{$_nocache});";
+ $_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "]->value = " . $parameter['if condition']['value'] . ") {?>";
+ }
+
+ return $_output;
+ } else {
+ return "<?php if ({$parameter['if condition']}) {?>";
+ }
+ }
+}
+
+/**
+ * Smarty Internal Plugin Compile Else Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Else extends Smarty_Internal_CompileBase {
+ /**
+ * Compiles code for the {else} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter) {
+ list($nesting, $compiler->tag_nocache) = $this->closeTag($compiler, array('if', 'elseif'));
+ $this->openTag($compiler, 'else', array($nesting, $compiler->tag_nocache));
+
+ return "<?php } else { ?>";
+ }
+}
+
+/**
+ * Smarty Internal Plugin Compile ElseIf Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Elseif extends Smarty_Internal_CompileBase {
+ /**
+ * Compiles code for the {elseif} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter) {
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+
+ list($nesting, $compiler->tag_nocache) = $this->closeTag($compiler, array('if', 'elseif'));
+
+ if (!array_key_exists("if condition", $parameter)) {
+ $compiler->trigger_template_error("missing elseif condition", $compiler->lex->taglineno);
+ }
+
+ if (is_array($parameter['if condition'])) {
+ $condition_by_assign = true;
+ if ($compiler->nocache) {
+ $_nocache = ',true';
+ // create nocache var to make it know for further compiling
+ if (is_array($parameter['if condition']['var'])) {
+ $var = trim($parameter['if condition']['var']['var'], "'");
+ } else {
+ $var = trim($parameter['if condition']['var'], "'");
+ }
+ if (isset($compiler->template->tpl_vars[$var])) {
+ $compiler->template->tpl_vars[$var]->nocache = true;
+ } else {
+ $compiler->template->tpl_vars[$var] = new Smarty_Variable(null, true);
+ }
+ } else {
+ $_nocache = '';
+ }
+ } else {
+ $condition_by_assign = false;
+ }
+
+ if (empty($compiler->prefix_code)) {
+ if ($condition_by_assign) {
+ $this->openTag($compiler, 'elseif', array($nesting + 1, $compiler->tag_nocache));
+ if (is_array($parameter['if condition']['var'])) {
+ $_output = "<?php } else { if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]) || !is_array(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value)) \$_smarty_tpl->createLocalArrayVariable(" . $parameter['if condition']['var']['var'] . "$_nocache);\n";
+ $_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value" . $parameter['if condition']['var']['smarty_internal_index'] . " = " . $parameter['if condition']['value'] . ") {?>";
+ } else {
+ $_output = "<?php } else { if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "])) \$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "] = new Smarty_Variable(null{$_nocache});";
+ $_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "]->value = " . $parameter['if condition']['value'] . ") {?>";
+ }
+
+ return $_output;
+ } else {
+ $this->openTag($compiler, 'elseif', array($nesting, $compiler->tag_nocache));
+
+ return "<?php } elseif ({$parameter['if condition']}) {?>";
+ }
+ } else {
+ $tmp = '';
+ foreach ($compiler->prefix_code as $code) {
+ $tmp = $compiler->appendCode($tmp, $code);
+ }
+ $compiler->prefix_code = array();
+ $tmp = $compiler->appendCode("<?php } else {?>", $tmp);
+ $this->openTag($compiler, 'elseif', array($nesting + 1, $compiler->tag_nocache));
+ if ($condition_by_assign) {
+ if (is_array($parameter['if condition']['var'])) {
+ $_output = $compiler->appendCode($tmp, "<?php if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]) || !is_array(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value)) \$_smarty_tpl->createLocalArrayVariable(" . $parameter['if condition']['var']['var'] . "$_nocache);\n");
+ $_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value" . $parameter['if condition']['var']['smarty_internal_index'] . " = " . $parameter['if condition']['value'] . ") {?>";
+ } else {
+ $_output = $compiler->appendCode($tmp, "<?php if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "])) \$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "] = new Smarty_Variable(null{$_nocache});");
+ $_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "]->value = " . $parameter['if condition']['value'] . ") {?>";
+ }
+
+ return $_output;
+ } else {
+ return $compiler->appendCode($tmp, "<?php if ({$parameter['if condition']}) {?>");
+ }
+ }
+ }
+}
+
+/**
+ * Smarty Internal Plugin Compile Ifclose Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Ifclose extends Smarty_Internal_CompileBase {
+ /**
+ * Compiles code for the {/if} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter) {
+ // must endblock be nocache?
+ if ($compiler->nocache) {
+ $compiler->tag_nocache = true;
+ }
+ list($nesting, $compiler->nocache) = $this->closeTag($compiler, array('if', 'else', 'elseif'));
+ $tmp = '';
+ for ($i = 0; $i < $nesting; $i++) {
+ $tmp .= '}';
+ }
+
+ return "<?php {$tmp}?>";
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_include.php
@@ -0,0 +1,296 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Include
+ * Compiles the {include} tag
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Include Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase {
+ /**
+ * caching mode to create nocache code but no cache file
+ */
+ const CACHING_NOCACHE_CODE = 9999;
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $required_attributes = array('file');
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $shorttag_order = array('file');
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $option_flags = array('nocache', 'inline', 'caching');
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $optional_attributes = array('_any');
+
+ /**
+ * Compiles code for the {include} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param Smarty_Internal_SmartyTemplateCompiler $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ *
+ * @throws SmartyCompilerException
+ * @return string compiled code
+ */
+ public function compile($args, Smarty_Internal_SmartyTemplateCompiler $compiler, $parameter) {
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+
+ // save possible attributes
+ $include_file = $_attr['file'];
+
+ if (isset($_attr['assign'])) {
+ // output will be stored in a smarty variable instead of being displayed
+ $_assign = $_attr['assign'];
+ }
+
+ $_parent_scope = Smarty::SCOPE_LOCAL;
+ if (isset($_attr['scope'])) {
+ $_attr['scope'] = trim($_attr['scope'], "'\"");
+ if ($_attr['scope'] == 'parent') {
+ $_parent_scope = Smarty::SCOPE_PARENT;
+ } elseif ($_attr['scope'] == 'root') {
+ $_parent_scope = Smarty::SCOPE_ROOT;
+ } elseif ($_attr['scope'] == 'global') {
+ $_parent_scope = Smarty::SCOPE_GLOBAL;
+ }
+ }
+
+ // assume caching is off
+ $_caching = Smarty::CACHING_OFF;
+
+ if ($_attr['nocache'] === true) {
+ $compiler->tag_nocache = true;
+ }
+
+ $call_nocache = $compiler->tag_nocache || $compiler->nocache;
+
+ // caching was on and {include} is not in nocache mode
+ if ($compiler->template->caching && !$compiler->nocache && !$compiler->tag_nocache) {
+ $_caching = self::CACHING_NOCACHE_CODE;
+ }
+
+ // flag if included template code should be merged into caller
+ $merge_compiled_includes = ($compiler->smarty->merge_compiled_includes || ($compiler->inheritance && $compiler->smarty->inheritance_merge_compiled_includes) || $_attr['inline'] === true) && !$compiler->template->source->recompiled;
+
+ if ($merge_compiled_includes && $_attr['inline'] !== true) {
+ // variable template name ?
+ if ($compiler->has_variable_string || !((substr_count($include_file, '"') == 2 || substr_count($include_file, "'") == 2)) || substr_count($include_file, '(') != 0 || substr_count($include_file, '$_smarty_tpl->') != 0) {
+ $merge_compiled_includes = false;
+ if ($compiler->template->caching) {
+ // must use individual cache file
+ //$_attr['caching'] = 1;
+ }
+ if ($compiler->inheritance && $compiler->smarty->inheritance_merge_compiled_includes && $_attr['inline'] !== true) {
+ $compiler->trigger_template_error(' variable template file names not allow within {block} tags');
+ }
+ }
+ // variable compile_id?
+ if (isset($_attr['compile_id'])) {
+ if (!((substr_count($_attr['compile_id'], '"') == 2 || substr_count($_attr['compile_id'], "'") == 2 || is_numeric($_attr['compile_id']))) || substr_count($_attr['compile_id'], '(') != 0 || substr_count($_attr['compile_id'], '$_smarty_tpl->') != 0) {
+ $merge_compiled_includes = false;
+ if ($compiler->template->caching) {
+ // must use individual cache file
+ //$_attr['caching'] = 1;
+ }
+ if ($compiler->inheritance && $compiler->smarty->inheritance_merge_compiled_includes && $_attr['inline'] !== true) {
+ $compiler->trigger_template_error(' variable compile_id not allow within {block} tags');
+ }
+ }
+ }
+ }
+
+ /*
+ * if the {include} tag provides individual parameter for caching or compile_id
+ * the subtemplate must not be included into the common cache file and is treated like
+ * a call in nocache mode.
+ *
+ */
+ if ($_attr['nocache'] !== true && $_attr['caching']) {
+ $_caching = $_new_caching = (int)$_attr['caching'];
+ $call_nocache = true;
+ } else {
+ $_new_caching = Smarty::CACHING_LIFETIME_CURRENT;
+ }
+ if (isset($_attr['cache_lifetime'])) {
+ $_cache_lifetime = $_attr['cache_lifetime'];
+ $call_nocache = true;
+ $_caching = $_new_caching;
+ } else {
+ $_cache_lifetime = '$_smarty_tpl->cache_lifetime';
+ }
+ if (isset($_attr['cache_id'])) {
+ $_cache_id = $_attr['cache_id'];
+ $call_nocache = true;
+ $_caching = $_new_caching;
+ } else {
+ $_cache_id = '$_smarty_tpl->cache_id';
+ }
+ if (isset($_attr['compile_id'])) {
+ $_compile_id = $_attr['compile_id'];
+ } else {
+ $_compile_id = '$_smarty_tpl->compile_id';
+ }
+
+ // if subtemplate will be called in nocache mode do not merge
+ if ($compiler->template->caching && $call_nocache) {
+ $merge_compiled_includes = false;
+ }
+
+ $has_compiled_template = false;
+ if ($merge_compiled_includes) {
+ if ($compiler->template->caching && ($compiler->tag_nocache || $compiler->nocache) && $_caching != self::CACHING_NOCACHE_CODE) {
+ // $merge_compiled_includes = false;
+ if ($compiler->inheritance && $compiler->smarty->inheritance_merge_compiled_includes) {
+ $compiler->trigger_template_error(' invalid caching mode of subtemplate within {block} tags');
+ }
+ }
+ $c_id = isset($_attr['compile_id']) ? $_attr['compile_id'] : $compiler->template->compile_id;
+ // we must observe different compile_id and caching
+ $uid = sha1($c_id . ($_caching ? '--caching' : '--nocaching'));
+ $tpl_name = null;
+
+ /** @var Smarty_Internal_Template $_smarty_tpl
+ * used in evaluated code
+ */
+ $_smarty_tpl = $compiler->template;
+ eval("\$tpl_name = $include_file;");
+ if (!isset($compiler->parent_compiler->mergedSubTemplatesData[$tpl_name][$uid])) {
+ $compiler->smarty->allow_ambiguous_resources = true;
+ $tpl = new $compiler->smarty->template_class ($tpl_name, $compiler->smarty, $compiler->template, $compiler->template->cache_id, $c_id, $_caching);
+ // save unique function name
+ $compiler->parent_compiler->mergedSubTemplatesData[$tpl_name][$uid]['func'] = $tpl->properties['unifunc'] = 'content_' . str_replace(array('.', ','), '_', uniqid('', true));
+ if ($compiler->inheritance) {
+ $tpl->compiler->inheritance = true;
+ }
+ // make sure whole chain gets compiled
+ $tpl->mustCompile = true;
+ if (!($tpl->source->uncompiled) && $tpl->source->exists) {
+ $tpl->compiler->suppressTemplatePropertyHeader = true;
+ $compiler->parent_compiler->mergedSubTemplatesData[$tpl_name][$uid]['nocache_hash'] = $tpl->properties['nocache_hash'] = str_replace(array('.', ','), '_', uniqid(rand(), true));
+ // get compiled code
+ $compiled_code = Smarty_Internal_Extension_CodeFrame::createFunctionFrame($tpl, $tpl->compiler->compileTemplate($tpl, null, $compiler->parent_compiler));
+ unset($tpl->compiler);
+
+ // remove header code
+ $compiled_code = preg_replace("/(<\?php \/\*%%SmartyHeaderCode:{$tpl->properties['nocache_hash']}%%\*\/(.+?)\/\*\/%%SmartyHeaderCode%%\*\/\?>\n)/s", '', $compiled_code);
+ if ($tpl->has_nocache_code) {
+ // replace nocache_hash
+ $compiled_code = str_replace("{$tpl->properties['nocache_hash']}", $compiler->template->properties['nocache_hash'], $compiled_code);
+ $compiler->template->has_nocache_code = true;
+ }
+ $compiler->parent_compiler->mergedSubTemplatesCode[$tpl->properties['unifunc']] = $compiled_code;
+ $has_compiled_template = true;
+ if (!empty($tpl->required_plugins['compiled'])) {
+ foreach ($tpl->required_plugins['compiled'] as $name => $callBack) {
+ if (!isset($compiler->template->required_plugins['compiled'][$name])) {
+ $compiler->template->required_plugins['compiled'][$name] = $callBack;
+ }
+ }
+ }
+ if (!empty($tpl->required_plugins['nocache'])) {
+ foreach ($tpl->required_plugins['nocache'] as $name => $callBack) {
+ if (!isset($compiler->template->required_plugins['nocache'][$name])) {
+ $compiler->template->required_plugins['nocache'][$name] = $callBack;
+ }
+ }
+ }
+ unset ($tpl);
+ }
+ } else {
+ $has_compiled_template = true;
+ }
+ }
+ // delete {include} standard attributes
+ unset($_attr['file'], $_attr['assign'], $_attr['cache_id'], $_attr['compile_id'], $_attr['cache_lifetime'], $_attr['nocache'], $_attr['caching'], $_attr['scope'], $_attr['inline']);
+ // remaining attributes must be assigned as smarty variable
+ $_vars_nc = '';
+ if (!empty($_attr)) {
+ if ($_parent_scope == Smarty::SCOPE_LOCAL) {
+ $_pairs = array();
+ // create variables
+ foreach ($_attr as $key => $value) {
+ $_pairs[] = "'$key'=>$value";
+ $_vars_nc .= "\$_smarty_tpl->tpl_vars['$key'] = new Smarty_Variable($value);\n";
+ }
+ $_vars = 'array(' . join(',', $_pairs) . ')';
+ } else {
+ $compiler->trigger_template_error('variable passing not allowed in parent/global scope', $compiler->lex->taglineno);
+ }
+ } else {
+ $_vars = 'array()';
+ }
+ $update_compile_id = $compiler->template->caching && !$compiler->tag_nocache && !$compiler->nocache && $_compile_id != '$_smarty_tpl->compile_id';
+ if ($has_compiled_template && !$call_nocache) {
+ // if ($has_compiled_template && !$compiler->tag_nocache && !$compiler->nocache) {
+ // never call inline templates in nocache mode
+ //$compiler->suppressNocacheProcessing = true;
+ $_hash = $compiler->parent_compiler->mergedSubTemplatesData[$tpl_name][$uid]['nocache_hash'];
+ $_output = "<?php /* Call merged included template \"" . $tpl_name . "\" */\n";
+ if ($update_compile_id) {
+ $_output .= $compiler->makeNocacheCode("\$_compile_id_save[] = \$_smarty_tpl->compile_id;\n\$_smarty_tpl->compile_id = {$_compile_id};\n");
+ }
+ if (!empty($_vars_nc) && $_caching == 9999 && $_smarty_tpl->caching) {
+ //$compiler->suppressNocacheProcessing = false;
+ $_output .= substr($compiler->processNocacheCode('<?php ' . $_vars_nc . "?>\n", true), 6, -3);
+ //$compiler->suppressNocacheProcessing = true;
+ }
+ if (isset($_assign)) {
+ $_output .= " \$_smarty_tpl->tpl_vars[$_assign] = new Smarty_Variable(\$_smarty_tpl->getInlineSubTemplate({$include_file}, {$_cache_id}, {$_compile_id}, {$_caching}, {$_cache_lifetime}, {$_vars}, {$_parent_scope}, '{$_hash}', '{$compiler->parent_compiler->mergedSubTemplatesData[$tpl_name][$uid]['func']}'));\n";
+ } else {
+ $_output .= "echo \$_smarty_tpl->getInlineSubTemplate({$include_file}, {$_cache_id}, {$_compile_id}, {$_caching}, {$_cache_lifetime}, {$_vars}, {$_parent_scope}, '{$_hash}', '{$compiler->parent_compiler->mergedSubTemplatesData[$tpl_name][$uid]['func']}');\n";
+ }
+ if ($update_compile_id) {
+ $_output .= $compiler->makeNocacheCode("\$_smarty_tpl->compile_id = array_pop(\$_compile_id_save);\n");
+ }
+ $_output .= "/* End of included template \"" . $tpl_name . "\" */?>\n";
+
+ return $_output;
+ }
+
+ if ($call_nocache) {
+ $compiler->tag_nocache = true;
+ }
+ $_output = "<?php ";
+ if ($update_compile_id) {
+ $_output .= "\$_compile_id_save[] = \$_smarty_tpl->compile_id;\n\$_smarty_tpl->compile_id = {$_compile_id};\n";
+ }
+ // was there an assign attribute
+ if (isset($_assign)) {
+ $_output .= "\$_smarty_tpl->tpl_vars[$_assign] = new Smarty_Variable(\$_smarty_tpl->getSubTemplate ($include_file, $_cache_id, $_compile_id, $_caching, $_cache_lifetime, $_vars, $_parent_scope));\n";
+ } else {
+ $_output .= "echo \$_smarty_tpl->getSubTemplate ($include_file, $_cache_id, $_compile_id, $_caching, $_cache_lifetime, $_vars, $_parent_scope);\n";
+ }
+ if ($update_compile_id) {
+ $_output .= "\$_smarty_tpl->compile_id = array_pop(\$_compile_id_save);\n";
+ }
+ $_output .= "?>\n";
+ return $_output;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_include_php.php
@@ -0,0 +1,105 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Include PHP
+ * Compiles the {include_php} tag
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Insert Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Include_Php extends Smarty_Internal_CompileBase {
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $required_attributes = array('file');
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $shorttag_order = array('file');
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $optional_attributes = array('once', 'assign');
+
+ /**
+ * Compiles code for the {include_php} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ *
+ * @throws SmartyException
+ * @return string compiled code
+ */
+ public function compile($args, $compiler) {
+ if (!($compiler->smarty instanceof SmartyBC)) {
+ throw new SmartyException("{include_php} is deprecated, use SmartyBC class to enable");
+ }
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+
+ /** @var Smarty_Internal_Template $_smarty_tpl
+ * used in evaluated code
+ */
+ $_smarty_tpl = $compiler->template;
+ $_filepath = false;
+ eval('$_file = ' . $_attr['file'] . ';');
+ if (!isset($compiler->smarty->security_policy) && file_exists($_file)) {
+ $_filepath = $_file;
+ } else {
+ if (isset($compiler->smarty->security_policy)) {
+ $_dir = $compiler->smarty->security_policy->trusted_dir;
+ } else {
+ $_dir = $compiler->smarty->trusted_dir;
+ }
+ if (!empty($_dir)) {
+ foreach ((array)$_dir as $_script_dir) {
+ $_script_dir = rtrim($_script_dir, '/\\') . DS;
+ if (file_exists($_script_dir . $_file)) {
+ $_filepath = $_script_dir . $_file;
+ break;
+ }
+ }
+ }
+ }
+ if ($_filepath == false) {
+ $compiler->trigger_template_error("{include_php} file '{$_file}' is not readable", $compiler->lex->taglineno);
+ }
+
+ if (isset($compiler->smarty->security_policy)) {
+ $compiler->smarty->security_policy->isTrustedPHPDir($_filepath);
+ }
+
+ if (isset($_attr['assign'])) {
+ // output will be stored in a smarty variable instead of being displayed
+ $_assign = $_attr['assign'];
+ }
+ $_once = '_once';
+ if (isset($_attr['once'])) {
+ if ($_attr['once'] == 'false') {
+ $_once = '';
+ }
+ }
+
+ if (isset($_assign)) {
+ return "<?php ob_start(); include{$_once} ('{$_filepath}'); \$_smarty_tpl->assign({$_assign},ob_get_contents()); ob_end_clean();?>";
+ } else {
+ return "<?php include{$_once} ('{$_filepath}');?>\n";
+ }
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_insert.php
@@ -0,0 +1,146 @@
+<?php
+
+/**
+ * Smarty Internal Plugin Compile Insert
+ * Compiles the {insert} tag
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Insert Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Insert extends Smarty_Internal_CompileBase {
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $required_attributes = array('name');
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $shorttag_order = array('name');
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $optional_attributes = array('_any');
+
+ /**
+ * Compiles code for the {insert} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler) {
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+ $nocacheParam = $compiler->template->caching && ($compiler->tag_nocache || $compiler->nocache);
+ if (!$nocacheParam) {
+ // do not compile as nocache code
+ $compiler->suppressNocacheProcessing = true;
+ }
+ $compiler->tag_nocache = true;
+ $_smarty_tpl = $compiler->template;
+ $_name = null;
+ $_script = null;
+
+ $_output = '<?php ';
+ // save possible attributes
+ eval('$_name = ' . $_attr['name'] . ';');
+ if (isset($_attr['assign'])) {
+ // output will be stored in a smarty variable instead of being displayed
+ $_assign = $_attr['assign'];
+ // create variable to make sure that the compiler knows about its nocache status
+ $var = trim($_attr['assign'], "'");
+ if (isset($compiler->template->tpl_vars[$var])) {
+ $compiler->template->tpl_vars[$var]->nocache = true;
+ } else {
+ $compiler->template->tpl_vars[$var] = new Smarty_Variable(null, true);
+ }
+ }
+ if (isset($_attr['script'])) {
+ // script which must be included
+ $_function = "smarty_insert_{$_name}";
+ $_smarty_tpl = $compiler->template;
+ $_filepath = false;
+ eval('$_script = ' . $_attr['script'] . ';');
+ if (!isset($compiler->smarty->security_policy) && file_exists($_script)) {
+ $_filepath = $_script;
+ } else {
+ if (isset($compiler->smarty->security_policy)) {
+ $_dir = $compiler->smarty->security_policy->trusted_dir;
+ } else {
+ $_dir = $compiler->smarty->trusted_dir;
+ }
+ if (!empty($_dir)) {
+ foreach ((array)$_dir as $_script_dir) {
+ $_script_dir = rtrim($_script_dir, '/\\') . DS;
+ if (file_exists($_script_dir . $_script)) {
+ $_filepath = $_script_dir . $_script;
+ break;
+ }
+ }
+ }
+ }
+ if ($_filepath == false) {
+ $compiler->trigger_template_error("{insert} missing script file '{$_script}'", $compiler->lex->taglineno);
+ }
+ // code for script file loading
+ $_output .= "require_once '{$_filepath}' ;";
+ require_once $_filepath;
+ if (!is_callable($_function)) {
+ $compiler->trigger_template_error(" {insert} function '{$_function}' is not callable in script file '{$_script}'", $compiler->lex->taglineno);
+ }
+ } else {
+ $_filepath = 'null';
+ $_function = "insert_{$_name}";
+ // function in PHP script ?
+ if (!is_callable($_function)) {
+ // try plugin
+ if (!$_function = $compiler->getPlugin($_name, 'insert')) {
+ $compiler->trigger_template_error("{insert} no function or plugin found for '{$_name}'", $compiler->lex->taglineno);
+ }
+ }
+ }
+ // delete {insert} standard attributes
+ unset($_attr['name'], $_attr['assign'], $_attr['script'], $_attr['nocache']);
+ // convert attributes into parameter array string
+ $_paramsArray = array();
+ foreach ($_attr as $_key => $_value) {
+ $_paramsArray[] = "'$_key' => $_value";
+ }
+ $_params = 'array(' . implode(", ", $_paramsArray) . ')';
+ // call insert
+ if (isset($_assign)) {
+ if ($_smarty_tpl->caching && !$nocacheParam) {
+ $_output .= "echo Smarty_Internal_Nocache_Insert::compile ('{$_function}',{$_params}, \$_smarty_tpl, '{$_filepath}',{$_assign});?>";
+ } else {
+ $_output .= "\$_smarty_tpl->assign({$_assign} , {$_function} ({$_params},\$_smarty_tpl), true);?>";
+ }
+ } else {
+ $compiler->has_output = true;
+ if ($_smarty_tpl->caching && !$nocacheParam) {
+ $_output .= "echo Smarty_Internal_Nocache_Insert::compile ('{$_function}',{$_params}, \$_smarty_tpl, '{$_filepath}');?>";
+ } else {
+ $_output .= "echo {$_function}({$_params},\$_smarty_tpl);?>";
+ }
+ }
+
+ return $_output;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_ldelim.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Ldelim
+ * Compiles the {ldelim} tag
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Ldelim Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Ldelim extends Smarty_Internal_CompileBase {
+ /**
+ * Compiles code for the {ldelim} tag
+ * This tag does output the left delimiter
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler) {
+ $_attr = $this->getAttributes($compiler, $args);
+ if ($_attr['nocache'] === true) {
+ $compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
+ }
+ // this tag does not return compiled code
+ $compiler->has_code = true;
+
+ return $compiler->smarty->left_delimiter;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_nocache.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Nocache
+ * Compiles the {nocache} {/nocache} tags.
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Nocache Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Nocache extends Smarty_Internal_CompileBase {
+ /**
+ * Array of names of valid option flags
+ *
+ * @var array
+ */
+ public $option_flags = array();
+
+ /**
+ * Compiles code for the {nocache} tag
+ * This tag does not generate compiled output. It only sets a compiler flag.
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ *
+ * @return bool
+ */
+ public function compile($args, $compiler) {
+ $_attr = $this->getAttributes($compiler, $args);
+ $this->openTag($compiler, 'nocache', array($compiler->nocache));
+ // enter nocache mode
+ $compiler->nocache = true;
+ // this tag does not return compiled code
+ $compiler->has_code = false;
+
+ return true;
+ }
+}
+
+/**
+ * Smarty Internal Plugin Compile Nocacheclose Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Nocacheclose extends Smarty_Internal_CompileBase {
+ /**
+ * Compiles code for the {/nocache} tag
+ * This tag does not generate compiled output. It only sets a compiler flag.
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ *
+ * @return bool
+ */
+ public function compile($args, $compiler) {
+ $_attr = $this->getAttributes($compiler, $args);
+ // leave nocache mode
+ list($compiler->nocache) = $this->closeTag($compiler, array('nocache'));
+ // this tag does not return compiled code
+ $compiler->has_code = false;
+
+ return true;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_private_block_plugin.php
@@ -0,0 +1,83 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Block Plugin
+ * Compiles code for the execution of block plugin
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Block Plugin Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Private_Block_Plugin extends Smarty_Internal_CompileBase {
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $optional_attributes = array('_any');
+
+ /**
+ * Compiles code for the execution of block plugin
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ * @param string $tag name of block plugin
+ * @param string $function PHP function name
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter, $tag, $function) {
+ if (!isset($tag[5]) || substr($tag, -5) != 'close') {
+ // opening tag of block plugin
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+ if ($_attr['nocache'] === true) {
+ $compiler->tag_nocache = true;
+ }
+ unset($_attr['nocache']);
+ // convert attributes into parameter array string
+ $_paramsArray = array();
+ foreach ($_attr as $_key => $_value) {
+ if (is_int($_key)) {
+ $_paramsArray[] = "$_key=>$_value";
+ } else {
+ $_paramsArray[] = "'$_key'=>$_value";
+ }
+ }
+ $_params = 'array(' . implode(",", $_paramsArray) . ')';
+
+ $this->openTag($compiler, $tag, array($_params, $compiler->nocache));
+ // maybe nocache because of nocache variables or nocache plugin
+ $compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
+ // compile code
+ $output = "<?php \$_smarty_tpl->smarty->_tag_stack[] = array('{$tag}', {$_params}); \$_block_repeat=true; echo {$function}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
+ } else {
+ // must endblock be nocache?
+ if ($compiler->nocache) {
+ $compiler->tag_nocache = true;
+ }
+ // closing tag of block plugin, restore nocache
+ list($_params, $compiler->nocache) = $this->closeTag($compiler, substr($tag, 0, -5));
+ // This tag does create output
+ $compiler->has_output = true;
+ // compile code
+ if (!isset($parameter['modifier_list'])) {
+ $mod_pre = $mod_post = '';
+ } else {
+ $mod_pre = ' ob_start(); ';
+ $mod_post = 'echo ' . $compiler->compileTag('private_modifier', array(), array('modifierlist' => $parameter['modifier_list'], 'value' => 'ob_get_clean()')) . ';';
+ }
+ $output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;" . $mod_pre . " echo {$function}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat); " . $mod_post . " } array_pop(\$_smarty_tpl->smarty->_tag_stack);?>";
+ }
+
+ return $output . "\n";
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_private_function_plugin.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Function Plugin
+ * Compiles code for the execution of function plugin
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Function Plugin Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Private_Function_Plugin extends Smarty_Internal_CompileBase {
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $required_attributes = array();
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $optional_attributes = array('_any');
+
+ /**
+ * Compiles code for the execution of function plugin
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ * @param string $tag name of function plugin
+ * @param string $function PHP function name
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter, $tag, $function) {
+ // This tag does create output
+ $compiler->has_output = true;
+
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+ if ($_attr['nocache'] === true) {
+ $compiler->tag_nocache = true;
+ }
+ unset($_attr['nocache']);
+ // convert attributes into parameter array string
+ $_paramsArray = array();
+ foreach ($_attr as $_key => $_value) {
+ if (is_int($_key)) {
+ $_paramsArray[] = "$_key=>$_value";
+ } else {
+ $_paramsArray[] = "'$_key'=>$_value";
+ }
+ }
+ $_params = 'array(' . implode(",", $_paramsArray) . ')';
+ // compile code
+ $output = "<?php echo {$function}({$_params},\$_smarty_tpl);?>\n";
+
+ return $output;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_private_modifier.php
@@ -0,0 +1,137 @@
+<?php
+
+/**
+ * Smarty Internal Plugin Compile Modifier
+ * Compiles code for modifier execution
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Modifier Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Private_Modifier extends Smarty_Internal_CompileBase {
+ /**
+ * Compiles code for modifier execution
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter) {
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+ $output = $parameter['value'];
+ // loop over list of modifiers
+ foreach ($parameter['modifierlist'] as $single_modifier) {
+ $modifier = $single_modifier[0];
+ $single_modifier[0] = $output;
+ $params = implode(',', $single_modifier);
+ // check if we know already the type of modifier
+ if (isset($compiler->known_modifier_type[$modifier])) {
+ $modifier_types = array($compiler->known_modifier_type[$modifier]);
+ } else {
+ $modifier_types = array(1, 2, 3, 4, 5, 6);
+ }
+ foreach ($modifier_types as $type) {
+ switch ($type) {
+ case 1:
+ // registered modifier
+ if (isset($compiler->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER][$modifier])) {
+ $function = $compiler->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER][$modifier][0];
+ if (!is_array($function)) {
+ $output = "{$function}({$params})";
+ } else {
+ if (is_object($function[0])) {
+ $output = '$_smarty_tpl->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER][\'' . $modifier . '\'][0][0]->' . $function[1] . '(' . $params . ')';
+ } else {
+ $output = $function[0] . '::' . $function[1] . '(' . $params . ')';
+ }
+ }
+ $compiler->known_modifier_type[$modifier] = $type;
+ break 2;
+ }
+ break;
+ case 2:
+ // registered modifier compiler
+ if (isset($compiler->smarty->registered_plugins[Smarty::PLUGIN_MODIFIERCOMPILER][$modifier][0])) {
+ $output = call_user_func($compiler->smarty->registered_plugins[Smarty::PLUGIN_MODIFIERCOMPILER][$modifier][0], $single_modifier, $compiler->smarty);
+ $compiler->known_modifier_type[$modifier] = $type;
+ break 2;
+ }
+ break;
+ case 3:
+ // modifiercompiler plugin
+ if ($compiler->smarty->loadPlugin('smarty_modifiercompiler_' . $modifier)) {
+ // check if modifier allowed
+ if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedModifier($modifier, $compiler)) {
+ $plugin = 'smarty_modifiercompiler_' . $modifier;
+ $output = $plugin($single_modifier, $compiler);
+ }
+ $compiler->known_modifier_type[$modifier] = $type;
+ break 2;
+ }
+ break;
+ case 4:
+ // modifier plugin
+ if ($function = $compiler->getPlugin($modifier, Smarty::PLUGIN_MODIFIER)) {
+ // check if modifier allowed
+ if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedModifier($modifier, $compiler)) {
+ $output = "{$function}({$params})";
+ }
+ $compiler->known_modifier_type[$modifier] = $type;
+ break 2;
+ }
+ break;
+ case 5:
+ // PHP function
+ if (is_callable($modifier)) {
+ // check if modifier allowed
+ if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedPhpModifier($modifier, $compiler)) {
+ $output = "{$modifier}({$params})";
+ }
+ $compiler->known_modifier_type[$modifier] = $type;
+ break 2;
+ }
+ break;
+ case 6:
+ // default plugin handler
+ if (isset($compiler->default_handler_plugins[Smarty::PLUGIN_MODIFIER][$modifier]) || (is_callable($compiler->smarty->default_plugin_handler_func) && $compiler->getPluginFromDefaultHandler($modifier, Smarty::PLUGIN_MODIFIER))) {
+ $function = $compiler->default_handler_plugins[Smarty::PLUGIN_MODIFIER][$modifier][0];
+ // check if modifier allowed
+ if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedModifier($modifier, $compiler)) {
+ if (!is_array($function)) {
+ $output = "{$function}({$params})";
+ } else {
+ if (is_object($function[0])) {
+ $output = '$_smarty_tpl->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER][\'' . $modifier . '\'][0][0]->' . $function[1] . '(' . $params . ')';
+ } else {
+ $output = $function[0] . '::' . $function[1] . '(' . $params . ')';
+ }
+ }
+ }
+ if (isset($compiler->template->required_plugins['nocache'][$modifier][Smarty::PLUGIN_MODIFIER]['file']) || isset($compiler->template->required_plugins['compiled'][$modifier][Smarty::PLUGIN_MODIFIER]['file'])) {
+ // was a plugin
+ $compiler->known_modifier_type[$modifier] = 4;
+ } else {
+ $compiler->known_modifier_type[$modifier] = $type;
+ }
+ break 2;
+ }
+ }
+ }
+ if (!isset($compiler->known_modifier_type[$modifier])) {
+ $compiler->trigger_template_error("unknown modifier \"" . $modifier . "\"", $compiler->lex->taglineno);
+ }
+ }
+
+ return $output;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_private_object_block_function.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Object Block Function
+ * Compiles code for registered objects as block function
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Object Block Function Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Private_Object_Block_Function extends Smarty_Internal_CompileBase {
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $optional_attributes = array('_any');
+
+ /**
+ * Compiles code for the execution of block plugin
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ * @param string $tag name of block object
+ * @param string $method name of method to call
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter, $tag, $method) {
+ if (!isset($tag[5]) || substr($tag, -5) != 'close') {
+ // opening tag of block plugin
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+ if ($_attr['nocache'] === true) {
+ $compiler->tag_nocache = true;
+ }
+ unset($_attr['nocache']);
+ // convert attributes into parameter array string
+ $_paramsArray = array();
+ foreach ($_attr as $_key => $_value) {
+ if (is_int($_key)) {
+ $_paramsArray[] = "$_key=>$_value";
+ } else {
+ $_paramsArray[] = "'$_key'=>$_value";
+ }
+ }
+ $_params = 'array(' . implode(",", $_paramsArray) . ')';
+
+ $this->openTag($compiler, $tag . '->' . $method, array($_params, $compiler->nocache));
+ // maybe nocache because of nocache variables or nocache plugin
+ $compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
+ // compile code
+ $output = "<?php \$_smarty_tpl->smarty->_tag_stack[] = array('{$tag}->{$method}', {$_params}); \$_block_repeat=true; echo \$_smarty_tpl->smarty->registered_objects['{$tag}'][0]->{$method}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
+ } else {
+ $base_tag = substr($tag, 0, -5);
+ // must endblock be nocache?
+ if ($compiler->nocache) {
+ $compiler->tag_nocache = true;
+ }
+ // closing tag of block plugin, restore nocache
+ list($_params, $compiler->nocache) = $this->closeTag($compiler, $base_tag . '->' . $method);
+ // This tag does create output
+ $compiler->has_output = true;
+ // compile code
+ if (!isset($parameter['modifier_list'])) {
+ $mod_pre = $mod_post = '';
+ } else {
+ $mod_pre = ' ob_start(); ';
+ $mod_post = 'echo ' . $compiler->compileTag('private_modifier', array(), array('modifierlist' => $parameter['modifier_list'], 'value' => 'ob_get_clean()')) . ';';
+ }
+ $output = "<?php \$_block_content = ob_get_contents(); ob_end_clean(); \$_block_repeat=false;" . $mod_pre . " echo \$_smarty_tpl->smarty->registered_objects['{$base_tag}'][0]->{$method}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat); " . $mod_post . " } array_pop(\$_smarty_tpl->smarty->_tag_stack);?>";
+ }
+
+ return $output . "\n";
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_private_object_function.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Object Function
+ * Compiles code for registered objects as function
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Object Function Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Private_Object_Function extends Smarty_Internal_CompileBase {
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $optional_attributes = array('_any');
+
+ /**
+ * Compiles code for the execution of function plugin
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ * @param string $tag name of function
+ * @param string $method name of method to call
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter, $tag, $method) {
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+ if ($_attr['nocache'] === true) {
+ $compiler->tag_nocache = true;
+ }
+ unset($_attr['nocache']);
+ $_assign = null;
+ if (isset($_attr['assign'])) {
+ $_assign = $_attr['assign'];
+ unset($_attr['assign']);
+ }
+ // method or property ?
+ if (method_exists($compiler->smarty->registered_objects[$tag][0], $method)) {
+ // convert attributes into parameter array string
+ if ($compiler->smarty->registered_objects[$tag][2]) {
+ $_paramsArray = array();
+ foreach ($_attr as $_key => $_value) {
+ if (is_int($_key)) {
+ $_paramsArray[] = "$_key=>$_value";
+ } else {
+ $_paramsArray[] = "'$_key'=>$_value";
+ }
+ }
+ $_params = 'array(' . implode(",", $_paramsArray) . ')';
+ $return = "\$_smarty_tpl->smarty->registered_objects['{$tag}'][0]->{$method}({$_params},\$_smarty_tpl)";
+ } else {
+ $_params = implode(",", $_attr);
+ $return = "\$_smarty_tpl->smarty->registered_objects['{$tag}'][0]->{$method}({$_params})";
+ }
+ } else {
+ // object property
+ $return = "\$_smarty_tpl->smarty->registered_objects['{$tag}'][0]->{$method}";
+ }
+
+ if (empty($_assign)) {
+ // This tag does create output
+ $compiler->has_output = true;
+ $output = "<?php echo {$return};?>\n";
+ } else {
+ $output = "<?php \$_smarty_tpl->assign({$_assign},{$return});?>\n";
+ }
+
+ return $output;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_private_php.php
@@ -0,0 +1,193 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile PHP Expression
+ * Compiles any tag which will output an expression or variable
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile PHP Expression Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Private_Php extends Smarty_Internal_CompileBase {
+
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $required_attributes = array('code', 'type');
+
+ /**
+ * Compiles code for generating output from any expression
+ *
+ * @param array $args array with attributes from parser
+ * @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ *
+ * @return string
+ * @throws \SmartyException
+ */
+ public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter) {
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+ $compiler->has_code = false;
+ if ($_attr['type'] == 'xml') {
+ $compiler->tag_nocache = true;
+ $save = $compiler->template->has_nocache_code;
+ $output = addcslashes($_attr['code'], "'\\");
+ $compiler->parser->current_buffer->append_subtree(new Smarty_Internal_ParseTree_Tag($compiler->parser, $compiler->processNocacheCode("<?php echo '" . $output . "';?>", $compiler, true)));
+ $compiler->template->has_nocache_code = $save;
+ return '';
+ }
+ if ($_attr['type'] != 'tag') {
+ if ($compiler->php_handling == Smarty::PHP_REMOVE) {
+ return '';
+ } elseif ($compiler->php_handling == Smarty::PHP_QUOTE) {
+ $output = preg_replace_callback('#(<\?(?:php|=)?)|(<%)|(<script\s+language\s*=\s*["\']?\s*php\s*["\']?\s*>)|(\?>)|(%>)|(<\/script>)#i', array($this,
+ 'quote'), $_attr['code']);
+ $compiler->parser->current_buffer->append_subtree(new Smarty_Internal_ParseTree_Text($compiler->parser, $output));
+ return '';
+ } elseif ($compiler->php_handling == Smarty::PHP_PASSTHRU || $_attr['type'] == 'unmatched') {
+ $compiler->tag_nocache = true;
+ $save = $compiler->template->has_nocache_code;
+ $output = addcslashes($_attr['code'], "'\\");
+ $compiler->parser->current_buffer->append_subtree(new Smarty_Internal_ParseTree_Tag($compiler->parser, $compiler->processNocacheCode("<?php echo '" . $output . "';?>", $compiler, true)));
+ $compiler->template->has_nocache_code = $save;
+ return '';
+ } elseif ($compiler->php_handling == Smarty::PHP_ALLOW) {
+ if (!($compiler->smarty instanceof SmartyBC)) {
+ $compiler->trigger_template_error('$smarty->php_handling PHP_ALLOW not allowed. Use SmartyBC to enable it', $compiler->lex->taglineno);
+ }
+ $compiler->has_code = true;
+ return $_attr['code'];
+ } else {
+ $compiler->trigger_template_error('Illegal $smarty->php_handling value', $compiler->lex->taglineno);
+ }
+ } else {
+ $compiler->has_code = true;
+ if (!($compiler->smarty instanceof SmartyBC)) {
+ $compiler->trigger_template_error('{php}[/php} tags not allowed. Use SmartyBC to enable them', $compiler->lex->taglineno);
+ }
+ $ldel = preg_quote($compiler->smarty->left_delimiter, '#');
+ $rdel = preg_quote($compiler->smarty->right_delimiter, '#');
+ preg_match("#^({$ldel}php\\s*)((.)*?)({$rdel})#", $_attr['code'], $match);
+ if (!empty($match[2])) {
+ if ('nocache' == trim($match[2])) {
+ $compiler->tag_nocache = true;
+ } else {
+ $compiler->trigger_template_error("illegal value of option flag \"{$match[2]}\"", $compiler->lex->taglineno);
+ }
+ }
+ return preg_replace(array("#^{$ldel}\\s*php\\s*(.)*?{$rdel}#",
+ "#{$ldel}\\s*/\\s*php\\s*{$rdel}$#"), array('<?php ', '?>'), $_attr['code']);
+ }
+ }
+
+ /**
+ * Lexer code for PHP tags
+ *
+ * This code has been moved from lexer here fo easier debugging and maintenance
+ *
+ * @param $lex
+ */
+ public function parsePhp($lex) {
+ $lex->token = Smarty_Internal_Templateparser::TP_PHP;
+ $close = 0;
+ $lex->taglineno = $lex->line;
+ $closeTag = '?>';
+ if (strpos($lex->value, '<?xml') === 0) {
+ $lex->is_xml = true;
+ $lex->token = Smarty_Internal_Templateparser::TP_NOCACHE;
+ return;
+ } elseif (strpos($lex->value, '<?') === 0) {
+ $lex->phpType = 'php';
+ } elseif (strpos($lex->value, '<%') === 0) {
+ $lex->phpType = 'asp';
+ $closeTag = '%>';
+ } elseif (strpos($lex->value, '%>') === 0) {
+ $lex->phpType = 'unmatched';
+ } elseif (strpos($lex->value, '?>') === 0) {
+ if ($lex->is_xml) {
+ $lex->is_xml = false;
+ $lex->token = Smarty_Internal_Templateparser::TP_NOCACHE;
+ return;
+ }
+ $lex->phpType = 'unmatched';
+ } elseif (strpos($lex->value, '<s') === 0) {
+ $lex->phpType = 'script';
+ $closeTag = '</script>';
+ } elseif (strpos($lex->value, $lex->smarty->left_delimiter) === 0) {
+ if ($lex->isAutoLiteral()) {
+ $lex->token = Smarty_Internal_Templateparser::TP_TEXT;
+ return;
+ }
+ $closeTag = "{$lex->smarty->left_delimiter}/php{$lex->smarty->right_delimiter}";
+ if ($lex->value == $closeTag) {
+ $lex->compiler->trigger_template_error("unexpected closing tag '{$closeTag}'");
+ }
+ $lex->phpType = 'tag';
+ }
+ if ($lex->phpType == 'unmatched') {
+ return;
+ }
+ if (($lex->phpType == 'php' || $lex->phpType == 'asp') && ($lex->compiler->php_handling == Smarty::PHP_PASSTHRU || $lex->compiler->php_handling == Smarty::PHP_QUOTE)) {
+ return;
+ }
+ $start = $lex->counter + strlen($lex->value);
+ $body = true;
+ if (preg_match('~' . preg_quote($closeTag, '~') . '~i', $lex->data, $match, PREG_OFFSET_CAPTURE, $start)) {
+ $close = $match[0][1];
+ } else {
+ $lex->compiler->trigger_template_error("missing closing tag '{$closeTag}'");
+ }
+ while ($body) {
+ if (preg_match('~([/][*])|([/][/][^\n]*)|(\'[^\'\\\\]*(?:\\.[^\'\\\\]*)*\')|("[^"\\\\]*(?:\\.[^"\\\\]*)*")~', $lex->data, $match, PREG_OFFSET_CAPTURE, $start)) {
+ $value = $match[0][0];
+ $from = $pos = $match[0][1];
+ if ($pos > $close) {
+ $body = false;
+ } else {
+ $start = $pos + strlen($value);
+ $phpCommentStart = $value == '/*';
+ if ($phpCommentStart) {
+ $phpCommentEnd = preg_match('~([*][/])~', $lex->data, $match, PREG_OFFSET_CAPTURE, $start);
+ if ($phpCommentEnd) {
+ $pos2 = $match[0][1];
+ $start = $pos2 + strlen($match[0][0]);
+ }
+ }
+ while ($close > $pos && $close < $start) {
+ if (preg_match('~' . preg_quote($closeTag, '~') . '~i', $lex->data, $match, PREG_OFFSET_CAPTURE, $from)) {
+ $close = $match[0][1];
+ $from = $close + strlen($match[0][0]);
+ } else {
+ $lex->compiler->trigger_template_error("missing closing tag '{$closeTag}'");
+ }
+ }
+ if ($phpCommentStart && (!$phpCommentEnd || $pos2 > $close)) {
+ $lex->taglineno = $lex->line + substr_count(substr($lex->data, $lex->counter, $start), "\n");
+ $lex->compiler->trigger_template_error("missing PHP comment closing tag '*/'");
+ }
+ }
+ } else {
+ $body = false;
+ }
+ }
+ $lex->value = substr($lex->data, $lex->counter, $close + strlen($closeTag) - $lex->counter);
+ }
+
+ /*
+ * Call back function for $php_handling = PHP_QUOTE
+ *
+ */
+ private function quote($match) {
+ return htmlspecialchars($match[0], ENT_QUOTES);
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_private_print_expression.php
@@ -0,0 +1,148 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Print Expression
+ * Compiles any tag which will output an expression or variable
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Print Expression Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Private_Print_Expression extends Smarty_Internal_CompileBase {
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $optional_attributes = array('assign');
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $option_flags = array('nocache', 'nofilter');
+
+ /**
+ * Compiles code for generating output from any expression
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ *
+ * @throws SmartyException
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter) {
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+ // nocache option
+ if ($_attr['nocache'] === true) {
+ $compiler->tag_nocache = true;
+ }
+ if (isset($_attr['assign'])) {
+ // assign output to variable
+ $output = "<?php \$_smarty_tpl->assign({$_attr['assign']},{$parameter['value']});?>";
+ } else {
+ // display value
+ $output = $parameter['value'];
+ // tag modifier
+ if (!empty($parameter['modifierlist'])) {
+ $output = $compiler->compileTag('private_modifier', array(), array('modifierlist' => $parameter['modifierlist'], 'value' => $output));
+ }
+ if (!$_attr['nofilter']) {
+ // default modifier
+ if (!empty($compiler->smarty->default_modifiers)) {
+ if (empty($compiler->default_modifier_list)) {
+ $modifierlist = array();
+ foreach ($compiler->smarty->default_modifiers as $key => $single_default_modifier) {
+ preg_match_all('/(\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'|"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|:|[^:]+)/', $single_default_modifier, $mod_array);
+ for ($i = 0, $count = count($mod_array[0]); $i < $count; $i++) {
+ if ($mod_array[0][$i] != ':') {
+ $modifierlist[$key][] = $mod_array[0][$i];
+ }
+ }
+ }
+ $compiler->default_modifier_list = $modifierlist;
+ }
+ $output = $compiler->compileTag('private_modifier', array(), array('modifierlist' => $compiler->default_modifier_list, 'value' => $output));
+ }
+ // autoescape html
+ if ($compiler->template->smarty->escape_html) {
+ $output = "htmlspecialchars({$output}, ENT_QUOTES, '" . addslashes(Smarty::$_CHARSET) . "')";
+ }
+ // loop over registered filters
+ if (!empty($compiler->template->smarty->registered_filters[Smarty::FILTER_VARIABLE])) {
+ foreach ($compiler->template->smarty->registered_filters[Smarty::FILTER_VARIABLE] as $key => $function) {
+ if (!is_array($function)) {
+ $output = "{$function}({$output},\$_smarty_tpl)";
+ } elseif (is_object($function[0])) {
+ $output = "\$_smarty_tpl->smarty->registered_filters[Smarty::FILTER_VARIABLE]['{$key}'][0]->{$function[1]}({$output},\$_smarty_tpl)";
+ } else {
+ $output = "{$function[0]}::{$function[1]}({$output},\$_smarty_tpl)";
+ }
+ }
+ }
+ // auto loaded filters
+ if (isset($compiler->smarty->autoload_filters[Smarty::FILTER_VARIABLE])) {
+ foreach ((array)$compiler->template->smarty->autoload_filters[Smarty::FILTER_VARIABLE] as $name) {
+ $result = $this->compile_output_filter($compiler, $name, $output);
+ if ($result !== false) {
+ $output = $result;
+ } else {
+ // not found, throw exception
+ throw new SmartyException("Unable to load filter '{$name}'");
+ }
+ }
+ }
+ if (isset($compiler->template->variable_filters)) {
+ foreach ($compiler->template->variable_filters as $filter) {
+ if (count($filter) == 1 && ($result = $this->compile_output_filter($compiler, $filter[0], $output)) !== false) {
+ $output = $result;
+ } else {
+ $output = $compiler->compileTag('private_modifier', array(), array('modifierlist' => array($filter), 'value' => $output));
+ }
+ }
+ }
+ }
+
+ $compiler->has_output = true;
+ $output = "<?php echo {$output};?>";
+ }
+
+ return $output;
+ }
+
+ /**
+ * @param object $compiler compiler object
+ * @param string $name name of variable filter
+ * @param string $output embedded output
+ *
+ * @return string
+ */
+ private function compile_output_filter($compiler, $name, $output) {
+ $plugin_name = "smarty_variablefilter_{$name}";
+ $path = $compiler->smarty->loadPlugin($plugin_name, false);
+ if ($path) {
+ if ($compiler->template->caching) {
+ $compiler->template->required_plugins['nocache'][$name][Smarty::FILTER_VARIABLE]['file'] = $path;
+ $compiler->template->required_plugins['nocache'][$name][Smarty::FILTER_VARIABLE]['function'] = $plugin_name;
+ } else {
+ $compiler->template->required_plugins['compiled'][$name][Smarty::FILTER_VARIABLE]['file'] = $path;
+ $compiler->template->required_plugins['compiled'][$name][Smarty::FILTER_VARIABLE]['function'] = $plugin_name;
+ }
+ } else {
+ // not found
+ return false;
+ }
+
+ return "{$plugin_name}({$output},\$_smarty_tpl)";
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_private_registered_block.php
@@ -0,0 +1,109 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Registered Block
+ * Compiles code for the execution of a registered block function
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Registered Block Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Private_Registered_Block extends Smarty_Internal_CompileBase {
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $optional_attributes = array('_any');
+
+ /**
+ * Compiles code for the execution of a block function
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ * @param string $tag name of block function
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter, $tag) {
+ if (!isset($tag[5]) || substr($tag, -5) != 'close') {
+ // opening tag of block plugin
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+ if ($_attr['nocache']) {
+ $compiler->tag_nocache = true;
+ }
+ unset($_attr['nocache']);
+ if (isset($compiler->smarty->registered_plugins[Smarty::PLUGIN_BLOCK][$tag])) {
+ $tag_info = $compiler->smarty->registered_plugins[Smarty::PLUGIN_BLOCK][$tag];
+ } else {
+ $tag_info = $compiler->default_handler_plugins[Smarty::PLUGIN_BLOCK][$tag];
+ }
+ // convert attributes into parameter array string
+ $_paramsArray = array();
+ foreach ($_attr as $_key => $_value) {
+ if (is_int($_key)) {
+ $_paramsArray[] = "$_key=>$_value";
+ } elseif ($compiler->template->caching && in_array($_key, $tag_info[2])) {
+ $_value = str_replace("'", "^#^", $_value);
+ $_paramsArray[] = "'$_key'=>^#^.var_export($_value,true).^#^";
+ } else {
+ $_paramsArray[] = "'$_key'=>$_value";
+ }
+ }
+ $_params = 'array(' . implode(",", $_paramsArray) . ')';
+
+ $this->openTag($compiler, $tag, array($_params, $compiler->nocache));
+ // maybe nocache because of nocache variables or nocache plugin
+ $compiler->nocache = !$tag_info[1] | $compiler->nocache | $compiler->tag_nocache;
+ $function = $tag_info[0];
+ // compile code
+ if (!is_array($function)) {
+ $output = "<?php \$_smarty_tpl->smarty->_tag_stack[] = array('{$tag}', {$_params}); \$_block_repeat=true; echo {$function}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
+ } elseif (is_object($function[0])) {
+ $output = "<?php \$_smarty_tpl->smarty->_tag_stack[] = array('{$tag}', {$_params}); \$_block_repeat=true; echo \$_smarty_tpl->smarty->registered_plugins['block']['{$tag}'][0][0]->{$function[1]}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
+ } else {
+ $output = "<?php \$_smarty_tpl->smarty->_tag_stack[] = array('{$tag}', {$_params}); \$_block_repeat=true; echo {$function[0]}::{$function[1]}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
+ }
+ } else {
+ // must endblock be nocache?
+ if ($compiler->nocache) {
+ $compiler->tag_nocache = true;
+ }
+ $base_tag = substr($tag, 0, -5);
+ // closing tag of block plugin, restore nocache
+ list($_params, $compiler->nocache) = $this->closeTag($compiler, $base_tag);
+ // This tag does create output
+ $compiler->has_output = true;
+ if (isset($compiler->smarty->registered_plugins[Smarty::PLUGIN_BLOCK][$base_tag])) {
+ $function = $compiler->smarty->registered_plugins[Smarty::PLUGIN_BLOCK][$base_tag][0];
+ } else {
+ $function = $compiler->default_handler_plugins[Smarty::PLUGIN_BLOCK][$base_tag][0];
+ }
+ // compile code
+ if (!isset($parameter['modifier_list'])) {
+ $mod_pre = $mod_post = '';
+ } else {
+ $mod_pre = ' ob_start(); ';
+ $mod_post = 'echo ' . $compiler->compileTag('private_modifier', array(), array('modifierlist' => $parameter['modifier_list'], 'value' => 'ob_get_clean()')) . ';';
+ }
+ if (!is_array($function)) {
+ $output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;" . $mod_pre . " echo {$function}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat);" . $mod_post . " } array_pop(\$_smarty_tpl->smarty->_tag_stack);?>";
+ } elseif (is_object($function[0])) {
+ $output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;" . $mod_pre . " echo \$_smarty_tpl->smarty->registered_plugins['block']['{$base_tag}'][0][0]->{$function[1]}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat); " . $mod_post . "} array_pop(\$_smarty_tpl->smarty->_tag_stack);?>";
+ } else {
+ $output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;" . $mod_pre . " echo {$function[0]}::{$function[1]}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat); " . $mod_post . "} array_pop(\$_smarty_tpl->smarty->_tag_stack);?>";
+ }
+ }
+
+ return $output . "\n";
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_private_registered_function.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Registered Function
+ * Compiles code for the execution of a registered function
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Registered Function Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Private_Registered_Function extends Smarty_Internal_CompileBase {
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $optional_attributes = array('_any');
+
+ /**
+ * Compiles code for the execution of a registered function
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ * @param string $tag name of function
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter, $tag) {
+ // This tag does create output
+ $compiler->has_output = true;
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+ if ($_attr['nocache']) {
+ $compiler->tag_nocache = true;
+ }
+ unset($_attr['nocache']);
+ if (isset($compiler->smarty->registered_plugins[Smarty::PLUGIN_FUNCTION][$tag])) {
+ $tag_info = $compiler->smarty->registered_plugins[Smarty::PLUGIN_FUNCTION][$tag];
+ } else {
+ $tag_info = $compiler->default_handler_plugins[Smarty::PLUGIN_FUNCTION][$tag];
+ }
+ // not cachable?
+ $compiler->tag_nocache = $compiler->tag_nocache || !$tag_info[1];
+ // convert attributes into parameter array string
+ $_paramsArray = array();
+ foreach ($_attr as $_key => $_value) {
+ if (is_int($_key)) {
+ $_paramsArray[] = "$_key=>$_value";
+ } elseif ($compiler->template->caching && in_array($_key, $tag_info[2])) {
+ $_value = str_replace("'", "^#^", $_value);
+ $_paramsArray[] = "'$_key'=>^#^.var_export($_value,true).^#^";
+ } else {
+ $_paramsArray[] = "'$_key'=>$_value";
+ }
+ }
+ $_params = 'array(' . implode(",", $_paramsArray) . ')';
+ $function = $tag_info[0];
+ // compile code
+ if (!is_array($function)) {
+ $output = "<?php echo {$function}({$_params},\$_smarty_tpl);?>\n";
+ } elseif (is_object($function[0])) {
+ $output = "<?php echo \$_smarty_tpl->smarty->registered_plugins[Smarty::PLUGIN_FUNCTION]['{$tag}'][0][0]->{$function[1]}({$_params},\$_smarty_tpl);?>\n";
+ } else {
+ $output = "<?php echo {$function[0]}::{$function[1]}({$_params},\$_smarty_tpl);?>\n";
+ }
+
+ return $output;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_private_special_variable.php
@@ -0,0 +1,118 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Special Smarty Variable
+ * Compiles the special $smarty variables
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile special Smarty Variable Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Private_Special_Variable extends Smarty_Internal_CompileBase {
+ /**
+ * Compiles code for the special $smarty variables
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param $parameter
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter) {
+ $_index = preg_split("/\]\[/", substr($parameter, 1, strlen($parameter) - 2));
+ $compiled_ref = ' ';
+ $variable = trim($_index[0], "'");
+ if (!isset($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedSpecialSmartyVar($variable, $compiler)) {
+ switch ($variable) {
+ case 'foreach':
+ $name = trim($_index[1], "'");
+ $foreachVar = "'__foreach_{$name}'";
+ return "(isset(\$_smarty_tpl->tpl_vars[$foreachVar]->value[{$_index[2]}]) ? \$_smarty_tpl->tpl_vars[$foreachVar]->value[{$_index[2]}] : null)";
+ case 'section':
+ return "\$_smarty_tpl->getVariable('smarty')->value$parameter";
+ case 'capture':
+ return "Smarty::\$_smarty_vars$parameter";
+ case 'now':
+ return 'time()';
+ case 'cookies':
+ if (isset($compiler->smarty->security_policy) && !$compiler->smarty->security_policy->allow_super_globals) {
+ $compiler->trigger_template_error("(secure mode) super globals not permitted");
+ break;
+ }
+ $compiled_ref = '$_COOKIE';
+ break;
+
+ case 'get':
+ case 'post':
+ case 'env':
+ case 'server':
+ case 'session':
+ case 'request':
+ if (isset($compiler->smarty->security_policy) && !$compiler->smarty->security_policy->allow_super_globals) {
+ $compiler->trigger_template_error("(secure mode) super globals not permitted");
+ break;
+ }
+ $compiled_ref = '$_' . strtoupper($variable);
+ break;
+
+ case 'template':
+ return 'basename($_smarty_tpl->source->filepath)';
+
+ case 'template_object':
+ return '$_smarty_tpl';
+
+ case 'current_dir':
+ return 'dirname($_smarty_tpl->source->filepath)';
+
+ case 'version':
+ $_version = Smarty::SMARTY_VERSION;
+
+ return "'$_version'";
+
+ case 'const':
+ if (isset($compiler->smarty->security_policy) && !$compiler->smarty->security_policy->allow_constants) {
+ $compiler->trigger_template_error("(secure mode) constants not permitted");
+ break;
+ }
+ if (strpos($_index[1], '$') === false && strpos($_index[1], '\'') === false) {
+ return "@constant('{$_index[1]}')";
+ } else {
+ return "@constant({$_index[1]})";
+ }
+
+ case 'config':
+ if (isset($_index[2])) {
+ return "(is_array(\$tmp = \$_smarty_tpl->getConfigVariable($_index[1])) ? \$tmp[$_index[2]] : null)";
+ } else {
+ return "\$_smarty_tpl->getConfigVariable($_index[1])";
+ }
+ case 'ldelim':
+ $_ldelim = $compiler->smarty->left_delimiter;
+
+ return "'$_ldelim'";
+
+ case 'rdelim':
+ $_rdelim = $compiler->smarty->right_delimiter;
+
+ return "'$_rdelim'";
+
+ default:
+ $compiler->trigger_template_error('$smarty.' . trim($_index[0], "'") . ' is invalid');
+ break;
+ }
+ if (isset($_index[1])) {
+ array_shift($_index);
+ foreach ($_index as $_ind) {
+ $compiled_ref = $compiled_ref . "[$_ind]";
+ }
+ }
+ }
+ return $compiled_ref;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_rdelim.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Rdelim
+ * Compiles the {rdelim} tag
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Rdelim Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Rdelim extends Smarty_Internal_CompileBase {
+ /**
+ * Compiles code for the {rdelim} tag
+ * This tag does output the right delimiter.
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler) {
+ $_attr = $this->getAttributes($compiler, $args);
+ if ($_attr['nocache'] === true) {
+ $compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
+ }
+ // this tag does not return compiled code
+ $compiler->has_code = true;
+
+ return $compiler->smarty->right_delimiter;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_section.php
@@ -0,0 +1,200 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Section
+ * Compiles the {section} {sectionelse} {/section} tags
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Section Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Section extends Smarty_Internal_CompileBase {
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $required_attributes = array('name', 'loop');
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $shorttag_order = array('name', 'loop');
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $optional_attributes = array('start', 'step', 'max', 'show');
+
+ /**
+ * Compiles code for the {section} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler) {
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+
+ $this->openTag($compiler, 'section', array('section', $compiler->nocache));
+ // maybe nocache because of nocache variables
+ $compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
+
+ $output = "<?php ";
+
+ $section_name = $_attr['name'];
+
+ $output .= "if (isset(\$_smarty_tpl->tpl_vars['smarty']->value['section'][$section_name])) unset(\$_smarty_tpl->tpl_vars['smarty']->value['section'][$section_name]);\n";
+ $section_props = "\$_smarty_tpl->tpl_vars['smarty']->value['section'][$section_name]";
+
+ foreach ($_attr as $attr_name => $attr_value) {
+ switch ($attr_name) {
+ case 'loop':
+ $output .= "{$section_props}['loop'] = is_array(\$_loop=$attr_value) ? count(\$_loop) : max(0, (int) \$_loop); unset(\$_loop);\n";
+ break;
+
+ case 'show':
+ if (is_bool($attr_value)) {
+ $show_attr_value = $attr_value ? 'true' : 'false';
+ } else {
+ $show_attr_value = "(bool) $attr_value";
+ }
+ $output .= "{$section_props}['show'] = $show_attr_value;\n";
+ break;
+
+ case 'name':
+ $output .= "{$section_props}['$attr_name'] = $attr_value;\n";
+ break;
+
+ case 'max':
+ case 'start':
+ $output .= "{$section_props}['$attr_name'] = (int) $attr_value;\n";
+ break;
+
+ case 'step':
+ $output .= "{$section_props}['$attr_name'] = ((int) $attr_value) == 0 ? 1 : (int) $attr_value;\n";
+ break;
+ }
+ }
+
+ if (!isset($_attr['show'])) {
+ $output .= "{$section_props}['show'] = true;\n";
+ }
+
+ if (!isset($_attr['loop'])) {
+ $output .= "{$section_props}['loop'] = 1;\n";
+ }
+
+ if (!isset($_attr['max'])) {
+ $output .= "{$section_props}['max'] = {$section_props}['loop'];\n";
+ } else {
+ $output .= "if ({$section_props}['max'] < 0)\n" . " {$section_props}['max'] = {$section_props}['loop'];\n";
+ }
+
+ if (!isset($_attr['step'])) {
+ $output .= "{$section_props}['step'] = 1;\n";
+ }
+
+ if (!isset($_attr['start'])) {
+ $output .= "{$section_props}['start'] = {$section_props}['step'] > 0 ? 0 : {$section_props}['loop']-1;\n";
+ } else {
+ $output .= "if ({$section_props}['start'] < 0)\n" . " {$section_props}['start'] = max({$section_props}['step'] > 0 ? 0 : -1, {$section_props}['loop'] + {$section_props}['start']);\n" . "else\n" . " {$section_props}['start'] = min({$section_props}['start'], {$section_props}['step'] > 0 ? {$section_props}['loop'] : {$section_props}['loop']-1);\n";
+ }
+
+ $output .= "if ({$section_props}['show']) {\n";
+ if (!isset($_attr['start']) && !isset($_attr['step']) && !isset($_attr['max'])) {
+ $output .= " {$section_props}['total'] = {$section_props}['loop'];\n";
+ } else {
+ $output .= " {$section_props}['total'] = min(ceil(({$section_props}['step'] > 0 ? {$section_props}['loop'] - {$section_props}['start'] : {$section_props}['start']+1)/abs({$section_props}['step'])), {$section_props}['max']);\n";
+ }
+ $output .= " if ({$section_props}['total'] == 0)\n" . " {$section_props}['show'] = false;\n" . "} else\n" . " {$section_props}['total'] = 0;\n";
+
+ $output .= "if ({$section_props}['show']):\n";
+ $output .= "
+ for ({$section_props}['index'] = {$section_props}['start'], {$section_props}['iteration'] = 1;
+ {$section_props}['iteration'] <= {$section_props}['total'];
+ {$section_props}['index'] += {$section_props}['step'], {$section_props}['iteration']++):\n";
+ $output .= "{$section_props}['rownum'] = {$section_props}['iteration'];\n";
+ $output .= "{$section_props}['index_prev'] = {$section_props}['index'] - {$section_props}['step'];\n";
+ $output .= "{$section_props}['index_next'] = {$section_props}['index'] + {$section_props}['step'];\n";
+ $output .= "{$section_props}['first'] = ({$section_props}['iteration'] == 1);\n";
+ $output .= "{$section_props}['last'] = ({$section_props}['iteration'] == {$section_props}['total']);\n";
+
+ $output .= "?>";
+
+ return $output;
+ }
+}
+
+/**
+ * Smarty Internal Plugin Compile Sectionelse Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Sectionelse extends Smarty_Internal_CompileBase {
+ /**
+ * Compiles code for the {sectionelse} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler) {
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+
+ list($openTag, $nocache) = $this->closeTag($compiler, array('section'));
+ $this->openTag($compiler, 'sectionelse', array('sectionelse', $nocache));
+
+ return "<?php endfor; else: ?>";
+ }
+}
+
+/**
+ * Smarty Internal Plugin Compile Sectionclose Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Sectionclose extends Smarty_Internal_CompileBase {
+ /**
+ * Compiles code for the {/section} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler) {
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+
+ // must endblock be nocache?
+ if ($compiler->nocache) {
+ $compiler->tag_nocache = true;
+ }
+
+ list($openTag, $compiler->nocache) = $this->closeTag($compiler, array('section', 'sectionelse'));
+
+ if ($openTag == 'sectionelse') {
+ return "<?php endif; ?>";
+ } else {
+ return "<?php endfor; endif; ?>";
+ }
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_setfilter.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile Setfilter
+ * Compiles code for setfilter tag
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Setfilter Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Setfilter extends Smarty_Internal_CompileBase {
+ /**
+ * Compiles code for setfilter tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter) {
+ $compiler->variable_filter_stack[] = $compiler->template->variable_filters;
+ $compiler->template->variable_filters = $parameter['modifier_list'];
+ // this tag does not return compiled code
+ $compiler->has_code = false;
+
+ return true;
+ }
+}
+
+/**
+ * Smarty Internal Plugin Compile Setfilterclose Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Setfilterclose extends Smarty_Internal_CompileBase {
+ /**
+ * Compiles code for the {/setfilter} tag
+ * This tag does not generate compiled output. It resets variable filter.
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler) {
+ $_attr = $this->getAttributes($compiler, $args);
+ // reset variable filter to previous state
+ if (count($compiler->variable_filter_stack)) {
+ $compiler->template->variable_filters = array_pop($compiler->variable_filter_stack);
+ } else {
+ $compiler->template->variable_filters = array();
+ }
+ // this tag does not return compiled code
+ $compiler->has_code = false;
+
+ return true;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compile_while.php
@@ -0,0 +1,94 @@
+<?php
+/**
+ * Smarty Internal Plugin Compile While
+ * Compiles the {while} tag
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile While Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_While extends Smarty_Internal_CompileBase {
+ /**
+ * Compiles code for the {while} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter) {
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+ $this->openTag($compiler, 'while', $compiler->nocache);
+
+ if (!array_key_exists("if condition", $parameter)) {
+ $compiler->trigger_template_error("missing while condition", $compiler->lex->taglineno);
+ }
+
+ // maybe nocache because of nocache variables
+ $compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
+ if (is_array($parameter['if condition'])) {
+ if ($compiler->nocache) {
+ $_nocache = ',true';
+ // create nocache var to make it know for further compiling
+ if (is_array($parameter['if condition']['var'])) {
+ $var = trim($parameter['if condition']['var']['var'], "'");
+ } else {
+ $var = trim($parameter['if condition']['var'], "'");
+ }
+ if (isset($compiler->template->tpl_vars[$var])) {
+ $compiler->template->tpl_vars[$var]->nocache = true;
+ } else {
+ $compiler->template->tpl_vars[$var] = new Smarty_Variable(null, true);
+ }
+ } else {
+ $_nocache = '';
+ }
+ if (is_array($parameter['if condition']['var'])) {
+ $_output = "<?php if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]) || !is_array(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value)) \$_smarty_tpl->createLocalArrayVariable(" . $parameter['if condition']['var']['var'] . "$_nocache);\n";
+ $_output .= "while (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value" . $parameter['if condition']['var']['smarty_internal_index'] . " = " . $parameter['if condition']['value'] . ") {?>";
+ } else {
+ $_output = "<?php if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "])) \$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "] = new Smarty_Variable(null{$_nocache});";
+ $_output .= "while (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "]->value = " . $parameter['if condition']['value'] . ") {?>";
+ }
+
+ return $_output;
+ } else {
+ return "<?php while ({$parameter['if condition']}) {?>";
+ }
+ }
+}
+
+/**
+ * Smarty Internal Plugin Compile Whileclose Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Whileclose extends Smarty_Internal_CompileBase {
+ /**
+ * Compiles code for the {/while} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ *
+ * @return string compiled code
+ */
+ public function compile($args, $compiler) {
+ // must endblock be nocache?
+ if ($compiler->nocache) {
+ $compiler->tag_nocache = true;
+ }
+ $compiler->nocache = $this->closeTag($compiler, array('while'));
+
+ return "<?php }?>";
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_compilebase.php
@@ -0,0 +1,170 @@
+<?php
+/**
+ * Smarty Internal Plugin CompileBase
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * This class does extend all internal compile plugins
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+abstract class Smarty_Internal_CompileBase {
+ /**
+ * Array of names of required attribute required by tag
+ *
+ * @var array
+ */
+ public $required_attributes = array();
+ /**
+ * Array of names of optional attribute required by tag
+ * use array('_any') if there is no restriction of attributes names
+ *
+ * @var array
+ */
+ public $optional_attributes = array();
+ /**
+ * Shorttag attribute order defined by its names
+ *
+ * @var array
+ */
+ public $shorttag_order = array();
+ /**
+ * Array of names of valid option flags
+ *
+ * @var array
+ */
+ public $option_flags = array('nocache');
+
+ /**
+ * This function checks if the attributes passed are valid
+ * The attributes passed for the tag to compile are checked against the list of required and
+ * optional attributes. Required attributes must be present. Optional attributes are check against
+ * the corresponding list. The keyword '_any' specifies that any attribute will be accepted
+ * as valid
+ *
+ * @param object $compiler compiler object
+ * @param array $attributes attributes applied to the tag
+ *
+ * @return array of mapped attributes for further processing
+ */
+ public function getAttributes($compiler, $attributes) {
+ $_indexed_attr = array();
+ // loop over attributes
+ foreach ($attributes as $key => $mixed) {
+ // shorthand ?
+ if (!is_array($mixed)) {
+ // option flag ?
+ if (in_array(trim($mixed, '\'"'), $this->option_flags)) {
+ $_indexed_attr[trim($mixed, '\'"')] = true;
+ // shorthand attribute ?
+ } elseif (isset($this->shorttag_order[$key])) {
+ $_indexed_attr[$this->shorttag_order[$key]] = $mixed;
+ } else {
+ // too many shorthands
+ $compiler->trigger_template_error('too many shorthand attributes', $compiler->lex->taglineno);
+ }
+ // named attribute
+ } else {
+ $kv = each($mixed);
+ // option flag?
+ if (in_array($kv['key'], $this->option_flags)) {
+ if (is_bool($kv['value'])) {
+ $_indexed_attr[$kv['key']] = $kv['value'];
+ } elseif (is_string($kv['value']) && in_array(trim($kv['value'], '\'"'), array('true', 'false'))) {
+ if (trim($kv['value']) == 'true') {
+ $_indexed_attr[$kv['key']] = true;
+ } else {
+ $_indexed_attr[$kv['key']] = false;
+ }
+ } elseif (is_numeric($kv['value']) && in_array($kv['value'], array(0, 1))) {
+ if ($kv['value'] == 1) {
+ $_indexed_attr[$kv['key']] = true;
+ } else {
+ $_indexed_attr[$kv['key']] = false;
+ }
+ } else {
+ $compiler->trigger_template_error("illegal value of option flag \"{$kv['key']}\"", $compiler->lex->taglineno);
+ }
+ // must be named attribute
+ } else {
+ reset($mixed);
+ $_indexed_attr[key($mixed)] = $mixed[key($mixed)];
+ }
+ }
+ }
+ // check if all required attributes present
+ foreach ($this->required_attributes as $attr) {
+ if (!array_key_exists($attr, $_indexed_attr)) {
+ $compiler->trigger_template_error("missing \"" . $attr . "\" attribute", $compiler->lex->taglineno);
+ }
+ }
+ // check for not allowed attributes
+ if ($this->optional_attributes != array('_any')) {
+ $tmp_array = array_merge($this->required_attributes, $this->optional_attributes, $this->option_flags);
+ foreach ($_indexed_attr as $key => $dummy) {
+ if (!in_array($key, $tmp_array) && $key !== 0) {
+ $compiler->trigger_template_error("unexpected \"" . $key . "\" attribute", $compiler->lex->taglineno);
+ }
+ }
+ }
+ // default 'false' for all option flags not set
+ foreach ($this->option_flags as $flag) {
+ if (!isset($_indexed_attr[$flag])) {
+ $_indexed_attr[$flag] = false;
+ }
+ }
+
+ return $_indexed_attr;
+ }
+
+ /**
+ * Push opening tag name on stack
+ * Optionally additional data can be saved on stack
+ *
+ * @param object $compiler compiler object
+ * @param string $openTag the opening tag's name
+ * @param mixed $data optional data saved
+ */
+ public function openTag($compiler, $openTag, $data = null) {
+ array_push($compiler->_tag_stack, array($openTag, $data));
+ }
+
+ /**
+ * Pop closing tag
+ * Raise an error if this stack-top doesn't match with expected opening tags
+ *
+ * @param object $compiler compiler object
+ * @param array|string $expectedTag the expected opening tag names
+ *
+ * @return mixed any type the opening tag's name or saved data
+ */
+ public function closeTag($compiler, $expectedTag) {
+ if (count($compiler->_tag_stack) > 0) {
+ // get stacked info
+ list($_openTag, $_data) = array_pop($compiler->_tag_stack);
+ // open tag must match with the expected ones
+ if (in_array($_openTag, (array)$expectedTag)) {
+ if (is_null($_data)) {
+ // return opening tag
+ return $_openTag;
+ } else {
+ // return restored data
+ return $_data;
+ }
+ }
+ // wrong nesting of tags
+ $compiler->trigger_template_error("unclosed {$compiler->smarty->left_delimiter}" . $_openTag . "{$compiler->smarty->right_delimiter} tag");
+
+ return;
+ }
+ // wrong nesting of tags
+ $compiler->trigger_template_error("unexpected closing tag", $compiler->lex->taglineno);
+
+ return;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_config_file_compiler.php
@@ -0,0 +1,186 @@
+<?php
+/**
+ * Smarty Internal Plugin Config File Compiler
+ * This is the config file compiler class. It calls the lexer and parser to
+ * perform the compiling.
+ *
+ * @package Smarty
+ * @subpackage Config
+ * @author Uwe Tews
+ */
+
+/**
+ * Main config file compiler class
+ *
+ * @package Smarty
+ * @subpackage Config
+ */
+class Smarty_Internal_Config_File_Compiler {
+ /**
+ * Lexer class name
+ *
+ * @var string
+ */
+ public $lexer_class;
+
+ /**
+ * Parser class name
+ *
+ * @var string
+ */
+ public $parser_class;
+ /**
+ * Lexer object
+ *
+ * @var object
+ */
+ public $lex;
+
+ /**
+ * Parser object
+ *
+ * @var object
+ */
+ public $parser;
+
+ /**
+ * Smarty object
+ *
+ * @var Smarty object
+ */
+ public $smarty;
+
+ /**
+ * Smarty object
+ *
+ * @var Smarty_Internal_Template object
+ */
+ public $template;
+
+ /**
+ * Compiled config data sections and variables
+ *
+ * @var array
+ */
+ public $config_data = array();
+
+ /**
+ * compiled config data must always be written
+ *
+ * @var bool
+ */
+ public $write_compiled_code = true;
+
+ /**
+ * Initialize compiler
+ *
+ * @param string $lexer_class class name
+ * @param string $parser_class class name
+ * @param Smarty $smarty global instance
+ */
+ public function __construct($lexer_class, $parser_class, Smarty $smarty) {
+ $this->smarty = $smarty;
+ // get required plugins
+ $this->lexer_class = $lexer_class;
+ $this->parser_class = $parser_class;
+ $this->smarty = $smarty;
+ $this->config_data['sections'] = array();
+ $this->config_data['vars'] = array();
+ }
+
+ /**
+ * Method to compile Smarty config source.
+ *
+ * @param Smarty_Internal_Template $template
+ *
+ * @return bool true if compiling succeeded, false if it failed
+ */
+ public function compileTemplate(Smarty_Internal_Template $template) {
+ $this->template = $template;
+ $this->template->properties['file_dependency'][$this->template->source->uid] = array($this->template->source->name, $this->template->source->timestamp, $this->template->source->type);
+ // on empty config just return
+ if ($template->source->content == '') {
+ return true;
+ }
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::start_compile($this->template);
+ }
+ // init the lexer/parser to compile the config file
+ $lex = new $this->lexer_class(str_replace(array("\r\n", "\r"), "\n", $template->source->content) . "\n", $this);
+ $parser = new $this->parser_class($lex, $this);
+
+ if (function_exists('mb_internal_encoding') && ((int)ini_get('mbstring.func_overload')) & 2) {
+ $mbEncoding = mb_internal_encoding();
+ mb_internal_encoding('ASCII');
+ } else {
+ $mbEncoding = null;
+ }
+
+ if ($this->smarty->_parserdebug) {
+ $parser->PrintTrace();
+ }
+ // get tokens from lexer and parse them
+ while ($lex->yylex()) {
+ if ($this->smarty->_parserdebug) {
+ echo "<br>Parsing {$parser->yyTokenName[$lex->token]} Token {$lex->value} Line {$lex->line} \n";
+ }
+ $parser->doParse($lex->token, $lex->value);
+ }
+ // finish parsing process
+ $parser->doParse(0, 0);
+
+ if ($mbEncoding) {
+ mb_internal_encoding($mbEncoding);
+ }
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::end_compile($this->template);
+ }
+ // template header code
+ $template_header = "<?php /* Smarty version " . Smarty::SMARTY_VERSION . ", created on " . strftime("%Y-%m-%d %H:%M:%S") . "\n";
+ $template_header .= " compiled from \"" . $this->template->source->filepath . "\" */ ?>\n";
+
+ $code = '<?php Smarty_Internal_Extension_Config::loadConfigVars($_smarty_tpl, ' . var_export($this->config_data, true) . '); ?>';
+ return $template_header . Smarty_Internal_Extension_CodeFrame::create($this->template, $code);
+ }
+
+ /**
+ * display compiler error messages without dying
+ * If parameter $args is empty it is a parser detected syntax error.
+ * In this case the parser is called to obtain information about expected tokens.
+ * If parameter $args contains a string this is used as error message
+ *
+ * @param string $args individual error message or null
+ *
+ * @throws SmartyCompilerException
+ */
+ public function trigger_config_file_error($args = null) {
+ $this->lex = Smarty_Internal_Configfilelexer::instance();
+ $this->parser = Smarty_Internal_Configfileparser::instance();
+ // get config source line which has error
+ $line = $this->lex->line;
+ if (isset($args)) {
+ // $line--;
+ }
+ $match = preg_split("/\n/", $this->lex->data);
+ $error_text = "Syntax error in config file '{$this->template->source->filepath}' on line {$line} '{$match[$line - 1]}' ";
+ if (isset($args)) {
+ // individual error message
+ $error_text .= $args;
+ } else {
+ // expected token from parser
+ foreach ($this->parser->yy_get_expected_tokens($this->parser->yymajor) as $token) {
+ $exp_token = $this->parser->yyTokenName[$token];
+ if (isset($this->lex->smarty_token_names[$exp_token])) {
+ // token type from lexer
+ $expect[] = '"' . $this->lex->smarty_token_names[$exp_token] . '"';
+ } else {
+ // otherwise internal token name
+ $expect[] = $this->parser->yyTokenName[$token];
+ }
+ }
+ // output parser error message
+ $error_text .= ' - Unexpected "' . $this->lex->value . '", expected one of: ' . implode(' , ', $expect);
+ }
+ throw new SmartyCompilerException($error_text);
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_configfilelexer.php
@@ -0,0 +1,660 @@
+<?php
+/**
+ * Smarty Internal Plugin Configfilelexer
+ *
+ * This is the lexer to break the config file source into tokens
+ *
+ * @package Smarty
+ * @subpackage Config
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty_Internal_Configfilelexer
+ *
+ * This is the config file lexer.
+ * It is generated from the smarty_internal_configfilelexer.plex file
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+class Smarty_Internal_Configfilelexer {
+ /**
+ * Source
+ *
+ * @var string
+ */
+ public $data;
+
+ /**
+ * byte counter
+ *
+ * @var int
+ */
+ public $counter;
+
+ /**
+ * token number
+ *
+ * @var int
+ */
+ public $token;
+
+ /**
+ * token value
+ *
+ * @var string
+ */
+ public $value;
+
+ /**
+ * current line
+ *
+ * @var int
+ */
+ public $line;
+
+ /**
+ * state number
+ *
+ * @var int
+ */
+ public $state = 1;
+
+ /**
+ * Smarty object
+ *
+ * @var Smarty
+ */
+ public $smarty = null;
+
+ /**
+ * compiler object
+ *
+ * @var Smarty_Internal_Config_File_Compiler
+ */
+ private $compiler = null;
+
+ /**
+ * copy of config_booleanize
+ *
+ * @var bool
+ */
+ private $configBooleanize = false;
+
+ /**
+ * trace file
+ *
+ * @var resource
+ */
+ public $yyTraceFILE;
+
+ /**
+ * trace prompt
+ *
+ * @var string
+ */
+ public $yyTracePrompt;
+
+ /**
+ * state names
+ *
+ * @var array
+ */
+ public $state_name = array(1 => 'START', 2 => 'VALUE', 3 => 'NAKED_STRING_VALUE', 4 => 'COMMENT', 5 => 'SECTION',
+ 6 => 'TRIPPLE');
+
+ /**
+ * storage for assembled token patterns
+ *
+ * @var sring
+ */
+ private $yy_global_pattern1 = null;
+
+ private $yy_global_pattern2 = null;
+
+ private $yy_global_pattern3 = null;
+
+ private $yy_global_pattern4 = null;
+
+ private $yy_global_pattern5 = null;
+
+ private $yy_global_pattern6 = null;
+
+ /**
+ * token names
+ *
+ * @var array
+ */
+ public $smarty_token_names = array( // Text for parser error messages
+ );
+
+ /**
+ * constructor
+ *
+ * @param string $data template source
+ * @param Smarty_Internal_Config_File_Compiler $compiler
+ */
+ function __construct($data, Smarty_Internal_Config_File_Compiler $compiler) {
+ // set instance object
+ self::instance($this);
+ $this->data = $data . "\n"; //now all lines are \n-terminated
+ $this->counter = 0;
+ if (preg_match('/^\xEF\xBB\xBF/', $this->data, $match)) {
+ $this->counter += strlen($match[0]);
+ }
+ $this->line = 1;
+ $this->compiler = $compiler;
+ $this->smarty = $compiler->smarty;
+ $this->configBooleanize = $this->smarty->config_booleanize;
+ }
+
+ public static function &instance($new_instance = null) {
+ static $instance = null;
+ if (isset($new_instance) && is_object($new_instance)) {
+ $instance = $new_instance;
+ }
+ return $instance;
+ }
+
+ public function PrintTrace() {
+ $this->yyTraceFILE = fopen('php://output', 'w');
+ $this->yyTracePrompt = '<br>';
+ }
+
+ private $_yy_state = 1;
+
+ private $_yy_stack = array();
+
+ public function yylex() {
+ return $this->{'yylex' . $this->_yy_state}();
+ }
+
+ public function yypushstate($state) {
+ if ($this->yyTraceFILE) {
+ fprintf($this->yyTraceFILE, "%sState push %s\n", $this->yyTracePrompt, isset($this->state_name[$this->_yy_state]) ? $this->state_name[$this->_yy_state] : $this->_yy_state);
+ }
+ array_push($this->_yy_stack, $this->_yy_state);
+ $this->_yy_state = $state;
+ if ($this->yyTraceFILE) {
+ fprintf($this->yyTraceFILE, "%snew State %s\n", $this->yyTracePrompt, isset($this->state_name[$this->_yy_state]) ? $this->state_name[$this->_yy_state] : $this->_yy_state);
+ }
+ }
+
+ public function yypopstate() {
+ if ($this->yyTraceFILE) {
+ fprintf($this->yyTraceFILE, "%sState pop %s\n", $this->yyTracePrompt, isset($this->state_name[$this->_yy_state]) ? $this->state_name[$this->_yy_state] : $this->_yy_state);
+ }
+ $this->_yy_state = array_pop($this->_yy_stack);
+ if ($this->yyTraceFILE) {
+ fprintf($this->yyTraceFILE, "%snew State %s\n", $this->yyTracePrompt, isset($this->state_name[$this->_yy_state]) ? $this->state_name[$this->_yy_state] : $this->_yy_state);
+ }
+ }
+
+ public function yybegin($state) {
+ $this->_yy_state = $state;
+ if ($this->yyTraceFILE) {
+ fprintf($this->yyTraceFILE, "%sState set %s\n", $this->yyTracePrompt, isset($this->state_name[$this->_yy_state]) ? $this->state_name[$this->_yy_state] : $this->_yy_state);
+ }
+ }
+
+ public function yylex1() {
+ if (!isset($this->yy_global_pattern1)) {
+ $this->yy_global_pattern1 = "/\G(#|;)|\G(\\[)|\G(\\])|\G(=)|\G([ \t\r]+)|\G(\n)|\G([0-9]*[a-zA-Z_]\\w*)|\G([\S\s])/isS";
+ }
+ if ($this->counter >= strlen($this->data)) {
+ return false; // end of input
+ }
+
+ do {
+ if (preg_match($this->yy_global_pattern1, $this->data, $yymatches, null, $this->counter)) {
+ $yysubmatches = $yymatches;
+ if (strlen($yysubmatches[0]) < 200) {
+ $yymatches = preg_grep("/(.|\s)+/", $yysubmatches);
+ } else {
+ $yymatches = array_filter($yymatches, 'strlen');
+ }
+ if (empty($yymatches)) {
+ throw new Exception('Error: lexing failed because a rule matched' . ' an empty string. Input "' . substr($this->data, $this->counter, 5) . '... state START');
+ }
+ next($yymatches); // skip global match
+ $this->token = key($yymatches); // token number
+ $this->value = current($yymatches); // token value
+ $r = $this->{'yy_r1_' . $this->token}();
+ if ($r === null) {
+ $this->counter += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ // accept this token
+ return true;
+ } elseif ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ $this->counter += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ if ($this->counter >= strlen($this->data)) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ }
+ } else {
+ throw new Exception('Unexpected input at line' . $this->line . ': ' . $this->data[$this->counter]);
+ }
+ break;
+ } while (true);
+ } // end function
+
+ const START = 1;
+
+ function yy_r1_1() {
+
+ $this->token = Smarty_Internal_Configfileparser::TPC_COMMENTSTART;
+ $this->yypushstate(self::COMMENT);
+ }
+
+ function yy_r1_2() {
+
+ $this->token = Smarty_Internal_Configfileparser::TPC_OPENB;
+ $this->yypushstate(self::SECTION);
+ }
+
+ function yy_r1_3() {
+
+ $this->token = Smarty_Internal_Configfileparser::TPC_CLOSEB;
+ }
+
+ function yy_r1_4() {
+
+ $this->token = Smarty_Internal_Configfileparser::TPC_EQUAL;
+ $this->yypushstate(self::VALUE);
+ }
+
+ function yy_r1_5() {
+
+ return false;
+ }
+
+ function yy_r1_6() {
+
+ $this->token = Smarty_Internal_Configfileparser::TPC_NEWLINE;
+ }
+
+ function yy_r1_7() {
+
+ $this->token = Smarty_Internal_Configfileparser::TPC_ID;
+ }
+
+ function yy_r1_8() {
+
+ $this->token = Smarty_Internal_Configfileparser::TPC_OTHER;
+ }
+
+ public function yylex2() {
+ if (!isset($this->yy_global_pattern2)) {
+ $this->yy_global_pattern2 = "/\G([ \t\r]+)|\G(\\d+\\.\\d+(?=[ \t\r]*[\n#;]))|\G(\\d+(?=[ \t\r]*[\n#;]))|\G(\"\"\")|\G('[^'\\\\]*(?:\\\\.[^'\\\\]*)*'(?=[ \t\r]*[\n#;]))|\G(\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\"(?=[ \t\r]*[\n#;]))|\G([a-zA-Z]+(?=[ \t\r]*[\n#;]))|\G([^\n]+?(?=[ \t\r]*\n))|\G(\n)/isS";
+ }
+ if ($this->counter >= strlen($this->data)) {
+ return false; // end of input
+ }
+
+ do {
+ if (preg_match($this->yy_global_pattern2, $this->data, $yymatches, null, $this->counter)) {
+ $yysubmatches = $yymatches;
+ if (strlen($yysubmatches[0]) < 200) {
+ $yymatches = preg_grep("/(.|\s)+/", $yysubmatches);
+ } else {
+ $yymatches = array_filter($yymatches, 'strlen');
+ }
+ if (empty($yymatches)) {
+ throw new Exception('Error: lexing failed because a rule matched' . ' an empty string. Input "' . substr($this->data, $this->counter, 5) . '... state VALUE');
+ }
+ next($yymatches); // skip global match
+ $this->token = key($yymatches); // token number
+ $this->value = current($yymatches); // token value
+ $r = $this->{'yy_r2_' . $this->token}();
+ if ($r === null) {
+ $this->counter += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ // accept this token
+ return true;
+ } elseif ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ $this->counter += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ if ($this->counter >= strlen($this->data)) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ }
+ } else {
+ throw new Exception('Unexpected input at line' . $this->line . ': ' . $this->data[$this->counter]);
+ }
+ break;
+ } while (true);
+ } // end function
+
+ const VALUE = 2;
+
+ function yy_r2_1() {
+
+ return false;
+ }
+
+ function yy_r2_2() {
+
+ $this->token = Smarty_Internal_Configfileparser::TPC_FLOAT;
+ $this->yypopstate();
+ }
+
+ function yy_r2_3() {
+
+ $this->token = Smarty_Internal_Configfileparser::TPC_INT;
+ $this->yypopstate();
+ }
+
+ function yy_r2_4() {
+
+ $this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_QUOTES;
+ $this->yypushstate(self::TRIPPLE);
+ }
+
+ function yy_r2_5() {
+
+ $this->token = Smarty_Internal_Configfileparser::TPC_SINGLE_QUOTED_STRING;
+ $this->yypopstate();
+ }
+
+ function yy_r2_6() {
+
+ $this->token = Smarty_Internal_Configfileparser::TPC_DOUBLE_QUOTED_STRING;
+ $this->yypopstate();
+ }
+
+ function yy_r2_7() {
+
+ if (!$this->configBooleanize || !in_array(strtolower($this->value), Array("true", "false", "on", "off", "yes",
+ "no"))
+ ) {
+ $this->yypopstate();
+ $this->yypushstate(self::NAKED_STRING_VALUE);
+ return true; //reprocess in new state
+ } else {
+ $this->token = Smarty_Internal_Configfileparser::TPC_BOOL;
+ $this->yypopstate();
+ }
+ }
+
+ function yy_r2_8() {
+
+ $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
+ $this->yypopstate();
+ }
+
+ function yy_r2_9() {
+
+ $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
+ $this->value = "";
+ $this->yypopstate();
+ }
+
+ public function yylex3() {
+ if (!isset($this->yy_global_pattern3)) {
+ $this->yy_global_pattern3 = "/\G([^\n]+?(?=[ \t\r]*\n))/isS";
+ }
+ if ($this->counter >= strlen($this->data)) {
+ return false; // end of input
+ }
+
+ do {
+ if (preg_match($this->yy_global_pattern3, $this->data, $yymatches, null, $this->counter)) {
+ $yysubmatches = $yymatches;
+ if (strlen($yysubmatches[0]) < 200) {
+ $yymatches = preg_grep("/(.|\s)+/", $yysubmatches);
+ } else {
+ $yymatches = array_filter($yymatches, 'strlen');
+ }
+ if (empty($yymatches)) {
+ throw new Exception('Error: lexing failed because a rule matched' . ' an empty string. Input "' . substr($this->data, $this->counter, 5) . '... state NAKED_STRING_VALUE');
+ }
+ next($yymatches); // skip global match
+ $this->token = key($yymatches); // token number
+ $this->value = current($yymatches); // token value
+ $r = $this->{'yy_r3_' . $this->token}();
+ if ($r === null) {
+ $this->counter += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ // accept this token
+ return true;
+ } elseif ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ $this->counter += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ if ($this->counter >= strlen($this->data)) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ }
+ } else {
+ throw new Exception('Unexpected input at line' . $this->line . ': ' . $this->data[$this->counter]);
+ }
+ break;
+ } while (true);
+ } // end function
+
+ const NAKED_STRING_VALUE = 3;
+
+ function yy_r3_1() {
+
+ $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
+ $this->yypopstate();
+ }
+
+ public function yylex4() {
+ if (!isset($this->yy_global_pattern4)) {
+ $this->yy_global_pattern4 = "/\G([ \t\r]+)|\G([^\n]+?(?=[ \t\r]*\n))|\G(\n)/isS";
+ }
+ if ($this->counter >= strlen($this->data)) {
+ return false; // end of input
+ }
+
+ do {
+ if (preg_match($this->yy_global_pattern4, $this->data, $yymatches, null, $this->counter)) {
+ $yysubmatches = $yymatches;
+ if (strlen($yysubmatches[0]) < 200) {
+ $yymatches = preg_grep("/(.|\s)+/", $yysubmatches);
+ } else {
+ $yymatches = array_filter($yymatches, 'strlen');
+ }
+ if (empty($yymatches)) {
+ throw new Exception('Error: lexing failed because a rule matched' . ' an empty string. Input "' . substr($this->data, $this->counter, 5) . '... state COMMENT');
+ }
+ next($yymatches); // skip global match
+ $this->token = key($yymatches); // token number
+ $this->value = current($yymatches); // token value
+ $r = $this->{'yy_r4_' . $this->token}();
+ if ($r === null) {
+ $this->counter += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ // accept this token
+ return true;
+ } elseif ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ $this->counter += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ if ($this->counter >= strlen($this->data)) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ }
+ } else {
+ throw new Exception('Unexpected input at line' . $this->line . ': ' . $this->data[$this->counter]);
+ }
+ break;
+ } while (true);
+ } // end function
+
+ const COMMENT = 4;
+
+ function yy_r4_1() {
+
+ return false;
+ }
+
+ function yy_r4_2() {
+
+ $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
+ }
+
+ function yy_r4_3() {
+
+ $this->token = Smarty_Internal_Configfileparser::TPC_NEWLINE;
+ $this->yypopstate();
+ }
+
+ public function yylex5() {
+ if (!isset($this->yy_global_pattern5)) {
+ $this->yy_global_pattern5 = "/\G(\\.)|\G(.*?(?=[\.=[\]\r\n]))/isS";
+ }
+ if ($this->counter >= strlen($this->data)) {
+ return false; // end of input
+ }
+
+ do {
+ if (preg_match($this->yy_global_pattern5, $this->data, $yymatches, null, $this->counter)) {
+ $yysubmatches = $yymatches;
+ if (strlen($yysubmatches[0]) < 200) {
+ $yymatches = preg_grep("/(.|\s)+/", $yysubmatches);
+ } else {
+ $yymatches = array_filter($yymatches, 'strlen');
+ }
+ if (empty($yymatches)) {
+ throw new Exception('Error: lexing failed because a rule matched' . ' an empty string. Input "' . substr($this->data, $this->counter, 5) . '... state SECTION');
+ }
+ next($yymatches); // skip global match
+ $this->token = key($yymatches); // token number
+ $this->value = current($yymatches); // token value
+ $r = $this->{'yy_r5_' . $this->token}();
+ if ($r === null) {
+ $this->counter += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ // accept this token
+ return true;
+ } elseif ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ $this->counter += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ if ($this->counter >= strlen($this->data)) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ }
+ } else {
+ throw new Exception('Unexpected input at line' . $this->line . ': ' . $this->data[$this->counter]);
+ }
+ break;
+ } while (true);
+ } // end function
+
+ const SECTION = 5;
+
+ function yy_r5_1() {
+
+ $this->token = Smarty_Internal_Configfileparser::TPC_DOT;
+ }
+
+ function yy_r5_2() {
+
+ $this->token = Smarty_Internal_Configfileparser::TPC_SECTION;
+ $this->yypopstate();
+ }
+
+ public function yylex6() {
+ if (!isset($this->yy_global_pattern6)) {
+ $this->yy_global_pattern6 = "/\G(\"\"\"(?=[ \t\r]*[\n#;]))|\G([\S\s])/isS";
+ }
+ if ($this->counter >= strlen($this->data)) {
+ return false; // end of input
+ }
+
+ do {
+ if (preg_match($this->yy_global_pattern6, $this->data, $yymatches, null, $this->counter)) {
+ $yysubmatches = $yymatches;
+ if (strlen($yysubmatches[0]) < 200) {
+ $yymatches = preg_grep("/(.|\s)+/", $yysubmatches);
+ } else {
+ $yymatches = array_filter($yymatches, 'strlen');
+ }
+ if (empty($yymatches)) {
+ throw new Exception('Error: lexing failed because a rule matched' . ' an empty string. Input "' . substr($this->data, $this->counter, 5) . '... state TRIPPLE');
+ }
+ next($yymatches); // skip global match
+ $this->token = key($yymatches); // token number
+ $this->value = current($yymatches); // token value
+ $r = $this->{'yy_r6_' . $this->token}();
+ if ($r === null) {
+ $this->counter += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ // accept this token
+ return true;
+ } elseif ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ $this->counter += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ if ($this->counter >= strlen($this->data)) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ }
+ } else {
+ throw new Exception('Unexpected input at line' . $this->line . ': ' . $this->data[$this->counter]);
+ }
+ break;
+ } while (true);
+ } // end function
+
+ const TRIPPLE = 6;
+
+ function yy_r6_1() {
+
+ $this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_QUOTES_END;
+ $this->yypopstate();
+ $this->yypushstate(self::START);
+ }
+
+ function yy_r6_2() {
+
+ $to = strlen($this->data);
+ preg_match("/\"\"\"[ \t\r]*[\n#;]/", $this->data, $match, PREG_OFFSET_CAPTURE, $this->counter);
+ if (isset($match[0][1])) {
+ $to = $match[0][1];
+ } else {
+ $this->compiler->trigger_template_error("missing or misspelled literal closing tag");
+ }
+ $this->value = substr($this->data, $this->counter, $to - $this->counter);
+ $this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_TEXT;
+ }
+
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_configfileparser.php
@@ -0,0 +1,960 @@
+<?php
+
+class TPC_yyToken implements ArrayAccess {
+ public $string = '';
+
+ public $metadata = array();
+
+ public function __construct($s, $m = array()) {
+ if ($s instanceof TPC_yyToken) {
+ $this->string = $s->string;
+ $this->metadata = $s->metadata;
+ } else {
+ $this->string = (string)$s;
+ if ($m instanceof TPC_yyToken) {
+ $this->metadata = $m->metadata;
+ } elseif (is_array($m)) {
+ $this->metadata = $m;
+ }
+ }
+ }
+
+ public function __toString() {
+ return $this->string;
+ }
+
+ public function offsetExists($offset) {
+ return isset($this->metadata[$offset]);
+ }
+
+ public function offsetGet($offset) {
+ return $this->metadata[$offset];
+ }
+
+ public function offsetSet($offset, $value) {
+ if ($offset === null) {
+ if (isset($value[0])) {
+ $x = ($value instanceof TPC_yyToken) ? $value->metadata : $value;
+ $this->metadata = array_merge($this->metadata, $x);
+
+ return;
+ }
+ $offset = count($this->metadata);
+ }
+ if ($value === null) {
+ return;
+ }
+ if ($value instanceof TPC_yyToken) {
+ if ($value->metadata) {
+ $this->metadata[$offset] = $value->metadata;
+ }
+ } elseif ($value) {
+ $this->metadata[$offset] = $value;
+ }
+ }
+
+ public function offsetUnset($offset) {
+ unset($this->metadata[$offset]);
+ }
+}
+
+class TPC_yyStackEntry {
+ public $stateno; /* The state-number */
+ public $major; /* The major token value. This is the code
+ ** number for the token at this stack level */
+ public $minor; /* The user-supplied minor token value. This
+ ** is the value of the token */
+}
+
+;
+
+#line 12 "../smarty/lexer/smarty_internal_configfileparser.y"
+
+/**
+ * Smarty Internal Plugin Configfileparse
+ *
+ * This is the config file parser.
+ * It is generated from the smarty_internal_configfileparser.y file
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+class Smarty_Internal_Configfileparser {
+ #line 25 "../smarty/lexer/smarty_internal_configfileparser.y"
+
+ /**
+ * result status
+ *
+ * @var bool
+ */
+ public $successful = true;
+
+ /**
+ * return value
+ *
+ * @var mixed
+ */
+ public $retvalue = 0;
+
+ /**
+ * @var
+ */
+ public $yymajor;
+
+ /**
+ * lexer object
+ *
+ * @var Smarty_Internal_Configfilelexer
+ */
+ private $lex;
+
+ /**
+ * internal error flag
+ *
+ * @var bool
+ */
+ private $internalError = false;
+
+ /**
+ * compiler object
+ *
+ * @var Smarty_Internal_Config_File_Compiler
+ */
+ public $compiler = null;
+
+ /**
+ * smarty object
+ *
+ * @var Smarty
+ */
+ public $smarty = null;
+
+ /**
+ * copy of config_overwrite property
+ *
+ * @var bool
+ */
+ private $configOverwrite = false;
+
+ /**
+ * copy of config_read_hidden property
+ *
+ * @var bool
+ */
+ private $configReadHidden = false;
+
+ /**
+ * helper map
+ *
+ * @var array
+ */
+ private static $escapes_single = Array('\\' => '\\', '\'' => '\'');
+
+ /**
+ * constructor
+ *
+ * @param Smarty_Internal_Configfilelexer $lex
+ * @param Smarty_Internal_Config_File_Compiler $compiler
+ */
+ function __construct(Smarty_Internal_Configfilelexer $lex, Smarty_Internal_Config_File_Compiler $compiler) {
+ // set instance object
+ self::instance($this);
+ $this->lex = $lex;
+ $this->smarty = $compiler->smarty;
+ $this->compiler = $compiler;
+ $this->configOverwrite = $this->smarty->config_overwrite;
+ $this->configReadHidden = $this->smarty->config_read_hidden;
+ }
+
+ /**
+ * @param null $new_instance
+ *
+ * @return null
+ */
+ public static function &instance($new_instance = null) {
+ static $instance = null;
+ if (isset($new_instance) && is_object($new_instance)) {
+ $instance = $new_instance;
+ }
+ return $instance;
+ }
+
+ /**
+ * parse optional boolean keywords
+ *
+ * @param string $str
+ *
+ * @return bool
+ */
+ private function parse_bool($str) {
+ $str = strtolower($str);
+ if (in_array($str, array('on', 'yes', 'true'))) {
+ $res = true;
+ } else {
+ $res = false;
+ }
+ return $res;
+ }
+
+ /**
+ * parse single quoted string
+ * remove outer quotes
+ * unescape inner quotes
+ *
+ * @param string $qstr
+ *
+ * @return string
+ */
+ private static function parse_single_quoted_string($qstr) {
+ $escaped_string = substr($qstr, 1, strlen($qstr) - 2); //remove outer quotes
+
+ $ss = preg_split('/(\\\\.)/', $escaped_string, -1, PREG_SPLIT_DELIM_CAPTURE);
+
+ $str = "";
+ foreach ($ss as $s) {
+ if (strlen($s) === 2 && $s[0] === '\\') {
+ if (isset(self::$escapes_single[$s[1]])) {
+ $s = self::$escapes_single[$s[1]];
+ }
+ }
+ $str .= $s;
+ }
+ return $str;
+ }
+
+ /**
+ * parse double quoted string
+ *
+ * @param string $qstr
+ *
+ * @return string
+ */
+ private static function parse_double_quoted_string($qstr) {
+ $inner_str = substr($qstr, 1, strlen($qstr) - 2);
+ return stripcslashes($inner_str);
+ }
+
+ /**
+ * parse triple quoted string
+ *
+ * @param string $qstr
+ *
+ * @return string
+ */
+ private static function parse_tripple_double_quoted_string($qstr) {
+ return stripcslashes($qstr);
+ }
+
+ /**
+ * set a config variable in target array
+ *
+ * @param array $var
+ * @param array $target_array
+ */
+ private function set_var(Array $var, Array &$target_array) {
+ $key = $var["key"];
+ $value = $var["value"];
+
+ if ($this->configOverwrite || !isset($target_array['vars'][$key])) {
+ $target_array['vars'][$key] = $value;
+ } else {
+ settype($target_array['vars'][$key], 'array');
+ $target_array['vars'][$key][] = $value;
+ }
+ }
+
+ /**
+ * add config variable to global vars
+ *
+ * @param array $vars
+ */
+ private function add_global_vars(Array $vars) {
+ if (!isset($this->compiler->config_data['vars'])) {
+ $this->compiler->config_data['vars'] = Array();
+ }
+ foreach ($vars as $var) {
+ $this->set_var($var, $this->compiler->config_data);
+ }
+ }
+
+ /**
+ * add config variable to section
+ *
+ * @param string $section_name
+ * @param array $vars
+ */
+ private function add_section_vars($section_name, Array $vars) {
+ if (!isset($this->compiler->config_data['sections'][$section_name]['vars'])) {
+ $this->compiler->config_data['sections'][$section_name]['vars'] = Array();
+ }
+ foreach ($vars as $var) {
+ $this->set_var($var, $this->compiler->config_data['sections'][$section_name]);
+ }
+ }
+
+ const TPC_OPENB = 1;
+
+ const TPC_SECTION = 2;
+
+ const TPC_CLOSEB = 3;
+
+ const TPC_DOT = 4;
+
+ const TPC_ID = 5;
+
+ const TPC_EQUAL = 6;
+
+ const TPC_FLOAT = 7;
+
+ const TPC_INT = 8;
+
+ const TPC_BOOL = 9;
+
+ const TPC_SINGLE_QUOTED_STRING = 10;
+
+ const TPC_DOUBLE_QUOTED_STRING = 11;
+
+ const TPC_TRIPPLE_QUOTES = 12;
+
+ const TPC_TRIPPLE_TEXT = 13;
+
+ const TPC_TRIPPLE_QUOTES_END = 14;
+
+ const TPC_NAKED_STRING = 15;
+
+ const TPC_OTHER = 16;
+
+ const TPC_NEWLINE = 17;
+
+ const TPC_COMMENTSTART = 18;
+
+ const YY_NO_ACTION = 60;
+
+ const YY_ACCEPT_ACTION = 59;
+
+ const YY_ERROR_ACTION = 58;
+
+ const YY_SZ_ACTTAB = 38;
+
+ static public $yy_action = array(29, 30, 34, 33, 24, 13, 19, 25, 35, 21, 59, 8, 3, 1, 20, 12, 14, 31, 20, 12, 15,
+ 17, 23, 18, 27, 26, 4, 5, 6, 32, 2, 11, 28, 22, 16, 9, 7, 10,);
+
+ static public $yy_lookahead = array(7, 8, 9, 10, 11, 12, 5, 27, 15, 16, 20, 21, 23, 23, 17, 18, 13, 14, 17, 18, 15,
+ 2, 17, 4, 25, 26, 6, 3, 3, 14, 23, 1, 24, 17, 2, 25, 22, 25,);
+
+ const YY_SHIFT_USE_DFLT = -8;
+
+ const YY_SHIFT_MAX = 19;
+
+ static public $yy_shift_ofst = array(-8, 1, 1, 1, -7, -3, -3, 30, -8, -8, -8, 19, 5, 3, 15, 16, 24, 25, 32,
+ 20,);
+
+ const YY_REDUCE_USE_DFLT = -21;
+
+ const YY_REDUCE_MAX = 10;
+
+ static public $yy_reduce_ofst = array(-10, -1, -1, -1, -20, 10, 12, 8, 14, 7, -11,);
+
+ static public $yyExpectedTokens = array(array(), array(5, 17, 18,), array(5, 17, 18,), array(5, 17, 18,),
+ array(7, 8, 9, 10, 11, 12, 15, 16,), array(17, 18,), array(17, 18,), array(1,), array(), array(), array(),
+ array(2, 4,), array(15, 17,), array(13, 14,), array(14,), array(17,), array(3,), array(3,), array(2,),
+ array(6,), array(), array(), array(), array(), array(), array(), array(), array(), array(), array(), array(),
+ array(), array(), array(), array(), array(),);
+
+ static public $yy_default = array(44, 37, 41, 40, 58, 58, 58, 36, 39, 44, 44, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 55, 54, 57, 56, 50, 45, 43, 42, 38, 46, 47, 52, 51, 49, 48, 53,);
+
+ const YYNOCODE = 29;
+
+ const YYSTACKDEPTH = 100;
+
+ const YYNSTATE = 36;
+
+ const YYNRULE = 22;
+
+ const YYERRORSYMBOL = 19;
+
+ const YYERRSYMDT = 'yy0';
+
+ const YYFALLBACK = 0;
+
+ public static $yyFallback = array();
+
+ public function Trace($TraceFILE, $zTracePrompt) {
+ if (!$TraceFILE) {
+ $zTracePrompt = 0;
+ } elseif (!$zTracePrompt) {
+ $TraceFILE = 0;
+ }
+ $this->yyTraceFILE = $TraceFILE;
+ $this->yyTracePrompt = $zTracePrompt;
+ }
+
+ public function PrintTrace() {
+ $this->yyTraceFILE = fopen('php://output', 'w');
+ $this->yyTracePrompt = '<br>';
+ }
+
+ public $yyTraceFILE;
+
+ public $yyTracePrompt;
+
+ public $yyidx; /* Index of top element in stack */
+ public $yyerrcnt; /* Shifts left before out of the error */
+ public $yystack = array(); /* The parser's stack */
+
+ public $yyTokenName = array('$', 'OPENB', 'SECTION', 'CLOSEB', 'DOT', 'ID', 'EQUAL', 'FLOAT', 'INT', 'BOOL',
+ 'SINGLE_QUOTED_STRING', 'DOUBLE_QUOTED_STRING', 'TRIPPLE_QUOTES', 'TRIPPLE_TEXT', 'TRIPPLE_QUOTES_END',
+ 'NAKED_STRING', 'OTHER', 'NEWLINE', 'COMMENTSTART', 'error', 'start', 'global_vars', 'sections', 'var_list',
+ 'section', 'newline', 'var', 'value',);
+
+ public static $yyRuleName = array('start ::= global_vars sections', 'global_vars ::= var_list',
+ 'sections ::= sections section', 'sections ::=', 'section ::= OPENB SECTION CLOSEB newline var_list',
+ 'section ::= OPENB DOT SECTION CLOSEB newline var_list', 'var_list ::= var_list newline',
+ 'var_list ::= var_list var', 'var_list ::=', 'var ::= ID EQUAL value', 'value ::= FLOAT', 'value ::= INT',
+ 'value ::= BOOL', 'value ::= SINGLE_QUOTED_STRING', 'value ::= DOUBLE_QUOTED_STRING',
+ 'value ::= TRIPPLE_QUOTES TRIPPLE_TEXT TRIPPLE_QUOTES_END', 'value ::= TRIPPLE_QUOTES TRIPPLE_QUOTES_END',
+ 'value ::= NAKED_STRING', 'value ::= OTHER', 'newline ::= NEWLINE', 'newline ::= COMMENTSTART NEWLINE',
+ 'newline ::= COMMENTSTART NAKED_STRING NEWLINE',);
+
+ public function tokenName($tokenType) {
+ if ($tokenType === 0) {
+ return 'End of Input';
+ }
+ if ($tokenType > 0 && $tokenType < count($this->yyTokenName)) {
+ return $this->yyTokenName[$tokenType];
+ } else {
+ return "Unknown";
+ }
+ }
+
+ public static function yy_destructor($yymajor, $yypminor) {
+ switch ($yymajor) {
+ default:
+ break; /* If no destructor action specified: do nothing */
+ }
+ }
+
+ public function yy_pop_parser_stack() {
+ if (empty($this->yystack)) {
+ return;
+ }
+ $yytos = array_pop($this->yystack);
+ if ($this->yyTraceFILE && $this->yyidx >= 0) {
+ fwrite($this->yyTraceFILE, $this->yyTracePrompt . 'Popping ' . $this->yyTokenName[$yytos->major] . "\n");
+ }
+ $yymajor = $yytos->major;
+ self::yy_destructor($yymajor, $yytos->minor);
+ $this->yyidx--;
+
+ return $yymajor;
+ }
+
+ public function __destruct() {
+ while ($this->yystack !== Array()) {
+ $this->yy_pop_parser_stack();
+ }
+ if (is_resource($this->yyTraceFILE)) {
+ fclose($this->yyTraceFILE);
+ }
+ }
+
+ public function yy_get_expected_tokens($token) {
+ static $res3 = array();
+ static $res4 = array();
+ $state = $this->yystack[$this->yyidx]->stateno;
+ $expected = self::$yyExpectedTokens[$state];
+ if (isset($res3[$state][$token])) {
+ if ($res3[$state][$token]) {
+ return $expected;
+ }
+ } else {
+ if ($res3[$state][$token] = in_array($token, self::$yyExpectedTokens[$state], true)) {
+ return $expected;
+ }
+ }
+ $stack = $this->yystack;
+ $yyidx = $this->yyidx;
+ do {
+ $yyact = $this->yy_find_shift_action($token);
+ if ($yyact >= self::YYNSTATE && $yyact < self::YYNSTATE + self::YYNRULE) {
+ // reduce action
+ $done = 0;
+ do {
+ if ($done++ == 100) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ // too much recursion prevents proper detection
+ // so give up
+ return array_unique($expected);
+ }
+ $yyruleno = $yyact - self::YYNSTATE;
+ $this->yyidx -= self::$yyRuleInfo[$yyruleno][1];
+ $nextstate = $this->yy_find_reduce_action($this->yystack[$this->yyidx]->stateno, self::$yyRuleInfo[$yyruleno][0]);
+ if (isset(self::$yyExpectedTokens[$nextstate])) {
+ $expected = array_merge($expected, self::$yyExpectedTokens[$nextstate]);
+ if (isset($res4[$nextstate][$token])) {
+ if ($res4[$nextstate][$token]) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ return array_unique($expected);
+ }
+ } else {
+ if ($res4[$nextstate][$token] = in_array($token, self::$yyExpectedTokens[$nextstate], true)) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ return array_unique($expected);
+ }
+ }
+ }
+ if ($nextstate < self::YYNSTATE) {
+ // we need to shift a non-terminal
+ $this->yyidx++;
+ $x = new TPC_yyStackEntry;
+ $x->stateno = $nextstate;
+ $x->major = self::$yyRuleInfo[$yyruleno][0];
+ $this->yystack[$this->yyidx] = $x;
+ continue 2;
+ } elseif ($nextstate == self::YYNSTATE + self::YYNRULE + 1) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ // the last token was just ignored, we can't accept
+ // by ignoring input, this is in essence ignoring a
+ // syntax error!
+ return array_unique($expected);
+ } elseif ($nextstate === self::YY_NO_ACTION) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ // input accepted, but not shifted (I guess)
+ return $expected;
+ } else {
+ $yyact = $nextstate;
+ }
+ } while (true);
+ }
+ break;
+ } while (true);
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+
+ return array_unique($expected);
+ }
+
+ public function yy_is_expected_token($token) {
+ static $res = array();
+ static $res2 = array();
+ if ($token === 0) {
+ return true; // 0 is not part of this
+ }
+ $state = $this->yystack[$this->yyidx]->stateno;
+ if (isset($res[$state][$token])) {
+ if ($res[$state][$token]) {
+ return true;
+ }
+ } else {
+ if ($res[$state][$token] = in_array($token, self::$yyExpectedTokens[$state], true)) {
+ return true;
+ }
+ }
+ $stack = $this->yystack;
+ $yyidx = $this->yyidx;
+ do {
+ $yyact = $this->yy_find_shift_action($token);
+ if ($yyact >= self::YYNSTATE && $yyact < self::YYNSTATE + self::YYNRULE) {
+ // reduce action
+ $done = 0;
+ do {
+ if ($done++ == 100) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ // too much recursion prevents proper detection
+ // so give up
+ return true;
+ }
+ $yyruleno = $yyact - self::YYNSTATE;
+ $this->yyidx -= self::$yyRuleInfo[$yyruleno][1];
+ $nextstate = $this->yy_find_reduce_action($this->yystack[$this->yyidx]->stateno, self::$yyRuleInfo[$yyruleno][0]);
+ if (isset($res2[$nextstate][$token])) {
+ if ($res2[$nextstate][$token]) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ return true;
+ }
+ } else {
+ if ($res2[$nextstate][$token] = (isset(self::$yyExpectedTokens[$nextstate]) && in_array($token, self::$yyExpectedTokens[$nextstate], true))) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ return true;
+ }
+ }
+ if ($nextstate < self::YYNSTATE) {
+ // we need to shift a non-terminal
+ $this->yyidx++;
+ $x = new TPC_yyStackEntry;
+ $x->stateno = $nextstate;
+ $x->major = self::$yyRuleInfo[$yyruleno][0];
+ $this->yystack[$this->yyidx] = $x;
+ continue 2;
+ } elseif ($nextstate == self::YYNSTATE + self::YYNRULE + 1) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ if (!$token) {
+ // end of input: this is valid
+ return true;
+ }
+ // the last token was just ignored, we can't accept
+ // by ignoring input, this is in essence ignoring a
+ // syntax error!
+ return false;
+ } elseif ($nextstate === self::YY_NO_ACTION) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ // input accepted, but not shifted (I guess)
+ return true;
+ } else {
+ $yyact = $nextstate;
+ }
+ } while (true);
+ }
+ break;
+ } while (true);
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+
+ return true;
+ }
+
+ public function yy_find_shift_action($iLookAhead) {
+ $stateno = $this->yystack[$this->yyidx]->stateno;
+
+ /* if ($this->yyidx < 0) return self::YY_NO_ACTION; */
+ if (!isset(self::$yy_shift_ofst[$stateno])) {
+ // no shift actions
+ return self::$yy_default[$stateno];
+ }
+ $i = self::$yy_shift_ofst[$stateno];
+ if ($i === self::YY_SHIFT_USE_DFLT) {
+ return self::$yy_default[$stateno];
+ }
+ if ($iLookAhead == self::YYNOCODE) {
+ return self::YY_NO_ACTION;
+ }
+ $i += $iLookAhead;
+ if ($i < 0 || $i >= self::YY_SZ_ACTTAB || self::$yy_lookahead[$i] != $iLookAhead) {
+ if (count(self::$yyFallback) && $iLookAhead < count(self::$yyFallback) && ($iFallback = self::$yyFallback[$iLookAhead]) != 0) {
+ if ($this->yyTraceFILE) {
+ fwrite($this->yyTraceFILE, $this->yyTracePrompt . "FALLBACK " . $this->yyTokenName[$iLookAhead] . " => " . $this->yyTokenName[$iFallback] . "\n");
+ }
+
+ return $this->yy_find_shift_action($iFallback);
+ }
+
+ return self::$yy_default[$stateno];
+ } else {
+ return self::$yy_action[$i];
+ }
+ }
+
+ public function yy_find_reduce_action($stateno, $iLookAhead) {
+ /* $stateno = $this->yystack[$this->yyidx]->stateno; */
+
+ if (!isset(self::$yy_reduce_ofst[$stateno])) {
+ return self::$yy_default[$stateno];
+ }
+ $i = self::$yy_reduce_ofst[$stateno];
+ if ($i == self::YY_REDUCE_USE_DFLT) {
+ return self::$yy_default[$stateno];
+ }
+ if ($iLookAhead == self::YYNOCODE) {
+ return self::YY_NO_ACTION;
+ }
+ $i += $iLookAhead;
+ if ($i < 0 || $i >= self::YY_SZ_ACTTAB || self::$yy_lookahead[$i] != $iLookAhead) {
+ return self::$yy_default[$stateno];
+ } else {
+ return self::$yy_action[$i];
+ }
+ }
+
+ public function yy_shift($yyNewState, $yyMajor, $yypMinor) {
+ $this->yyidx++;
+ if ($this->yyidx >= self::YYSTACKDEPTH) {
+ $this->yyidx--;
+ if ($this->yyTraceFILE) {
+ fprintf($this->yyTraceFILE, "%sStack Overflow!\n", $this->yyTracePrompt);
+ }
+ while ($this->yyidx >= 0) {
+ $this->yy_pop_parser_stack();
+ }
+ #line 255 "../smarty/lexer/smarty_internal_configfileparser.y"
+
+ $this->internalError = true;
+ $this->compiler->trigger_config_file_error("Stack overflow in configfile parser");
+
+ return;
+ }
+ $yytos = new TPC_yyStackEntry;
+ $yytos->stateno = $yyNewState;
+ $yytos->major = $yyMajor;
+ $yytos->minor = $yypMinor;
+ $this->yystack[] = $yytos;
+ if ($this->yyTraceFILE && $this->yyidx > 0) {
+ fprintf($this->yyTraceFILE, "%sShift %d\n", $this->yyTracePrompt, $yyNewState);
+ fprintf($this->yyTraceFILE, "%sStack:", $this->yyTracePrompt);
+ for ($i = 1; $i <= $this->yyidx; $i++) {
+ fprintf($this->yyTraceFILE, " %s", $this->yyTokenName[$this->yystack[$i]->major]);
+ }
+ fwrite($this->yyTraceFILE, "\n");
+ }
+ }
+
+ public static $yyRuleInfo = array(array(0 => 20, 1 => 2), array(0 => 21, 1 => 1), array(0 => 22, 1 => 2),
+ array(0 => 22, 1 => 0), array(0 => 24, 1 => 5), array(0 => 24, 1 => 6), array(0 => 23, 1 => 2),
+ array(0 => 23, 1 => 2), array(0 => 23, 1 => 0), array(0 => 26, 1 => 3), array(0 => 27, 1 => 1),
+ array(0 => 27, 1 => 1), array(0 => 27, 1 => 1), array(0 => 27, 1 => 1), array(0 => 27, 1 => 1),
+ array(0 => 27, 1 => 3), array(0 => 27, 1 => 2), array(0 => 27, 1 => 1), array(0 => 27, 1 => 1),
+ array(0 => 25, 1 => 1), array(0 => 25, 1 => 2), array(0 => 25, 1 => 3),);
+
+ public static $yyReduceMap = array(0 => 0, 2 => 0, 3 => 0, 19 => 0, 20 => 0, 21 => 0, 1 => 1, 4 => 4, 5 => 5,
+ 6 => 6, 7 => 7, 8 => 8, 9 => 9, 10 => 10, 11 => 11, 12 => 12, 13 => 13,
+ 14 => 14, 15 => 15, 16 => 16, 17 => 17, 18 => 17,);
+
+ #line 261 "../smarty/lexer/smarty_internal_configfileparser.y"
+ function yy_r0() {
+ $this->_retvalue = null;
+ }
+
+ #line 266 "../smarty/lexer/smarty_internal_configfileparser.y"
+ function yy_r1() {
+ $this->add_global_vars($this->yystack[$this->yyidx + 0]->minor);
+ $this->_retvalue = null;
+ }
+
+ #line 280 "../smarty/lexer/smarty_internal_configfileparser.y"
+ function yy_r4() {
+ $this->add_section_vars($this->yystack[$this->yyidx + -3]->minor, $this->yystack[$this->yyidx + 0]->minor);
+ $this->_retvalue = null;
+ }
+
+ #line 285 "../smarty/lexer/smarty_internal_configfileparser.y"
+ function yy_r5() {
+ if ($this->configReadHidden) {
+ $this->add_section_vars($this->yystack[$this->yyidx + -3]->minor, $this->yystack[$this->yyidx + 0]->minor);
+ }
+ $this->_retvalue = null;
+ }
+
+ #line 293 "../smarty/lexer/smarty_internal_configfileparser.y"
+ function yy_r6() {
+ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor;
+ }
+
+ #line 297 "../smarty/lexer/smarty_internal_configfileparser.y"
+ function yy_r7() {
+ $this->_retvalue = array_merge($this->yystack[$this->yyidx + -1]->minor, Array($this->yystack[$this->yyidx + 0]->minor));
+ }
+
+ #line 301 "../smarty/lexer/smarty_internal_configfileparser.y"
+ function yy_r8() {
+ $this->_retvalue = Array();
+ }
+
+ #line 307 "../smarty/lexer/smarty_internal_configfileparser.y"
+ function yy_r9() {
+ $this->_retvalue = Array("key" => $this->yystack[$this->yyidx + -2]->minor,
+ "value" => $this->yystack[$this->yyidx + 0]->minor);
+ }
+
+ #line 312 "../smarty/lexer/smarty_internal_configfileparser.y"
+ function yy_r10() {
+ $this->_retvalue = (float)$this->yystack[$this->yyidx + 0]->minor;
+ }
+
+ #line 316 "../smarty/lexer/smarty_internal_configfileparser.y"
+ function yy_r11() {
+ $this->_retvalue = (int)$this->yystack[$this->yyidx + 0]->minor;
+ }
+
+ #line 320 "../smarty/lexer/smarty_internal_configfileparser.y"
+ function yy_r12() {
+ $this->_retvalue = $this->parse_bool($this->yystack[$this->yyidx + 0]->minor);
+ }
+
+ #line 324 "../smarty/lexer/smarty_internal_configfileparser.y"
+ function yy_r13() {
+ $this->_retvalue = self::parse_single_quoted_string($this->yystack[$this->yyidx + 0]->minor);
+ }
+
+ #line 328 "../smarty/lexer/smarty_internal_configfileparser.y"
+ function yy_r14() {
+ $this->_retvalue = self::parse_double_quoted_string($this->yystack[$this->yyidx + 0]->minor);
+ }
+
+ #line 332 "../smarty/lexer/smarty_internal_configfileparser.y"
+ function yy_r15() {
+ $this->_retvalue = self::parse_tripple_double_quoted_string($this->yystack[$this->yyidx + -1]->minor);
+ }
+
+ #line 336 "../smarty/lexer/smarty_internal_configfileparser.y"
+ function yy_r16() {
+ $this->_retvalue = '';
+ }
+
+ #line 340 "../smarty/lexer/smarty_internal_configfileparser.y"
+ function yy_r17() {
+ $this->_retvalue = $this->yystack[$this->yyidx + 0]->minor;
+ }
+
+ private $_retvalue;
+
+ public function yy_reduce($yyruleno) {
+ if ($this->yyTraceFILE && $yyruleno >= 0 && $yyruleno < count(self::$yyRuleName)) {
+ fprintf($this->yyTraceFILE, "%sReduce (%d) [%s].\n", $this->yyTracePrompt, $yyruleno, self::$yyRuleName[$yyruleno]);
+ }
+
+ $this->_retvalue = $yy_lefthand_side = null;
+ if (isset(self::$yyReduceMap[$yyruleno])) {
+ // call the action
+ $this->_retvalue = null;
+ $this->{'yy_r' . self::$yyReduceMap[$yyruleno]}();
+ $yy_lefthand_side = $this->_retvalue;
+ }
+ $yygoto = self::$yyRuleInfo[$yyruleno][0];
+ $yysize = self::$yyRuleInfo[$yyruleno][1];
+ $this->yyidx -= $yysize;
+ for ($i = $yysize; $i; $i--) {
+ // pop all of the right-hand side parameters
+ array_pop($this->yystack);
+ }
+ $yyact = $this->yy_find_reduce_action($this->yystack[$this->yyidx]->stateno, $yygoto);
+ if ($yyact < self::YYNSTATE) {
+ if (!$this->yyTraceFILE && $yysize) {
+ $this->yyidx++;
+ $x = new TPC_yyStackEntry;
+ $x->stateno = $yyact;
+ $x->major = $yygoto;
+ $x->minor = $yy_lefthand_side;
+ $this->yystack[$this->yyidx] = $x;
+ } else {
+ $this->yy_shift($yyact, $yygoto, $yy_lefthand_side);
+ }
+ } elseif ($yyact == self::YYNSTATE + self::YYNRULE + 1) {
+ $this->yy_accept();
+ }
+ }
+
+ public function yy_parse_failed() {
+ if ($this->yyTraceFILE) {
+ fprintf($this->yyTraceFILE, "%sFail!\n", $this->yyTracePrompt);
+ }
+ while ($this->yyidx >= 0) {
+ $this->yy_pop_parser_stack();
+ }
+ }
+
+ public function yy_syntax_error($yymajor, $TOKEN) {
+ #line 248 "../smarty/lexer/smarty_internal_configfileparser.y"
+
+ $this->internalError = true;
+ $this->yymajor = $yymajor;
+ $this->compiler->trigger_config_file_error();
+ }
+
+ public function yy_accept() {
+ if ($this->yyTraceFILE) {
+ fprintf($this->yyTraceFILE, "%sAccept!\n", $this->yyTracePrompt);
+ }
+ while ($this->yyidx >= 0) {
+ $this->yy_pop_parser_stack();
+ }
+ #line 241 "../smarty/lexer/smarty_internal_configfileparser.y"
+
+ $this->successful = !$this->internalError;
+ $this->internalError = false;
+ $this->retvalue = $this->_retvalue;
+ }
+
+ public function doParse($yymajor, $yytokenvalue) {
+ $yyerrorhit = 0; /* True if yymajor has invoked an error */
+
+ if ($this->yyidx === null || $this->yyidx < 0) {
+ $this->yyidx = 0;
+ $this->yyerrcnt = -1;
+ $x = new TPC_yyStackEntry;
+ $x->stateno = 0;
+ $x->major = 0;
+ $this->yystack = array();
+ $this->yystack[] = $x;
+ }
+ $yyendofinput = ($yymajor == 0);
+
+ if ($this->yyTraceFILE) {
+ fprintf($this->yyTraceFILE, "%sInput %s\n", $this->yyTracePrompt, $this->yyTokenName[$yymajor]);
+ }
+
+ do {
+ $yyact = $this->yy_find_shift_action($yymajor);
+ if ($yymajor < self::YYERRORSYMBOL && !$this->yy_is_expected_token($yymajor)) {
+ // force a syntax error
+ $yyact = self::YY_ERROR_ACTION;
+ }
+ if ($yyact < self::YYNSTATE) {
+ $this->yy_shift($yyact, $yymajor, $yytokenvalue);
+ $this->yyerrcnt--;
+ if ($yyendofinput && $this->yyidx >= 0) {
+ $yymajor = 0;
+ } else {
+ $yymajor = self::YYNOCODE;
+ }
+ } elseif ($yyact < self::YYNSTATE + self::YYNRULE) {
+ $this->yy_reduce($yyact - self::YYNSTATE);
+ } elseif ($yyact == self::YY_ERROR_ACTION) {
+ if ($this->yyTraceFILE) {
+ fprintf($this->yyTraceFILE, "%sSyntax Error!\n", $this->yyTracePrompt);
+ }
+ if (self::YYERRORSYMBOL) {
+ if ($this->yyerrcnt < 0) {
+ $this->yy_syntax_error($yymajor, $yytokenvalue);
+ }
+ $yymx = $this->yystack[$this->yyidx]->major;
+ if ($yymx == self::YYERRORSYMBOL || $yyerrorhit) {
+ if ($this->yyTraceFILE) {
+ fprintf($this->yyTraceFILE, "%sDiscard input token %s\n", $this->yyTracePrompt, $this->yyTokenName[$yymajor]);
+ }
+ $this->yy_destructor($yymajor, $yytokenvalue);
+ $yymajor = self::YYNOCODE;
+ } else {
+ while ($this->yyidx >= 0 && $yymx != self::YYERRORSYMBOL && ($yyact = $this->yy_find_shift_action(self::YYERRORSYMBOL)) >= self::YYNSTATE) {
+ $this->yy_pop_parser_stack();
+ }
+ if ($this->yyidx < 0 || $yymajor == 0) {
+ $this->yy_destructor($yymajor, $yytokenvalue);
+ $this->yy_parse_failed();
+ $yymajor = self::YYNOCODE;
+ } elseif ($yymx != self::YYERRORSYMBOL) {
+ $u2 = 0;
+ $this->yy_shift($yyact, self::YYERRORSYMBOL, $u2);
+ }
+ }
+ $this->yyerrcnt = 3;
+ $yyerrorhit = 1;
+ } else {
+ if ($this->yyerrcnt <= 0) {
+ $this->yy_syntax_error($yymajor, $yytokenvalue);
+ }
+ $this->yyerrcnt = 3;
+ $this->yy_destructor($yymajor, $yytokenvalue);
+ if ($yyendofinput) {
+ $this->yy_parse_failed();
+ }
+ $yymajor = self::YYNOCODE;
+ }
+ } else {
+ $this->yy_accept();
+ $yymajor = self::YYNOCODE;
+ }
+ } while ($yymajor != self::YYNOCODE && $this->yyidx >= 0);
+ }
+}
+
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_data.php
@@ -0,0 +1,389 @@
+<?php
+/**
+ * Smarty Internal Plugin Data
+ * This file contains the basic classes and methods for template and variable creation
+ *
+ * @package Smarty
+ * @subpackage Template
+ * @author Uwe Tews
+ */
+
+/**
+ * Base class with template and variable methods
+ *
+ * @package Smarty
+ * @subpackage Template
+ */
+class Smarty_Internal_Data {
+ /**
+ * name of class used for templates
+ *
+ * @var string
+ */
+ public $template_class = 'Smarty_Internal_Template';
+ /**
+ * template variables
+ *
+ * @var array
+ */
+ public $tpl_vars = array();
+ /**
+ * parent template (if any)
+ *
+ * @var Smarty_Internal_Template
+ */
+ public $parent = null;
+ /**
+ * configuration settings
+ *
+ * @var array
+ */
+ public $config_vars = array();
+
+ /**
+ * assigns a Smarty variable
+ *
+ * @param array|string $tpl_var the template variable name(s)
+ * @param mixed $value the value to assign
+ * @param boolean $nocache if true any output of this variable will be not cached
+ *
+ * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
+ */
+ public function assign($tpl_var, $value = null, $nocache = false) {
+ if (is_array($tpl_var)) {
+ foreach ($tpl_var as $_key => $_val) {
+ if ($_key != '') {
+ $this->tpl_vars[$_key] = new Smarty_Variable($_val, $nocache);
+ }
+ }
+ } else {
+ if ($tpl_var != '') {
+ $this->tpl_vars[$tpl_var] = new Smarty_Variable($value, $nocache);
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * assigns a global Smarty variable
+ *
+ * @param string $varname the global variable name
+ * @param mixed $value the value to assign
+ * @param boolean $nocache if true any output of this variable will be not cached
+ *
+ * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
+ */
+ public function assignGlobal($varname, $value = null, $nocache = false) {
+ if ($varname != '') {
+ Smarty::$global_tpl_vars[$varname] = new Smarty_Variable($value, $nocache);
+ $ptr = $this;
+ while ($ptr instanceof Smarty_Internal_Template) {
+ $ptr->tpl_vars[$varname] = clone Smarty::$global_tpl_vars[$varname];
+ $ptr = $ptr->parent;
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * assigns values to template variables by reference
+ *
+ * @param string $tpl_var the template variable name
+ * @param $value
+ * @param boolean $nocache if true any output of this variable will be not cached
+ *
+ * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
+ */
+ public function assignByRef($tpl_var, &$value, $nocache = false) {
+ if ($tpl_var != '') {
+ $this->tpl_vars[$tpl_var] = new Smarty_Variable(null, $nocache);
+ $this->tpl_vars[$tpl_var]->value = &$value;
+ }
+
+ return $this;
+ }
+
+ /**
+ * appends values to template variables
+ *
+ * @param array|string $tpl_var the template variable name(s)
+ * @param mixed $value the value to append
+ * @param boolean $merge flag if array elements shall be merged
+ * @param boolean $nocache if true any output of this variable will be not cached
+ *
+ * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
+ */
+ public function append($tpl_var, $value = null, $merge = false, $nocache = false) {
+ if (is_array($tpl_var)) {
+ // $tpl_var is an array, ignore $value
+ foreach ($tpl_var as $_key => $_val) {
+ if ($_key != '') {
+ if (!isset($this->tpl_vars[$_key])) {
+ $tpl_var_inst = $this->getVariable($_key, null, true, false);
+ if ($tpl_var_inst instanceof Smarty_Undefined_Variable) {
+ $this->tpl_vars[$_key] = new Smarty_Variable(null, $nocache);
+ } else {
+ $this->tpl_vars[$_key] = clone $tpl_var_inst;
+ }
+ }
+ if (!(is_array($this->tpl_vars[$_key]->value) || $this->tpl_vars[$_key]->value instanceof ArrayAccess)) {
+ settype($this->tpl_vars[$_key]->value, 'array');
+ }
+ if ($merge && is_array($_val)) {
+ foreach ($_val as $_mkey => $_mval) {
+ $this->tpl_vars[$_key]->value[$_mkey] = $_mval;
+ }
+ } else {
+ $this->tpl_vars[$_key]->value[] = $_val;
+ }
+ }
+ }
+ } else {
+ if ($tpl_var != '' && isset($value)) {
+ if (!isset($this->tpl_vars[$tpl_var])) {
+ $tpl_var_inst = $this->getVariable($tpl_var, null, true, false);
+ if ($tpl_var_inst instanceof Smarty_Undefined_Variable) {
+ $this->tpl_vars[$tpl_var] = new Smarty_Variable(null, $nocache);
+ } else {
+ $this->tpl_vars[$tpl_var] = clone $tpl_var_inst;
+ }
+ }
+ if (!(is_array($this->tpl_vars[$tpl_var]->value) || $this->tpl_vars[$tpl_var]->value instanceof ArrayAccess)) {
+ settype($this->tpl_vars[$tpl_var]->value, 'array');
+ }
+ if ($merge && is_array($value)) {
+ foreach ($value as $_mkey => $_mval) {
+ $this->tpl_vars[$tpl_var]->value[$_mkey] = $_mval;
+ }
+ } else {
+ $this->tpl_vars[$tpl_var]->value[] = $value;
+ }
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * appends values to template variables by reference
+ *
+ * @param string $tpl_var the template variable name
+ * @param mixed &$value the referenced value to append
+ * @param boolean $merge flag if array elements shall be merged
+ *
+ * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
+ */
+ public function appendByRef($tpl_var, &$value, $merge = false) {
+ if ($tpl_var != '' && isset($value)) {
+ if (!isset($this->tpl_vars[$tpl_var])) {
+ $this->tpl_vars[$tpl_var] = new Smarty_Variable();
+ }
+ if (!is_array($this->tpl_vars[$tpl_var]->value)) {
+ settype($this->tpl_vars[$tpl_var]->value, 'array');
+ }
+ if ($merge && is_array($value)) {
+ foreach ($value as $_key => $_val) {
+ $this->tpl_vars[$tpl_var]->value[$_key] = &$value[$_key];
+ }
+ } else {
+ $this->tpl_vars[$tpl_var]->value[] = &$value;
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Returns a single or all template variables
+ *
+ * @param string $varname variable name or null
+ * @param object $_ptr optional pointer to data object
+ * @param boolean $search_parents include parent templates?
+ *
+ * @return string variable value or or array of variables
+ */
+ public function getTemplateVars($varname = null, $_ptr = null, $search_parents = true) {
+ if (isset($varname)) {
+ $_var = $this->getVariable($varname, $_ptr, $search_parents, false);
+ if (is_object($_var)) {
+ return $_var->value;
+ } else {
+ return null;
+ }
+ } else {
+ $_result = array();
+ if ($_ptr === null) {
+ $_ptr = $this;
+ }
+ while ($_ptr !== null) {
+ foreach ($_ptr->tpl_vars AS $key => $var) {
+ if (!array_key_exists($key, $_result)) {
+ $_result[$key] = $var->value;
+ }
+ }
+ // not found, try at parent
+ if ($search_parents) {
+ $_ptr = $_ptr->parent;
+ } else {
+ $_ptr = null;
+ }
+ }
+ if ($search_parents && isset(Smarty::$global_tpl_vars)) {
+ foreach (Smarty::$global_tpl_vars AS $key => $var) {
+ if (!array_key_exists($key, $_result)) {
+ $_result[$key] = $var->value;
+ }
+ }
+ }
+
+ return $_result;
+ }
+ }
+
+ /**
+ * clear the given assigned template variable.
+ *
+ * @param string|array $tpl_var the template variable(s) to clear
+ *
+ * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
+ */
+ public function clearAssign($tpl_var) {
+ if (is_array($tpl_var)) {
+ foreach ($tpl_var as $curr_var) {
+ unset($this->tpl_vars[$curr_var]);
+ }
+ } else {
+ unset($this->tpl_vars[$tpl_var]);
+ }
+
+ return $this;
+ }
+
+ /**
+ * clear all the assigned template variables.
+ *
+ * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
+ */
+ public function clearAllAssign() {
+ $this->tpl_vars = array();
+
+ return $this;
+ }
+
+ /**
+ * load a config file, optionally load just selected sections
+ *
+ * @param string $config_file filename
+ * @param mixed $sections array of section names, single section or null
+ *
+ * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
+ */
+ public function configLoad($config_file, $sections = null) {
+ // load Config class
+ Smarty_Internal_Extension_Config::configLoad($this, $config_file, $sections);
+ return $this;
+ }
+
+ /**
+ * gets the object of a Smarty variable
+ *
+ * @param string $variable the name of the Smarty variable
+ * @param object $_ptr optional pointer to data object
+ * @param boolean $search_parents search also in parent data
+ * @param bool $error_enable
+ *
+ * @return object the object of the variable
+ */
+ public function getVariable($variable, $_ptr = null, $search_parents = true, $error_enable = true) {
+ if ($_ptr === null) {
+ $_ptr = $this;
+ }
+ while ($_ptr !== null) {
+ if (isset($_ptr->tpl_vars[$variable])) {
+ // found it, return it
+ return $_ptr->tpl_vars[$variable];
+ }
+ // not found, try at parent
+ if ($search_parents) {
+ $_ptr = $_ptr->parent;
+ } else {
+ $_ptr = null;
+ }
+ }
+ if (isset(Smarty::$global_tpl_vars[$variable])) {
+ // found it, return it
+ return Smarty::$global_tpl_vars[$variable];
+ }
+ $smarty = isset($this->smarty) ? $this->smarty : $this;
+ if ($smarty->error_unassigned && $error_enable) {
+ // force a notice
+ $x = $$variable;
+ }
+
+ return new Smarty_Undefined_Variable;
+ }
+
+ /**
+ * gets a config variable
+ *
+ * @param string $variable the name of the config variable
+ * @param bool $error_enable
+ *
+ * @return mixed the value of the config variable
+ */
+ public function getConfigVariable($variable, $error_enable = true) {
+ return Smarty_Internal_Extension_Config::getConfigVariable($this, $variable, $error_enable = true);
+ }
+
+ /**
+ * Returns a single or all config variables
+ *
+ * @param string $varname variable name or null
+ * @param bool $search_parents
+ *
+ * @return string variable value or or array of variables
+ */
+ public function getConfigVars($varname = null, $search_parents = true) {
+ return Smarty_Internal_Extension_Config::getConfigVars($this, $varname, $search_parents);
+ }
+
+ /**
+ * Deassigns a single or all config variables
+ *
+ * @param string $varname variable name or null
+ *
+ * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
+ */
+ public function clearConfig($varname = null) {
+ return Smarty_Internal_Extension_Config::clearConfig($this, $varname);
+ }
+
+ /**
+ * gets a stream variable
+ *
+ * @param string $variable the stream of the variable
+ *
+ * @throws SmartyException
+ * @return mixed the value of the stream variable
+ */
+ public function getStreamVariable($variable) {
+ $_result = '';
+ $fp = fopen($variable, 'r+');
+ if ($fp) {
+ while (!feof($fp) && ($current_line = fgets($fp)) !== false) {
+ $_result .= $current_line;
+ }
+ fclose($fp);
+
+ return $_result;
+ }
+ $smarty = isset($this->smarty) ? $this->smarty : $this;
+ if ($smarty->error_unassigned) {
+ throw new SmartyException('Undefined stream variable "' . $variable . '"');
+ } else {
+ return null;
+ }
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_debug.php
@@ -0,0 +1,408 @@
+<?php
+/**
+ * Smarty Internal Plugin Debug
+ * Class to collect data for the Smarty Debugging Console
+ *
+ * @package Smarty
+ * @subpackage Debug
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Debug Class
+ *
+ * @package Smarty
+ * @subpackage Debug
+ */
+class Smarty_Internal_Debug extends Smarty_Internal_Data {
+ /**
+ * template data
+ *
+ * @var array
+ */
+ public static $template_data = array();
+
+ /**
+ * List of uid's which shall be ignored
+ *
+ * @var array
+ */
+ public static $ignore_uid = array();
+
+ /**
+ * Index of display() and fetch() calls
+ *
+ * @var int
+ */
+ public static $index = 0;
+
+ /**
+ * Counter for window offset
+ *
+ * @var int
+ */
+ public static $offset = 0;
+
+ /**
+ * Start logging template
+ *
+ * @param \Smarty_Internal_Template $template template
+ * @param null $mode true: display false: fetch null: subtemolate
+ */
+ public static function start_template(Smarty_Internal_Template $template, $mode = null) {
+ if (isset($mode)) {
+ self::$index++;
+ self::$offset++;
+ self::$template_data[self::$index] = null;
+ }
+ $key = self::get_key($template);
+ self::$template_data[self::$index][$key]['start_template_time'] = microtime(true);
+ }
+
+ /**
+ * End logging of cache time
+ *
+ * @param \Smarty_Internal_Template $template cached template
+ */
+ public static function end_template(Smarty_Internal_Template $template) {
+ $key = self::get_key($template);
+ self::$template_data[self::$index][$key]['total_time'] += microtime(true) - self::$template_data[self::$index][$key]['start_template_time'];
+ self::$template_data[self::$index][$key]['properties'] = $template->properties;
+ }
+
+ /**
+ * Start logging of compile time
+ *
+ * @param \Smarty_Internal_Template $template
+ */
+ public static function start_compile(Smarty_Internal_Template $template) {
+ static $_is_stringy = array('string' => true, 'eval' => true);
+ if (!empty($template->compiler->trace_uid)) {
+ $key = $template->compiler->trace_uid;
+ if (!isset(self::$template_data[self::$index][$key])) {
+ if (isset($_is_stringy[$template->source->type])) {
+ self::$template_data[self::$index][$key]['name'] = '\'' . substr($template->source->name, 0, 25) . '...\'';
+ } else {
+ self::$template_data[self::$index][$key]['name'] = $template->source->filepath;
+ }
+ self::$template_data[self::$index][$key]['compile_time'] = 0;
+ self::$template_data[self::$index][$key]['render_time'] = 0;
+ self::$template_data[self::$index][$key]['cache_time'] = 0;
+ }
+ } else {
+ if (isset(self::$ignore_uid[$template->source->uid])) {
+ return;
+ }
+ $key = self::get_key($template);
+ }
+ self::$template_data[self::$index][$key]['start_time'] = microtime(true);
+ }
+
+ /**
+ * End logging of compile time
+ *
+ * @param \Smarty_Internal_Template $template
+ */
+ public static function end_compile(Smarty_Internal_Template $template) {
+ if (!empty($template->compiler->trace_uid)) {
+ $key = $template->compiler->trace_uid;
+ } else {
+ if (isset(self::$ignore_uid[$template->source->uid])) {
+ return;
+ }
+
+ $key = self::get_key($template);
+ }
+ self::$template_data[self::$index][$key]['compile_time'] += microtime(true) - self::$template_data[self::$index][$key]['start_time'];
+ }
+
+ /**
+ * Start logging of render time
+ *
+ * @param \Smarty_Internal_Template $template
+ */
+ public static function start_render(Smarty_Internal_Template $template) {
+ $key = self::get_key($template);
+ self::$template_data[self::$index][$key]['start_time'] = microtime(true);
+ }
+
+ /**
+ * End logging of compile time
+ *
+ * @param \Smarty_Internal_Template $template
+ */
+ public static function end_render(Smarty_Internal_Template $template) {
+ $key = self::get_key($template);
+ self::$template_data[self::$index][$key]['render_time'] += microtime(true) - self::$template_data[self::$index][$key]['start_time'];
+ }
+
+ /**
+ * Start logging of cache time
+ *
+ * @param \Smarty_Internal_Template $template cached template
+ */
+ public static function start_cache(Smarty_Internal_Template $template) {
+ $key = self::get_key($template);
+ self::$template_data[self::$index][$key]['start_time'] = microtime(true);
+ }
+
+ /**
+ * End logging of cache time
+ *
+ * @param \Smarty_Internal_Template $template cached template
+ */
+ public static function end_cache(Smarty_Internal_Template $template) {
+ $key = self::get_key($template);
+ self::$template_data[self::$index][$key]['cache_time'] += microtime(true) - self::$template_data[self::$index][$key]['start_time'];
+ }
+
+ /**
+ * Register template object
+ *
+ * @param \Smarty_Internal_Template $template cached template
+ */
+ public static function register_template(Smarty_Internal_Template $template) {
+ }
+
+ /**
+ * Register data object
+ *
+ * @param \Smarty_Data $data data object
+ */
+ public static function register_data(Smarty_Data $data) {
+ }
+
+ /**
+ * Opens a window for the Smarty Debugging Console and display the data
+ *
+ * @param Smarty_Internal_Template|Smarty $obj object to debug
+ * @param bool $full
+ */
+ public static function display_debug($obj, $full = false) {
+ if (!$full) {
+ self::$offset++;
+ $savedIndex = self::$index;
+ self::$index = 9999;
+ }
+ if ($obj instanceof Smarty) {
+ $smarty = $obj;
+ } else {
+ $smarty = $obj->smarty;
+ }
+ // create fresh instance of smarty for displaying the debug console
+ // to avoid problems if the application did overload the Smarty class
+ $debObj = new Smarty();
+ // copy the working dirs from application
+ $debObj->setCompileDir($smarty->getCompileDir());
+ // init properties by hand as user may have edited the original Smarty class
+ $debObj->setPluginsDir(is_dir(__DIR__ . '/../plugins') ? __DIR__ . '/../plugins' : $smarty->getPluginsDir());
+ $debObj->force_compile = false;
+ $debObj->compile_check = true;
+ $debObj->left_delimiter = '{';
+ $debObj->right_delimiter = '}';
+ $debObj->security_policy = null;
+ $debObj->debugging = false;
+ $debObj->debugging_ctrl = 'NONE';
+ $debObj->error_reporting = E_ALL & ~E_NOTICE;
+ $debObj->debug_tpl = isset($smarty->debug_tpl) ? $smarty->debug_tpl : 'file:' . __DIR__ . '/../debug.tpl';
+ $debObj->registered_plugins = array();
+ $debObj->registered_resources = array();
+ $debObj->registered_filters = array();
+ $debObj->autoload_filters = array();
+ $debObj->default_modifiers = array();
+ $debObj->escape_html = true;
+ $debObj->caching = false;
+ $debObj->compile_id = null;
+ $debObj->cache_id = null;
+ // prepare information of assigned variables
+ $ptr = self::get_debug_vars($obj);
+ $_assigned_vars = $ptr->tpl_vars;
+ ksort($_assigned_vars);
+ $_config_vars = $ptr->config_vars;
+ ksort($_config_vars);
+ $debugging = $smarty->debugging;
+
+ $_template = new Smarty_Internal_Template($debObj->debug_tpl, $debObj);
+ if ($obj instanceof Smarty_Internal_Template) {
+ $_template->assign('template_name', $obj->source->type . ':' . $obj->source->name);
+ }
+ if ($obj instanceof Smarty || $full) {
+ $_template->assign('template_data', self::$template_data[self::$index]);
+ } else {
+ $_template->assign('template_data', null);
+ }
+ $_template->assign('assigned_vars', $_assigned_vars);
+ $_template->assign('config_vars', $_config_vars);
+ $_template->assign('execution_time', microtime(true) - $smarty->start_time);
+ $_template->assign('display_mode', $debugging == 2 || !$full);
+ $_template->assign('offset', self::$offset * 50);
+ echo $_template->fetch();
+ if (isset($full)) {
+ self::$index--;
+ }
+ if (!$full) {
+ self::$index = $savedIndex;
+ }
+ }
+
+ /**
+ * Recursively gets variables from all template/data scopes
+ *
+ * @param Smarty_Internal_Template|Smarty_Data $obj object to debug
+ *
+ * @return StdClass
+ */
+ public static function get_debug_vars($obj) {
+ $config_vars = array();
+ foreach ($obj->config_vars as $key => $var) {
+ $config_vars[$key]['value'] = $var;
+ if ($obj instanceof Smarty_Internal_Template) {
+ $config_vars[$key]['scope'] = $obj->source->type . ':' . $obj->source->name;
+ } elseif ($obj instanceof Smarty_Data) {
+ $tpl_vars[$key]['scope'] = $obj->dataObjectName;
+ } else {
+ $config_vars[$key]['scope'] = 'Smarty object';
+ }
+ }
+ $tpl_vars = array();
+ foreach ($obj->tpl_vars as $key => $var) {
+ foreach ($var as $varkey => $varvalue) {
+ if ($varkey == 'value') {
+ $tpl_vars[$key][$varkey] = $varvalue;
+ } else {
+ if ($varkey == 'nocache') {
+ if ($varvalue == true) {
+ $tpl_vars[$key][$varkey] = $varvalue;
+ }
+ } else {
+ if ($varkey != 'scope' || $varvalue !== 0) {
+ $tpl_vars[$key]['attributes'][$varkey] = $varvalue;
+ }
+ }
+ }
+ }
+ if ($obj instanceof Smarty_Internal_Template) {
+ $tpl_vars[$key]['scope'] = $obj->source->type . ':' . $obj->source->name;
+ } elseif ($obj instanceof Smarty_Data) {
+ $tpl_vars[$key]['scope'] = $obj->dataObjectName;
+ } else {
+ $tpl_vars[$key]['scope'] = 'Smarty object';
+ }
+ }
+
+ if (isset($obj->parent)) {
+ $parent = self::get_debug_vars($obj->parent);
+ foreach ($parent->tpl_vars as $name => $pvar) {
+ if (isset($tpl_vars[$name]) && $tpl_vars[$name]['value'] === $pvar['value']) {
+ $tpl_vars[$name]['scope'] = $pvar['scope'];
+ }
+ }
+ $tpl_vars = array_merge($parent->tpl_vars, $tpl_vars);
+
+ foreach ($parent->config_vars as $name => $pvar) {
+ if (isset($config_vars[$name]) && $config_vars[$name]['value'] === $pvar['value']) {
+ $config_vars[$name]['scope'] = $pvar['scope'];
+ }
+ }
+ $config_vars = array_merge($parent->config_vars, $config_vars);
+ } else {
+ foreach (Smarty::$global_tpl_vars as $key => $var) {
+ if (!array_key_exists($key, $tpl_vars)) {
+ foreach ($var as $varkey => $varvalue) {
+ if ($varkey == 'value') {
+ $tpl_vars[$key][$varkey] = $varvalue;
+ } else {
+ if ($varkey == 'nocache') {
+ if ($varvalue == true) {
+ $tpl_vars[$key][$varkey] = $varvalue;
+ }
+ } else {
+ if ($varkey != 'scope' || $varvalue !== 0) {
+ $tpl_vars[$key]['attributes'][$varkey] = $varvalue;
+ }
+ }
+ }
+ }
+ $tpl_vars[$key]['scope'] = 'Global';
+ }
+ }
+ }
+
+ return (object)array('tpl_vars' => $tpl_vars, 'config_vars' => $config_vars);
+ }
+
+ /**
+ * Return key into $template_data for template
+ *
+ * @param \Smarty_Internal_Template $template template object
+ *
+ * @return string key into $template_data
+ */
+ private static function get_key(Smarty_Internal_Template $template) {
+ static $_is_stringy = array('string' => true, 'eval' => true);
+ // calculate Uid if not already done
+ if ($template->source->uid == '') {
+ $template->source->filepath;
+ }
+ $key = $template->source->uid;
+ if (isset(self::$template_data[self::$index][$key])) {
+ return $key;
+ } else {
+ if (isset($_is_stringy[$template->source->type])) {
+ self::$template_data[self::$index][$key]['name'] = '\'' . substr($template->source->name, 0, 25) . '...\'';
+ } else {
+ self::$template_data[self::$index][$key]['name'] = $template->source->filepath;
+ }
+ self::$template_data[self::$index][$key]['compile_time'] = 0;
+ self::$template_data[self::$index][$key]['render_time'] = 0;
+ self::$template_data[self::$index][$key]['cache_time'] = 0;
+ self::$template_data[self::$index][$key]['total_time'] = 0;
+
+ return $key;
+ }
+ }
+
+ /**
+ * Ignore template
+ *
+ * @param \Smarty_Internal_Template $template
+ */
+ public static function ignore(Smarty_Internal_Template $template) {
+ // calculate Uid if not already done
+ if ($template->source->uid == '') {
+ $template->source->filepath;
+ }
+ self::$ignore_uid[$template->source->uid] = true;
+ }
+
+ /**
+ * handle 'URL' debugging mode
+ *
+ * @param Smarty_Internal_Template $_template
+ */
+ public static function debugUrl(Smarty_Internal_Template $_template) {
+ if (isset($_SERVER['QUERY_STRING'])) {
+ $_query_string = $_SERVER['QUERY_STRING'];
+ } else {
+ $_query_string = '';
+ }
+ if (false !== strpos($_query_string, $_template->smarty->smarty_debug_id)) {
+ if (false !== strpos($_query_string, $_template->smarty->smarty_debug_id . '=on')) {
+ // enable debugging for this browser session
+ setcookie('SMARTY_DEBUG', true);
+ $_template->smarty->debugging = true;
+ } elseif (false !== strpos($_query_string, $_template->smarty->smarty_debug_id . '=off')) {
+ // disable debugging for this browser session
+ setcookie('SMARTY_DEBUG', false);
+ $_template->smarty->debugging = false;
+ } else {
+ // enable debugging for this page
+ $_template->smarty->debugging = true;
+ }
+ } else {
+ if (isset($_COOKIE['SMARTY_DEBUG'])) {
+ $_template->smarty->debugging = true;
+ }
+ }
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_extension_codeframe.php
@@ -0,0 +1,123 @@
+<?php
+/**
+ * Smarty Internal Extension
+ * This file contains the Smarty template extension to create a code frame
+ *
+ * @package Smarty
+ * @subpackage Template
+ * @author Uwe Tews
+ */
+
+/**
+ * Class Smarty_Internal_Extension_CodeFrame
+ * Create code frame for compiled and cached templates
+ */
+class Smarty_Internal_Extension_CodeFrame {
+ /**
+ * Create code frame for compiled and cached templates
+ *
+ * @param Smarty_Internal_Template $_template
+ * @param string $content optional template content
+ * @param bool $cache flag for cache file
+ *
+ * @return string
+ */
+ public static function create(Smarty_Internal_Template $_template, $content = '', $cache = false) {
+ // build property code
+ $_template->properties['has_nocache_code'] = $_template->has_nocache_code || !empty($_template->required_plugins['nocache']);
+ $_template->properties['version'] = Smarty::SMARTY_VERSION;
+ if (!isset($_template->properties['unifunc'])) {
+ $_template->properties['unifunc'] = 'content_' . str_replace(array('.', ','), '_', uniqid('', true));
+ }
+ $properties = $_template->properties;
+ if (!$cache) {
+ unset($properties['tpl_function']);
+ if (!empty($_template->compiler->templateProperties)) {
+ $properties['tpl_function'] = $_template->compiler->templateProperties['tpl_function'];
+ }
+ }
+ $output = "<?php\n";
+ $output .= "/*%%SmartyHeaderCode:{$_template->properties['nocache_hash']}%%*/\n";
+ if ($_template->smarty->direct_access_security) {
+ $output .= "if(!defined('SMARTY_DIR')) exit('no direct access allowed');\n";
+ }
+ $output .= "\$_valid = \$_smarty_tpl->decodeProperties(" . var_export($properties, true) . ',' . ($cache ? 'true' : 'false') . ");\n";
+ $output .= "/*/%%SmartyHeaderCode%%*/\n";
+ $output .= "if (\$_valid && !is_callable('{$_template->properties['unifunc']}')) {\n";
+ $output .= "function {$_template->properties['unifunc']} (\$_smarty_tpl) {\n";
+ // include code for plugins
+ if (!$cache) {
+ if (!empty($_template->required_plugins['compiled'])) {
+ foreach ($_template->required_plugins['compiled'] as $tmp) {
+ foreach ($tmp as $data) {
+ $file = addslashes($data['file']);
+ if (is_Array($data['function'])) {
+ $output .= "if (!is_callable(array('{$data['function'][0]}','{$data['function'][1]}'))) require_once '{$file}';\n";
+ } else {
+ $output .= "if (!is_callable('{$data['function']}')) require_once '{$file}';\n";
+ }
+ }
+ }
+ }
+ if (!empty($_template->required_plugins['nocache'])) {
+ $_template->has_nocache_code = true;
+ $output .= "echo '/*%%SmartyNocache:{$_template->properties['nocache_hash']}%%*/<?php \$_smarty = \$_smarty_tpl->smarty; ";
+ foreach ($_template->required_plugins['nocache'] as $tmp) {
+ foreach ($tmp as $data) {
+ $file = addslashes($data['file']);
+ if (is_Array($data['function'])) {
+ $output .= addslashes("if (!is_callable(array('{$data['function'][0]}','{$data['function'][1]}'))) require_once '{$file}';\n");
+ } else {
+ $output .= addslashes("if (!is_callable('{$data['function']}')) require_once '{$file}';\n");
+ }
+ }
+ }
+ $output .= "?>/*/%%SmartyNocache:{$_template->properties['nocache_hash']}%%*/';\n";
+ }
+ }
+ $output .= "?>\n";
+ $output = self::appendCode($output, $content);
+ return self::appendCode($output, "<?php }\n}\n?>");
+ }
+
+ /**
+ * Create code frame of compiled template function
+ *
+ * @param \Smarty_Internal_Template $_template
+ * @param string $content
+ *
+ * @return string
+ */
+ public static function createFunctionFrame(Smarty_Internal_Template $_template, $content = '') {
+ if (!isset($_template->properties['unifunc'])) {
+ $_template->properties['unifunc'] = 'content_' . str_replace(array('.', ','), '_', uniqid('', true));
+ }
+ $output = "<?php\n";
+ $output .= "/*%%SmartyHeaderCode:{$_template->properties['nocache_hash']}%%*/\n";
+ $output .= "if (\$_valid && !is_callable('{$_template->properties['unifunc']}')) {\n";
+ $output .= "function {$_template->properties['unifunc']} (\$_smarty_tpl) {\n";
+ $output .= "?>\n" . $content;
+ $output .= "<?php\n";
+ $output .= "/*/%%SmartyNocache:{$_template->properties['nocache_hash']}%%*/\n";
+ $output .= "}\n}\n?>";
+ return $output;
+ }
+
+ /**
+ * Append code segments and remove unneeded ?> <?php transitions
+ *
+ * @param string $left
+ * @param string $right
+ *
+ * @return string
+ */
+ public static function appendCode($left, $right) {
+ if (preg_match('/\s*\?>$/', $left) && preg_match('/^<\?php\s+/', $right)) {
+ $left = preg_replace('/\s*\?>$/', "\n", $left);
+ $left .= preg_replace('/^<\?php\s+/', '', $right);
+ } else {
+ $left .= $right;
+ }
+ return $left;
+ }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_extension_config.php
@@ -0,0 +1,154 @@
+<?php
+
+/**
+ * @package Smarty
+ * @subpackage PluginsInternal
+ */
+class Smarty_Internal_Extension_Config {
+ /**
+ * @param $obj
+ * @param $config_file
+ * @param null $sections
+ * @param string $scope
+ */
+ static function configLoad($obj, $config_file, $sections = null, $scope = 'local') {
+ $smarty = isset($obj->smarty) ? $obj->smarty : $obj;
+ $confObj = new $smarty->template_class($config_file, $smarty, $obj);
+ $confObj->caching = Smarty::CACHING_OFF;
+ $confObj->source = Smarty_Template_Config::load($confObj);
+ $confObj->source->config_sections = $sections;
+ $confObj->source->scope = $scope;
+ $confObj->compiled = Smarty_Template_Compiled::load($confObj);
+ if ($confObj->smarty->debugging) {
+ Smarty_Internal_Debug::start_render($confObj);
+ }
+ $confObj->compiled->render($confObj);
+ if ($confObj->smarty->debugging) {
+ Smarty_Internal_Debug::end_render($confObj);
+ }
+ if ($obj instanceof Smarty_Internal_Template) {
+ $obj->properties['file_dependency'][$confObj->source->uid] = array($confObj->source->filepath, $confObj->source->timestamp, $confObj->source->type);
+ }
+ }
+
+ /**
+ * load config variables
+ *
+ * @param mixed $sections array of section names, single section or null
+ * @param string $scope global,parent or local
+ *
+ * @throws Exception
+ */
+ static function loadConfigVars($_template, $_config_vars) {
+ $scope = $_template->source->scope;
+ // pointer to scope (local scope is parent of template object
+ $scope_ptr = $_template->parent;
+ if ($scope == 'parent') {
+ if (isset($_template->parent->parent)) {
+ $scope_ptr = $_template->parent->parent;
+ }
+ } elseif ($scope == 'root' || $scope == 'global') {
+ while (isset($scope_ptr->parent)) {
+ $scope_ptr = $scope_ptr->parent;
+ }
+ }
+ // copy global config vars
+ foreach ($_config_vars['vars'] as $variable => $value) {
+ if ($_template->smarty->config_overwrite || !isset($scope_ptr->config_vars[$variable])) {
+ $scope_ptr->config_vars[$variable] = $value;
+ } else {
+ $scope_ptr->config_vars[$variable] = array_merge((array)$scope_ptr->config_vars[$variable], (array)$value);
+ }
+ }
+ // scan sections
+ $sections = $_template->source->config_sections;
+ if (!empty($sections)) {
+ foreach ((array)$sections as $_template_section) {
+ if (isset($_config_vars['sections'][$_template_section])) {
+ foreach ($_config_vars['sections'][$_template_section]['vars'] as $variable => $value) {
+ if ($_template->smarty->config_overwrite || !isset($scope_ptr->config_vars[$variable])) {
+ $scope_ptr->config_vars[$variable] = $value;
+ } else {
+ $scope_ptr->config_vars[$variable] = array_merge((array)$scope_ptr->config_vars[$variable], (array)$value);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns a single or all config variables
+ *
+ * @param string $varname variable name or null
+ * @param bool $search_parents
+ *
+ * @return string variable value or or array of variables
+ */
+ static function getConfigVars($obj, $varname = null, $search_parents = true) {
+ $_ptr = $obj;
+ $var_array = array();
+ while ($_ptr !== null) {
+ if (isset($varname)) {
+ if (isset($_ptr->config_vars[$varname])) {
+ return $_ptr->config_vars[$varname];
+ }
+ } else {
+ $var_array = array_merge($_ptr->config_vars, $var_array);
+ }
+ // not found, try at parent
+ if ($search_parents) {
+ $_ptr = $_ptr->parent;
+ } else {
+ $_ptr = null;
+ }
+ }
+ if (isset($varname)) {
+ return '';
+ } else {
+ return $var_array;
+ }
+ }
+
+ /**
+ * gets a config variable
+ *
+ * @param string $variable the name of the config variable
+ * @param bool $error_enable
+ *
+ * @return mixed the value of the config variable
+ */
+ static function getConfigVariable($obj, $variable, $error_enable = true) {
+ $_ptr = $obj;
+ while ($_ptr !== null) {
+ if (isset($_ptr->config_vars[$variable])) {
+ // found it, return it
+ return $_ptr->config_vars[$variable];
+ }
+ // not found, try at parent
+ $_ptr = $_ptr->parent;
+ }
+ if ($obj->error_unassigned && $error_enable) {
+ // force a notice
+ $x = $$variable;
+ }
+
+ return null;
+ }
+
+ /**
+ * remove a single or all config variables
+ *
+ * @param string $name variable name or null
+ *
+ * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
+ */
+ static function clearConfig($obj, $name = null) {
+ if (isset($name)) {
+ unset($obj->config_vars[$name]);
+ } else {
+ $obj->config_vars = array();
+ }
+ return $obj;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_extension_defaulttemplatehandler.php
@@ -0,0 +1,81 @@
+<?php
+/**
+ * Smarty Resource Extension
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Resource Extension
+ * Default template and config file handling
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ */
+class Smarty_Internal_Extension_DefaultTemplateHandler {
+
+ /**
+ * get default content from template of config resource handler
+ *
+ * @param Smarty_Internal_Template $_template
+ * @param Smarty_Internal_Template_Source $source
+ * @param Smarty_Resource $resObj
+ */
+ static function _getDefault(Smarty_Internal_Template $_template, &$source, &$resObj) {
+ if ($source->isConfig) {
+ $default_handler = $_template->smarty->default_config_handler_func;
+ } else {
+ $default_handler = $_template->smarty->default_template_handler_func;
+ }
+ $_content = $_timestamp = null;
+ $_return = call_user_func_array($default_handler,
+ array($source->type, $source->name, &$_content, &$_timestamp, $source->smarty));
+ if (is_string($_return)) {
+ $source->exists = is_file($_return);
+ if ($source->exists) {
+ $source->timestamp = filemtime($_return);
+ }
+ $source->filepath = $_return;
+ } elseif ($_return === true) {
+ $source->content = $_content;
+ $source->timestamp = $_timestamp;
+ $source->exists = true;
+ $source->recompiled = true;
+ $source->filepath = false;
+ }
+ }
+
+ /**
+ * register template default handler
+ *
+ * @param Smarty $smarty
+ * @param mixed $callback
+ *
+ * @throws SmartyException
+ */
+ static function registerDefaultTemplateHandler(Smarty $smarty, $callback) {
+ if (is_callable($callback)) {
+ $smarty->default_template_handler_func = $callback;
+ } else {
+ throw new SmartyException("Default template handler not callable");
+ }
+ }
+
+ /**
+ * register config default handler
+ *
+ * @param Smarty $smarty
+ * @param mixed $callback
+ *
+ * @throws SmartyException
+ */
+ static function registerDefaultConfigHandler(Smarty $smarty, $callback) {
+ if (is_callable($callback)) {
+ $smarty->default_config_handler_func = $callback;
+ } else {
+ throw new SmartyException("Default config handler not callable");
+ }
+ }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_filter_handler.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Smarty Internal Plugin Filter Handler
+ * Smarty filter handler class
+ *
+ * @package Smarty
+ * @subpackage PluginsInternal
+ * @author Uwe Tews
+ */
+
+/**
+ * Class for filter processing
+ *
+ * @package Smarty
+ * @subpackage PluginsInternal
+ */
+class Smarty_Internal_Filter_Handler {
+ /**
+ * Run filters over content
+ * The filters will be lazy loaded if required
+ * class name format: Smarty_FilterType_FilterName
+ * plugin filename format: filtertype.filtername.php
+ * Smarty2 filter plugins could be used
+ *
+ * @param string $type the type of filter ('pre','post','output') which shall run
+ * @param string $content the content which shall be processed by the filters
+ * @param Smarty_Internal_Template $template template object
+ *
+ * @throws SmartyException
+ * @return string the filtered content
+ */
+ public static function runFilter($type, $content, Smarty_Internal_Template $template) {
+ $output = $content;
+ // loop over autoload filters of specified type
+ if (!empty($template->smarty->autoload_filters[$type])) {
+ foreach ((array)$template->smarty->autoload_filters[$type] as $name) {
+ $plugin_name = "Smarty_{$type}filter_{$name}";
+ if ($template->smarty->loadPlugin($plugin_name)) {
+ if (function_exists($plugin_name)) {
+ // use loaded Smarty2 style plugin
+ $output = $plugin_name($output, $template);
+ } elseif (class_exists($plugin_name, false)) {
+ // loaded class of filter plugin
+ $output = call_user_func(array($plugin_name, 'execute'), $output, $template);
+ }
+ } else {
+ // nothing found, throw exception
+ throw new SmartyException("Unable to load filter {$plugin_name}");
+ }
+ }
+ }
+ // loop over registerd filters of specified type
+ if (!empty($template->smarty->registered_filters[$type])) {
+ foreach ($template->smarty->registered_filters[$type] as $key => $name) {
+ if (is_array($template->smarty->registered_filters[$type][$key])) {
+ $output = call_user_func($template->smarty->registered_filters[$type][$key], $output, $template);
+ } else {
+ $output = $template->smarty->registered_filters[$type][$key]($output, $template);
+ }
+ }
+ }
+ // return filtered output
+ return $output;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_function_call_handler.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Smarty Internal Plugin Function Call Handler
+ *
+ * @package Smarty
+ * @subpackage PluginsInternal
+ * @author Uwe Tews
+ */
+
+/**
+ * This class does handles template functions defined with the {function} tag missing in cache file.
+ * It can happen when the template function was called with the nocache option or within a nocache section.
+ * The template function will be loaded from it's compiled template file, executed and added to the cache file
+ * for later use.
+ *
+ * @package Smarty
+ * @subpackage PluginsInternal
+ */
+class Smarty_Internal_Function_Call_Handler {
+ /**
+ * This function handles calls to template functions defined by {function}
+ * It does create a PHP function at the first call
+ *
+ * @param string $_name template function name
+ * @param Smarty_Internal_Template $_smarty_tpl
+ * @param string $_function PHP function name
+ * @param array $_params Smarty variables passed as call parameter
+ * @param bool $_nocache nocache flag
+ *
+ * @return bool
+ */
+ public static function call($_name, Smarty_Internal_Template $_smarty_tpl, $_function, $_params, $_nocache) {
+ $funcParam = $_smarty_tpl->properties['tpl_function'][$_name];
+ if (is_file($funcParam['compiled_filepath'])) {
+ // read compiled file
+ $code = file_get_contents($funcParam['compiled_filepath']);
+ // grab template function
+ if (preg_match("/\/\* {$_function} \*\/([\S\s]*?)\/\*\/ {$_function} \*\//", $code, $match)) {
+ // grab source info from file dependency
+ preg_match("/\s*'{$funcParam['uid']}'([\S\s]*?)\),/", $code, $match1);
+ unset($code);
+ $output = '';
+ // make PHP function known
+ eval($match[0]);
+ if (function_exists($_function)) {
+ // search cache file template
+ $tplPtr = $_smarty_tpl;
+ while (!isset($tplPtr->cached) && isset($tplPtr->parent)) {
+ $tplPtr = $tplPtr->parent;
+ }
+ // add template function code to cache file
+ if (isset($tplPtr->cached)) {
+ $cache = $tplPtr->cached;
+ $content = $cache->read($tplPtr);
+ if ($content) {
+ // check if we must update file dependency
+ if (!preg_match("/'{$funcParam['uid']}'([\S\s]*?)'nocache_hash'/", $content, $match2)) {
+ $content = preg_replace("/('file_dependency'([\S\s]*?)\()/", "\\1{$match1[0]}", $content);
+ }
+ $cache->write($tplPtr, $content . "<?php " . $match[0] . "?>\n");
+ }
+ }
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_get_include_path.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Smarty read include path plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsInternal
+ * @author Monte Ohrt
+ */
+
+/**
+ * Smarty Internal Read Include Path Class
+ *
+ * @package Smarty
+ * @subpackage PluginsInternal
+ */
+class Smarty_Internal_Get_Include_Path {
+ /**
+ * Return full file path from PHP include_path
+ *
+ * @param string $filepath filepath
+ *
+ * @return string|boolean full filepath or false
+ */
+ public static function getIncludePath($filepath) {
+ static $_include_path = null;
+
+ if (function_exists('stream_resolve_include_path')) {
+ // available since PHP 5.3.2
+ return stream_resolve_include_path($filepath);
+ }
+
+ if ($_include_path === null) {
+ $_include_path = explode(PATH_SEPARATOR, get_include_path());
+ }
+
+ foreach ($_include_path as $_path) {
+ if (file_exists($_path . DS . $filepath)) {
+ return $_path . DS . $filepath;
+ }
+ }
+
+ return false;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_nocache_insert.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Smarty Internal Plugin Nocache Insert
+ * Compiles the {insert} tag into the cache file
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Insert Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Nocache_Insert {
+ /**
+ * Compiles code for the {insert} tag into cache file
+ *
+ * @param string $_function insert function name
+ * @param array $_attr array with parameter
+ * @param Smarty_Internal_Template $_template template object
+ * @param string $_script script name to load or 'null'
+ * @param string $_assign optional variable name
+ *
+ * @return string compiled code
+ */
+ public static function compile($_function, $_attr, $_template, $_script, $_assign = null) {
+ $_output = '<?php ';
+ if ($_script != 'null') {
+ // script which must be included
+ // code for script file loading
+ $_output .= "require_once '{$_script}';";
+ }
+ // call insert
+ if (isset($_assign)) {
+ $_output .= "\$_smarty_tpl->assign('{$_assign}' , {$_function} (" . var_export($_attr, true) . ",\$_smarty_tpl), true);?>";
+ } else {
+ $_output .= "echo {$_function}(" . var_export($_attr, true) . ",\$_smarty_tpl);?>";
+ }
+ $_tpl = $_template;
+ while ($_tpl->parent instanceof Smarty_Internal_Template) {
+ $_tpl = $_tpl->parent;
+ }
+
+ return "/*%%SmartyNocache:{$_tpl->properties['nocache_hash']}%%*/" . $_output . "/*/%%SmartyNocache:{$_tpl->properties['nocache_hash']}%%*/";
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_parsetree.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Smarty Internal Plugin Templateparser Parsetrees
+ * These are classes to build parsetrees in the template parser
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Thue Kristensen
+ * @author Uwe Tews
+ */
+
+/**
+ * @package Smarty
+ * @subpackage Compiler
+ * @ignore
+ */
+abstract class Smarty_Internal_ParseTree {
+
+ /**
+ * Parser object
+ *
+ * @var object
+ */
+ public $parser;
+
+ /**
+ * Buffer content
+ *
+ * @var mixed
+ */
+ public $data;
+
+ /**
+ * Subtree array
+ *
+ * @var array
+ */
+ public $subtrees = array();
+
+ /**
+ * Return buffer
+ *
+ * @return string buffer content
+ */
+ abstract public function to_smarty_php();
+}
+
+
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_parsetree_code.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Smarty Internal Plugin Templateparser Parse Tree
+ * These are classes to build parse trees in the template parser
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Thue Kristensen
+ * @author Uwe Tews
+ */
+
+/**
+ * Code fragment inside a tag .
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @ignore
+ */
+class Smarty_Internal_ParseTree_Code extends Smarty_Internal_ParseTree {
+ /**
+ * Create parse tree buffer for code fragment
+ *
+ * @param object $parser parser object
+ * @param string $data content
+ */
+ public function __construct($parser, $data) {
+ $this->parser = $parser;
+ $this->data = $data;
+ }
+
+ /**
+ * Return buffer content in parentheses
+ *
+ * @return string content
+ */
+ public function to_smarty_php() {
+ return sprintf("(%s)", $this->data);
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_parsetree_dq.php
@@ -0,0 +1,82 @@
+<?php
+
+/**
+ * Double quoted string inside a tag.
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @ignore
+ */
+
+/**
+ * Double quoted string inside a tag.
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @ignore
+ */
+class Smarty_Internal_ParseTree_Dq extends Smarty_Internal_ParseTree {
+ /**
+ * Create parse tree buffer for double quoted string subtrees
+ *
+ * @param object $parser parser object
+ * @param Smarty_Internal_ParseTree $subtree parse tree buffer
+ */
+ public function __construct($parser, Smarty_Internal_ParseTree $subtree) {
+ $this->parser = $parser;
+ $this->subtrees[] = $subtree;
+ if ($subtree instanceof Smarty_Internal_ParseTree_Tag) {
+ $this->parser->block_nesting_level = count($this->parser->compiler->_tag_stack);
+ }
+ }
+
+ /**
+ * Append buffer to subtree
+ *
+ * @param Smarty_Internal_ParseTree $subtree parse tree buffer
+ */
+ public function append_subtree(Smarty_Internal_ParseTree $subtree) {
+ $last_subtree = count($this->subtrees) - 1;
+ if ($last_subtree >= 0 && $this->subtrees[$last_subtree] instanceof Smarty_Internal_ParseTree_Tag && $this->subtrees[$last_subtree]->saved_block_nesting < $this->parser->block_nesting_level) {
+ if ($subtree instanceof Smarty_Internal_ParseTree_Code) {
+ $this->subtrees[$last_subtree]->data = $this->parser->compiler->appendCode($this->subtrees[$last_subtree]->data, '<?php echo ' . $subtree->data . ';?>');
+ } elseif ($subtree instanceof Smarty_Internal_ParseTree_DqContent) {
+ $this->subtrees[$last_subtree]->data = $this->parser->compiler->appendCode($this->subtrees[$last_subtree]->data, '<?php echo "' . $subtree->data . '";?>');
+ } else {
+ $this->subtrees[$last_subtree]->data = $this->parser->compiler->appendCode($this->subtrees[$last_subtree]->data, $subtree->data);
+ }
+ } else {
+ $this->subtrees[] = $subtree;
+ }
+ if ($subtree instanceof Smarty_Internal_ParseTree_Tag) {
+ $this->parser->block_nesting_level = count($this->parser->compiler->_tag_stack);
+ }
+ }
+
+ /**
+ * Merge subtree buffer content together
+ *
+ * @return string compiled template code
+ */
+ public function to_smarty_php() {
+ $code = '';
+ foreach ($this->subtrees as $subtree) {
+ if ($code !== "") {
+ $code .= ".";
+ }
+ if ($subtree instanceof Smarty_Internal_ParseTree_Tag) {
+ $more_php = $subtree->assign_to_var();
+ } else {
+ $more_php = $subtree->to_smarty_php();
+ }
+
+ $code .= $more_php;
+
+ if (!$subtree instanceof Smarty_Internal_ParseTree_DqContent) {
+ $this->parser->compiler->has_variable_string = true;
+ }
+ }
+
+ return $code;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_parsetree_dqcontent.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Smarty Internal Plugin Templateparser Parse Tree
+ * These are classes to build parse tree in the template parser
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Thue Kristensen
+ * @author Uwe Tews
+ */
+
+/**
+ * Raw chars as part of a double quoted string.
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @ignore
+ */
+class Smarty_Internal_ParseTree_DqContent extends Smarty_Internal_ParseTree {
+ /**
+ * Create parse tree buffer with string content
+ *
+ * @param object $parser parser object
+ * @param string $data string section
+ */
+ public function __construct($parser, $data) {
+ $this->parser = $parser;
+ $this->data = $data;
+ }
+
+ /**
+ * Return content as double quoted string
+ *
+ * @return string doubled quoted string
+ */
+ public function to_smarty_php() {
+ return '"' . $this->data . '"';
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_parsetree_tag.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * Smarty Internal Plugin Templateparser Parse Tree
+ * These are classes to build parse tree in the template parser
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Thue Kristensen
+ * @author Uwe Tews
+ */
+
+/**
+ * A complete smarty tag.
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @ignore
+ */
+class Smarty_Internal_ParseTree_Tag extends Smarty_Internal_ParseTree {
+
+ /**
+ * Saved block nesting level
+ *
+ * @var int
+ */
+ public $saved_block_nesting;
+
+ /**
+ * Create parse tree buffer for Smarty tag
+ *
+ * @param object $parser parser object
+ * @param string $data content
+ */
+ public function __construct($parser, $data) {
+ $this->parser = $parser;
+ $this->data = $data;
+ $this->saved_block_nesting = $parser->block_nesting_level;
+ }
+
+ /**
+ * Return buffer content
+ *
+ * @return string content
+ */
+ public function to_smarty_php() {
+ return $this->data;
+ }
+
+ /**
+ * Return complied code that loads the evaluated output of buffer content into a temporary variable
+ *
+ * @return string template code
+ */
+ public function assign_to_var() {
+ $var = sprintf('$_tmp%d', ++Smarty_Internal_Templateparser::$prefix_number);
+ $tmp = $this->parser->compiler->appendCode('<?php ob_start();?>', $this->data);
+ $tmp = $this->parser->compiler->appendCode($tmp, "<?php {$var}=ob_get_clean();?>");
+ $this->parser->compiler->prefix_code[] = sprintf("%s", $tmp);
+
+ return $var;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_parsetree_template.php
@@ -0,0 +1,94 @@
+<?php
+/**
+ * Smarty Internal Plugin Templateparser Parse Tree
+ * These are classes to build parse tree in the template parser
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Thue Kristensen
+ * @author Uwe Tews
+ */
+
+/**
+ * Template element
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @ignore
+ */
+class Smarty_Internal_ParseTree_Template extends Smarty_Internal_ParseTree {
+
+ /**
+ * Array of template elements
+ *
+ * @var array
+ */
+ public $subtrees = Array();
+
+ /**
+ * Create root of parse tree for template elements
+ *
+ * @param object $parser parse object
+ */
+ public function __construct($parser) {
+ $this->parser = $parser;
+ }
+
+ /**
+ * Append buffer to subtree
+ *
+ * @param Smarty_Internal_ParseTree $subtree
+ */
+ public function append_subtree(Smarty_Internal_ParseTree $subtree) {
+ if (!empty($subtree->subtrees)) {
+ $this->subtrees = array_merge($this->subtrees, $subtree->subtrees);
+ } else {
+ if ($subtree->data !== '') {
+ $this->subtrees[] = $subtree;
+ }
+ }
+ }
+
+ /**
+ * Sanitize and merge subtree buffers together
+ *
+ * @return string template code content
+ */
+ public function to_smarty_php() {
+ $code = '';
+ for ($key = 0, $cnt = count($this->subtrees); $key < $cnt; $key++) {
+ if ($this->subtrees[$key] instanceof Smarty_Internal_ParseTree_Text) {
+ $subtree = $this->subtrees[$key]->to_smarty_php();
+ while ($key + 1 < $cnt && ($this->subtrees[$key + 1] instanceof Smarty_Internal_ParseTree_Text || $this->subtrees[$key + 1]->data == '')) {
+ $key++;
+ if ($this->subtrees[$key]->data == '') {
+ continue;
+ }
+ $subtree .= $this->subtrees[$key]->to_smarty_php();
+ }
+ if ($subtree == '') {
+ continue;
+ }
+ $code .= preg_replace('/((<%)|(%>)|(<\?php)|(<\?)|(\?>)|(<\/?script))/', "<?php echo '\$1'; ?>\n", $subtree);
+ continue;
+ }
+ if ($this->subtrees[$key] instanceof Smarty_Internal_ParseTree_Tag) {
+ $subtree = $this->subtrees[$key]->to_smarty_php();
+ while ($key + 1 < $cnt && ($this->subtrees[$key + 1] instanceof Smarty_Internal_ParseTree_Tag || $this->subtrees[$key + 1]->data == '')) {
+ $key++;
+ if ($this->subtrees[$key]->data == '') {
+ continue;
+ }
+ $subtree = $this->parser->compiler->appendCode($subtree, $this->subtrees[$key]->to_smarty_php());
+ }
+ if ($subtree == '') {
+ continue;
+ }
+ $code .= $subtree;
+ continue;
+ }
+ $code .= $this->subtrees[$key]->to_smarty_php();
+ }
+ return $code;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_parsetree_text.php
@@ -0,0 +1,37 @@
+<?php
+
+/**
+ * Smarty Internal Plugin Templateparser Parse Tree
+ * These are classes to build parse tree in the template parser
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Thue Kristensen
+ * @author Uwe Tews
+ * *
+ * template text
+ * @package Smarty
+ * @subpackage Compiler
+ * @ignore
+ */
+class Smarty_Internal_ParseTree_Text extends Smarty_Internal_ParseTree {
+ /**
+ * Create template text buffer
+ *
+ * @param object $parser parser object
+ * @param string $data text
+ */
+ public function __construct($parser, $data) {
+ $this->parser = $parser;
+ $this->data = $data;
+ }
+
+ /**
+ * Return buffer content
+ *
+ * @return string text
+ */
+ public function to_smarty_php() {
+ return $this->data;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_resource_eval.php
@@ -0,0 +1,90 @@
+<?php
+/**
+ * Smarty Internal Plugin Resource Eval
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Uwe Tews
+ * @author Rodney Rehm
+ */
+
+/**
+ * Smarty Internal Plugin Resource Eval
+ * Implements the strings as resource for Smarty template
+ * {@internal unlike string-resources the compiled state of eval-resources is NOT saved for subsequent access}}
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ */
+class Smarty_Internal_Resource_Eval extends Smarty_Resource_Recompiled {
+ /**
+ * populate Source Object with meta data from Resource
+ *
+ * @param Smarty_Template_Source $source source object
+ * @param Smarty_Internal_Template $_template template object
+ *
+ * @return void
+ */
+ public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template = null) {
+ $source->uid = $source->filepath = sha1($source->name);
+ $source->timestamp = false;
+ $source->exists = true;
+ }
+
+ /**
+ * Load template's source from $resource_name into current template object
+ *
+ * @uses decode() to decode base64 and urlencoded template_resources
+ *
+ * @param Smarty_Template_Source $source source object
+ *
+ * @return string template source
+ */
+ public function getContent(Smarty_Template_Source $source) {
+ return $this->decode($source->name);
+ }
+
+ /**
+ * decode base64 and urlencode
+ *
+ * @param string $string template_resource to decode
+ *
+ * @return string decoded template_resource
+ */
+ protected function decode($string) {
+ // decode if specified
+ if (($pos = strpos($string, ':')) !== false) {
+ if (!strncmp($string, 'base64', 6)) {
+ return base64_decode(substr($string, 7));
+ } elseif (!strncmp($string, 'urlencode', 9)) {
+ return urldecode(substr($string, 10));
+ }
+ }
+
+ return $string;
+ }
+
+ /**
+ * modify resource_name according to resource handlers specifications
+ *
+ * @param Smarty $smarty Smarty instance
+ * @param string $resource_name resource_name to make unique
+ * @param boolean $isConfig flag for config resource
+ *
+ * @return string unique resource name
+ */
+ public function buildUniqueResourceName(Smarty $smarty, $resource_name, $isConfig = false) {
+ return get_class($this) . '#' . $this->decode($resource_name);
+ }
+
+ /**
+ * Determine basename for compiled filename
+ *
+ * @param Smarty_Template_Source $source source object
+ *
+ * @return string resource's basename
+ */
+ public function getBasename(Smarty_Template_Source $source) {
+ return '';
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_resource_extends.php
@@ -0,0 +1,107 @@
+<?php
+/**
+ * Smarty Internal Plugin Resource Extends
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Uwe Tews
+ * @author Rodney Rehm
+ */
+
+/**
+ * Smarty Internal Plugin Resource Extends
+ * Implements the file system as resource for Smarty which {extend}s a chain of template files templates
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ */
+class Smarty_Internal_Resource_Extends extends Smarty_Resource {
+ /**
+ * mbstring.overload flag
+ *
+ * @var int
+ */
+ public $mbstring_overload = 0;
+
+ /**
+ * populate Source Object with meta data from Resource
+ *
+ * @param Smarty_Template_Source $source source object
+ * @param Smarty_Internal_Template $_template template object
+ *
+ * @throws SmartyException
+ */
+ public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template = null) {
+ $uid = sha1(getcwd());
+ $sources = array();
+ $components = explode('|', $source->name);
+ $exists = true;
+ foreach ($components as $component) {
+ $s = Smarty_Resource::source(null, $source->smarty, $component);
+ if ($s->type == 'php') {
+ throw new SmartyException("Resource type {$s->type} cannot be used with the extends resource type");
+ }
+ $sources[$s->uid] = $s;
+ $uid .= realpath($s->filepath);
+ if ($_template && $_template->smarty->compile_check) {
+ $exists = $exists && $s->exists;
+ }
+ }
+ $source->components = $sources;
+ $source->filepath = $s->filepath;
+ $source->uid = sha1($uid);
+ if ($_template && $_template->smarty->compile_check) {
+ $source->timestamp = $s->timestamp;
+ $source->exists = $exists;
+ }
+ // need the template at getContent()
+ $source->template = $_template;
+ }
+
+ /**
+ * populate Source Object with timestamp and exists from Resource
+ *
+ * @param Smarty_Template_Source $source source object
+ */
+ public function populateTimestamp(Smarty_Template_Source $source) {
+ $source->exists = true;
+ foreach ($source->components as $s) {
+ $source->exists = $source->exists && $s->exists;
+ }
+ $source->timestamp = $s->timestamp;
+ }
+
+ /**
+ * Load template's source from files into current template object
+ *
+ * @param Smarty_Template_Source $source source object
+ *
+ * @return string template source
+ * @throws SmartyException if source cannot be loaded
+ */
+ public function getContent(Smarty_Template_Source $source) {
+ if (!$source->exists) {
+ throw new SmartyException("Unable to read template {$source->type} '{$source->name}'");
+ }
+
+ $_components = array_reverse($source->components);
+
+ $_content = '';
+ foreach ($_components as $_component) {
+ // read content
+ $_content .= $_component->content;
+ }
+ return $_content;
+ }
+
+ /**
+ * Determine basename for compiled filename
+ *
+ * @param Smarty_Template_Source $source source object
+ *
+ * @return string resource's basename
+ */
+ public function getBasename(Smarty_Template_Source $source) {
+ return str_replace(':', '.', basename($source->filepath));
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_resource_file.php
@@ -0,0 +1,208 @@
+<?php
+/**
+ * Smarty Internal Plugin Resource File
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Uwe Tews
+ * @author Rodney Rehm
+ */
+
+/**
+ * Smarty Internal Plugin Resource File
+ * Implements the file system as resource for Smarty templates
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ */
+class Smarty_Internal_Resource_File extends Smarty_Resource {
+ /**
+ * build template filepath by traversing the template_dir array
+ *
+ * @param Smarty_Template_Source $source source object
+ * @param Smarty_Internal_Template $_template template object
+ *
+ * @return string fully qualified filepath
+ * @throws SmartyException
+ */
+ protected function buildFilepath(Smarty_Template_Source $source, Smarty_Internal_Template $_template = null) {
+ $file = $source->name;
+ preg_match('#^(?P<absolute>[\\\/]|[a-zA-Z]:[\\\/])|(\[(?P<index>[^\]]+)\])|(?P<rel>\.[\\\/])#', $file, $fileMatch);
+ // save basename
+ if (!empty($fileMatch['absolute'])) {
+ $file = $this->normalizePath($file);
+ return is_file($file) ? $file : false;
+ }
+ // go relative to a given template?
+ if (!empty($fileMatch['rel']) && $_template && $_template->parent instanceof Smarty_Internal_Template) {
+ if ($_template->parent->source->type != 'file' && $_template->parent->source->type != 'extends' && !$_template->parent->allow_relative_path) {
+ throw new SmartyException("Template '{$file}' cannot be relative to template of resource type '{$_template->parent->source->type}'");
+ }
+ $path = dirname($_template->parent->source->filepath) . DS . $file;
+ // normalize path
+ $path = $this->normalizePath($path);
+ // files relative to a template only get one shot
+ return is_file($path) ? $path : false;
+ }
+
+ if ($source->isConfig) {
+ $_directories = $source->smarty->getConfigDir();
+ } else {
+ $_directories = $source->smarty->getTemplateDir();
+ }
+ // template_dir index?
+ if (!empty($fileMatch['index'])) {
+ $index = $fileMatch['index'];
+ $_directory = null;
+ // try string indexes
+ if (isset($_directories[$index])) {
+ $_directory = $_directories[$index];
+ } elseif (is_numeric($index)) {
+ // try numeric index
+ $index = (int)$index;
+ if (isset($_directories[$index])) {
+ $_directory = $_directories[$index];
+ } else {
+ // try at location index
+ $keys = array_keys($_directories);
+ $_directory = $_directories[$keys[$index]];
+ }
+ }
+ if ($_directory) {
+ preg_match('#\](.+)$#', $file, $fileMatch);
+ $path = $_directory . $fileMatch[1];
+ $path = $this->normalizePath($path);
+ if (is_file($path)) {
+ return $path;
+ }
+ } else {
+ // index not found
+ return false;
+ }
+ }
+
+ // relative file name?
+ foreach ($_directories as $_directory) {
+ $_filepath = $_directory . $file;
+ $path = $this->normalizePath($_filepath);
+ if (is_file($path)) {
+ return $path;
+ }
+ if ($source->smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_directory)) {
+ // try PHP include_path
+ if (function_exists('stream_resolve_include_path')) {
+ $_filepath = stream_resolve_include_path($_filepath);
+ } else {
+ $_filepath = Smarty_Internal_Get_Include_Path::getIncludePath($_filepath);
+ }
+ if ($_filepath !== false) {
+ $path = $this->normalizePath($_filepath);
+ if (is_file($path)) {
+ return $path;
+ }
+ }
+ }
+ }
+ // Could be relative to cwd
+ $path = $this->normalizePath(getcwd() . DS . $file);
+ return is_file($path) ? $path : false;
+ }
+
+ /**
+ * Normalize path
+ * - remove /./ and /../
+ * - make it absolute
+ *
+ * @param string $path file path
+ *
+ * @return string
+ */
+ public function normalizePath($path) {
+ if ($path[0] == '.') {
+ $path = getcwd() . DS . $path;
+ }
+ $path = preg_replace('#[\\\/]+([.][\\\/]+)*#', DS, $path);
+ while (strrpos($path, '.' . DS) !== false) {
+ $path = preg_replace('#([\\\/]([^\\\/]+[\\\/]){2}([.][.][\\\/]){2})|([\\\/][^\\\/]+[\\\/][.][.][\\\/])#', DS, $path);
+ }
+ return $path;
+ }
+
+ /**
+ * test is file exists and save timestamp
+ *
+ * @param Smarty_Template_Source $source source object
+ * @param string $file file name
+ *
+ * @return bool true if file exists
+ */
+ protected function fileExists(Smarty_Template_Source $source, $file) {
+ $source->timestamp = is_file($file) ? @filemtime($file) : false;
+ return $source->exists = !!$source->timestamp;
+ }
+
+ /**
+ * populate Source Object with meta data from Resource
+ *
+ * @param Smarty_Template_Source $source source object
+ * @param Smarty_Internal_Template $_template template object
+ */
+ public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template = null) {
+ $source->filepath = $this->buildFilepath($source, $_template);
+
+ if ($source->filepath !== false) {
+ if (is_object($source->smarty->security_policy)) {
+ $source->smarty->security_policy->isTrustedResourceDir($source->filepath);
+ }
+ $source->exists = true;
+ $source->uid = sha1($source->filepath);
+ if ($source->smarty->compile_check && !isset($source->timestamp)) {
+ $source->timestamp = @filemtime($source->filepath);
+ }
+ } else {
+ $source->timestamp = false;
+ $source->exists = false;
+ }
+ }
+
+ /**
+ * populate Source Object with timestamp and exists from Resource
+ *
+ * @param Smarty_Template_Source $source source object
+ */
+ public function populateTimestamp(Smarty_Template_Source $source) {
+ $source->timestamp = $source->exists = is_file($source->filepath);
+ if ($source->exists) {
+ $source->timestamp = @filemtime($source->filepath);
+ }
+ }
+
+ /**
+ * Load template's source from file into current template object
+ *
+ * @param Smarty_Template_Source $source source object
+ *
+ * @return string template source
+ * @throws SmartyException if source cannot be loaded
+ */
+ public function getContent(Smarty_Template_Source $source) {
+ if ($source->timestamp) {
+ return file_get_contents($source->filepath);
+ }
+ if ($source instanceof Smarty_Config_Source) {
+ throw new SmartyException("Unable to read config {$source->type} '{$source->name}'");
+ }
+ throw new SmartyException("Unable to read template {$source->type} '{$source->name}'");
+ }
+
+ /**
+ * Determine basename for compiled filename
+ *
+ * @param Smarty_Template_Source $source source object
+ *
+ * @return string resource's basename
+ */
+ public function getBasename(Smarty_Template_Source $source) {
+ return basename($source->filepath);
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_resource_php.php
@@ -0,0 +1,94 @@
+<?php
+
+/**
+ * Smarty Internal Plugin Resource PHP
+ * Implements the file system as resource for PHP templates
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Uwe Tews
+ * @author Rodney Rehm
+ */
+class Smarty_Internal_Resource_Php extends Smarty_Internal_Resource_File {
+ /**
+ * Flag that it's an uncompiled resource
+ *
+ * @var bool
+ */
+ public $uncompiled = true;
+ /**
+ * container for short_open_tag directive's value before executing PHP templates
+ *
+ * @var string
+ */
+ protected $short_open_tag;
+
+ /**
+ * Create a new PHP Resource
+ */
+ public function __construct() {
+ $this->short_open_tag = ini_get('short_open_tag');
+ }
+
+ /**
+ * Load template's source from file into current template object
+ *
+ * @param Smarty_Template_Source $source source object
+ *
+ * @return string template source
+ * @throws SmartyException if source cannot be loaded
+ */
+ public function getContent(Smarty_Template_Source $source) {
+ if ($source->timestamp) {
+ return '';
+ }
+ throw new SmartyException("Unable to read template {$source->type} '{$source->name}'");
+ }
+
+ /**
+ * Render and output the template (without using the compiler)
+ *
+ * @param Smarty_Template_Source $source source object
+ * @param Smarty_Internal_Template $_template template object
+ *
+ * @return void
+ * @throws SmartyException if template cannot be loaded or allow_php_templates is disabled
+ */
+ public function renderUncompiled(Smarty_Template_Source $source, Smarty_Internal_Template $_template) {
+ if (!$source->smarty->allow_php_templates) {
+ throw new SmartyException("PHP templates are disabled");
+ }
+ if (!$source->exists) {
+ if ($_template->parent instanceof Smarty_Internal_Template) {
+ $parent_resource = " in '{$_template->parent->template_resource}'";
+ } else {
+ $parent_resource = '';
+ }
+ throw new SmartyException("Unable to load template {$source->type} '{$source->name}'{$parent_resource}");
+ }
+
+ // prepare variables
+ extract($_template->getTemplateVars());
+
+ // include PHP template with short open tags enabled
+ ini_set('short_open_tag', '1');
+ /** @var Smarty_Internal_Template $_smarty_template
+ * used in included file
+ */
+ $_smarty_template = $_template;
+ include($source->filepath);
+ ini_set('short_open_tag', $this->short_open_tag);
+ }
+
+ /**
+ * populate compiled object with compiled filepath
+ *
+ * @param Smarty_Template_Compiled $compiled compiled object
+ * @param Smarty_Internal_Template $_template template object (is ignored)
+ */
+ public function populateCompiledFilepath(Smarty_Template_Compiled $compiled, Smarty_Internal_Template $_template) {
+ $compiled->filepath = false;
+ $compiled->timestamp = false;
+ $compiled->exists = false;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_resource_registered.php
@@ -0,0 +1,92 @@
+<?php
+/**
+ * Smarty Internal Plugin Resource Registered
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Uwe Tews
+ * @author Rodney Rehm
+ */
+
+/**
+ * Smarty Internal Plugin Resource Registered
+ * Implements the registered resource for Smarty template
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @deprecated
+ */
+class Smarty_Internal_Resource_Registered extends Smarty_Resource {
+ /**
+ * populate Source Object with meta data from Resource
+ *
+ * @param Smarty_Template_Source $source source object
+ * @param Smarty_Internal_Template $_template template object
+ *
+ * @return void
+ */
+ public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template = null) {
+ $source->filepath = $source->type . ':' . $source->name;
+ $source->uid = sha1($source->filepath);
+ if ($source->smarty->compile_check) {
+ $source->timestamp = $this->getTemplateTimestamp($source);
+ $source->exists = !!$source->timestamp;
+ }
+ }
+
+ /**
+ * populate Source Object with timestamp and exists from Resource
+ *
+ * @param Smarty_Template_Source $source source object
+ *
+ * @return void
+ */
+ public function populateTimestamp(Smarty_Template_Source $source) {
+ $source->timestamp = $this->getTemplateTimestamp($source);
+ $source->exists = !!$source->timestamp;
+ }
+
+ /**
+ * Get timestamp (epoch) the template source was modified
+ *
+ * @param Smarty_Template_Source $source source object
+ *
+ * @return integer|boolean timestamp (epoch) the template was modified, false if resources has no timestamp
+ */
+ public function getTemplateTimestamp(Smarty_Template_Source $source) {
+ // return timestamp
+ $time_stamp = false;
+ call_user_func_array($source->smarty->registered_resources[$source->type][0][1], array($source->name, &$time_stamp, $source->smarty));
+
+ return is_numeric($time_stamp) ? (int)$time_stamp : $time_stamp;
+ }
+
+ /**
+ * Load template's source by invoking the registered callback into current template object
+ *
+ * @param Smarty_Template_Source $source source object
+ *
+ * @return string template source
+ * @throws SmartyException if source cannot be loaded
+ */
+ public function getContent(Smarty_Template_Source $source) {
+ // return template string
+ $t = call_user_func_array($source->smarty->registered_resources[$source->type][0][0], array($source->name, &$source->content, $source->smarty));
+ if (is_bool($t) && !$t) {
+ throw new SmartyException("Unable to read template {$source->type} '{$source->name}'");
+ }
+
+ return $source->content;
+ }
+
+ /**
+ * Determine basename for compiled filename
+ *
+ * @param Smarty_Template_Source $source source object
+ *
+ * @return string resource's basename
+ */
+ public function getBasename(Smarty_Template_Source $source) {
+ return basename($source->name);
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_resource_stream.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Smarty Internal Plugin Resource Stream
+ * Implements the streams as resource for Smarty template
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Uwe Tews
+ * @author Rodney Rehm
+ */
+
+/**
+ * Smarty Internal Plugin Resource Stream
+ * Implements the streams as resource for Smarty template
+ *
+ * @link http://php.net/streams
+ * @package Smarty
+ * @subpackage TemplateResources
+ */
+class Smarty_Internal_Resource_Stream extends Smarty_Resource_Recompiled {
+ /**
+ * populate Source Object with meta data from Resource
+ *
+ * @param Smarty_Template_Source $source source object
+ * @param Smarty_Internal_Template $_template template object
+ *
+ * @return void
+ */
+ public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template = null) {
+ if (strpos($source->resource, '://') !== false) {
+ $source->filepath = $source->resource;
+ } else {
+ $source->filepath = str_replace(':', '://', $source->resource);
+ }
+ $source->uid = false;
+ $source->content = $this->getContent($source);
+ $source->timestamp = false;
+ $source->exists = !!$source->content;
+ }
+
+ /**
+ * Load template's source from stream into current template object
+ *
+ * @param Smarty_Template_Source $source source object
+ *
+ * @return string template source
+ * @throws SmartyException if source cannot be loaded
+ */
+ public function getContent(Smarty_Template_Source $source) {
+ $t = '';
+ // the availability of the stream has already been checked in Smarty_Resource::fetch()
+ $fp = fopen($source->filepath, 'r+');
+ if ($fp) {
+ while (!feof($fp) && ($current_line = fgets($fp)) !== false) {
+ $t .= $current_line;
+ }
+ fclose($fp);
+
+ return $t;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * modify resource_name according to resource handlers specifications
+ *
+ * @param Smarty $smarty Smarty instance
+ * @param string $resource_name resource_name to make unique
+ * @param boolean $isConfig flag for config resource
+ *
+ * @return string unique resource name
+ */
+ public function buildUniqueResourceName(Smarty $smarty, $resource_name, $isConfig = false) {
+ return get_class($this) . '#' . $resource_name;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_resource_string.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ * Smarty Internal Plugin Resource String
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Uwe Tews
+ * @author Rodney Rehm
+ */
+
+/**
+ * Smarty Internal Plugin Resource String
+ * Implements the strings as resource for Smarty template
+ * {@internal unlike eval-resources the compiled state of string-resources is saved for subsequent access}}
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ */
+class Smarty_Internal_Resource_String extends Smarty_Resource {
+ /**
+ * populate Source Object with meta data from Resource
+ *
+ * @param Smarty_Template_Source $source source object
+ * @param Smarty_Internal_Template $_template template object
+ *
+ * @return void
+ */
+ public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template = null) {
+ $source->uid = $source->filepath = sha1($source->name);
+ $source->timestamp = 0;
+ $source->exists = true;
+ }
+
+ /**
+ * Load template's source from $resource_name into current template object
+ *
+ * @uses decode() to decode base64 and urlencoded template_resources
+ *
+ * @param Smarty_Template_Source $source source object
+ *
+ * @return string template source
+ */
+ public function getContent(Smarty_Template_Source $source) {
+ return $this->decode($source->name);
+ }
+
+ /**
+ * decode base64 and urlencode
+ *
+ * @param string $string template_resource to decode
+ *
+ * @return string decoded template_resource
+ */
+ protected function decode($string) {
+ // decode if specified
+ if (($pos = strpos($string, ':')) !== false) {
+ if (!strncmp($string, 'base64', 6)) {
+ return base64_decode(substr($string, 7));
+ } elseif (!strncmp($string, 'urlencode', 9)) {
+ return urldecode(substr($string, 10));
+ }
+ }
+
+ return $string;
+ }
+
+ /**
+ * modify resource_name according to resource handlers specifications
+ *
+ * @param Smarty $smarty Smarty instance
+ * @param string $resource_name resource_name to make unique
+ * @param boolean $isConfig flag for config resource
+ *
+ * @return string unique resource name
+ */
+ public function buildUniqueResourceName(Smarty $smarty, $resource_name, $isConfig = false) {
+ return get_class($this) . '#' . $this->decode($resource_name);
+ }
+
+ /**
+ * Determine basename for compiled filename
+ * Always returns an empty string.
+ *
+ * @param Smarty_Template_Source $source source object
+ *
+ * @return string resource's basename
+ */
+ public function getBasename(Smarty_Template_Source $source) {
+ return '';
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_smartytemplatecompiler.php
@@ -0,0 +1,133 @@
+<?php
+/**
+ * Smarty Internal Plugin Smarty Template Compiler Base
+ * This file contains the basic classes and methods for compiling Smarty templates with lexer/parser
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * @ignore
+ */
+//include 'smarty_internal_parsetree.php';
+
+/**
+ * Class SmartyTemplateCompiler
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_SmartyTemplateCompiler extends Smarty_Internal_TemplateCompilerBase {
+ /**
+ * Lexer class name
+ *
+ * @var string
+ */
+ public $lexer_class;
+
+ /**
+ * Parser class name
+ *
+ * @var string
+ */
+ public $parser_class;
+
+ /**
+ * Lexer object
+ *
+ * @var object
+ */
+ public $lex;
+
+ /**
+ * Parser object
+ *
+ * @var object
+ */
+ public $parser;
+
+ /**
+ * array of vars which can be compiled in local scope
+ *
+ * @var array
+ */
+ public $local_var = array();
+
+ /**
+ * Initialize compiler
+ *
+ * @param string $lexer_class class name
+ * @param string $parser_class class name
+ * @param Smarty $smarty global instance
+ */
+ public function __construct($lexer_class, $parser_class, $smarty) {
+ $this->smarty = $smarty;
+ parent::__construct();
+ // get required plugins
+ $this->lexer_class = $lexer_class;
+ $this->parser_class = $parser_class;
+ }
+
+ /**
+ * method to compile a Smarty template
+ *
+ * @param mixed $_content template source
+ *
+ * @return bool true if compiling succeeded, false if it failed
+ */
+ protected function doCompile($_content, $isTemplateSource = false) {
+ /* here is where the compiling takes place. Smarty
+ tags in the templates are replaces with PHP code,
+ then written to compiled files. */
+ // init the lexer/parser to compile the template
+ $this->lex = new $this->lexer_class(str_replace(array("\r\n", "\r"), "\n", $_content), $this);
+ $this->parser = new $this->parser_class($this->lex, $this);
+ if ($isTemplateSource) {
+ $this->parser->insertPhpCode("<?php\n\$_smarty_tpl->properties['nocache_hash'] = '{$this->nocache_hash}';\n?>\n");
+ }
+ if ($this->inheritance_child) {
+ // start state on child templates
+ $this->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBODY);
+ }
+ if (function_exists('mb_internal_encoding') && ((int)ini_get('mbstring.func_overload')) & 2) {
+ $mbEncoding = mb_internal_encoding();
+ mb_internal_encoding('ASCII');
+ } else {
+ $mbEncoding = null;
+ }
+
+ if ($this->smarty->_parserdebug) {
+ $this->parser->PrintTrace();
+ $this->lex->PrintTrace();
+ }
+ // get tokens from lexer and parse them
+ while ($this->lex->yylex() && !$this->abort_and_recompile) {
+ if ($this->smarty->_parserdebug) {
+ echo "<pre>Line {$this->lex->line} Parsing {$this->parser->yyTokenName[$this->lex->token]} Token " .
+ htmlentities($this->lex->value) . "</pre>";
+ }
+ $this->parser->doParse($this->lex->token, $this->lex->value);
+ }
+
+ if ($this->abort_and_recompile) {
+ // exit here on abort
+ return false;
+ }
+ // finish parsing process
+ $this->parser->doParse(0, 0);
+ if ($mbEncoding) {
+ mb_internal_encoding($mbEncoding);
+ }
+ // check for unclosed tags
+ if (count($this->_tag_stack) > 0) {
+ // get stacked info
+ list($openTag, $_data) = array_pop($this->_tag_stack);
+ $this->trigger_template_error("unclosed {$this->smarty->left_delimiter}" . $openTag . "{$this->smarty->right_delimiter} tag");
+ }
+ // return compiled code
+ // return str_replace(array("? >\n<?php","? ><?php"), array('',''), $this->parser->retvalue);
+ return $this->parser->retvalue;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_template.php
@@ -0,0 +1,893 @@
+<?php
+/**
+ * Smarty Internal Plugin Template
+ * This file contains the Smarty template engine
+ *
+ * @package Smarty
+ * @subpackage Template
+ * @author Uwe Tews
+ */
+
+/**
+ * Main class with template data structures and methods
+ *
+ * @package Smarty
+ * @subpackage Template
+ *
+ * @property Smarty_Template_Source $source
+ * @property Smarty_Template_Compiled $compiled
+ * @property Smarty_Template_Cached $cached
+ */
+class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
+ /**
+ * Global smarty instance
+ *
+ * @var Smarty
+ */
+ public $smarty = null;
+
+ /**
+ * Template resource
+ *
+ * @var string
+ */
+ public $template_resource = null;
+ /**
+ * Saved template Id
+ *
+ * @var null|string
+ */
+ public $templateId = null;
+ /**
+ * flag if compiled template is invalid and must be (re)compiled
+ *
+ * @var bool
+ */
+ public $mustCompile = null;
+ /**
+ * flag if template does contain nocache code sections
+ *
+ * @var bool
+ */
+ public $has_nocache_code = false;
+ /**
+ * special compiled and cached template properties
+ *
+ * @var array
+ */
+ public $properties = array('file_dependency' => array(),
+ 'nocache_hash' => '',
+ 'tpl_function' => array(),
+ );
+ /**
+ * required plugins
+ *
+ * @var array
+ */
+ public $required_plugins = array('compiled' => array(), 'nocache' => array());
+ /**
+ * blocks for template inheritance
+ *
+ * @var array
+ */
+ public $block_data = array();
+ /**
+ * variable filters
+ *
+ * @var array
+ */
+ public $variable_filters = array();
+ /**
+ * optional log of tag/attributes
+ *
+ * @var array
+ */
+ public $used_tags = array();
+ /**
+ * internal flag to allow relative path in child template blocks
+ *
+ * @var bool
+ */
+ public $allow_relative_path = false;
+ /**
+ * internal capture runtime stack
+ *
+ * @var array
+ */
+ public $_capture_stack = array(0 => array());
+
+ /**
+ * Create template data object
+ * Some of the global Smarty settings copied to template scope
+ * It load the required template resources and caching plugins
+ *
+ * @param string $template_resource template resource string
+ * @param Smarty $smarty Smarty instance
+ * @param Smarty_Internal_Template $_parent back pointer to parent object with variables or null
+ * @param mixed $_cache_id cache id or null
+ * @param mixed $_compile_id compile id or null
+ * @param bool $_caching use caching?
+ * @param int $_cache_lifetime cache life-time in seconds
+ */
+ public function __construct($template_resource, $smarty, $_parent = null, $_cache_id = null, $_compile_id = null, $_caching = null, $_cache_lifetime = null) {
+ $this->smarty = &$smarty;
+ // Smarty parameter
+ $this->cache_id = $_cache_id === null ? $this->smarty->cache_id : $_cache_id;
+ $this->compile_id = $_compile_id === null ? $this->smarty->compile_id : $_compile_id;
+ $this->caching = $_caching === null ? $this->smarty->caching : $_caching;
+ if ($this->caching === true) {
+ $this->caching = Smarty::CACHING_LIFETIME_CURRENT;
+ }
+ $this->cache_lifetime = $_cache_lifetime === null ? $this->smarty->cache_lifetime : $_cache_lifetime;
+ $this->parent = $_parent;
+ // Template resource
+ $this->template_resource = $template_resource;
+ // copy block data of template inheritance
+ if ($this->parent instanceof Smarty_Internal_Template) {
+ $this->block_data = $this->parent->block_data;
+ }
+ }
+
+ /**
+ * fetches rendered template
+ *
+ * @throws Exception
+ * @throws SmartyException
+ * @return string rendered template output
+ */
+ public function fetch() {
+ return $this->render(true, false, false);
+ }
+
+ /**
+ * displays a Smarty template
+ */
+ public function display() {
+ $this->render(true, false, true);
+ }
+
+ /**
+ * render template
+ *
+ * @param bool $merge_tpl_vars if true parent template variables merged in to local scope
+ * @param bool $no_output_filter if true do not run output filter
+ * @param bool $display true: display, false: fetch null: subtemplate
+ *
+ * @throws Exception
+ * @throws SmartyException
+ * @return string rendered template output
+ */
+ public function render($merge_tpl_vars = false, $no_output_filter = true, $display = null) {
+ $parentIsTpl = $this->parent instanceof Smarty_Internal_Template;
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::start_template($this, $display);
+ }
+ $save_tpl_vars = null;
+ $save_config_vars = null;
+ // merge all variable scopes into template
+ if ($merge_tpl_vars) {
+ // save local variables
+ $save_tpl_vars = $this->tpl_vars;
+ $save_config_vars = $this->config_vars;
+ $ptr_array = array($this);
+ $ptr = $this;
+ while (isset($ptr->parent)) {
+ $ptr_array[] = $ptr = $ptr->parent;
+ }
+ $ptr_array = array_reverse($ptr_array);
+ $parent_ptr = reset($ptr_array);
+ $tpl_vars = $parent_ptr->tpl_vars;
+ $config_vars = $parent_ptr->config_vars;
+ while ($parent_ptr = next($ptr_array)) {
+ if (!empty($parent_ptr->tpl_vars)) {
+ $tpl_vars = array_merge($tpl_vars, $parent_ptr->tpl_vars);
+ }
+ if (!empty($parent_ptr->config_vars)) {
+ $config_vars = array_merge($config_vars, $parent_ptr->config_vars);
+ }
+ }
+ if (!empty(Smarty::$global_tpl_vars)) {
+ $tpl_vars = array_merge(Smarty::$global_tpl_vars, $tpl_vars);
+ }
+ $this->tpl_vars = $tpl_vars;
+ $this->config_vars = $config_vars;
+ }
+ // dummy local smarty variable
+ if (!isset($this->tpl_vars['smarty'])) {
+ $this->tpl_vars['smarty'] = new Smarty_Variable;
+ }
+ $_smarty_old_error_level = isset($this->smarty->error_reporting) ? error_reporting($this->smarty->error_reporting) : null;
+ // check URL debugging control
+ if (!$this->smarty->debugging && $this->smarty->debugging_ctrl == 'URL') {
+ Smarty_Internal_Debug::debugUrl($this);
+ }
+ if (!isset($this->source)) {
+ $this->loadSource();
+ }
+ // checks if template exists
+ if (!$this->source->exists) {
+ if ($parentIsTpl) {
+ $parent_resource = " in '{$this->parent->template_resource}'";
+ } else {
+ $parent_resource = '';
+ }
+ throw new SmartyException("Unable to load template {$this->source->type} '{$this->source->name}'{$parent_resource}");
+ }
+ // disable caching for evaluated code
+ if ($this->source->recompiled) {
+ $this->caching = false;
+ }
+ // read from cache or render
+ $isCacheTpl = $this->caching == Smarty::CACHING_LIFETIME_CURRENT || $this->caching == Smarty::CACHING_LIFETIME_SAVED;
+ if ($isCacheTpl) {
+ if (!isset($this->cached)) {
+ $this->loadCached();
+ }
+ $this->cached->isCached($this);
+ }
+ if (!($isCacheTpl) || !$this->cached->valid) {
+ if ($isCacheTpl) {
+ $this->properties['tpl_function'] = array();
+ }
+ // render template (not loaded and not in cache)
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::start_render($this);
+ }
+ if (!$this->source->uncompiled) {
+ // render compiled code
+ if (!isset($this->compiled)) {
+ $this->loadCompiled();
+ }
+ $content = $this->compiled->render($this);
+ } else {
+ $content = $this->source->renderUncompiled($this);
+ }
+ if (!$this->source->recompiled && empty($this->properties['file_dependency'][$this->source->uid])) {
+ $this->properties['file_dependency'][$this->source->uid] = array($this->source->filepath, $this->source->timestamp, $this->source->type);
+ }
+ if ($parentIsTpl) {
+ $this->parent->properties['file_dependency'] = array_merge($this->parent->properties['file_dependency'], $this->properties['file_dependency']);
+ //$this->parent->properties['tpl_function'] = array_merge($this->parent->properties['tpl_function'], $this->properties['tpl_function']);
+ }
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::end_render($this);
+ }
+ // write to cache when necessary
+ if (!$this->source->recompiled && $isCacheTpl) {
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::start_cache($this);
+ }
+ $this->cached->updateCache($this, $content, $no_output_filter);
+ $compile_check = $this->smarty->compile_check;
+ $this->smarty->compile_check = false;
+ if ($parentIsTpl) {
+ $this->properties['tpl_function'] = $this->parent->properties['tpl_function'];
+ }
+ if (!$this->cached->processed) {
+ $this->cached->process($this);
+ }
+ $this->smarty->compile_check = $compile_check;
+ $content = $this->getRenderedTemplateCode();
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::end_cache($this);
+ }
+ } else {
+ if (!empty($this->properties['nocache_hash']) && !empty($this->parent->properties['nocache_hash'])) {
+ // replace nocache_hash
+ $content = str_replace("{$this->properties['nocache_hash']}", $this->parent->properties['nocache_hash'], $content);
+ $this->parent->has_nocache_code = $this->parent->has_nocache_code || $this->has_nocache_code;
+ }
+ }
+ } else {
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::start_cache($this);
+ }
+ $content = $this->cached->render($this);
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::end_cache($this);
+ }
+ }
+ if ((!$this->caching || $this->has_nocache_code || $this->source->recompiled) && !$no_output_filter && (isset($this->smarty->autoload_filters['output']) || isset($this->smarty->registered_filters['output']))) {
+ $content = Smarty_Internal_Filter_Handler::runFilter('output', $content, $this);
+ }
+ if (isset($_smarty_old_error_level)) {
+ error_reporting($_smarty_old_error_level);
+ }
+ // display or fetch
+ if ($display) {
+ if ($this->caching && $this->smarty->cache_modified_check) {
+ $this->cached->cacheModifiedCheck($this, $content);
+ } else {
+ echo $content;
+ }
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::end_template($this);
+ }
+ // debug output
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::display_debug($this, true);
+ }
+ if ($merge_tpl_vars) {
+ // restore local variables
+ $this->tpl_vars = $save_tpl_vars;
+ $this->config_vars = $save_config_vars;
+ }
+ return '';
+ } else {
+ if ($merge_tpl_vars) {
+ // restore local variables
+ $this->tpl_vars = $save_tpl_vars;
+ $this->config_vars = $save_config_vars;
+ }
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::end_template($this);
+ }
+ if ($this->smarty->debugging == 2 and $display === false) {
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::display_debug($this, true);
+ }
+ }
+ if ($parentIsTpl) {
+ $this->parent->properties['tpl_function'] = array_merge($this->parent->properties['tpl_function'], $this->properties['tpl_function']);
+ foreach ($this->required_plugins as $code => $tmp1) {
+ foreach ($tmp1 as $name => $tmp) {
+ foreach ($tmp as $type => $data) {
+ $this->parent->required_plugins[$code][$name][$type] = $data;
+ }
+ }
+ }
+ }
+ // return cache content
+ return $content;
+ }
+ }
+
+ /**
+ * get rendered template content by calling compiled or cached template code
+ *
+ * @return string
+ * @throws Exception
+ */
+ public function getRenderedTemplateCode() {
+ $level = ob_get_level();
+ try {
+ ob_start();
+ if (empty($this->properties['unifunc']) || !is_callable($this->properties['unifunc'])) {
+ throw new SmartyException("Invalid compiled template for '{$this->template_resource}'");
+ }
+ if (isset($this->smarty->security_policy)) {
+ $this->smarty->security_policy->startTemplate($this);
+ }
+ array_unshift($this->_capture_stack, array());
+ //
+ // render compiled or saved template code
+ //
+ $this->properties['unifunc']($this);
+ // any unclosed {capture} tags ?
+ if (isset($this->_capture_stack[0][0])) {
+ $this->capture_error();
+ }
+ array_shift($this->_capture_stack);
+ if (isset($this->smarty->security_policy)) {
+ $this->smarty->security_policy->exitTemplate($this);
+ }
+ return ob_get_clean();
+ } catch (Exception $e) {
+ while (ob_get_level() > $level) {
+ ob_end_clean();
+ }
+ throw $e;
+ }
+ }
+
+ /**
+ * Returns if the current template must be compiled by the Smarty compiler
+ * It does compare the timestamps of template source and the compiled templates and checks the force compile
+ * configuration
+ *
+ * @throws SmartyException
+ * @return boolean true if the template must be compiled
+ */
+ public function mustCompile() {
+ if (!$this->source->exists) {
+ if ($this->parent instanceof Smarty_Internal_Template) {
+ $parent_resource = " in '$this->parent->template_resource}'";
+ } else {
+ $parent_resource = '';
+ }
+ throw new SmartyException("Unable to load template {$this->source->type} '{$this->source->name}'{$parent_resource}");
+ }
+ if ($this->mustCompile === null) {
+ $this->mustCompile = (!$this->source->uncompiled && ($this->smarty->force_compile || $this->source->recompiled || $this->compiled->timestamp === false ||
+ ($this->smarty->compile_check && $this->compiled->timestamp < $this->source->timestamp)));
+ }
+
+ return $this->mustCompile;
+ }
+
+ /**
+ * Compiles the template
+ * If the template is not evaluated the compiled template is saved on disk
+ */
+ public function compileTemplateSource() {
+ return $this->compiled->compileTemplateSource($this);
+ }
+
+ /**
+ * Writes the content to cache resource
+ *
+ * @param string $content
+ *
+ * @return bool
+ */
+ public function writeCachedContent($content) {
+ return $this->cached->writeCachedContent($this, $content);
+ }
+
+ /**
+ * Template code runtime function to get subtemplate content
+ *
+ * @param string $template the resource handle of the template file
+ * @param mixed $cache_id cache id to be used with this template
+ * @param mixed $compile_id compile id to be used with this template
+ * @param integer $caching cache mode
+ * @param integer $cache_lifetime life time of cache data
+ * @param $data
+ * @param int $parent_scope scope in which {include} should execute
+ *
+ * @returns string template content
+ */
+ public function getSubTemplate($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope) {
+ $tpl = $this->setupSubTemplate($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope);
+ return $tpl->render();
+ }
+
+ /**
+ * Template code runtime function to set up an inline subtemplate
+ *
+ * @param string $template the resource handle of the template file
+ * @param mixed $cache_id cache id to be used with this template
+ * @param mixed $compile_id compile id to be used with this template
+ * @param integer $caching cache mode
+ * @param integer $cache_lifetime life time of cache data
+ * @param array $data passed parameter template variables
+ * @param int $parent_scope scope in which {include} should execute
+ *
+ * @returns object template object
+ */
+ public function setupSubTemplate($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope) {
+ $_templateId = $this->getTemplateId($template, $cache_id, $compile_id);
+ // already in template cache?
+ if (isset($this->smarty->template_objects[$_templateId])) {
+ // clone cached template object because of possible recursive call
+ $tpl = clone $this->smarty->template_objects[$_templateId];
+ $tpl->parent = $this;
+ if ((bool)$tpl->caching !== (bool)$caching) {
+ unset($tpl->compiled);
+ }
+ $tpl->caching = $caching;
+ $tpl->cache_lifetime = $cache_lifetime;
+ } else {
+ $tpl = new $this->smarty->template_class($template, $this->smarty, $this, $cache_id, $compile_id, $caching, $cache_lifetime);
+ $tpl->templateId = $_templateId;
+ }
+ // get variables from calling scope
+ if ($parent_scope == Smarty::SCOPE_LOCAL) {
+ $tpl->tpl_vars = $this->tpl_vars;
+ $tpl->tpl_vars['smarty'] = clone $this->tpl_vars['smarty'];
+ } elseif ($parent_scope == Smarty::SCOPE_PARENT) {
+ $tpl->tpl_vars = &$this->tpl_vars;
+ } elseif ($parent_scope == Smarty::SCOPE_GLOBAL) {
+ $tpl->tpl_vars = &Smarty::$global_tpl_vars;
+ } elseif (($scope_ptr = $this->getScopePointer($parent_scope)) == null) {
+ $tpl->tpl_vars = &$this->tpl_vars;
+ } else {
+ $tpl->tpl_vars = &$scope_ptr->tpl_vars;
+ }
+ $tpl->config_vars = $this->config_vars;
+ if (!empty($data)) {
+ // set up variable values
+ foreach ($data as $_key => $_val) {
+ $tpl->tpl_vars[$_key] = new Smarty_Variable($_val);
+ }
+ }
+ $tpl->properties['tpl_function'] = $this->properties['tpl_function'];
+ return $tpl;
+ }
+
+ /**
+ * Template code runtime function to set up an inline subtemplate
+ *
+ * @param string $template the resource handle of the template file
+ * @param mixed $cache_id cache id to be used with this template
+ * @param mixed $compile_id compile id to be used with this template
+ * @param integer $caching cache mode
+ * @param integer $cache_lifetime life time of cache data
+ * @param array $data passed parameter template variables
+ * @param int $parent_scope scope in which {include} should execute
+ * @param string $hash nocache hash code
+ * @param string $content_func name of content function
+ *
+ * @returns object template content
+ */
+ public function getInlineSubTemplate($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope, $hash, $content_func) {
+ $tpl = $this->setupSubTemplate($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope);
+ $tpl->properties['nocache_hash'] = $hash;
+ if (!isset($this->smarty->template_objects[$tpl->templateId])) {
+ $this->smarty->template_objects[$tpl->templateId] = $tpl;
+ }
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::start_template($tpl);
+ Smarty_Internal_Debug::start_render($tpl);
+ }
+ $tpl->properties['unifunc'] = $content_func;
+ $output = $tpl->getRenderedTemplateCode();
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::end_template($tpl);
+ Smarty_Internal_Debug::end_render($tpl);
+ }
+ if (!empty($tpl->properties['file_dependency'])) {
+ $this->properties['file_dependency'] = array_merge($this->properties['file_dependency'], $tpl->properties['file_dependency']);
+ }
+ $this->properties['tpl_function'] = $tpl->properties['tpl_function'];
+ return str_replace($tpl->properties['nocache_hash'], $this->properties['nocache_hash'], $output);
+ }
+
+ /**
+ * Call template function
+ *
+ * @param string $name template function name
+ * @param object|\Smarty_Internal_Template $_smarty_tpl template object
+ * @param array $params parameter array
+ * @param bool $nocache true if called nocache
+ *
+ * @throws \SmartyException
+ */
+ public function callTemplateFunction($name, Smarty_Internal_Template $_smarty_tpl, $params, $nocache) {
+ if (isset($_smarty_tpl->properties['tpl_function'][$name])) {
+ if (!$_smarty_tpl->caching || ($_smarty_tpl->caching && $nocache)) {
+ $function = $_smarty_tpl->properties['tpl_function'][$name]['call_name'];
+ } else {
+ if (isset($_smarty_tpl->properties['tpl_function'][$name]['call_name_caching'])) {
+ $function = $_smarty_tpl->properties['tpl_function'][$name]['call_name_caching'];
+ } else {
+ $function = $_smarty_tpl->properties['tpl_function'][$name]['call_name'];
+ }
+ }
+ if (function_exists($function)) {
+ $function ($_smarty_tpl, $params);
+ return;
+ }
+ // try to load template function dynamically
+ if (Smarty_Internal_Function_Call_Handler::call($name, $_smarty_tpl, $function, $params, $nocache)) {
+ $function ($_smarty_tpl, $params);
+ return;
+ }
+ }
+ throw new SmartyException("Unable to find template function '{$name}'");
+ }
+
+ /**
+ * This function is executed automatically when a compiled or cached template file is included
+ * - Decode saved properties from compiled template and cache files
+ * - Check if compiled or cache file is valid
+ *
+ * @param array $properties special template properties
+ * @param bool $cache flag if called from cache file
+ *
+ * @return bool flag if compiled or cache file is valid
+ */
+ public function decodeProperties($properties, $cache = false) {
+ $properties['version'] = (isset($properties['version'])) ? $properties['version'] : '';
+ $is_valid = true;
+ if (Smarty::SMARTY_VERSION != $properties['version']) {
+ // new version must rebuild
+ $is_valid = false;
+ } elseif ((!$cache && $this->smarty->compile_check || $cache && ($this->smarty->compile_check === true || $this->smarty->compile_check === Smarty::COMPILECHECK_ON)) && !empty($properties['file_dependency'])) {
+ // check file dependencies at compiled code
+ foreach ($properties['file_dependency'] as $_file_to_check) {
+ if ($_file_to_check[2] == 'file' || $_file_to_check[2] == 'php') {
+ if ($this->source->filepath == $_file_to_check[0] && isset($this->source->timestamp)) {
+ // do not recheck current template
+ $mtime = $this->source->timestamp;
+ } else {
+ // file and php types can be checked without loading the respective resource handlers
+ $mtime = is_file($_file_to_check[0]) ? @filemtime($_file_to_check[0]) : false;
+ }
+ } elseif ($_file_to_check[2] == 'string') {
+ continue;
+ } else {
+ $source = Smarty_Resource::source(null, $this->smarty, $_file_to_check[0]);
+ $mtime = $source->timestamp;
+ }
+ if (!$mtime || $mtime > $_file_to_check[1]) {
+ $is_valid = false;
+ break;
+ }
+ }
+ }
+ if ($cache) {
+ // CACHING_LIFETIME_SAVED cache expiry has to be validated here since otherwise we'd define the unifunc
+ if ($this->caching === Smarty::CACHING_LIFETIME_SAVED &&
+ $properties['cache_lifetime'] >= 0 &&
+ (time() > ($this->cached->timestamp + $properties['cache_lifetime']))
+ ) {
+ $is_valid = false;
+ }
+ $this->cached->valid = $is_valid;
+ } else {
+ $this->mustCompile = !$is_valid;
+ }
+ if ($is_valid) {
+ $this->has_nocache_code = $properties['has_nocache_code'];
+ // $this->properties['nocache_hash'] = $properties['nocache_hash'];
+ if (isset($properties['cache_lifetime'])) {
+ $this->properties['cache_lifetime'] = $properties['cache_lifetime'];
+ }
+ if (isset($properties['file_dependency'])) {
+ $this->properties['file_dependency'] = array_merge($this->properties['file_dependency'], $properties['file_dependency']);
+ }
+ if (isset($properties['tpl_function'])) {
+ $this->properties['tpl_function'] = array_merge($this->properties['tpl_function'], $properties['tpl_function']);
+ }
+ $this->properties['version'] = $properties['version'];
+ $this->properties['unifunc'] = $properties['unifunc'];
+ }
+ return $is_valid;
+ }
+
+ /**
+ * Template code runtime function to create a local Smarty variable for array assignments
+ *
+ * @param string $tpl_var template variable name
+ * @param bool $nocache cache mode of variable
+ * @param int $scope scope of variable
+ */
+ public function createLocalArrayVariable($tpl_var, $nocache = false, $scope = Smarty::SCOPE_LOCAL) {
+ if (!isset($this->tpl_vars[$tpl_var])) {
+ $this->tpl_vars[$tpl_var] = new Smarty_Variable(array(), $nocache, $scope);
+ } else {
+ $this->tpl_vars[$tpl_var] = clone $this->tpl_vars[$tpl_var];
+ if ($scope != Smarty::SCOPE_LOCAL) {
+ $this->tpl_vars[$tpl_var]->scope = $scope;
+ }
+ if (!(is_array($this->tpl_vars[$tpl_var]->value) || $this->tpl_vars[$tpl_var]->value instanceof ArrayAccess)) {
+ settype($this->tpl_vars[$tpl_var]->value, 'array');
+ }
+ }
+ }
+
+ /**
+ * Template code runtime function to get pointer to template variable array of requested scope
+ *
+ * @param int $scope requested variable scope
+ *
+ * @return array array of template variables
+ */
+ public function &getScope($scope) {
+ if ($scope == Smarty::SCOPE_PARENT && !empty($this->parent)) {
+ return $this->parent->tpl_vars;
+ } elseif ($scope == Smarty::SCOPE_ROOT && !empty($this->parent)) {
+ $ptr = $this->parent;
+ while (!empty($ptr->parent)) {
+ $ptr = $ptr->parent;
+ }
+
+ return $ptr->tpl_vars;
+ } elseif ($scope == Smarty::SCOPE_GLOBAL) {
+ return Smarty::$global_tpl_vars;
+ }
+ $null = null;
+
+ return $null;
+ }
+
+ /**
+ * Get parent or root of template parent chain
+ *
+ * @param int $scope parent or root scope
+ *
+ * @return mixed object
+ */
+ public function getScopePointer($scope) {
+ if ($scope == Smarty::SCOPE_PARENT && !empty($this->parent)) {
+ return $this->parent;
+ } elseif ($scope == Smarty::SCOPE_ROOT && !empty($this->parent)) {
+ $ptr = $this->parent;
+ while (!empty($ptr->parent)) {
+ $ptr = $ptr->parent;
+ }
+
+ return $ptr;
+ }
+
+ return null;
+ }
+
+ /**
+ * [util function] counts an array, arrayAccess/traversable or PDOStatement object
+ *
+ * @param mixed $value
+ *
+ * @return int the count for arrays and objects that implement countable, 1 for other objects that don't, and 0
+ * for empty elements
+ */
+ public function _count($value) {
+ if (is_array($value) === true || $value instanceof Countable) {
+ return count($value);
+ } elseif ($value instanceof IteratorAggregate) {
+ // Note: getIterator() returns a Traversable, not an Iterator
+ // thus rewind() and valid() methods may not be present
+ return iterator_count($value->getIterator());
+ } elseif ($value instanceof Iterator) {
+ return iterator_count($value);
+ } elseif ($value instanceof PDOStatement) {
+ return $value->rowCount();
+ } elseif ($value instanceof Traversable) {
+ return iterator_count($value);
+ } elseif ($value instanceof ArrayAccess) {
+ if ($value->offsetExists(0)) {
+ return 1;
+ }
+ } elseif (is_object($value)) {
+ return count($value);
+ }
+
+ return 0;
+ }
+
+ /**
+ * runtime error not matching capture tags
+ */
+ public function capture_error() {
+ throw new SmartyException("Not matching {capture} open/close in \"{$this->template_resource}\"");
+ }
+
+ /**
+ * Empty cache for this template
+ *
+ * @param integer $exp_time expiration time
+ *
+ * @return integer number of cache files deleted
+ */
+ public function clearCache($exp_time = null) {
+ Smarty_CacheResource::invalidLoadedCache($this->smarty);
+
+ return $this->cached->handler->clear($this->smarty, $this->template_resource, $this->cache_id, $this->compile_id, $exp_time);
+ }
+
+ /**
+ * Load source resource
+ *
+ * @throws SmartyException
+ */
+ public function loadSource() {
+ $this->source = Smarty_Template_Source::load($this);
+ if ($this->smarty->template_resource_caching && !$this->source->recompiled && isset($this->templateId)) {
+ $this->smarty->template_objects[$this->templateId] = $this;
+ }
+ }
+
+ /**
+ * Load compiled object
+ *
+ */
+ public function loadCompiled() {
+ if (!isset($this->compiled)) {
+ if (!class_exists('Smarty_Template_Compiled', false)) {
+ require SMARTY_SYSPLUGINS_DIR . 'smarty_template_compiled.php';
+ }
+ $this->compiled = Smarty_Template_Compiled::load($this);
+ }
+ }
+
+ /**
+ * Load cached object
+ *
+ */
+ public function loadCached() {
+ if (!isset($this->cached)) {
+ if (!class_exists('Smarty_Template_Cached', false)) {
+ require SMARTY_SYSPLUGINS_DIR . 'smarty_template_cached.php';
+ }
+ $this->cached = Smarty_Template_Cached::load($this);
+ }
+ }
+
+ /**
+ * Load compiler object
+ *
+ * @throws \SmartyException
+ */
+ public function loadCompiler() {
+ $this->smarty->loadPlugin($this->source->compiler_class);
+ $this->compiler = new $this->source->compiler_class($this->source->template_lexer_class, $this->source->template_parser_class, $this->smarty);
+ }
+
+ /**
+ * Handle unknown class methods
+ *
+ * @param string $name unknown method-name
+ * @param array $args argument array
+ *
+ * @return mixed
+ * @throws SmartyException
+ */
+ public function __call($name, $args) {
+ // method of Smarty object?
+ if (method_exists($this->smarty, $name)) {
+ return call_user_func_array(array($this->smarty, $name), $args);
+ }
+ // parent
+ return parent::__call($name, $args);
+ }
+
+ /**
+ * set Smarty property in template context
+ *
+ * @param string $property_name property name
+ * @param mixed $value value
+ *
+ * @throws SmartyException
+ */
+ public function __set($property_name, $value) {
+ switch ($property_name) {
+ case 'source':
+ case 'compiled':
+ case 'cached':
+ case 'compiler':
+ $this->$property_name = $value;
+ return;
+ default:
+ // Smarty property ?
+ if (property_exists($this->smarty, $property_name)) {
+ $this->smarty->$property_name = $value;
+ return;
+ }
+ }
+ throw new SmartyException("invalid template property '$property_name'.");
+ }
+
+ /**
+ * get Smarty property in template context
+ *
+ * @param string $property_name property name
+ *
+ * @return mixed|Smarty_Template_Cached
+ * @throws SmartyException
+ */
+ public function __get($property_name) {
+ switch ($property_name) {
+ case 'source':
+ $this->loadSource();
+ return $this->source;
+
+ case 'compiled':
+ $this->loadCompiled();
+ return $this->compiled;
+
+ case 'cached':
+ $this->loadCached();
+ return $this->cached;
+
+ case 'compiler':
+ $this->loadCompiler();
+ return $this->compiler;
+ default:
+ // Smarty property ?
+ if (property_exists($this->smarty, $property_name)) {
+ return $this->smarty->$property_name;
+ }
+ }
+ throw new SmartyException("template property '$property_name' does not exist.");
+ }
+
+ /**
+ * Template data object destructor
+ */
+ public function __destruct() {
+ if ($this->smarty->cache_locking && isset($this->cached) && $this->cached->is_locked) {
+ $this->cached->handler->releaseLock($this->smarty, $this->cached);
+ }
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_templatebase.php
@@ -0,0 +1,533 @@
+<?php
+/**
+ * Smarty Internal Plugin Smarty Template Base
+ * This file contains the basic shared methods for template handling
+ *
+ * @package Smarty
+ * @subpackage Template
+ * @author Uwe Tews
+ */
+
+/**
+ * Class with shared template methods
+ *
+ * @package Smarty
+ * @subpackage Template
+ */
+abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data {
+ /**
+ * Set this if you want different sets of cache files for the same
+ * templates.
+ *
+ * @var string
+ */
+ public $cache_id = null;
+ /**
+ * Set this if you want different sets of compiled files for the same
+ * templates.
+ *
+ * @var string
+ */
+ public $compile_id = null;
+ /**
+ * caching enabled
+ *
+ * @var boolean
+ */
+ public $caching = false;
+ /**
+ * cache lifetime in seconds
+ *
+ * @var integer
+ */
+ public $cache_lifetime = 3600;
+
+ /**
+ * test if cache is valid
+ *
+ * @param string|object $template the resource handle of the template file or template object
+ * @param mixed $cache_id cache id to be used with this template
+ * @param mixed $compile_id compile id to be used with this template
+ * @param object $parent next higher level of Smarty variables
+ *
+ * @return boolean cache status
+ */
+ public function isCached($template = null, $cache_id = null, $compile_id = null, $parent = null) {
+ if ($template === null && $this instanceof $this->template_class) {
+ $template = $this;
+ } else {
+ if (!($template instanceof $this->template_class)) {
+ if ($parent === null) {
+ $parent = $this;
+ }
+ $smarty = isset($this->smarty) ? $this->smarty : $this;
+ $template = $smarty->createTemplate($template, $cache_id, $compile_id, $parent, false);
+ }
+ }
+ // return cache status of template
+ if (!isset($template->cached)) {
+ $template->loadCached();
+ }
+ return $template->cached->isCached($template);
+ }
+
+ /**
+ * creates a data object
+ *
+ * @param object $parent next higher level of Smarty variables
+ * @param string $name optional data block name
+ *
+ * @returns Smarty_Data data object
+ */
+ public function createData($parent = null, $name = null) {
+ $dataObj = new Smarty_Data($parent, $this, $name);
+ if ($this->debugging) {
+ Smarty_Internal_Debug::register_data($dataObj);
+ }
+ return $dataObj;
+ }
+
+ /**
+ * Get unique template id
+ *
+ * @param string $template_name
+ * @param null|mixed $cache_id
+ * @param null|mixed $compile_id
+ *
+ * @return string
+ */
+ public function getTemplateId($template_name, $cache_id = null, $compile_id = null) {
+ $cache_id = isset($cache_id) ? $cache_id : $this->cache_id;
+ $compile_id = isset($compile_id) ? $compile_id : $this->compile_id;
+ $smarty = isset($this->smarty) ? $this->smarty : $this;
+ if ($smarty->allow_ambiguous_resources) {
+ $_templateId = Smarty_Resource::getUniqueTemplateName($this, $template_name) . "#{$cache_id}#{$compile_id}";
+ } else {
+ $_templateId = $smarty->joined_template_dir . "#{$template_name}#{$cache_id}#{$compile_id}";
+ }
+ if (isset($_templateId[150])) {
+ $_templateId = sha1($_templateId);
+ }
+ return $_templateId;
+ }
+
+ /**
+ * Registers plugin to be used in templates
+ *
+ * @param string $type plugin type
+ * @param string $tag name of template tag
+ * @param callback $callback PHP callback to register
+ * @param boolean $cacheable if true (default) this fuction is cachable
+ * @param array $cache_attr caching attributes if any
+ *
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
+ * Smarty_Internal_Template) instance for chaining
+ * @throws SmartyException when the plugin tag is invalid
+ */
+ public function registerPlugin($type, $tag, $callback, $cacheable = true, $cache_attr = null) {
+ $smarty = isset($this->smarty) ? $this->smarty : $this;
+ if (isset($smarty->registered_plugins[$type][$tag])) {
+ throw new SmartyException("Plugin tag \"{$tag}\" already registered");
+ } elseif (!is_callable($callback)) {
+ throw new SmartyException("Plugin \"{$tag}\" not callable");
+ } else {
+ $smarty->registered_plugins[$type][$tag] = array($callback, (bool)$cacheable, (array)$cache_attr);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Unregister Plugin
+ *
+ * @param string $type of plugin
+ * @param string $tag name of plugin
+ *
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
+ * Smarty_Internal_Template) instance for chaining
+ */
+ public function unregisterPlugin($type, $tag) {
+ $smarty = isset($this->smarty) ? $this->smarty : $this;
+ if (isset($smarty->registered_plugins[$type][$tag])) {
+ unset($smarty->registered_plugins[$type][$tag]);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Registers a resource to fetch a template
+ *
+ * @param string $type name of resource type
+ * @param Smarty_Resource|array $callback or instance of Smarty_Resource, or array of callbacks to handle resource
+ * (deprecated)
+ *
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
+ * Smarty_Internal_Template) instance for chaining
+ */
+ public function registerResource($type, $callback) {
+ $smarty = isset($this->smarty) ? $this->smarty : $this;
+ $smarty->registered_resources[$type] = $callback instanceof Smarty_Resource ? $callback : array($callback, false);
+
+ return $this;
+ }
+
+ /**
+ * Unregisters a resource
+ *
+ * @param string $type name of resource type
+ *
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
+ * Smarty_Internal_Template) instance for chaining
+ */
+ public function unregisterResource($type) {
+ $smarty = isset($this->smarty) ? $this->smarty : $this;
+ if (isset($smarty->registered_resources[$type])) {
+ unset($smarty->registered_resources[$type]);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Registers a cache resource to cache a template's output
+ *
+ * @param string $type name of cache resource type
+ * @param Smarty_CacheResource $callback instance of Smarty_CacheResource to handle output caching
+ *
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
+ * Smarty_Internal_Template) instance for chaining
+ */
+ public function registerCacheResource($type, Smarty_CacheResource $callback) {
+ $smarty = isset($this->smarty) ? $this->smarty : $this;
+ $smarty->registered_cache_resources[$type] = $callback;
+
+ return $this;
+ }
+
+ /**
+ * Unregisters a cache resource
+ *
+ * @param string $type name of cache resource type
+ *
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
+ * Smarty_Internal_Template) instance for chaining
+ */
+ public function unregisterCacheResource($type) {
+ $smarty = isset($this->smarty) ? $this->smarty : $this;
+ if (isset($smarty->registered_cache_resources[$type])) {
+ unset($smarty->registered_cache_resources[$type]);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Registers object to be used in templates
+ *
+ * @param $object_name
+ * @param object $object_impl the referenced PHP object to register
+ * @param array $allowed list of allowed methods (empty = all)
+ * @param boolean $smarty_args smarty argument format, else traditional
+ * @param array $block_methods list of block-methods
+ *
+ * @throws SmartyException
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
+ * Smarty_Internal_Template) instance for chaining
+ */
+ public function registerObject($object_name, $object_impl, $allowed = array(), $smarty_args = true, $block_methods = array()) {
+ // test if allowed methods callable
+ if (!empty($allowed)) {
+ foreach ((array)$allowed as $method) {
+ if (!is_callable(array($object_impl, $method)) && !property_exists($object_impl, $method)) {
+ throw new SmartyException("Undefined method or property '$method' in registered object");
+ }
+ }
+ }
+ // test if block methods callable
+ if (!empty($block_methods)) {
+ foreach ((array)$block_methods as $method) {
+ if (!is_callable(array($object_impl, $method))) {
+ throw new SmartyException("Undefined method '$method' in registered object");
+ }
+ }
+ }
+ // register the object
+ $smarty = isset($this->smarty) ? $this->smarty : $this;
+ $smarty->registered_objects[$object_name] =
+ array($object_impl, (array)$allowed, (boolean)$smarty_args, (array)$block_methods);
+
+ return $this;
+ }
+
+ /**
+ * return a reference to a registered object
+ *
+ * @param string $name object name
+ *
+ * @return object
+ * @throws SmartyException if no such object is found
+ */
+ public function getRegisteredObject($name) {
+ $smarty = isset($this->smarty) ? $this->smarty : $this;
+ if (!isset($smarty->registered_objects[$name])) {
+ throw new SmartyException("'$name' is not a registered object");
+ }
+ if (!is_object($smarty->registered_objects[$name][0])) {
+ throw new SmartyException("registered '$name' is not an object");
+ }
+
+ return $smarty->registered_objects[$name][0];
+ }
+
+ /**
+ * unregister an object
+ *
+ * @param string $name object name
+ *
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
+ * Smarty_Internal_Template) instance for chaining
+ */
+ public function unregisterObject($name) {
+ $smarty = isset($this->smarty) ? $this->smarty : $this;
+ if (isset($smarty->registered_objects[$name])) {
+ unset($smarty->registered_objects[$name]);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Registers static classes to be used in templates
+ *
+ * @param $class_name
+ * @param string $class_impl the referenced PHP class to register
+ *
+ * @throws SmartyException
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
+ * Smarty_Internal_Template) instance for chaining
+ */
+ public function registerClass($class_name, $class_impl) {
+ // test if exists
+ if (!class_exists($class_impl)) {
+ throw new SmartyException("Undefined class '$class_impl' in register template class");
+ }
+ // register the class
+ $smarty = isset($this->smarty) ? $this->smarty : $this;
+ $smarty->registered_classes[$class_name] = $class_impl;
+
+ return $this;
+ }
+
+ /**
+ * Registers a default plugin handler
+ *
+ * @param callable $callback class/method name
+ *
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
+ * Smarty_Internal_Template) instance for chaining
+ * @throws SmartyException if $callback is not callable
+ */
+ public function registerDefaultPluginHandler($callback) {
+ $smarty = isset($this->smarty) ? $this->smarty : $this;
+ if (is_callable($callback)) {
+ $smarty->default_plugin_handler_func = $callback;
+ } else {
+ throw new SmartyException("Default plugin handler '$callback' not callable");
+ }
+
+ return $this;
+ }
+
+ /**
+ * Registers a default template handler
+ *
+ * @param callable $callback class/method name
+ *
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
+ * Smarty_Internal_Template) instance for chaining
+ * @throws SmartyException if $callback is not callable
+ */
+ public function registerDefaultTemplateHandler($callback) {
+ Smarty_Internal_Extension_DefaultTemplateHandler::registerDefaultTemplateHandler($this, $callback);
+ return $this;
+ }
+
+ /**
+ * Registers a default template handler
+ *
+ * @param callable $callback class/method name
+ *
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
+ * Smarty_Internal_Template) instance for chaining
+ * @throws SmartyException if $callback is not callable
+ */
+ public function registerDefaultConfigHandler($callback) {
+ Smarty_Internal_Extension_DefaultTemplateHandler::registerDefaultConfigHandler($this, $callback);
+ return $this;
+ }
+
+ /**
+ * Registers a filter function
+ *
+ * @param string $type filter type
+ * @param callback $callback
+ *
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
+ * Smarty_Internal_Template) instance for chaining
+ */
+ public function registerFilter($type, $callback) {
+ $smarty = isset($this->smarty) ? $this->smarty : $this;
+ $smarty->registered_filters[$type][$this->_get_filter_name($callback)] = $callback;
+
+ return $this;
+ }
+
+ /**
+ * Unregisters a filter function
+ *
+ * @param string $type filter type
+ * @param callback $callback
+ *
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
+ * Smarty_Internal_Template) instance for chaining
+ */
+ public function unregisterFilter($type, $callback) {
+ $name = $this->_get_filter_name($callback);
+ $smarty = isset($this->smarty) ? $this->smarty : $this;
+ if (isset($smarty->registered_filters[$type][$name])) {
+ unset($smarty->registered_filters[$type][$name]);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Return internal filter name
+ *
+ * @param callback $function_name
+ *
+ * @return string internal filter name
+ */
+ public function _get_filter_name($function_name) {
+ if (is_array($function_name)) {
+ $_class_name = (is_object($function_name[0]) ?
+ get_class($function_name[0]) : $function_name[0]);
+
+ return $_class_name . '_' . $function_name[1];
+ } else {
+ return $function_name;
+ }
+ }
+
+ /**
+ * load a filter of specified type and name
+ *
+ * @param string $type filter type
+ * @param string $name filter name
+ *
+ * @throws SmartyException if filter could not be loaded
+ */
+ public function loadFilter($type, $name) {
+ $smarty = isset($this->smarty) ? $this->smarty : $this;
+ $_plugin = "smarty_{$type}filter_{$name}";
+ $_filter_name = $_plugin;
+ if ($smarty->loadPlugin($_plugin)) {
+ if (class_exists($_plugin, false)) {
+ $_plugin = array($_plugin, 'execute');
+ }
+ if (is_callable($_plugin)) {
+ $smarty->registered_filters[$type][$_filter_name] = $_plugin;
+
+ return true;
+ }
+ }
+ throw new SmartyException("{$type}filter \"{$name}\" not callable");
+ }
+
+ /**
+ * unload a filter of specified type and name
+ *
+ * @param string $type filter type
+ * @param string $name filter name
+ *
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
+ * Smarty_Internal_Template) instance for chaining
+ */
+ public function unloadFilter($type, $name) {
+ $smarty = isset($this->smarty) ? $this->smarty : $this;
+ $_filter_name = "smarty_{$type}filter_{$name}";
+ if (isset($smarty->registered_filters[$type][$_filter_name])) {
+ unset ($smarty->registered_filters[$type][$_filter_name]);
+ }
+
+ return $this;
+ }
+
+ /**
+ * preg_replace callback to convert camelcase getter/setter to underscore property names
+ *
+ * @param string $match match string
+ *
+ * @return string replacemant
+ */
+ private function replaceCamelcase($match) {
+ return "_" . strtolower($match[1]);
+ }
+
+ /**
+ * Handle unknown class methods
+ *
+ * @param string $name unknown method-name
+ * @param array $args argument array
+ *
+ * @throws SmartyException
+ */
+ public function __call($name, $args) {
+ static $_prefixes = array('set' => true, 'get' => true);
+ static $_resolved_property_name = array();
+ static $_resolved_property_source = array();
+
+ // see if this is a set/get for a property
+ $first3 = strtolower(substr($name, 0, 3));
+ if (isset($_prefixes[$first3]) && isset($name[3]) && $name[3] !== '_') {
+ if (isset($_resolved_property_name[$name])) {
+ $property_name = $_resolved_property_name[$name];
+ } else {
+ // try to keep case correct for future PHP 6.0 case-sensitive class methods
+ // lcfirst() not available < PHP 5.3.0, so improvise
+ $property_name = strtolower(substr($name, 3, 1)) . substr($name, 4);
+ // convert camel case to underscored name
+ $property_name = preg_replace_callback('/([A-Z])/', array($this, 'replaceCamelcase'), $property_name);
+ $_resolved_property_name[$name] = $property_name;
+ }
+ if (isset($_resolved_property_source[$property_name])) {
+ $status = $_resolved_property_source[$property_name];
+ } else {
+ $status = null;
+ if (property_exists($this, $property_name)) {
+ $status = true;
+ } elseif (property_exists($this->smarty, $property_name)) {
+ $status = false;
+ }
+ $_resolved_property_source[$property_name] = $status;
+ }
+ $smarty = null;
+ if ($status === true) {
+ $smarty = $this;
+ } elseif ($status === false) {
+ $smarty = $this->smarty;
+ }
+ if ($smarty) {
+ if ($first3 == 'get') {
+ return $smarty->$property_name;
+ } else {
+ return $smarty->$property_name = $args[0];
+ }
+ }
+ throw new SmartyException("property '$property_name' does not exist.");
+ }
+ throw new SmartyException("Call of unknown method '$name'.");
+ }
+}
+
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_templatecompilerbase.php
@@ -0,0 +1,1010 @@
+<?php
+
+/**
+ * Smarty Internal Plugin Smarty Template Compiler Base
+ * This file contains the basic classes and methods for compiling Smarty templates with lexer/parser
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Main abstract compiler class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+abstract class Smarty_Internal_TemplateCompilerBase {
+
+ /**
+ * Smarty object
+ *
+ * @var Smarty
+ */
+ public $smarty = null;
+
+ /**
+ * hash for nocache sections
+ *
+ * @var mixed
+ */
+ public $nocache_hash = null;
+
+ /**
+ * suppress generation of nocache code
+ *
+ * @var bool
+ */
+ public $suppressNocacheProcessing = false;
+
+ /**
+ * compile tag objects
+ *
+ * @var array
+ */
+ public static $_tag_objects = array();
+
+ /**
+ * tag stack
+ *
+ * @var array
+ */
+ public $_tag_stack = array();
+
+ /**
+ * current template
+ *
+ * @var Smarty_Internal_Template
+ */
+ public $template = null;
+
+ /**
+ * merged included sub template data
+ *
+ * @var array
+ */
+ public $mergedSubTemplatesData = array();
+
+ /**
+ * merged sub template code
+ *
+ * @var array
+ */
+ public $mergedSubTemplatesCode = array();
+
+ /**
+ * collected template properties during compilation
+ *
+ * @var array
+ */
+ public $templateProperties = array();
+
+ /**
+ * sources which must be compiled
+ *
+ * @var array
+ */
+ public $sources = array();
+
+ /**
+ * flag that we are inside {block}
+ *
+ * @var bool
+ */
+ public $inheritance = false;
+
+ /**
+ * flag when compiling inheritance child template
+ *
+ * @var bool
+ */
+ public $inheritance_child = false;
+
+ /**
+ * uid of templates called by {extends} for recursion check
+ *
+ * @var array
+ */
+ public $extends_uid = array();
+
+ /**
+ * source line offset for error messages
+ *
+ * @var int
+ */
+ public $trace_line_offset = 0;
+
+ /**
+ * trace uid
+ *
+ * @var string
+ */
+ public $trace_uid = '';
+
+ /**
+ * trace file path
+ *
+ * @var string
+ */
+ public $trace_filepath = '';
+
+ /**
+ * stack for tracing file and line of nested {block} tags
+ *
+ * @var array
+ */
+ public $trace_stack = array();
+
+ /**
+ * plugins loaded by default plugin handler
+ *
+ * @var array
+ */
+ public $default_handler_plugins = array();
+
+ /**
+ * saved preprocessed modifier list
+ *
+ * @var mixed
+ */
+ public $default_modifier_list = null;
+
+ /**
+ * force compilation of complete template as nocache
+ *
+ * @var boolean
+ */
+ public $forceNocache = false;
+
+ /**
+ * suppress Smarty header code in compiled template
+ *
+ * @var bool
+ */
+ public $suppressHeader = false;
+
+ /**
+ * suppress template property header code in compiled template
+ *
+ * @var bool
+ */
+ public $suppressTemplatePropertyHeader = false;
+
+ /**
+ * suppress pre and post filter
+ *
+ * @var bool
+ */
+ public $suppressFilter = false;
+
+ /**
+ * flag if compiled template file shall we written
+ *
+ * @var bool
+ */
+ public $write_compiled_code = true;
+
+ /**
+ * flag if currently a template function is compiled
+ *
+ * @var bool
+ */
+ public $compiles_template_function = false;
+
+ /**
+ * called sub functions from template function
+ *
+ * @var array
+ */
+ public $called_functions = array();
+
+ /**
+ * compiled template function code
+ *
+ * @var string
+ */
+ public $templateFunctionCode = '';
+
+ /**
+ * php_handling setting either from Smarty or security
+ *
+ * @var int
+ */
+ public $php_handling = 0;
+
+ /**
+ * flags for used modifier plugins
+ *
+ * @var array
+ */
+ public $modifier_plugins = array();
+
+ /**
+ * type of already compiled modifier
+ *
+ * @var array
+ */
+ public $known_modifier_type = array();
+
+ /**
+ * parent compiler object for merged subtemplates and template functions
+ *
+ * @var Smarty_Internal_TemplateCompilerBase
+ */
+ public $parent_compiler = null;
+
+ /**
+ * Flag true when compiling nocache section
+ *
+ * @var bool
+ */
+ public $nocache = false;
+
+ /**
+ * Flag true when tag is compiled as nocache
+ *
+ * @var bool
+ */
+ public $tag_nocache = false;
+
+ /**
+ * Flag to restart parsing
+ *
+ * @var bool
+ */
+ public $abort_and_recompile = false;
+
+ /**
+ * Compiled tag prefix code
+ *
+ * @var array
+ */
+ public $prefix_code = array();
+
+ /**
+ * Prefix code stack
+ *
+ * @var array
+ */
+ public $prefixCodeStack = array();
+
+ /**
+ * Tag has compiled code
+ *
+ * @var bool
+ */
+ public $has_code = false;
+
+ /**
+ * A variable string was compiled
+ *
+ * @var bool
+ */
+ public $has_variable_string = false;
+
+ /**
+ * Tag creates output
+ *
+ * @var bool
+ */
+ public $has_output = false;
+
+ /**
+ * Strip preg pattern
+ *
+ * @var string
+ */
+ public $stripRegEx = '![\t ]*[\r\n]+[\t ]*!';
+
+ /**
+ * method to compile a Smarty template
+ *
+ * @param mixed $_content template source
+ *
+ * @return bool true if compiling succeeded, false if it failed
+ */
+ abstract protected function doCompile($_content);
+
+ /**
+ * Initialize compiler
+ */
+ public function __construct() {
+ $this->nocache_hash = str_replace(array('.', ','), '_', uniqid(rand(), true));
+ }
+
+ /**
+ * Method to compile a Smarty template
+ *
+ * @param Smarty_Internal_Template $template template object to compile
+ * @param bool $nocache true is shall be compiled in nocache mode
+ * @param null|Smarty_Internal_TemplateCompilerBase $parent_compiler
+ *
+ * @return bool true if compiling succeeded, false if it failed
+ */
+ public function compileTemplate(Smarty_Internal_Template $template, $nocache = null, $parent_compiler = null) {
+ // save template object in compiler class
+ $this->template = $template;
+ if (isset($this->template->smarty->security_policy)) {
+ $this->php_handling = $this->template->smarty->security_policy->php_handling;
+ } else {
+ $this->php_handling = $this->template->smarty->php_handling;
+ }
+ $this->parent_compiler = $parent_compiler ? $parent_compiler : $this;
+ $nocache = isset($nocache) ? $nocache : false;
+ if (empty($template->properties['nocache_hash'])) {
+ $template->properties['nocache_hash'] = $this->nocache_hash;
+ } else {
+ $this->nocache_hash = $template->properties['nocache_hash'];
+ }
+ $save_source = $this->template->source;
+ // template header code
+ $template_header = '';
+ if (!$this->suppressHeader) {
+ $template_header .= "<?php /* Smarty version " . Smarty::SMARTY_VERSION . ", created on " . strftime("%Y-%m-%d %H:%M:%S") . "\n";
+ $template_header .= " compiled from \"" . $this->template->source->filepath . "\" */ ?>\n";
+ }
+
+ if (empty($this->template->source->components)) {
+ $this->sources = array($template->source);
+ } else {
+ // we have array of inheritance templates by extends: resource
+ $this->sources = array_reverse($template->source->components);
+ }
+ $loop = 0;
+ // the $this->sources array can get additional elements while compiling by the {extends} tag
+ while ($this->template->source = array_shift($this->sources)) {
+ $this->smarty->_current_file = $this->template->source->filepath;
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::start_compile($this->template);
+ }
+ $no_sources = count($this->sources);
+ $this->parent_compiler->template->properties['file_dependency'][$this->template->source->uid] = array($this->template->source->filepath, $this->template->source->timestamp, $this->template->source->type);
+ $loop++;
+ if ($no_sources) {
+ $this->inheritance_child = true;
+ } else {
+ $this->inheritance_child = false;
+ }
+ do {
+ // flag for nochache sections
+ $this->nocache = $nocache;
+ $this->tag_nocache = false;
+ // reset has nocache code flag
+ $this->template->has_nocache_code = false;
+ $this->has_variable_string = false;
+ $this->prefix_code = array();
+ $_compiled_code = '';
+ // flag for aborting current and start recompile
+ $this->abort_and_recompile = false;
+ // get template source
+ $_content = $this->template->source->content;
+ if ($_content != '') {
+ // run prefilter if required
+ if ((isset($this->smarty->autoload_filters['pre']) || isset($this->smarty->registered_filters['pre'])) && !$this->suppressFilter) {
+ $_content = Smarty_Internal_Filter_Handler::runFilter('pre', $_content, $template);
+ }
+ // call compiler
+ $_compiled_code = $this->doCompile($_content, true);
+ }
+ } while ($this->abort_and_recompile);
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::end_compile($this->template);
+ }
+ }
+ // restore source
+ $this->template->source = $save_source;
+ unset($save_source);
+ $this->smarty->_current_file = $this->template->source->filepath;
+ // free memory
+ unset($this->parser->root_buffer, $this->parser->current_buffer, $this->parser, $this->lex);
+ self::$_tag_objects = array();
+ // return compiled code to template object
+ $merged_code = '';
+ if (!empty($this->mergedSubTemplatesCode)) {
+ foreach ($this->mergedSubTemplatesCode as $code) {
+ $merged_code .= $code;
+ }
+ }
+ // run postfilter if required on compiled template code
+ if ((isset($this->smarty->autoload_filters['post']) || isset($this->smarty->registered_filters['post'])) && !$this->suppressFilter && $_compiled_code != '') {
+ $_compiled_code = Smarty_Internal_Filter_Handler::runFilter('post', $_compiled_code, $template);
+ }
+ if ($this->suppressTemplatePropertyHeader) {
+ $_compiled_code .= $merged_code;
+ } else {
+ $_compiled_code = $template_header . Smarty_Internal_Extension_CodeFrame::create($template, $_compiled_code) . $merged_code;
+ }
+ if (!empty($this->templateFunctionCode)) {
+ // run postfilter if required on compiled template code
+ if ((isset($this->smarty->autoload_filters['post']) || isset($this->smarty->registered_filters['post'])) && !$this->suppressFilter) {
+ $_compiled_code .= Smarty_Internal_Filter_Handler::runFilter('post', $this->templateFunctionCode, $template);
+ } else {
+ $_compiled_code .= $this->templateFunctionCode;
+ }
+ }
+ // unset content because template inheritance could have replace source with parent code
+ unset ($template->source->content);
+ $this->parent_compiler = null;
+ $this->template = null;
+ return $_compiled_code;
+ }
+
+ /**
+ * Compile Tag
+ * This is a call back from the lexer/parser
+ *
+ * Save current prefix code
+ * Compile tag
+ * Merge tag prefix code with saved one
+ * (required nested tags in attributes)
+ *
+ * @param string $tag tag name
+ * @param array $args array with tag attributes
+ * @param array $parameter array with compilation parameter
+ *
+ * @throws SmartyCompilerException
+ * @throws SmartyException
+ * @return string compiled code
+ */
+ public function compileTag($tag, $args, $parameter = array()) {
+ $this->prefixCodeStack[] = $this->prefix_code;
+ $this->prefix_code = array();
+ $result = $this->compileTag2($tag, $args, $parameter);
+ $this->prefix_code = array_merge($this->prefix_code, array_pop($this->prefixCodeStack));
+ return $result;
+ }
+
+ /**
+ * Compile Tag
+ *
+ * @param string $tag tag name
+ * @param array $args array with tag attributes
+ * @param array $parameter array with compilation parameter
+ *
+ * @throws SmartyCompilerException
+ * @throws SmartyException
+ * @return string compiled code
+ */
+ private function compileTag2($tag, $args, $parameter) {
+ $plugin_type = '';
+ // $args contains the attributes parsed and compiled by the lexer/parser
+ // assume that tag does compile into code, but creates no HTML output
+ $this->has_code = true;
+ $this->has_output = false;
+ // log tag/attributes
+ if (isset($this->smarty->get_used_tags) && $this->smarty->get_used_tags) {
+ $this->template->used_tags[] = array($tag, $args);
+ }
+ // check nocache option flag
+ if (in_array("'nocache'", $args) || in_array(array('nocache' => 'true'), $args) || in_array(array('nocache' => '"true"'), $args) || in_array(array('nocache' => "'true'"), $args)
+ ) {
+ $this->tag_nocache = true;
+ }
+ // compile the smarty tag (required compile classes to compile the tag are autoloaded)
+ if (($_output = $this->callTagCompiler($tag, $args, $parameter)) === false) {
+ if (isset($this->parent_compiler->templateProperties['tpl_function'][$tag])) {
+ // template defined by {template} tag
+ $args['_attr']['name'] = "'" . $tag . "'";
+ $_output = $this->callTagCompiler('call', $args, $parameter);
+ }
+ }
+ if ($_output !== false) {
+ if ($_output !== true) {
+ // did we get compiled code
+ if ($this->has_code) {
+ // Does it create output?
+ if ($this->has_output) {
+ $_output .= "\n";
+ }
+ // return compiled code
+ return $_output;
+ }
+ }
+ // tag did not produce compiled code
+ return null;
+ } else {
+ // map_named attributes
+ if (isset($args['_attr'])) {
+ foreach ($args['_attr'] as $key => $attribute) {
+ if (is_array($attribute)) {
+ $args = array_merge($args, $attribute);
+ }
+ }
+ }
+ // not an internal compiler tag
+ if (strlen($tag) < 6 || substr($tag, -5) != 'close') {
+ // check if tag is a registered object
+ if (isset($this->smarty->registered_objects[$tag]) && isset($parameter['object_method'])) {
+ $method = $parameter['object_method'];
+ if (!in_array($method, $this->smarty->registered_objects[$tag][3]) && (empty($this->smarty->registered_objects[$tag][1]) || in_array($method, $this->smarty->registered_objects[$tag][1]))
+ ) {
+ return $this->callTagCompiler('private_object_function', $args, $parameter, $tag, $method);
+ } elseif (in_array($method, $this->smarty->registered_objects[$tag][3])) {
+ return $this->callTagCompiler('private_object_block_function', $args, $parameter, $tag, $method);
+ } else {
+ // throw exception
+ $this->trigger_template_error('not allowed method "' . $method . '" in registered object "' . $tag . '"', $this->lex->taglineno);
+ }
+ }
+ // check if tag is registered
+ foreach (array(Smarty::PLUGIN_COMPILER, Smarty::PLUGIN_FUNCTION, Smarty::PLUGIN_BLOCK) as $plugin_type) {
+ if (isset($this->smarty->registered_plugins[$plugin_type][$tag])) {
+ // if compiler function plugin call it now
+ if ($plugin_type == Smarty::PLUGIN_COMPILER) {
+ $new_args = array();
+ foreach ($args as $key => $mixed) {
+ if (is_array($mixed)) {
+ $new_args = array_merge($new_args, $mixed);
+ } else {
+ $new_args[$key] = $mixed;
+ }
+ }
+ if (!$this->smarty->registered_plugins[$plugin_type][$tag][1]) {
+ $this->tag_nocache = true;
+ }
+ $function = $this->smarty->registered_plugins[$plugin_type][$tag][0];
+ if (!is_array($function)) {
+ return $function($new_args, $this);
+ } elseif (is_object($function[0])) {
+ return $this->smarty->registered_plugins[$plugin_type][$tag][0][0]->$function[1]($new_args, $this);
+ } else {
+ return call_user_func_array($function, array($new_args, $this));
+ }
+ }
+ // compile registered function or block function
+ if ($plugin_type == Smarty::PLUGIN_FUNCTION || $plugin_type == Smarty::PLUGIN_BLOCK) {
+ return $this->callTagCompiler('private_registered_' . $plugin_type, $args, $parameter, $tag);
+ }
+ }
+ }
+ // check plugins from plugins folder
+ foreach ($this->smarty->plugin_search_order as $plugin_type) {
+ if ($plugin_type == Smarty::PLUGIN_COMPILER && $this->smarty->loadPlugin('smarty_compiler_' . $tag) && (!isset($this->smarty->security_policy) || $this->smarty->security_policy->isTrustedTag($tag, $this))) {
+ $plugin = 'smarty_compiler_' . $tag;
+ if (is_callable($plugin)) {
+ // convert arguments format for old compiler plugins
+ $new_args = array();
+ foreach ($args as $key => $mixed) {
+ if (is_array($mixed)) {
+ $new_args = array_merge($new_args, $mixed);
+ } else {
+ $new_args[$key] = $mixed;
+ }
+ }
+
+ return $plugin($new_args, $this->smarty);
+ }
+ if (class_exists($plugin, false)) {
+ $plugin_object = new $plugin;
+ if (method_exists($plugin_object, 'compile')) {
+ return $plugin_object->compile($args, $this);
+ }
+ }
+ throw new SmartyException("Plugin \"{$tag}\" not callable");
+ } else {
+ if ($function = $this->getPlugin($tag, $plugin_type)) {
+ if (!isset($this->smarty->security_policy) || $this->smarty->security_policy->isTrustedTag($tag, $this)) {
+ return $this->callTagCompiler('private_' . $plugin_type . '_plugin', $args, $parameter, $tag, $function);
+ }
+ }
+ }
+ }
+ if (is_callable($this->smarty->default_plugin_handler_func)) {
+ $found = false;
+ // look for already resolved tags
+ foreach ($this->smarty->plugin_search_order as $plugin_type) {
+ if (isset($this->default_handler_plugins[$plugin_type][$tag])) {
+ $found = true;
+ break;
+ }
+ }
+ if (!$found) {
+ // call default handler
+ foreach ($this->smarty->plugin_search_order as $plugin_type) {
+ if ($this->getPluginFromDefaultHandler($tag, $plugin_type)) {
+ $found = true;
+ break;
+ }
+ }
+ }
+ if ($found) {
+ // if compiler function plugin call it now
+ if ($plugin_type == Smarty::PLUGIN_COMPILER) {
+ $new_args = array();
+ foreach ($args as $mixed) {
+ $new_args = array_merge($new_args, $mixed);
+ }
+ $function = $this->default_handler_plugins[$plugin_type][$tag][0];
+ if (!is_array($function)) {
+ return $function($new_args, $this);
+ } elseif (is_object($function[0])) {
+ return $this->default_handler_plugins[$plugin_type][$tag][0][0]->$function[1]($new_args, $this);
+ } else {
+ return call_user_func_array($function, array($new_args, $this));
+ }
+ } else {
+ return $this->callTagCompiler('private_registered_' . $plugin_type, $args, $parameter, $tag);
+ }
+ }
+ }
+ } else {
+ // compile closing tag of block function
+ $base_tag = substr($tag, 0, -5);
+ // check if closing tag is a registered object
+ if (isset($this->smarty->registered_objects[$base_tag]) && isset($parameter['object_method'])) {
+ $method = $parameter['object_method'];
+ if (in_array($method, $this->smarty->registered_objects[$base_tag][3])) {
+ return $this->callTagCompiler('private_object_block_function', $args, $parameter, $tag, $method);
+ } else {
+ // throw exception
+ $this->trigger_template_error('not allowed closing tag method "' . $method . '" in registered object "' . $base_tag . '"', $this->lex->taglineno);
+ }
+ }
+ // registered block tag ?
+ if (isset($this->smarty->registered_plugins[Smarty::PLUGIN_BLOCK][$base_tag]) || isset($this->default_handler_plugins[Smarty::PLUGIN_BLOCK][$base_tag])) {
+ return $this->callTagCompiler('private_registered_block', $args, $parameter, $tag);
+ }
+ // block plugin?
+ if ($function = $this->getPlugin($base_tag, Smarty::PLUGIN_BLOCK)) {
+ return $this->callTagCompiler('private_block_plugin', $args, $parameter, $tag, $function);
+ }
+ // registered compiler plugin ?
+ if (isset($this->smarty->registered_plugins[Smarty::PLUGIN_COMPILER][$tag])) {
+ // if compiler function plugin call it now
+ $args = array();
+ if (!$this->smarty->registered_plugins[Smarty::PLUGIN_COMPILER][$tag][1]) {
+ $this->tag_nocache = true;
+ }
+ $function = $this->smarty->registered_plugins[Smarty::PLUGIN_COMPILER][$tag][0];
+ if (!is_array($function)) {
+ return $function($args, $this);
+ } elseif (is_object($function[0])) {
+ return $this->smarty->registered_plugins[Smarty::PLUGIN_COMPILER][$tag][0][0]->$function[1]($args, $this);
+ } else {
+ return call_user_func_array($function, array($args, $this));
+ }
+ }
+ if ($this->smarty->loadPlugin('smarty_compiler_' . $tag)) {
+ $plugin = 'smarty_compiler_' . $tag;
+ if (is_callable($plugin)) {
+ return $plugin($args, $this->smarty);
+ }
+ if (class_exists($plugin, false)) {
+ $plugin_object = new $plugin;
+ if (method_exists($plugin_object, 'compile')) {
+ return $plugin_object->compile($args, $this);
+ }
+ }
+ throw new SmartyException("Plugin \"{$tag}\" not callable");
+ }
+ }
+ $this->trigger_template_error("unknown tag \"" . $tag . "\"", $this->lex->taglineno);
+ }
+ }
+
+ /**
+ * compile variable
+ *
+ * @param string $variable
+ *
+ * @return string
+ */
+ public function compileVariable($variable) {
+ if (strpos($variable, '(') == 0) {
+ // not a variable variable
+ $var = trim($variable, '\'');
+ $this->tag_nocache = $this->tag_nocache | $this->template->getVariable($var, null, true, false)->nocache;
+ $this->template->properties['variables'][$var] = $this->tag_nocache | $this->nocache;
+ }
+ return '$_smarty_tpl->tpl_vars[' . $variable . ']->value';
+ }
+
+ /**
+ * This method is called from parser to process a text content section
+ * - remove text from inheritance child templates as they may generate output
+ * - strip text if strip is enabled
+ *
+ * @param string $text
+ *
+ * @return null|\Smarty_Internal_ParseTree_Text
+ */
+ public function processText($text) {
+ if ($this->parser->strip) {
+ return new Smarty_Internal_ParseTree_Text($this->parser, preg_replace($this->stripRegEx, '', $text));
+ } else {
+ return new Smarty_Internal_ParseTree_Text($this->parser, $text);
+ }
+ }
+
+ /**
+ * lazy loads internal compile plugin for tag and calls the compile method
+ * compile objects cached for reuse.
+ * class name format: Smarty_Internal_Compile_TagName
+ * plugin filename format: Smarty_Internal_Tagname.php
+ *
+ * @param string $tag tag name
+ * @param array $args list of tag attributes
+ * @param mixed $param1 optional parameter
+ * @param mixed $param2 optional parameter
+ * @param mixed $param3 optional parameter
+ *
+ * @return string compiled code
+ */
+ public function callTagCompiler($tag, $args, $param1 = null, $param2 = null, $param3 = null) {
+ // check if tag allowed by security
+ if (!isset($this->smarty->security_policy) || $this->smarty->security_policy->isTrustedTag($tag, $this)) {
+ // re-use object if already exists
+ if (!isset(self::$_tag_objects[$tag])) {
+ // lazy load internal compiler plugin
+ $class_name = 'Smarty_Internal_Compile_' . $tag;
+ if ($this->smarty->loadPlugin($class_name)) {
+ self::$_tag_objects[$tag] = new $class_name;
+ } else {
+ return false;
+ }
+ }
+ // compile this tag
+ return self::$_tag_objects[$tag]->compile($args, $this, $param1, $param2, $param3);
+ }
+ // no internal compile plugin for this tag
+ return false;
+ }
+
+ /**
+ * Check for plugins and return function name
+ *
+ * @param $plugin_name
+ * @param string $plugin_type type of plugin
+ *
+ * @return string call name of function
+ */
+ public function getPlugin($plugin_name, $plugin_type) {
+ $function = null;
+ if ($this->template->caching && ($this->nocache || $this->tag_nocache)) {
+ if (isset($this->template->required_plugins['nocache'][$plugin_name][$plugin_type])) {
+ $function = $this->template->required_plugins['nocache'][$plugin_name][$plugin_type]['function'];
+ } elseif (isset($this->template->required_plugins['compiled'][$plugin_name][$plugin_type])) {
+ $this->template->required_plugins['nocache'][$plugin_name][$plugin_type] = $this->template->required_plugins['compiled'][$plugin_name][$plugin_type];
+ $function = $this->template->required_plugins['nocache'][$plugin_name][$plugin_type]['function'];
+ }
+ } else {
+ if (isset($this->template->required_plugins['compiled'][$plugin_name][$plugin_type])) {
+ $function = $this->template->required_plugins['compiled'][$plugin_name][$plugin_type]['function'];
+ } elseif (isset($this->template->required_plugins['nocache'][$plugin_name][$plugin_type])) {
+ $this->template->required_plugins['compiled'][$plugin_name][$plugin_type] = $this->template->required_plugins['nocache'][$plugin_name][$plugin_type];
+ $function = $this->template->required_plugins['compiled'][$plugin_name][$plugin_type]['function'];
+ }
+ }
+ if (isset($function)) {
+ if ($plugin_type == 'modifier') {
+ $this->modifier_plugins[$plugin_name] = true;
+ }
+
+ return $function;
+ }
+ // loop through plugin dirs and find the plugin
+ $function = 'smarty_' . $plugin_type . '_' . $plugin_name;
+ $file = $this->smarty->loadPlugin($function, false);
+
+ if (is_string($file)) {
+ if ($this->template->caching && ($this->nocache || $this->tag_nocache)) {
+ $this->template->required_plugins['nocache'][$plugin_name][$plugin_type]['file'] = $file;
+ $this->template->required_plugins['nocache'][$plugin_name][$plugin_type]['function'] = $function;
+ } else {
+ $this->template->required_plugins['compiled'][$plugin_name][$plugin_type]['file'] = $file;
+ $this->template->required_plugins['compiled'][$plugin_name][$plugin_type]['function'] = $function;
+ }
+ if ($plugin_type == 'modifier') {
+ $this->modifier_plugins[$plugin_name] = true;
+ }
+
+ return $function;
+ }
+ if (is_callable($function)) {
+ // plugin function is defined in the script
+ return $function;
+ }
+
+ return false;
+ }
+
+ /**
+ * Check for plugins by default plugin handler
+ *
+ * @param string $tag name of tag
+ * @param string $plugin_type type of plugin
+ *
+ * @return boolean true if found
+ */
+ public function getPluginFromDefaultHandler($tag, $plugin_type) {
+ $callback = null;
+ $script = null;
+ $cacheable = true;
+ $result = call_user_func_array($this->smarty->default_plugin_handler_func, array($tag, $plugin_type, $this->template, &$callback, &$script, &$cacheable));
+ if ($result) {
+ $this->tag_nocache = $this->tag_nocache || !$cacheable;
+ if ($script !== null) {
+ if (is_file($script)) {
+ if ($this->template->caching && ($this->nocache || $this->tag_nocache)) {
+ $this->template->required_plugins['nocache'][$tag][$plugin_type]['file'] = $script;
+ $this->template->required_plugins['nocache'][$tag][$plugin_type]['function'] = $callback;
+ } else {
+ $this->template->required_plugins['compiled'][$tag][$plugin_type]['file'] = $script;
+ $this->template->required_plugins['compiled'][$tag][$plugin_type]['function'] = $callback;
+ }
+ require_once $script;
+ } else {
+ $this->trigger_template_error("Default plugin handler: Returned script file \"{$script}\" for \"{$tag}\" not found");
+ }
+ }
+ if (!is_string($callback) && !(is_array($callback) && is_string($callback[0]) && is_string($callback[1]))) {
+ $this->trigger_template_error("Default plugin handler: Returned callback for \"{$tag}\" must be a static function name or array of class and function name");
+ }
+ if (is_callable($callback)) {
+ $this->default_handler_plugins[$plugin_type][$tag] = array($callback, true, array());
+
+ return true;
+ } else {
+ $this->trigger_template_error("Default plugin handler: Returned callback for \"{$tag}\" not callable");
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Append code segments and remove unneeded ?> <?php transitions
+ *
+ * @param string $left
+ * @param string $right
+ *
+ * @return string
+ */
+ public function appendCode($left, $right) {
+ if (preg_match('/\s*\?>\s*$/', $left) && preg_match('/^\s*<\?php\s+/', $right)) {
+ $left = preg_replace('/\s*\?>\s*$/', "\n", $left);
+ $left .= preg_replace('/^\s*<\?php\s+/', '', $right);
+ } else {
+ $left .= $right;
+ }
+ return $left;
+ }
+
+ /**
+ * Inject inline code for nocache template sections
+ * This method gets the content of each template element from the parser.
+ * If the content is compiled code and it should be not cached the code is injected
+ * into the rendered output.
+ *
+ * @param string $content content of template element
+ * @param boolean $is_code true if content is compiled code
+ *
+ * @return string content
+ */
+ public function processNocacheCode($content, $is_code) {
+ // If the template is not evaluated and we have a nocache section and or a nocache tag
+ if ($is_code && !empty($content)) {
+ // generate replacement code
+ if ((!($this->template->source->recompiled) || $this->forceNocache) && $this->template->caching && !$this->suppressNocacheProcessing && ($this->nocache || $this->tag_nocache)
+ ) {
+ $this->template->has_nocache_code = true;
+ $_output = addcslashes($content, '\'\\');
+ $_output = str_replace("^#^", "'", $_output);
+ $_output = "<?php echo '/*%%SmartyNocache:{$this->nocache_hash}%%*/" . $_output . "/*/%%SmartyNocache:{$this->nocache_hash}%%*/';?>\n";
+ // make sure we include modifier plugins for nocache code
+ foreach ($this->modifier_plugins as $plugin_name => $dummy) {
+ if (isset($this->template->required_plugins['compiled'][$plugin_name]['modifier'])) {
+ $this->template->required_plugins['nocache'][$plugin_name]['modifier'] = $this->template->required_plugins['compiled'][$plugin_name]['modifier'];
+ }
+ }
+ } else {
+ $_output = $content;
+ }
+ } else {
+ $_output = $content;
+ }
+ $this->modifier_plugins = array();
+ $this->suppressNocacheProcessing = false;
+ $this->tag_nocache = false;
+
+ return $_output;
+ }
+
+ /**
+ * Generate nocache code string
+ *
+ * @param string $code PHP code
+ *
+ * @return string
+ */
+ public function makeNocacheCode($code) {
+ return "echo '/*%%SmartyNocache:{$this->nocache_hash}%%*/<?php " . str_replace("^#^", "'", addcslashes($code, '\'\\')) . "?>/*/%%SmartyNocache:{$this->nocache_hash}%%*/';\n";
+ }
+
+ /**
+ * push current file and line offset on stack for tracing {block} source lines
+ *
+ * @param string $file new filename
+ * @param string $uid uid of file
+ * @param int $line line offset to source
+ * @param bool $debug false debug end_compile shall not be called
+ */
+ public function pushTrace($file, $uid, $line, $debug = true) {
+ if ($this->smarty->debugging && $debug) {
+ Smarty_Internal_Debug::end_compile($this->template);
+ }
+ array_push($this->trace_stack, array($this->smarty->_current_file, $this->trace_filepath, $this->trace_uid, $this->trace_line_offset));
+ $this->trace_filepath = $this->smarty->_current_file = $file;
+ $this->trace_uid = $uid;
+ $this->trace_line_offset = $line;
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::start_compile($this->template);
+ }
+ }
+
+ /**
+ * restore file and line offset
+ */
+ public function popTrace() {
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::end_compile($this->template);
+ }
+ $r = array_pop($this->trace_stack);
+ $this->smarty->_current_file = $r[0];
+ $this->trace_filepath = $r[1];
+ $this->trace_uid = $r[2];
+ $this->trace_line_offset = $r[3];
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::start_compile($this->template);
+ }
+ }
+
+ /**
+ * display compiler error messages without dying
+ * If parameter $args is empty it is a parser detected syntax error.
+ * In this case the parser is called to obtain information about expected tokens.
+ * If parameter $args contains a string this is used as error message
+ *
+ * @param string $args individual error message or null
+ * @param string $line line-number
+ *
+ * @throws SmartyCompilerException when an unexpected token is found
+ */
+ public function trigger_template_error($args = null, $line = null) {
+ // get template source line which has error
+ if (!isset($line)) {
+ $line = $this->lex->line;
+ }
+ // $line += $this->trace_line_offset;
+ $match = preg_split("/\n/", $this->lex->data);
+ $error_text = 'Syntax error in template "' . (empty($this->trace_filepath) ? $this->template->source->filepath : $this->trace_filepath) . '" on line ' . ($line + $this->trace_line_offset) . ' "' . trim(preg_replace('![\t\r\n]+!', ' ', $match[$line - 1])) . '" ';
+ if (isset($args)) {
+ // individual error message
+ $error_text .= $args;
+ } else {
+ $expect = array();
+ // expected token from parser
+ $error_text .= ' - Unexpected "' . $this->lex->value . '"';
+ if (count($this->parser->yy_get_expected_tokens($this->parser->yymajor)) <= 4) {
+ foreach ($this->parser->yy_get_expected_tokens($this->parser->yymajor) as $token) {
+ $exp_token = $this->parser->yyTokenName[$token];
+ if (isset($this->lex->smarty_token_names[$exp_token])) {
+ // token type from lexer
+ $expect[] = '"' . $this->lex->smarty_token_names[$exp_token] . '"';
+ } else {
+ // otherwise internal token name
+ $expect[] = $this->parser->yyTokenName[$token];
+ }
+ }
+ $error_text .= ', expected one of: ' . implode(' , ', $expect);
+ }
+ }
+ $e = new SmartyCompilerException($error_text);
+ $e->line = $line;
+ $e->source = trim(preg_replace('![\t\r\n]+!', ' ', $match[$line - 1]));
+ $e->desc = $args;
+ $e->template = $this->template->source->filepath;
+ throw $e;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_templatelexer.php
@@ -0,0 +1,1266 @@
+<?php
+/**
+ * Smarty Internal Plugin Templatelexer
+ * This is the lexer to break the template source into tokens
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty_Internal_Templatelexer
+ * This is the template file lexer.
+ * It is generated from the smarty_internal_templatelexer.plex file
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+class Smarty_Internal_Templatelexer {
+ /**
+ * Source
+ *
+ * @var string
+ */
+ public $data;
+
+ /**
+ * byte counter
+ *
+ * @var int
+ */
+ public $counter;
+
+ /**
+ * token number
+ *
+ * @var int
+ */
+ public $token;
+
+ /**
+ * token value
+ *
+ * @var string
+ */
+ public $value;
+
+ /**
+ * current line
+ *
+ * @var int
+ */
+ public $line;
+
+ /**
+ * tag start line
+ *
+ * @var
+ */
+ public $taglineno;
+
+ /**
+ * php code type
+ *
+ * @var string
+ */
+ public $phpType = '';
+
+ /**
+ * escaped left delimiter
+ *
+ * @var string
+ */
+ public $ldel = '';
+
+ /**
+ * escaped left delimiter length
+ *
+ * @var int
+ */
+ public $ldel_length = 0;
+
+ /**
+ * escaped right delimiter
+ *
+ * @var string
+ */
+ public $rdel = '';
+
+ /**
+ * escaped right delimiter length
+ *
+ * @var int
+ */
+ public $rdel_length = 0;
+
+ /**
+ * state number
+ *
+ * @var int
+ */
+ public $state = 1;
+
+ /**
+ * Smarty object
+ *
+ * @var Smarty
+ */
+ public $smarty = null;
+
+ /**
+ * compiler object
+ *
+ * @var Smarty_Internal_TemplateCompilerBase
+ */
+ public $compiler = null;
+
+ /**
+ * literal tag nesting level
+ *
+ * @var int
+ */
+ private $literal_cnt = 0;
+
+ /**
+ * PHP start tag string
+ *
+ * @var string
+ */
+
+ /**
+ * trace file
+ *
+ * @var resource
+ */
+ public $yyTraceFILE;
+
+ /**
+ * trace prompt
+ *
+ * @var string
+ */
+ public $yyTracePrompt;
+
+ /**
+ * XML flag true while processing xml
+ *
+ * @var bool
+ */
+ public $is_xml = false;
+
+ /**
+ * state names
+ *
+ * @var array
+ */
+ public $state_name = array(1 => 'TEXT', 2 => 'TAG', 3 => 'TAGBODY', 4 => 'LITERAL', 5 => 'DOUBLEQUOTEDSTRING',
+ 6 => 'CHILDBODY', 7 => 'CHILDBLOCK', 8 => 'CHILDLITERAL');
+
+ /**
+ * storage for assembled token patterns
+ *
+ * @var string
+ */
+ private $yy_global_pattern1 = null;
+
+ private $yy_global_pattern2 = null;
+
+ private $yy_global_pattern3 = null;
+
+ private $yy_global_pattern4 = null;
+
+ private $yy_global_pattern5 = null;
+
+ private $yy_global_pattern6 = null;
+
+ private $yy_global_pattern7 = null;
+
+ private $yy_global_pattern8 = null;
+
+ /**
+ * token names
+ *
+ * @var array
+ */
+ public $smarty_token_names = array( // Text for parser error messages
+ 'NOT' => '(!,not)', 'OPENP' => '(', 'CLOSEP' => ')', 'OPENB' => '[', 'CLOSEB' => ']', 'PTR' => '->',
+ 'APTR' => '=>', 'EQUAL' => '=', 'NUMBER' => 'number', 'UNIMATH' => '+" , "-', 'MATH' => '*" , "/" , "%',
+ 'INCDEC' => '++" , "--', 'SPACE' => ' ', 'DOLLAR' => '$', 'SEMICOLON' => ';', 'COLON' => ':',
+ 'DOUBLECOLON' => '::', 'AT' => '@', 'HATCH' => '#', 'QUOTE' => '"', 'BACKTICK' => '`', 'VERT' => '"|" modifier',
+ 'DOT' => '.', 'COMMA' => '","', 'QMARK' => '"?"', 'ID' => 'id, name', 'TEXT' => 'text',
+ 'LDELSLASH' => '{/..} closing tag', 'LDEL' => '{...} Smarty tag', 'COMMENT' => 'comment', 'AS' => 'as',
+ 'TO' => 'to', 'PHP' => '"<?php", "<%", "{php}" tag', 'LOGOP' => '"<", "==" ... logical operator',
+ 'TLOGOP' => '"lt", "eq" ... logical operator; "is div by" ... if condition',
+ 'SCOND' => '"is even" ... if condition',);
+
+ /**
+ * constructor
+ *
+ * @param string $data template source
+ * @param Smarty_Internal_TemplateCompilerBase $compiler
+ */
+ function __construct($data, Smarty_Internal_TemplateCompilerBase $compiler) {
+ $this->data = $data;
+ $this->counter = 0;
+ if (preg_match('~^\xEF\xBB\xBF~i', $this->data, $match)) {
+ $this->counter += strlen($match[0]);
+ }
+ $this->line = 1;
+ $this->smarty = $compiler->smarty;
+ $this->compiler = $compiler;
+ $this->ldel = preg_quote($this->smarty->left_delimiter, '~');
+ $this->ldel_length = strlen($this->smarty->left_delimiter);
+ $this->rdel = preg_quote($this->smarty->right_delimiter, '~');
+ $this->rdel_length = strlen($this->smarty->right_delimiter);
+ $this->smarty_token_names['LDEL'] = $this->smarty->left_delimiter;
+ $this->smarty_token_names['RDEL'] = $this->smarty->right_delimiter;
+ }
+
+ public function PrintTrace() {
+ $this->yyTraceFILE = fopen('php://output', 'w');
+ $this->yyTracePrompt = '<br>';
+ }
+
+ /*
+ * Check if this tag is autoliteral
+ */
+ public function isAutoLiteral() {
+ return $this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false;
+ }
+
+ private $_yy_state = 1;
+
+ private $_yy_stack = array();
+
+ public function yylex() {
+ return $this->{'yylex' . $this->_yy_state}();
+ }
+
+ public function yypushstate($state) {
+ if ($this->yyTraceFILE) {
+ fprintf($this->yyTraceFILE, "%sState push %s\n", $this->yyTracePrompt, isset($this->state_name[$this->_yy_state]) ? $this->state_name[$this->_yy_state] : $this->_yy_state);
+ }
+ array_push($this->_yy_stack, $this->_yy_state);
+ $this->_yy_state = $state;
+ if ($this->yyTraceFILE) {
+ fprintf($this->yyTraceFILE, "%snew State %s\n", $this->yyTracePrompt, isset($this->state_name[$this->_yy_state]) ? $this->state_name[$this->_yy_state] : $this->_yy_state);
+ }
+ }
+
+ public function yypopstate() {
+ if ($this->yyTraceFILE) {
+ fprintf($this->yyTraceFILE, "%sState pop %s\n", $this->yyTracePrompt, isset($this->state_name[$this->_yy_state]) ? $this->state_name[$this->_yy_state] : $this->_yy_state);
+ }
+ $this->_yy_state = array_pop($this->_yy_stack);
+ if ($this->yyTraceFILE) {
+ fprintf($this->yyTraceFILE, "%snew State %s\n", $this->yyTracePrompt, isset($this->state_name[$this->_yy_state]) ? $this->state_name[$this->_yy_state] : $this->_yy_state);
+ }
+ }
+
+ public function yybegin($state) {
+ $this->_yy_state = $state;
+ if ($this->yyTraceFILE) {
+ fprintf($this->yyTraceFILE, "%sState set %s\n", $this->yyTracePrompt, isset($this->state_name[$this->_yy_state]) ? $this->state_name[$this->_yy_state] : $this->_yy_state);
+ }
+ }
+
+ public function yylex1() {
+ if (!isset($this->yy_global_pattern1)) {
+ $this->yy_global_pattern1 = "/\G([{][}])|\G(" . $this->ldel . "[*])|\G((<[?]((php\\s+|=)|\\s+))|(<[%])|(<[?]xml\\s+)|(<script\\s+language\\s*=\\s*[\"']?\\s*php\\s*[\"']?\\s*>)|([?][>])|([%][>])|(" . $this->ldel . "\\s*php(.*?)" . $this->rdel . ")|(" . $this->ldel . "\\s*[\/]php" . $this->rdel . "))|\G(" . $this->ldel . "\\s*literal\\s*" . $this->rdel . ")|\G(" . $this->ldel . "\\s*)|\G(\\s*" . $this->rdel . ")|\G([\S\s])/isS";
+ }
+ if ($this->counter >= strlen($this->data)) {
+ return false; // end of input
+ }
+
+ do {
+ if (preg_match($this->yy_global_pattern1, $this->data, $yymatches, null, $this->counter)) {
+ $yysubmatches = $yymatches;
+ if (strlen($yysubmatches[0]) < 200) {
+ $yymatches = preg_grep("/(.|\s)+/", $yysubmatches);
+ } else {
+ $yymatches = array_filter($yymatches, 'strlen');
+ }
+ if (empty($yymatches)) {
+ throw new Exception('Error: lexing failed because a rule matched' . ' an empty string. Input "' . substr($this->data, $this->counter, 5) . '... state TEXT');
+ }
+ next($yymatches); // skip global match
+ $this->token = key($yymatches); // token number
+ $this->value = current($yymatches); // token value
+ $r = $this->{'yy_r1_' . $this->token}();
+ if ($r === null) {
+ $this->counter += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ // accept this token
+ return true;
+ } elseif ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ $this->counter += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ if ($this->counter >= strlen($this->data)) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ }
+ } else {
+ throw new Exception('Unexpected input at line' . $this->line . ': ' . $this->data[$this->counter]);
+ }
+ break;
+ } while (true);
+ } // end function
+
+ const TEXT = 1;
+
+ function yy_r1_1() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ }
+
+ function yy_r1_2() {
+
+ preg_match("~[*]{$this->rdel}~", $this->data, $match, PREG_OFFSET_CAPTURE, $this->counter);
+ if (isset($match[0][1])) {
+ $to = $match[0][1] + strlen($match[0][0]);
+ } else {
+ $this->compiler->trigger_template_error("missing or misspelled comment closing tag '*{$this->smarty->right_delimiter}'");
+ }
+ $this->value = substr($this->data, $this->counter, $to - $this->counter);
+ return false;
+ }
+
+ function yy_r1_3() {
+
+ $obj = new Smarty_Internal_Compile_Private_Php();
+ $obj->parsePhp($this);
+ }
+
+ function yy_r1_15() {
+
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_LITERALSTART;
+ $this->yypushstate(self::LITERAL);
+ }
+ }
+
+ function yy_r1_16() {
+
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->yypushstate(self::TAG);
+ return true;
+ }
+ }
+
+ function yy_r1_17() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ }
+
+ function yy_r1_18() {
+
+ $to = strlen($this->data);
+ preg_match("~($this->ldel)|([<]script\s+language\s*=\s*[\"\']?\s*php\s*[\"\']?\s*[>])|([<][?])|([<][%])|([?][>])|([%][>])~i", $this->data, $match, PREG_OFFSET_CAPTURE, $this->counter);
+ if (isset($match[0][1])) {
+ $to = $match[0][1];
+ }
+ $this->value = substr($this->data, $this->counter, $to - $this->counter);
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ }
+
+ public function yylex2() {
+ if (!isset($this->yy_global_pattern2)) {
+ $this->yy_global_pattern2 = "/\G(" . $this->ldel . "\\s*(if|elseif|else if|while)\\s+)|\G(" . $this->ldel . "\\s*for\\s+)|\G(" . $this->ldel . "\\s*foreach(?![^\s]))|\G(" . $this->ldel . "\\s*setfilter\\s+)|\G(" . $this->ldel . "\\s*[0-9]*[a-zA-Z_]\\w*(\\s+nocache)?\\s*" . $this->rdel . ")|\G(" . $this->ldel . "\\s*[\/](?:(?!block)[0-9]*[a-zA-Z_]\\w*)\\s*" . $this->rdel . ")|\G(" . $this->ldel . "\\s*[$][0-9]*[a-zA-Z_]\\w*(\\s+nocache)?\\s*" . $this->rdel . ")|\G(" . $this->ldel . "\\s*[\/])|\G(" . $this->ldel . "\\s*)/isS";
+ }
+ if ($this->counter >= strlen($this->data)) {
+ return false; // end of input
+ }
+
+ do {
+ if (preg_match($this->yy_global_pattern2, $this->data, $yymatches, null, $this->counter)) {
+ $yysubmatches = $yymatches;
+ if (strlen($yysubmatches[0]) < 200) {
+ $yymatches = preg_grep("/(.|\s)+/", $yysubmatches);
+ } else {
+ $yymatches = array_filter($yymatches, 'strlen');
+ }
+ if (empty($yymatches)) {
+ throw new Exception('Error: lexing failed because a rule matched' . ' an empty string. Input "' . substr($this->data, $this->counter, 5) . '... state TAG');
+ }
+ next($yymatches); // skip global match
+ $this->token = key($yymatches); // token number
+ $this->value = current($yymatches); // token value
+ $r = $this->{'yy_r2_' . $this->token}();
+ if ($r === null) {
+ $this->counter += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ // accept this token
+ return true;
+ } elseif ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ $this->counter += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ if ($this->counter >= strlen($this->data)) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ }
+ } else {
+ throw new Exception('Unexpected input at line' . $this->line . ': ' . $this->data[$this->counter]);
+ }
+ break;
+ } while (true);
+ } // end function
+
+ const TAG = 2;
+
+ function yy_r2_1() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_LDELIF;
+ $this->yybegin(self::TAGBODY);
+ $this->taglineno = $this->line;
+ }
+
+ function yy_r2_3() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_LDELFOR;
+ $this->yybegin(self::TAGBODY);
+ $this->taglineno = $this->line;
+ }
+
+ function yy_r2_4() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_LDELFOREACH;
+ $this->yybegin(self::TAGBODY);
+ $this->taglineno = $this->line;
+ }
+
+ function yy_r2_5() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_LDELSETFILTER;
+ $this->yybegin(self::TAGBODY);
+ $this->taglineno = $this->line;
+ }
+
+ function yy_r2_6() {
+
+ $this->yypopstate();
+ $this->token = Smarty_Internal_Templateparser::TP_SIMPLETAG;
+ $this->taglineno = $this->line;
+ }
+
+ function yy_r2_8() {
+
+ $this->yypopstate();
+ $this->token = Smarty_Internal_Templateparser::TP_CLOSETAG;
+ $this->taglineno = $this->line;
+ }
+
+ function yy_r2_9() {
+
+ if ($this->_yy_stack[count($this->_yy_stack) - 1] == self::TEXT) {
+ $this->yypopstate();
+ $this->token = Smarty_Internal_Templateparser::TP_SIMPLEOUTPUT;
+ $this->taglineno = $this->line;
+ } else {
+ $this->value = $this->smarty->left_delimiter;
+ $this->token = Smarty_Internal_Templateparser::TP_LDEL;
+ $this->yybegin(self::TAGBODY);
+ $this->taglineno = $this->line;
+ }
+ }
+
+ function yy_r2_11() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_LDELSLASH;
+ $this->yybegin(self::TAGBODY);
+ $this->taglineno = $this->line;
+ }
+
+ function yy_r2_12() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_LDEL;
+ $this->yybegin(self::TAGBODY);
+ $this->taglineno = $this->line;
+ }
+
+ public function yylex3() {
+ if (!isset($this->yy_global_pattern3)) {
+ $this->yy_global_pattern3 = "/\G(\\s*" . $this->rdel . ")|\G([\"])|\G('[^'\\\\]*(?:\\\\.[^'\\\\]*)*')|\G([$]smarty\\.block\\.(child|parent))|\G([$][0-9]*[a-zA-Z_]\\w*)|\G([$])|\G(\\s+is\\s+in\\s+)|\G(\\s+as\\s+)|\G(\\s+to\\s+)|\G(\\s+step\\s+)|\G(\\s+instanceof\\s+)|\G(\\s*(([!=][=]{1,2})|([<][=>]?)|([>][=]?)|[&|]{2})\\s*)|\G(\\s+(eq|ne|neq|gt|ge|gte|lt|le|lte|mod|and|or|xor|(is\\s+(not\\s+)?(odd|even|div)\\s+by))\\s+)|\G(\\s+is\\s+(not\\s+)?(odd|even))|\G(([!]\\s*)|(not\\s+))|\G([(](int(eger)?|bool(ean)?|float|double|real|string|binary|array|object)[)]\\s*)|\G(\\s*[(]\\s*)|\G(\\s*[)])|\G(\\[\\s*)|\G(\\s*\\])|\G(\\s*[-][>]\\s*)|\G(\\s*[=][>]\\s*)|\G(\\s*[=]\\s*)|\G(([+]|[-]){2})|\G(\\s*([+]|[-])\\s*)|\G(\\s*([*]{1,2}|[%\/^&]|[<>]{2})\\s*)|\G([@])|\G([#])|\G(\\s+[0-9]*[a-zA-Z_][a-zA-Z0-9_\-:]*\\s*[=]\\s*)|\G(([0-9]*[a-zA-Z_]\\w*)?(\\\\[0-9]*[a-zA-Z_]\\w*)+)|\G([0-9]*[a-zA-Z_]\\w*)|\G(\\d+)|\G([`])|\G([|])|\G([.])|\G(\\s*[,]\\s*)|\G(\\s*[;]\\s*)|\G([:]{2})|\G(\\s*[:]\\s*)|\G(\\s*[?]\\s*)|\G(0[xX][0-9a-fA-F]+)|\G(\\s+)|\G(" . $this->ldel . "\\s*)|\G([\S\s])/isS";
+ }
+ if ($this->counter >= strlen($this->data)) {
+ return false; // end of input
+ }
+
+ do {
+ if (preg_match($this->yy_global_pattern3, $this->data, $yymatches, null, $this->counter)) {
+ $yysubmatches = $yymatches;
+ if (strlen($yysubmatches[0]) < 200) {
+ $yymatches = preg_grep("/(.|\s)+/", $yysubmatches);
+ } else {
+ $yymatches = array_filter($yymatches, 'strlen');
+ }
+ if (empty($yymatches)) {
+ throw new Exception('Error: lexing failed because a rule matched' . ' an empty string. Input "' . substr($this->data, $this->counter, 5) . '... state TAGBODY ');
+ }
+ next($yymatches); // skip global match
+ $this->token = key($yymatches); // token number
+ $this->value = current($yymatches); // token value
+ $r = $this->{'yy_r3_' . $this->token}();
+ if ($r === null) {
+ $this->counter += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ // accept this token
+ return true;
+ } elseif ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ $this->counter += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ if ($this->counter >= strlen($this->data)) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ }
+ } else {
+ throw new Exception('Unexpected input at line' . $this->line . ': ' . $this->data[$this->counter]);
+ }
+ break;
+ } while (true);
+ } // end function
+
+ const TAGBODY = 3;
+
+ function yy_r3_1() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_RDEL;
+ $this->yypopstate();
+ }
+
+ function yy_r3_2() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_QUOTE;
+ $this->yypushstate(self::DOUBLEQUOTEDSTRING);
+ }
+
+ function yy_r3_3() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_SINGLEQUOTESTRING;
+ }
+
+ function yy_r3_4() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_SMARTYBLOCKCHILDPARENT;
+ $this->taglineno = $this->line;
+ }
+
+ function yy_r3_6() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_DOLLARID;
+ }
+
+ function yy_r3_7() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_DOLLAR;
+ }
+
+ function yy_r3_8() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_ISIN;
+ }
+
+ function yy_r3_9() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_AS;
+ }
+
+ function yy_r3_10() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_TO;
+ }
+
+ function yy_r3_11() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_STEP;
+ }
+
+ function yy_r3_12() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_INSTANCEOF;
+ }
+
+ function yy_r3_13() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_LOGOP;
+ }
+
+ function yy_r3_18() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_TLOGOP;
+ }
+
+ function yy_r3_23() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_SINGLECOND;
+ }
+
+ function yy_r3_26() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_NOT;
+ }
+
+ function yy_r3_29() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_TYPECAST;
+ }
+
+ function yy_r3_33() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_OPENP;
+ }
+
+ function yy_r3_34() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_CLOSEP;
+ }
+
+ function yy_r3_35() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_OPENB;
+ }
+
+ function yy_r3_36() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_CLOSEB;
+ }
+
+ function yy_r3_37() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_PTR;
+ }
+
+ function yy_r3_38() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_APTR;
+ }
+
+ function yy_r3_39() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_EQUAL;
+ }
+
+ function yy_r3_40() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_INCDEC;
+ }
+
+ function yy_r3_42() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_UNIMATH;
+ }
+
+ function yy_r3_44() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_MATH;
+ }
+
+ function yy_r3_46() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_AT;
+ }
+
+ function yy_r3_47() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_HATCH;
+ }
+
+ function yy_r3_48() {
+
+ // resolve conflicts with shorttag and right_delimiter starting with '='
+ if (substr($this->data, $this->counter + strlen($this->value) - 1, $this->rdel_length) == $this->smarty->right_delimiter) {
+ preg_match("~\s+~", $this->value, $match);
+ $this->value = $match[0];
+ $this->token = Smarty_Internal_Templateparser::TP_SPACE;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_ATTR;
+ }
+ }
+
+ function yy_r3_49() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_NAMESPACE;
+ }
+
+ function yy_r3_52() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_ID;
+ }
+
+ function yy_r3_53() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_INTEGER;
+ }
+
+ function yy_r3_54() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_BACKTICK;
+ $this->yypopstate();
+ }
+
+ function yy_r3_55() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_VERT;
+ }
+
+ function yy_r3_56() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_DOT;
+ }
+
+ function yy_r3_57() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_COMMA;
+ }
+
+ function yy_r3_58() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_SEMICOLON;
+ }
+
+ function yy_r3_59() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_DOUBLECOLON;
+ }
+
+ function yy_r3_60() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_COLON;
+ }
+
+ function yy_r3_61() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_QMARK;
+ }
+
+ function yy_r3_62() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_HEX;
+ }
+
+ function yy_r3_63() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_SPACE;
+ }
+
+ function yy_r3_64() {
+
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->yypushstate(self::TAG);
+ return true;
+ }
+ }
+
+ function yy_r3_65() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ }
+
+ public function yylex4() {
+ if (!isset($this->yy_global_pattern4)) {
+ $this->yy_global_pattern4 = "/\G(" . $this->ldel . "\\s*literal\\s*" . $this->rdel . ")|\G(" . $this->ldel . "\\s*[\/]literal\\s*" . $this->rdel . ")|\G([\S\s])/isS";
+ }
+ if ($this->counter >= strlen($this->data)) {
+ return false; // end of input
+ }
+
+ do {
+ if (preg_match($this->yy_global_pattern4, $this->data, $yymatches, null, $this->counter)) {
+ $yysubmatches = $yymatches;
+ if (strlen($yysubmatches[0]) < 200) {
+ $yymatches = preg_grep("/(.|\s)+/", $yysubmatches);
+ } else {
+ $yymatches = array_filter($yymatches, 'strlen');
+ }
+ if (empty($yymatches)) {
+ throw new Exception('Error: lexing failed because a rule matched' . ' an empty string. Input "' . substr($this->data, $this->counter, 5) . '... state LITERAL');
+ }
+ next($yymatches); // skip global match
+ $this->token = key($yymatches); // token number
+ $this->value = current($yymatches); // token value
+ $r = $this->{'yy_r4_' . $this->token}();
+ if ($r === null) {
+ $this->counter += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ // accept this token
+ return true;
+ } elseif ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ $this->counter += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ if ($this->counter >= strlen($this->data)) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ }
+ } else {
+ throw new Exception('Unexpected input at line' . $this->line . ': ' . $this->data[$this->counter]);
+ }
+ break;
+ } while (true);
+ } // end function
+
+ const LITERAL = 4;
+
+ function yy_r4_1() {
+
+ $this->literal_cnt++;
+ $this->token = Smarty_Internal_Templateparser::TP_LITERAL;
+ }
+
+ function yy_r4_2() {
+
+ if ($this->literal_cnt) {
+ $this->literal_cnt--;
+ $this->token = Smarty_Internal_Templateparser::TP_LITERAL;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_LITERALEND;
+ $this->yypopstate();
+ }
+ }
+
+ function yy_r4_3() {
+
+ $to = strlen($this->data);
+ preg_match("~{$this->ldel}[/]?literal{$this->rdel}~i", $this->data, $match, PREG_OFFSET_CAPTURE, $this->counter);
+ if (isset($match[0][1])) {
+ $to = $match[0][1];
+ } else {
+ $this->compiler->trigger_template_error("missing or misspelled literal closing tag");
+ }
+ $this->value = substr($this->data, $this->counter, $to - $this->counter);
+ $this->token = Smarty_Internal_Templateparser::TP_LITERAL;
+ }
+
+ public function yylex5() {
+ if (!isset($this->yy_global_pattern5)) {
+ $this->yy_global_pattern5 = "/\G(" . $this->ldel . "\\s*literal\\s*" . $this->rdel . ")|\G(" . $this->ldel . "\\s*[\/]literal\\s*" . $this->rdel . ")|\G(" . $this->ldel . "\\s*[\/])|\G(" . $this->ldel . "\\s*[0-9]*[a-zA-Z_]\\w*)|\G(" . $this->ldel . "\\s*)|\G([\"])|\G([`][$])|\G([$][0-9]*[a-zA-Z_]\\w*)|\G([$])|\G(([^\"\\\\]*?)((?:\\\\.[^\"\\\\]*?)*?)(?=(" . $this->ldel . "|\\$|`\\$|\")))|\G([\S\s])/isS";
+ }
+ if ($this->counter >= strlen($this->data)) {
+ return false; // end of input
+ }
+
+ do {
+ if (preg_match($this->yy_global_pattern5, $this->data, $yymatches, null, $this->counter)) {
+ $yysubmatches = $yymatches;
+ if (strlen($yysubmatches[0]) < 200) {
+ $yymatches = preg_grep("/(.|\s)+/", $yysubmatches);
+ } else {
+ $yymatches = array_filter($yymatches, 'strlen');
+ }
+ if (empty($yymatches)) {
+ throw new Exception('Error: lexing failed because a rule matched' . ' an empty string. Input "' . substr($this->data, $this->counter, 5) . '... state DOUBLEQUOTEDSTRING');
+ }
+ next($yymatches); // skip global match
+ $this->token = key($yymatches); // token number
+ $this->value = current($yymatches); // token value
+ $r = $this->{'yy_r5_' . $this->token}();
+ if ($r === null) {
+ $this->counter += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ // accept this token
+ return true;
+ } elseif ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ $this->counter += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ if ($this->counter >= strlen($this->data)) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ }
+ } else {
+ throw new Exception('Unexpected input at line' . $this->line . ': ' . $this->data[$this->counter]);
+ }
+ break;
+ } while (true);
+ } // end function
+
+ const DOUBLEQUOTEDSTRING = 5;
+
+ function yy_r5_1() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ }
+
+ function yy_r5_2() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ }
+
+ function yy_r5_3() {
+
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->yypushstate(self::TAG);
+ return true;
+ }
+ }
+
+ function yy_r5_4() {
+
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->yypushstate(self::TAG);
+ return true;
+ }
+ }
+
+ function yy_r5_5() {
+
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_LDEL;
+ $this->taglineno = $this->line;
+ $this->yypushstate(self::TAGBODY);
+ }
+ }
+
+ function yy_r5_6() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_QUOTE;
+ $this->yypopstate();
+ }
+
+ function yy_r5_7() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_BACKTICK;
+ $this->value = substr($this->value, 0, -1);
+ $this->yypushstate(self::TAGBODY);
+ $this->taglineno = $this->line;
+ }
+
+ function yy_r5_8() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_DOLLARID;
+ }
+
+ function yy_r5_9() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ }
+
+ function yy_r5_10() {
+
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ }
+
+ function yy_r5_14() {
+
+ $to = strlen($this->data);
+ $this->value = substr($this->data, $this->counter, $to - $this->counter);
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ }
+
+ public function yylex6() {
+ if (!isset($this->yy_global_pattern6)) {
+ $this->yy_global_pattern6 = "/\G(" . $this->ldel . "\\s*strip\\s*" . $this->rdel . ")|\G(" . $this->ldel . "\\s*[\/]strip\\s*" . $this->rdel . ")|\G(" . $this->ldel . "\\s*block)|\G([\S\s])/isS";
+ }
+ if ($this->counter >= strlen($this->data)) {
+ return false; // end of input
+ }
+
+ do {
+ if (preg_match($this->yy_global_pattern6, $this->data, $yymatches, null, $this->counter)) {
+ $yysubmatches = $yymatches;
+ if (strlen($yysubmatches[0]) < 200) {
+ $yymatches = preg_grep("/(.|\s)+/", $yysubmatches);
+ } else {
+ $yymatches = array_filter($yymatches, 'strlen');
+ }
+ if (empty($yymatches)) {
+ throw new Exception('Error: lexing failed because a rule matched' . ' an empty string. Input "' . substr($this->data, $this->counter, 5) . '... state CHILDBODY');
+ }
+ next($yymatches); // skip global match
+ $this->token = key($yymatches); // token number
+ $this->value = current($yymatches); // token value
+ $r = $this->{'yy_r6_' . $this->token}();
+ if ($r === null) {
+ $this->counter += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ // accept this token
+ return true;
+ } elseif ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ $this->counter += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ if ($this->counter >= strlen($this->data)) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ }
+ } else {
+ throw new Exception('Unexpected input at line' . $this->line . ': ' . $this->data[$this->counter]);
+ }
+ break;
+ } while (true);
+ } // end function
+
+ const CHILDBODY = 6;
+
+ function yy_r6_1() {
+
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ return false;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_STRIPON;
+ }
+ }
+
+ function yy_r6_2() {
+
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ return false;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_STRIPOFF;
+ }
+ }
+
+ function yy_r6_3() {
+
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ return false;
+ } else {
+ $this->yypopstate();
+ return true;
+ }
+ }
+
+ function yy_r6_4() {
+
+ $to = strlen($this->data);
+ preg_match("~" . $this->ldel . "\s*(([/])?strip\s*" . $this->rdel . "|block\s+)~i", $this->data, $match, PREG_OFFSET_CAPTURE, $this->counter);
+ if (isset($match[0][1])) {
+ $to = $match[0][1];
+ }
+ $this->value = substr($this->data, $this->counter, $to - $this->counter);
+ return false;
+ }
+
+ public function yylex7() {
+ if (!isset($this->yy_global_pattern7)) {
+ $this->yy_global_pattern7 = "/\G(" . $this->ldel . "\\s*literal\\s*" . $this->rdel . ")|\G(" . $this->ldel . "\\s*block)|\G(" . $this->ldel . "\\s*[\/]block)|\G(" . $this->ldel . "\\s*[$]smarty\\.block\\.(child|parent))|\G([\S\s])/isS";
+ }
+ if ($this->counter >= strlen($this->data)) {
+ return false; // end of input
+ }
+
+ do {
+ if (preg_match($this->yy_global_pattern7, $this->data, $yymatches, null, $this->counter)) {
+ $yysubmatches = $yymatches;
+ if (strlen($yysubmatches[0]) < 200) {
+ $yymatches = preg_grep("/(.|\s)+/", $yysubmatches);
+ } else {
+ $yymatches = array_filter($yymatches, 'strlen');
+ }
+ if (empty($yymatches)) {
+ throw new Exception('Error: lexing failed because a rule matched' . ' an empty string. Input "' . substr($this->data, $this->counter, 5) . '... state CHILDBLOCK');
+ }
+ next($yymatches); // skip global match
+ $this->token = key($yymatches); // token number
+ $this->value = current($yymatches); // token value
+ $r = $this->{'yy_r7_' . $this->token}();
+ if ($r === null) {
+ $this->counter += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ // accept this token
+ return true;
+ } elseif ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ $this->counter += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ if ($this->counter >= strlen($this->data)) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ }
+ } else {
+ throw new Exception('Unexpected input at line' . $this->line . ': ' . $this->data[$this->counter]);
+ }
+ break;
+ } while (true);
+ } // end function
+
+ const CHILDBLOCK = 7;
+
+ function yy_r7_1() {
+
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ $this->yypushstate(self::CHILDLITERAL);
+ }
+ }
+
+ function yy_r7_2() {
+
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ } else {
+ $this->yypopstate();
+ return true;
+ }
+ }
+
+ function yy_r7_3() {
+
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ } else {
+ $this->yypopstate();
+ return true;
+ }
+ }
+
+ function yy_r7_4() {
+
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ } else {
+ $this->yypopstate();
+ return true;
+ }
+ }
+
+ function yy_r7_6() {
+
+ $to = strlen($this->data);
+ preg_match("~" . $this->ldel . "\s*(literal\s*" . $this->rdel . "|([/])?block(\s|" . $this->rdel . ")|[\$]smarty\.block\.(child|parent))~i", $this->data, $match, PREG_OFFSET_CAPTURE, $this->counter);
+ if (isset($match[0][1])) {
+ $to = $match[0][1];
+ }
+ $this->value = substr($this->data, $this->counter, $to - $this->counter);
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ }
+
+ public function yylex8() {
+ if (!isset($this->yy_global_pattern8)) {
+ $this->yy_global_pattern8 = "/\G(" . $this->ldel . "\\s*literal\\s*" . $this->rdel . ")|\G(" . $this->ldel . "\\s*[\/]literal\\s*" . $this->rdel . ")|\G([\S\s])/isS";
+ }
+ if ($this->counter >= strlen($this->data)) {
+ return false; // end of input
+ }
+
+ do {
+ if (preg_match($this->yy_global_pattern8, $this->data, $yymatches, null, $this->counter)) {
+ $yysubmatches = $yymatches;
+ if (strlen($yysubmatches[0]) < 200) {
+ $yymatches = preg_grep("/(.|\s)+/", $yysubmatches);
+ } else {
+ $yymatches = array_filter($yymatches, 'strlen');
+ }
+ if (empty($yymatches)) {
+ throw new Exception('Error: lexing failed because a rule matched' . ' an empty string. Input "' . substr($this->data, $this->counter, 5) . '... state CHILDLITERAL');
+ }
+ next($yymatches); // skip global match
+ $this->token = key($yymatches); // token number
+ $this->value = current($yymatches); // token value
+ $r = $this->{'yy_r8_' . $this->token}();
+ if ($r === null) {
+ $this->counter += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ // accept this token
+ return true;
+ } elseif ($r === true) {
+ // we have changed state
+ // process this token in the new state
+ return $this->yylex();
+ } elseif ($r === false) {
+ $this->counter += strlen($this->value);
+ $this->line += substr_count($this->value, "\n");
+ if ($this->counter >= strlen($this->data)) {
+ return false; // end of input
+ }
+ // skip this token
+ continue;
+ }
+ } else {
+ throw new Exception('Unexpected input at line' . $this->line . ': ' . $this->data[$this->counter]);
+ }
+ break;
+ } while (true);
+ } // end function
+
+ const CHILDLITERAL = 8;
+
+ function yy_r8_1() {
+
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ $this->yypushstate(self::CHILDLITERAL);
+ }
+ }
+
+ function yy_r8_2() {
+
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ $this->yypopstate();
+ }
+ }
+
+ function yy_r8_3() {
+
+ $to = strlen($this->data);
+ preg_match("~{$this->ldel}[/]?literal\s*{$this->rdel}~i", $this->data, $match, PREG_OFFSET_CAPTURE, $this->counter);
+ if (isset($match[0][1])) {
+ $to = $match[0][1];
+ } else {
+ $this->compiler->trigger_template_error("missing or misspelled literal closing tag");
+ }
+ $this->value = substr($this->data, $this->counter, $to - $this->counter);
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ }
+
+}
+
+
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_templateparser.php
@@ -0,0 +1,2244 @@
+<?php
+
+class TP_yyToken implements ArrayAccess {
+ public $string = '';
+
+ public $metadata = array();
+
+ public function __construct($s, $m = array()) {
+ if ($s instanceof TP_yyToken) {
+ $this->string = $s->string;
+ $this->metadata = $s->metadata;
+ } else {
+ $this->string = (string)$s;
+ if ($m instanceof TP_yyToken) {
+ $this->metadata = $m->metadata;
+ } elseif (is_array($m)) {
+ $this->metadata = $m;
+ }
+ }
+ }
+
+ public function __toString() {
+ return $this->string;
+ }
+
+ public function offsetExists($offset) {
+ return isset($this->metadata[$offset]);
+ }
+
+ public function offsetGet($offset) {
+ return $this->metadata[$offset];
+ }
+
+ public function offsetSet($offset, $value) {
+ if ($offset === null) {
+ if (isset($value[0])) {
+ $x = ($value instanceof TP_yyToken) ? $value->metadata : $value;
+ $this->metadata = array_merge($this->metadata, $x);
+
+ return;
+ }
+ $offset = count($this->metadata);
+ }
+ if ($value === null) {
+ return;
+ }
+ if ($value instanceof TP_yyToken) {
+ if ($value->metadata) {
+ $this->metadata[$offset] = $value->metadata;
+ }
+ } elseif ($value) {
+ $this->metadata[$offset] = $value;
+ }
+ }
+
+ public function offsetUnset($offset) {
+ unset($this->metadata[$offset]);
+ }
+}
+
+class TP_yyStackEntry {
+ public $stateno; /* The state-number */
+ public $major; /* The major token value. This is the code
+ ** number for the token at this stack level */
+ public $minor; /* The user-supplied minor token value. This
+ ** is the value of the token */
+}
+
+;
+
+#line 13 "../smarty/lexer/smarty_internal_templateparser.y"
+
+/**
+ * Smarty Internal Plugin Templateparser
+ *
+ * This is the template parser.
+ * It is generated from the smarty_internal_templateparser.y file
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+class Smarty_Internal_Templateparser {
+ #line 26 "../smarty/lexer/smarty_internal_templateparser.y"
+
+ const Err1 = "Security error: Call to private object member not allowed";
+
+ const Err2 = "Security error: Call to dynamic object member not allowed";
+
+ const Err3 = "PHP in template not allowed. Use SmartyBC to enable it";
+
+ /**
+ * result status
+ *
+ * @var bool
+ */
+ public $successful = true;
+
+ /**
+ * return value
+ *
+ * @var mixed
+ */
+ public $retvalue = 0;
+
+ /**
+ * counter for prefix code
+ *
+ * @var int
+ */
+ public static $prefix_number = 0;
+
+ /**
+ * @var
+ */
+ public $yymajor;
+
+ /**
+ * last index of array variable
+ *
+ * @var mixed
+ */
+ public $last_index;
+
+ /**
+ * last variable name
+ *
+ * @var string
+ */
+ public $last_variable;
+
+ /**
+ * root parse tree buffer
+ *
+ * @var Smarty_Internal_ParseTree
+ */
+ public $root_buffer;
+
+ /**
+ * current parse tree object
+ *
+ * @var Smarty_Internal_ParseTree
+ */
+ public $current_buffer;
+
+ /**
+ * lexer object
+ *
+ * @var Smarty_Internal_Templatelexer
+ */
+ private $lex;
+
+ /**
+ * internal error flag
+ *
+ * @var bool
+ */
+ private $internalError = false;
+
+ /**
+ * {strip} status
+ *
+ * @var bool
+ */
+ public $strip = false;
+
+ /**
+ * compiler object
+ *
+ * @var Smarty_Internal_TemplateCompilerBase
+ */
+ public $compiler = null;
+
+ /**
+ * smarty object
+ *
+ * @var Smarty
+ */
+ public $smarty = null;
+
+ /**
+ * template object
+ *
+ * @var Smarty_Internal_Template
+ */
+ public $template = null;
+
+ /**
+ * block nesting level
+ *
+ * @var int
+ */
+ public $block_nesting_level = 0;
+
+ /**
+ * security object
+ *
+ * @var Smarty_Security
+ */
+ private $security = null;
+
+ /**
+ * constructor
+ *
+ * @param Smarty_Internal_Templatelexer $lex
+ * @param Smarty_Internal_TemplateCompilerBase $compiler
+ */
+ function __construct(Smarty_Internal_Templatelexer $lex, Smarty_Internal_TemplateCompilerBase $compiler) {
+ $this->lex = $lex;
+ $this->compiler = $compiler;
+ $this->template = $this->compiler->template;
+ $this->smarty = $this->template->smarty;
+ $this->security = isset($this->smarty->security_policy) ? $this->smarty->security_policy : false;
+ $this->current_buffer = $this->root_buffer = new Smarty_Internal_ParseTree_Template($this);
+ }
+
+ /**
+ * insert PHP code in current buffer
+ *
+ * @param string $code
+ */
+ public function insertPhpCode($code) {
+ $this->current_buffer->append_subtree(new Smarty_Internal_ParseTree_Tag($this, $code));
+ }
+
+ /**
+ * merge PHP code with prefix code and return parse tree tag object
+ *
+ * @param string $code
+ *
+ * @return Smarty_Internal_ParseTree_Tag
+ */
+ public function mergePrefixCode($code) {
+ $tmp = '';
+ foreach ($this->compiler->prefix_code as $preCode) {
+ $tmp = empty($tmp) ? $preCode : $this->compiler->appendCode($tmp, $preCode);
+ }
+ $this->compiler->prefix_code = array();
+ $tmp = empty($tmp) ? $code : $this->compiler->appendCode($tmp, $code);
+ return new Smarty_Internal_ParseTree_Tag($this, $this->compiler->processNocacheCode($tmp, true));
+ }
+
+ const TP_VERT = 1;
+
+ const TP_COLON = 2;
+
+ const TP_PHP = 3;
+
+ const TP_NOCACHE = 4;
+
+ const TP_TEXT = 5;
+
+ const TP_STRIPON = 6;
+
+ const TP_STRIPOFF = 7;
+
+ const TP_BLOCKSOURCE = 8;
+
+ const TP_LITERALSTART = 9;
+
+ const TP_LITERALEND = 10;
+
+ const TP_LITERAL = 11;
+
+ const TP_RDEL = 12;
+
+ const TP_SIMPLEOUTPUT = 13;
+
+ const TP_LDEL = 14;
+
+ const TP_DOLLARID = 15;
+
+ const TP_EQUAL = 16;
+
+ const TP_SIMPLETAG = 17;
+
+ const TP_ID = 18;
+
+ const TP_PTR = 19;
+
+ const TP_LDELIF = 20;
+
+ const TP_LDELFOR = 21;
+
+ const TP_SEMICOLON = 22;
+
+ const TP_INCDEC = 23;
+
+ const TP_TO = 24;
+
+ const TP_STEP = 25;
+
+ const TP_LDELFOREACH = 26;
+
+ const TP_SPACE = 27;
+
+ const TP_AS = 28;
+
+ const TP_APTR = 29;
+
+ const TP_LDELSETFILTER = 30;
+
+ const TP_SMARTYBLOCKCHILDPARENT = 31;
+
+ const TP_CLOSETAG = 32;
+
+ const TP_LDELSLASH = 33;
+
+ const TP_ATTR = 34;
+
+ const TP_INTEGER = 35;
+
+ const TP_COMMA = 36;
+
+ const TP_OPENP = 37;
+
+ const TP_CLOSEP = 38;
+
+ const TP_MATH = 39;
+
+ const TP_UNIMATH = 40;
+
+ const TP_ISIN = 41;
+
+ const TP_INSTANCEOF = 42;
+
+ const TP_QMARK = 43;
+
+ const TP_NOT = 44;
+
+ const TP_TYPECAST = 45;
+
+ const TP_HEX = 46;
+
+ const TP_DOT = 47;
+
+ const TP_SINGLEQUOTESTRING = 48;
+
+ const TP_DOUBLECOLON = 49;
+
+ const TP_NAMESPACE = 50;
+
+ const TP_AT = 51;
+
+ const TP_HATCH = 52;
+
+ const TP_OPENB = 53;
+
+ const TP_CLOSEB = 54;
+
+ const TP_DOLLAR = 55;
+
+ const TP_LOGOP = 56;
+
+ const TP_TLOGOP = 57;
+
+ const TP_SINGLECOND = 58;
+
+ const TP_QUOTE = 59;
+
+ const TP_BACKTICK = 60;
+
+ const YY_NO_ACTION = 525;
+
+ const YY_ACCEPT_ACTION = 524;
+
+ const YY_ERROR_ACTION = 523;
+
+ const YY_SZ_ACTTAB = 1908;
+
+ static public $yy_action = array(287, 9, 129, 251, 273, 194, 441, 2, 82, 280, 281, 282, 216, 110, 353, 223, 212,
+ 229, 441, 258, 217, 12, 199, 240, 32, 257, 257, 39, 17, 12, 25, 43, 42, 263, 224, 233, 17, 206, 441, 80, 1, 244,
+ 311, 311, 172, 172, 52, 287, 9, 128, 441, 273, 65, 178, 2, 82, 268, 14, 184, 298, 110, 262, 13, 319, 229, 297,
+ 258, 217, 31, 225, 12, 32, 170, 257, 39, 239, 189, 17, 43, 42, 263, 224, 292, 214, 206, 249, 80, 1, 113, 311,
+ 164, 442, 172, 52, 287, 9, 132, 201, 273, 209, 260, 2, 82, 442, 14, 141, 256, 110, 262, 88, 303, 229, 261, 258,
+ 217, 260, 225, 12, 32, 168, 36, 39, 241, 12, 17, 43, 42, 263, 224, 292, 17, 206, 189, 80, 1, 7, 311, 180, 257,
+ 219, 52, 287, 9, 132, 134, 273, 193, 470, 2, 82, 10, 470, 156, 304, 110, 300, 89, 172, 229, 310, 258, 217, 260,
+ 205, 223, 32, 257, 14, 39, 324, 12, 262, 43, 42, 263, 224, 292, 17, 206, 189, 80, 1, 470, 311, 470, 172, 470,
+ 52, 287, 9, 131, 201, 273, 209, 257, 2, 82, 83, 307, 232, 201, 110, 399, 454, 230, 229, 237, 258, 217, 454, 225,
+ 355, 32, 133, 201, 39, 215, 399, 144, 43, 42, 263, 224, 292, 399, 206, 12, 80, 1, 326, 311, 157, 236, 17, 52,
+ 287, 9, 133, 201, 273, 209, 260, 2, 82, 214, 201, 235, 202, 110, 113, 80, 99, 229, 311, 258, 217, 396, 225, 187,
+ 19, 14, 323, 39, 18, 262, 28, 43, 42, 263, 224, 292, 396, 206, 12, 80, 1, 143, 311, 396, 134, 17, 52, 287, 9,
+ 132, 10, 273, 209, 4, 2, 82, 313, 14, 146, 454, 110, 262, 181, 158, 229, 454, 258, 217, 260, 192, 12, 32, 20,
+ 260, 39, 99, 441, 17, 43, 42, 263, 224, 292, 243, 206, 189, 80, 1, 441, 311, 187, 182, 298, 52, 287, 9, 130,
+ 201, 273, 209, 14, 2, 82, 93, 262, 104, 24, 110, 399, 99, 169, 229, 154, 258, 217, 220, 225, 113, 5, 124, 260,
+ 39, 135, 399, 100, 43, 42, 263, 224, 292, 399, 206, 261, 80, 1, 325, 311, 228, 112, 104, 52, 287, 9, 132, 92,
+ 273, 191, 173, 2, 82, 174, 291, 285, 16, 110, 330, 312, 260, 229, 310, 258, 217, 311, 225, 223, 32, 259, 90, 39,
+ 261, 6, 264, 43, 42, 263, 224, 292, 181, 206, 175, 80, 1, 116, 311, 171, 201, 21, 52, 287, 9, 132, 37, 273, 195,
+ 260, 2, 82, 36, 296, 238, 189, 110, 189, 259, 201, 229, 261, 258, 217, 214, 225, 218, 32, 35, 113, 39, 36, 232,
+ 299, 43, 42, 263, 224, 292, 15, 206, 183, 80, 1, 211, 311, 17, 91, 226, 52, 287, 9, 133, 177, 273, 209, 179, 2,
+ 82, 318, 470, 99, 18, 110, 470, 454, 121, 229, 288, 258, 217, 289, 225, 316, 19, 145, 189, 39, 187, 189, 121,
+ 43, 42, 263, 224, 292, 161, 206, 261, 80, 99, 104, 311, 454, 14, 454, 52, 470, 262, 454, 279, 278, 276, 277,
+ 283, 284, 174, 159, 470, 261, 287, 9, 470, 454, 273, 311, 317, 2, 82, 176, 298, 223, 204, 110, 115, 68, 107,
+ 229, 117, 258, 217, 100, 3, 201, 272, 329, 138, 29, 210, 271, 293, 454, 325, 454, 359, 470, 260, 454, 254, 317,
+ 139, 275, 200, 306, 223, 204, 111, 119, 72, 107, 260, 201, 37, 242, 100, 255, 151, 272, 329, 213, 4, 210, 271,
+ 293, 150, 325, 245, 167, 20, 152, 317, 81, 208, 149, 260, 223, 204, 260, 119, 60, 102, 186, 218, 185, 265, 100,
+ 269, 22, 272, 329, 286, 270, 210, 271, 293, 317, 325, 248, 147, 148, 223, 204, 178, 119, 72, 107, 153, 232, 260,
+ 274, 100, 13, 319, 272, 329, 261, 397, 210, 271, 293, 231, 325, 268, 136, 317, 189, 165, 106, 207, 223, 204,
+ 397, 115, 68, 107, 84, 327, 85, 397, 100, 103, 441, 272, 329, 290, 86, 210, 271, 293, 87, 325, 299, 299, 441,
+ 317, 299, 155, 299, 299, 223, 204, 305, 119, 50, 102, 299, 108, 299, 299, 100, 299, 299, 272, 329, 299, 299,
+ 210, 271, 293, 317, 325, 299, 299, 299, 223, 204, 299, 119, 72, 107, 299, 299, 299, 299, 100, 27, 227, 272, 329,
+ 160, 299, 210, 271, 293, 299, 325, 299, 299, 317, 299, 299, 299, 203, 223, 204, 299, 109, 46, 107, 299, 299,
+ 299, 299, 100, 299, 299, 272, 329, 299, 308, 210, 271, 293, 299, 325, 299, 311, 287, 8, 309, 299, 273, 299, 317,
+ 2, 82, 299, 299, 223, 204, 110, 119, 49, 107, 229, 299, 258, 217, 100, 299, 142, 272, 329, 299, 178, 210, 271,
+ 293, 299, 325, 260, 317, 299, 13, 319, 299, 223, 204, 299, 119, 70, 107, 299, 294, 23, 299, 100, 189, 299, 272,
+ 329, 299, 299, 210, 271, 293, 317, 325, 299, 299, 299, 223, 204, 299, 119, 77, 107, 299, 299, 299, 299, 100,
+ 299, 299, 272, 329, 299, 308, 210, 271, 293, 299, 325, 299, 299, 287, 8, 309, 299, 273, 299, 317, 2, 82, 299,
+ 299, 223, 204, 110, 119, 71, 107, 229, 299, 258, 217, 100, 299, 299, 272, 329, 299, 299, 210, 271, 293, 299,
+ 325, 299, 317, 299, 299, 299, 299, 223, 204, 299, 119, 60, 107, 299, 295, 23, 299, 100, 299, 299, 272, 329, 299,
+ 299, 210, 271, 293, 317, 325, 299, 140, 299, 223, 204, 178, 119, 73, 107, 299, 299, 260, 299, 100, 13, 319, 272,
+ 329, 299, 299, 210, 271, 293, 299, 325, 317, 201, 299, 189, 299, 223, 204, 299, 119, 62, 107, 299, 41, 40, 38,
+ 100, 299, 299, 272, 329, 299, 299, 210, 271, 293, 299, 325, 317, 163, 321, 322, 328, 223, 204, 299, 119, 63,
+ 107, 299, 41, 40, 38, 100, 299, 299, 272, 329, 299, 299, 210, 271, 293, 299, 325, 317, 201, 321, 322, 328, 223,
+ 204, 299, 97, 69, 107, 299, 299, 299, 299, 100, 299, 299, 272, 329, 299, 299, 210, 271, 293, 299, 325, 317, 299,
+ 299, 299, 299, 223, 204, 299, 119, 75, 107, 222, 41, 40, 38, 100, 299, 299, 272, 329, 299, 299, 210, 271, 293,
+ 299, 325, 317, 201, 321, 322, 328, 223, 204, 299, 119, 64, 107, 299, 247, 299, 299, 100, 299, 299, 272, 329,
+ 299, 299, 210, 271, 293, 299, 325, 317, 201, 26, 299, 299, 223, 204, 299, 98, 74, 107, 299, 41, 40, 38, 100,
+ 299, 299, 272, 329, 299, 299, 210, 271, 293, 299, 325, 317, 201, 321, 322, 328, 223, 198, 299, 105, 59, 107,
+ 299, 41, 40, 38, 100, 299, 299, 272, 329, 299, 299, 210, 271, 293, 299, 325, 317, 299, 321, 322, 328, 223, 204,
+ 299, 119, 45, 107, 246, 41, 40, 38, 100, 299, 299, 272, 329, 299, 299, 210, 271, 293, 299, 325, 317, 201, 321,
+ 322, 328, 223, 94, 299, 79, 48, 101, 299, 252, 299, 299, 100, 299, 299, 272, 329, 299, 299, 210, 271, 293, 299,
+ 325, 317, 299, 299, 299, 299, 223, 204, 299, 119, 56, 107, 299, 41, 40, 38, 100, 299, 299, 272, 329, 299, 299,
+ 210, 271, 293, 299, 325, 317, 201, 321, 322, 328, 223, 204, 299, 119, 61, 107, 299, 190, 299, 299, 100, 299,
+ 299, 272, 329, 299, 299, 210, 271, 293, 299, 325, 317, 299, 299, 299, 299, 223, 204, 299, 96, 58, 107, 299, 41,
+ 40, 38, 100, 299, 299, 272, 329, 299, 299, 210, 271, 293, 299, 325, 317, 201, 321, 322, 328, 223, 204, 299, 119,
+ 66, 107, 299, 188, 299, 299, 100, 299, 299, 272, 329, 299, 299, 210, 271, 293, 299, 325, 317, 201, 299, 299,
+ 299, 223, 204, 299, 119, 47, 107, 299, 41, 40, 38, 100, 299, 299, 272, 329, 299, 299, 210, 271, 293, 299, 325,
+ 317, 299, 321, 322, 328, 223, 204, 299, 119, 78, 107, 299, 41, 40, 38, 100, 299, 299, 272, 329, 299, 299, 210,
+ 271, 293, 299, 325, 317, 299, 321, 322, 328, 223, 204, 299, 119, 54, 107, 299, 299, 299, 299, 100, 299, 299,
+ 272, 329, 299, 299, 210, 271, 293, 299, 325, 317, 299, 299, 299, 299, 223, 204, 299, 119, 53, 107, 299, 299,
+ 299, 299, 100, 299, 299, 272, 329, 299, 299, 210, 271, 293, 299, 325, 317, 299, 299, 299, 299, 223, 95, 299, 79,
+ 44, 101, 299, 299, 299, 299, 100, 299, 299, 272, 329, 299, 299, 210, 271, 293, 299, 325, 317, 299, 299, 299,
+ 299, 223, 197, 299, 119, 57, 107, 299, 299, 299, 299, 100, 299, 299, 272, 329, 299, 299, 210, 271, 293, 299,
+ 325, 317, 299, 299, 299, 299, 223, 204, 299, 119, 76, 107, 299, 299, 299, 299, 100, 299, 299, 272, 329, 299,
+ 299, 210, 271, 293, 299, 325, 317, 299, 299, 299, 299, 223, 204, 299, 119, 55, 107, 299, 299, 299, 299, 100,
+ 299, 299, 272, 329, 299, 299, 210, 271, 293, 299, 325, 317, 299, 299, 299, 299, 223, 204, 299, 119, 67, 107,
+ 299, 299, 299, 299, 100, 299, 299, 272, 329, 299, 299, 210, 271, 293, 299, 325, 317, 299, 299, 299, 299, 223,
+ 234, 299, 122, 299, 107, 299, 299, 299, 299, 100, 299, 299, 299, 320, 299, 299, 210, 271, 293, 299, 325, 317,
+ 409, 409, 299, 299, 223, 234, 299, 127, 299, 107, 299, 299, 299, 299, 100, 299, 299, 299, 250, 299, 299, 210,
+ 271, 293, 299, 325, 524, 51, 253, 281, 282, 216, 299, 299, 223, 299, 441, 317, 409, 409, 409, 201, 223, 234,
+ 299, 126, 299, 107, 441, 299, 299, 299, 100, 299, 299, 409, 409, 409, 299, 210, 271, 293, 201, 325, 299, 33,
+ 299, 12, 299, 299, 299, 299, 299, 301, 17, 299, 299, 299, 299, 41, 40, 38, 299, 299, 317, 299, 299, 299, 12,
+ 223, 234, 299, 123, 299, 107, 17, 321, 322, 328, 100, 41, 40, 38, 299, 299, 299, 210, 271, 293, 299, 325, 299,
+ 299, 403, 299, 299, 299, 321, 322, 328, 299, 317, 299, 403, 299, 403, 223, 234, 403, 118, 299, 107, 299, 299,
+ 299, 403, 100, 403, 299, 403, 299, 299, 299, 210, 271, 293, 317, 325, 232, 299, 299, 223, 234, 299, 125, 299,
+ 107, 299, 299, 226, 299, 100, 299, 201, 299, 299, 299, 299, 210, 271, 293, 470, 325, 317, 201, 470, 454, 226,
+ 223, 234, 299, 120, 299, 107, 299, 299, 299, 299, 100, 470, 299, 30, 299, 470, 454, 210, 271, 293, 201, 325, 12,
+ 41, 40, 38, 454, 299, 454, 17, 470, 299, 454, 314, 41, 40, 38, 299, 315, 299, 321, 322, 328, 201, 454, 34, 454,
+ 299, 470, 299, 454, 321, 322, 328, 299, 299, 226, 470, 41, 40, 38, 470, 454, 299, 114, 299, 299, 299, 470, 299,
+ 299, 299, 470, 454, 299, 321, 322, 328, 299, 302, 299, 41, 40, 38, 201, 299, 299, 299, 299, 299, 454, 299, 454,
+ 299, 470, 365, 454, 299, 321, 322, 328, 454, 221, 454, 299, 470, 299, 454, 166, 299, 12, 299, 178, 299, 299,
+ 299, 299, 17, 260, 299, 441, 13, 319, 162, 299, 11, 196, 178, 299, 266, 137, 299, 441, 260, 178, 189, 13, 319,
+ 299, 299, 260, 299, 299, 13, 319, 299, 267, 299, 299, 299, 189, 299, 299, 299, 299, 299, 299, 189, 299, 299,
+ 299, 299, 299, 299, 299, 299, 311,);
+
+ static public $yy_lookahead = array(13, 14, 15, 15, 17, 18, 37, 20, 21, 64, 65, 66, 67, 26, 12, 70, 47, 30, 49, 32,
+ 33, 27, 35, 54, 37, 23, 23, 40, 34, 27, 29, 44, 45, 46, 47, 48, 34, 50, 37, 52, 53, 54, 55, 55, 42, 42, 59, 13,
+ 14, 15, 49, 17, 18, 76, 20, 21, 93, 14, 95, 96, 26, 18, 85, 86, 30, 31, 32, 33, 16, 35, 27, 37, 29, 23, 40, 23,
+ 99, 34, 44, 45, 46, 47, 48, 75, 50, 77, 52, 53, 80, 55, 72, 37, 42, 59, 13, 14, 15, 1, 17, 18, 82, 20, 21, 49,
+ 14, 72, 18, 26, 18, 76, 60, 30, 94, 32, 33, 82, 35, 27, 37, 29, 36, 40, 38, 27, 34, 44, 45, 46, 47, 48, 34, 50,
+ 99, 52, 53, 36, 55, 81, 23, 51, 59, 13, 14, 15, 47, 17, 18, 14, 20, 21, 53, 18, 72, 54, 26, 12, 76, 42, 30, 65,
+ 32, 33, 82, 35, 70, 37, 23, 14, 40, 54, 27, 18, 44, 45, 46, 47, 48, 34, 50, 99, 52, 53, 14, 55, 51, 42, 18, 59,
+ 13, 14, 15, 1, 17, 18, 23, 20, 21, 103, 104, 47, 1, 26, 12, 47, 51, 30, 54, 32, 33, 53, 35, 12, 37, 15, 1, 40,
+ 18, 27, 28, 44, 45, 46, 47, 48, 34, 50, 27, 52, 53, 18, 55, 72, 19, 34, 59, 13, 14, 15, 1, 17, 18, 82, 20, 21,
+ 75, 1, 77, 78, 26, 80, 52, 19, 30, 55, 32, 33, 12, 35, 99, 37, 14, 50, 40, 16, 18, 14, 44, 45, 46, 47, 48, 27,
+ 50, 27, 52, 53, 92, 55, 34, 47, 34, 59, 13, 14, 15, 53, 17, 18, 37, 20, 21, 54, 14, 72, 47, 26, 18, 76, 72, 30,
+ 53, 32, 33, 82, 35, 27, 37, 16, 82, 40, 19, 37, 34, 44, 45, 46, 47, 48, 54, 50, 99, 52, 53, 49, 55, 99, 95, 96,
+ 59, 13, 14, 15, 1, 17, 18, 14, 20, 21, 81, 18, 49, 16, 26, 12, 19, 72, 30, 75, 32, 33, 71, 35, 80, 37, 75, 82,
+ 40, 15, 27, 80, 44, 45, 46, 47, 48, 34, 50, 94, 52, 53, 91, 55, 51, 80, 49, 59, 13, 14, 15, 37, 17, 18, 72, 20,
+ 21, 9, 10, 11, 22, 26, 97, 96, 82, 30, 65, 32, 33, 55, 35, 70, 37, 100, 36, 40, 94, 37, 35, 44, 45, 46, 47, 48,
+ 76, 50, 76, 52, 53, 49, 55, 72, 1, 16, 59, 13, 14, 15, 2, 17, 18, 82, 20, 21, 36, 104, 38, 99, 26, 99, 100, 1,
+ 30, 94, 32, 33, 75, 35, 77, 37, 29, 80, 40, 36, 47, 38, 44, 45, 46, 47, 48, 27, 50, 15, 52, 53, 18, 55, 34, 92,
+ 2, 59, 13, 14, 15, 76, 17, 18, 76, 20, 21, 90, 14, 19, 16, 26, 18, 19, 97, 30, 66, 32, 33, 69, 35, 90, 37, 15,
+ 99, 40, 99, 99, 97, 44, 45, 46, 47, 48, 92, 50, 94, 52, 19, 49, 55, 47, 14, 49, 59, 51, 18, 53, 3, 4, 5, 6, 7,
+ 8, 9, 92, 14, 94, 13, 14, 18, 19, 17, 55, 65, 20, 21, 95, 96, 70, 71, 26, 73, 74, 75, 30, 18, 32, 33, 80, 37, 1,
+ 83, 84, 72, 24, 87, 88, 89, 47, 91, 49, 12, 51, 82, 53, 18, 65, 72, 5, 101, 102, 70, 71, 18, 73, 74, 75, 82, 1,
+ 2, 38, 80, 18, 52, 83, 84, 18, 37, 87, 88, 89, 72, 91, 54, 72, 16, 52, 65, 18, 98, 92, 82, 70, 71, 82, 73, 74,
+ 75, 18, 77, 81, 18, 80, 18, 43, 83, 84, 12, 35, 87, 88, 89, 65, 91, 18, 72, 92, 70, 71, 76, 73, 74, 75, 92, 47,
+ 82, 82, 80, 85, 86, 83, 84, 94, 12, 87, 88, 89, 16, 91, 93, 80, 65, 99, 92, 79, 98, 70, 71, 27, 73, 74, 75, 80,
+ 87, 80, 34, 80, 68, 37, 83, 84, 10, 80, 87, 88, 89, 80, 91, 105, 105, 49, 65, 105, 92, 105, 105, 70, 71, 102,
+ 73, 74, 75, 105, 77, 105, 105, 80, 105, 105, 83, 84, 105, 105, 87, 88, 89, 65, 91, 105, 105, 105, 70, 71, 105,
+ 73, 74, 75, 105, 105, 105, 105, 80, 14, 15, 83, 84, 18, 105, 87, 88, 89, 105, 91, 105, 105, 65, 105, 105, 105,
+ 98, 70, 71, 105, 73, 74, 75, 105, 105, 105, 105, 80, 105, 105, 83, 84, 105, 5, 87, 88, 89, 105, 91, 105, 55, 13,
+ 14, 15, 105, 17, 105, 65, 20, 21, 105, 105, 70, 71, 26, 73, 74, 75, 30, 105, 32, 33, 80, 105, 72, 83, 84, 105,
+ 76, 87, 88, 89, 105, 91, 82, 65, 105, 85, 86, 105, 70, 71, 105, 73, 74, 75, 105, 59, 60, 105, 80, 99, 105, 83,
+ 84, 105, 105, 87, 88, 89, 65, 91, 105, 105, 105, 70, 71, 105, 73, 74, 75, 105, 105, 105, 105, 80, 105, 105, 83,
+ 84, 105, 5, 87, 88, 89, 105, 91, 105, 105, 13, 14, 15, 105, 17, 105, 65, 20, 21, 105, 105, 70, 71, 26, 73, 74,
+ 75, 30, 105, 32, 33, 80, 105, 105, 83, 84, 105, 105, 87, 88, 89, 105, 91, 105, 65, 105, 105, 105, 105, 70, 71,
+ 105, 73, 74, 75, 105, 59, 60, 105, 80, 105, 105, 83, 84, 105, 105, 87, 88, 89, 65, 91, 105, 72, 105, 70, 71, 76,
+ 73, 74, 75, 105, 105, 82, 105, 80, 85, 86, 83, 84, 105, 105, 87, 88, 89, 105, 91, 65, 1, 105, 99, 105, 70, 71,
+ 105, 73, 74, 75, 105, 39, 40, 41, 80, 105, 105, 83, 84, 105, 105, 87, 88, 89, 105, 91, 65, 28, 56, 57, 58, 70,
+ 71, 105, 73, 74, 75, 105, 39, 40, 41, 80, 105, 105, 83, 84, 105, 105, 87, 88, 89, 105, 91, 65, 1, 56, 57, 58,
+ 70, 71, 105, 73, 74, 75, 105, 105, 105, 105, 80, 105, 105, 83, 84, 105, 105, 87, 88, 89, 105, 91, 65, 105, 105,
+ 105, 105, 70, 71, 105, 73, 74, 75, 38, 39, 40, 41, 80, 105, 105, 83, 84, 105, 105, 87, 88, 89, 105, 91, 65, 1,
+ 56, 57, 58, 70, 71, 105, 73, 74, 75, 105, 12, 105, 105, 80, 105, 105, 83, 84, 105, 105, 87, 88, 89, 105, 91, 65,
+ 1, 2, 105, 105, 70, 71, 105, 73, 74, 75, 105, 39, 40, 41, 80, 105, 105, 83, 84, 105, 105, 87, 88, 89, 105, 91,
+ 65, 1, 56, 57, 58, 70, 71, 105, 73, 74, 75, 105, 39, 40, 41, 80, 105, 105, 83, 84, 105, 105, 87, 88, 89, 105,
+ 91, 65, 105, 56, 57, 58, 70, 71, 105, 73, 74, 75, 38, 39, 40, 41, 80, 105, 105, 83, 84, 105, 105, 87, 88, 89,
+ 105, 91, 65, 1, 56, 57, 58, 70, 71, 105, 73, 74, 75, 105, 12, 105, 105, 80, 105, 105, 83, 84, 105, 105, 87, 88,
+ 89, 105, 91, 65, 105, 105, 105, 105, 70, 71, 105, 73, 74, 75, 105, 39, 40, 41, 80, 105, 105, 83, 84, 105, 105,
+ 87, 88, 89, 105, 91, 65, 1, 56, 57, 58, 70, 71, 105, 73, 74, 75, 105, 12, 105, 105, 80, 105, 105, 83, 84, 105,
+ 105, 87, 88, 89, 105, 91, 65, 105, 105, 105, 105, 70, 71, 105, 73, 74, 75, 105, 39, 40, 41, 80, 105, 105, 83,
+ 84, 105, 105, 87, 88, 89, 105, 91, 65, 1, 56, 57, 58, 70, 71, 105, 73, 74, 75, 105, 12, 105, 105, 80, 105, 105,
+ 83, 84, 105, 105, 87, 88, 89, 105, 91, 65, 1, 105, 105, 105, 70, 71, 105, 73, 74, 75, 105, 39, 40, 41, 80, 105,
+ 105, 83, 84, 105, 105, 87, 88, 89, 105, 91, 65, 105, 56, 57, 58, 70, 71, 105, 73, 74, 75, 105, 39, 40, 41, 80,
+ 105, 105, 83, 84, 105, 105, 87, 88, 89, 105, 91, 65, 105, 56, 57, 58, 70, 71, 105, 73, 74, 75, 105, 105, 105,
+ 105, 80, 105, 105, 83, 84, 105, 105, 87, 88, 89, 105, 91, 65, 105, 105, 105, 105, 70, 71, 105, 73, 74, 75, 105,
+ 105, 105, 105, 80, 105, 105, 83, 84, 105, 105, 87, 88, 89, 105, 91, 65, 105, 105, 105, 105, 70, 71, 105, 73, 74,
+ 75, 105, 105, 105, 105, 80, 105, 105, 83, 84, 105, 105, 87, 88, 89, 105, 91, 65, 105, 105, 105, 105, 70, 71,
+ 105, 73, 74, 75, 105, 105, 105, 105, 80, 105, 105, 83, 84, 105, 105, 87, 88, 89, 105, 91, 65, 105, 105, 105,
+ 105, 70, 71, 105, 73, 74, 75, 105, 105, 105, 105, 80, 105, 105, 83, 84, 105, 105, 87, 88, 89, 105, 91, 65, 105,
+ 105, 105, 105, 70, 71, 105, 73, 74, 75, 105, 105, 105, 105, 80, 105, 105, 83, 84, 105, 105, 87, 88, 89, 105, 91,
+ 65, 105, 105, 105, 105, 70, 71, 105, 73, 74, 75, 105, 105, 105, 105, 80, 105, 105, 83, 84, 105, 105, 87, 88, 89,
+ 105, 91, 65, 105, 105, 105, 105, 70, 71, 105, 73, 105, 75, 105, 105, 105, 105, 80, 105, 105, 105, 84, 105, 105,
+ 87, 88, 89, 105, 91, 65, 1, 2, 105, 105, 70, 71, 105, 73, 105, 75, 105, 105, 105, 105, 80, 105, 105, 105, 84,
+ 105, 105, 87, 88, 89, 105, 91, 62, 63, 64, 65, 66, 67, 105, 105, 70, 105, 37, 65, 39, 40, 41, 1, 70, 71, 105,
+ 73, 105, 75, 49, 105, 105, 105, 80, 105, 105, 56, 57, 58, 105, 87, 88, 89, 1, 91, 105, 25, 105, 27, 105, 105,
+ 105, 105, 105, 12, 34, 105, 105, 105, 105, 39, 40, 41, 105, 105, 65, 105, 105, 105, 27, 70, 71, 105, 73, 105,
+ 75, 34, 56, 57, 58, 80, 39, 40, 41, 105, 105, 105, 87, 88, 89, 105, 91, 105, 105, 12, 105, 105, 105, 56, 57, 58,
+ 105, 65, 105, 22, 105, 24, 70, 71, 27, 73, 105, 75, 105, 105, 105, 34, 80, 36, 105, 38, 105, 105, 105, 87, 88,
+ 89, 65, 91, 47, 105, 105, 70, 71, 105, 73, 105, 75, 105, 105, 2, 105, 80, 105, 1, 105, 105, 105, 105, 87, 88,
+ 89, 14, 91, 65, 1, 18, 19, 2, 70, 71, 105, 73, 105, 75, 105, 105, 105, 105, 80, 14, 105, 16, 105, 18, 19, 87,
+ 88, 89, 1, 91, 27, 39, 40, 41, 47, 105, 49, 34, 51, 105, 53, 54, 39, 40, 41, 105, 54, 105, 56, 57, 58, 1, 47, 2,
+ 49, 105, 51, 105, 53, 56, 57, 58, 105, 105, 2, 14, 39, 40, 41, 18, 19, 105, 22, 105, 105, 105, 14, 105, 105,
+ 105, 18, 19, 105, 56, 57, 58, 105, 60, 105, 39, 40, 41, 1, 105, 105, 105, 105, 105, 47, 105, 49, 105, 51, 12,
+ 53, 105, 56, 57, 58, 47, 19, 49, 105, 51, 105, 53, 72, 105, 27, 105, 76, 105, 105, 105, 105, 34, 82, 105, 37,
+ 85, 86, 72, 105, 14, 15, 76, 105, 18, 72, 105, 49, 82, 76, 99, 85, 86, 105, 105, 82, 105, 105, 85, 86, 105, 35,
+ 105, 105, 105, 99, 105, 105, 105, 105, 105, 105, 99, 105, 105, 105, 105, 105, 105, 105, 105, 55,);
+
+ const YY_SHIFT_USE_DFLT = -32;
+
+ const YY_SHIFT_MAX = 236;
+
+ static public $yy_shift_ofst = array(517, 410, 316, 81, 81, 316, 81, 410, 34, 34, -13, 81, 128, 81, 81, 128, 81,
+ 81, 269, 81, 81, 81, 175, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 363, 81, 81, 222, 222, 457, 457, 457, 457,
+ 457, 1624, 1603, 1736, 1736, 1736, 1736, 1736, 517, 754, 1211, 1265, 1076, 1157, 1760, 941, 1725, 995, 1103,
+ 1049, 1783, 1292, 1824, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 914, 914, 199, 198,
+ 96, 342, 842, 90, 43, 278, 246, 96, 96, 342, 232, 342, 580, 2, 143, 190, 244, 331, 711, 321, 325, 291, 376, 446,
+ 237, -6, 462, -6, 552, 432, 213, 500, 500, 480, 419, 446, 438, 438, 438, 438, 491, 438, 438, 491, 438, 438,
+ -32, 1738, 1720, 466, 1784, 1795, 514, 1852, 247, 153, -6, -6, -6, -6, -6, -6, 97, -12, 168, -6, -6,
+ 97, 97, -6, 156, 156, 97, 52, 97, -6, -6, -6, 97, 251, 97, -6, -12, -6, 97, -6, -6, -12, -6, -12,
+ -6, 211, -6, 664, 438, 491, 438, 438, 438, 424, 438, 491, 515, 491, 424, -32, -32, -32, -32, -32, 1562,
+ 1664, 634, -31, 1, 133, 50, 115, 152, 99, 88, 366, 84, 3, 405, 54, 415, 396, 274, 368, 553, 571, 542, 582, 534,
+ 566, 558, 545, 567, 547, 583, 574, 608, 586, 590, 598, 515, 550, 593, 596, 609, 371, 264, 171, 533, 530,);
+
+ const YY_REDUCE_USE_DFLT = -56;
+
+ const YY_REDUCE_MAX = 190;
+
+ static public $yy_reduce_ofst = array(1527, 471, 619, 560, 644, 535, 504, 589, 1335, 1092, 1038, 1119, 1011, 984,
+ 876, 1173, 903, 930, 957, 1146, 1200, 1443, 1416, 1362, 1227, 1389, 1254, 1281, 1308, 1065, 673, 849, 824, 708,
+ 761, 736, 796, 1497, 1470, 1619, 1535, 1671, 1644, 1582, 1792, 1777, 1799, 845, 1792, 718, 556, -55, 94, -23,
+ -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, 33, -23, -23, -23, -23, -23, -23, -23,
+ -23, -23, -23, -23, -23, -23, 221, 279, 80, 169, 329, 347, 310, 18, 273, 159, 226, 8, -37, 369, 338, 525,
+ 525, 336, 336, 336, 293, 414, 231, 231, 422, 389, 336, 522, 231, 498, 336, 484, 400, 435, 414, 272, 336, 403,
+ 397, 336, 336, 336, 444, 336, 336, 231, 336, 336, 336, 184, 184, 184, 184, 184, 184, 573, 184, 551, 557, 557,
+ 557, 557, 557, 557, 559, 585, 184, 557, 557, 559, 559, 557, 544, 564, 559, 578, 559, 557, 557, 557, 559, 594,
+ 559, 557, 587, 557, 559, 557, 557, 595, 557, 599, 557, 579, 557, 602, 399, 295, 399, 399, 399, 301, 399, 295,
+ 375, 295, 301, 257, 56, 537, 532, 511,);
+
+ static public $yyExpectedTokens = array(array(3, 4, 5, 6, 7, 8, 9, 13, 14, 17, 20, 21, 26, 30, 32, 33,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 31, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 31, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 54, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 53, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 55, 59,),
+ array(13, 14, 15, 17, 18, 20, 21, 26, 30, 32, 33, 35, 37, 40, 44, 45, 46, 47, 48, 50, 52, 55, 59,),
+ array(1, 12, 27, 34, 39, 40, 41, 56, 57, 58,), array(1, 25, 27, 34, 39, 40, 41, 56, 57, 58,),
+ array(1, 27, 34, 39, 40, 41, 56, 57, 58,), array(1, 27, 34, 39, 40, 41, 56, 57, 58,),
+ array(1, 27, 34, 39, 40, 41, 56, 57, 58,), array(1, 27, 34, 39, 40, 41, 56, 57, 58,),
+ array(1, 27, 34, 39, 40, 41, 56, 57, 58,), array(3, 4, 5, 6, 7, 8, 9, 13, 14, 17, 20, 21, 26, 30, 32, 33,),
+ array(5, 13, 14, 15, 17, 20, 21, 26, 30, 32, 33, 59, 60,), array(1, 12, 39, 40, 41, 56, 57, 58,),
+ array(1, 12, 39, 40, 41, 56, 57, 58,), array(1, 2, 39, 40, 41, 56, 57, 58,),
+ array(1, 12, 39, 40, 41, 56, 57, 58,), array(1, 39, 40, 41, 56, 57, 58, 60,),
+ array(1, 28, 39, 40, 41, 56, 57, 58,), array(1, 39, 40, 41, 54, 56, 57, 58,),
+ array(1, 38, 39, 40, 41, 56, 57, 58,), array(1, 38, 39, 40, 41, 56, 57, 58,),
+ array(1, 12, 39, 40, 41, 56, 57, 58,), array(1, 22, 39, 40, 41, 56, 57, 58,), array(1, 39, 40, 41, 56, 57, 58,),
+ array(1, 12, 19, 27, 34, 37, 49,), array(1, 39, 40, 41, 56, 57, 58,), array(1, 39, 40, 41, 56, 57, 58,),
+ array(1, 39, 40, 41, 56, 57, 58,), array(1, 39, 40, 41, 56, 57, 58,), array(1, 39, 40, 41, 56, 57, 58,),
+ array(1, 39, 40, 41, 56, 57, 58,), array(1, 39, 40, 41, 56, 57, 58,), array(1, 39, 40, 41, 56, 57, 58,),
+ array(1, 39, 40, 41, 56, 57, 58,), array(1, 39, 40, 41, 56, 57, 58,), array(1, 39, 40, 41, 56, 57, 58,),
+ array(39, 40, 41, 56, 57, 58,), array(39, 40, 41, 56, 57, 58,), array(1, 12, 27, 34,), array(15, 18, 52, 55,),
+ array(1, 27, 34,), array(15, 37, 55,), array(5, 13, 14, 15, 17, 20, 21, 26, 30, 32, 33, 59, 60,),
+ array(14, 18, 27, 29, 34,), array(14, 18, 27, 29, 34,), array(14, 18, 27, 34,), array(14, 18, 27, 34,),
+ array(1, 27, 34,), array(1, 27, 34,), array(15, 37, 55,), array(19, 47, 53,), array(15, 37, 55,), array(1, 2,),
+ array(12, 23, 27, 34, 42,), array(12, 23, 27, 34, 42,), array(1, 12, 27, 28, 34,), array(1, 12, 27, 34,),
+ array(1, 12, 27, 34,), array(14, 15, 18, 55,), array(14, 18, 51,), array(16, 19, 49,), array(16, 19, 49,),
+ array(9, 10, 11,), array(15, 18,), array(1, 54,), array(27, 34,), array(19, 49,), array(27, 34,), array(1, 12,),
+ array(27, 34,), array(1, 19,), array(14, 18,), array(14, 18,), array(15, 55,), array(1, 29,), array(15, 18,),
+ array(1,), array(1,), array(1,), array(1,), array(19,), array(1,), array(1,), array(19,), array(1,), array(1,),
+ array(), array(2, 14, 16, 18, 19, 47, 49, 51, 53,), array(2, 14, 18, 19, 47, 49, 51, 53, 54,),
+ array(2, 14, 16, 18, 19, 47, 49, 51, 53,), array(2, 14, 18, 19, 47, 49, 51, 53,),
+ array(2, 14, 18, 19, 47, 49, 51, 53,), array(14, 18, 19, 47, 49, 51, 53,), array(14, 15, 18, 35, 55,),
+ array(16, 47, 53,), array(14, 18, 51,), array(27, 34,), array(27, 34,), array(27, 34,), array(27, 34,),
+ array(27, 34,), array(27, 34,), array(47, 53,), array(15, 55,), array(14, 18,), array(27, 34,), array(27, 34,),
+ array(47, 53,), array(47, 53,), array(27, 34,), array(47, 53,), array(47, 53,), array(47, 53,), array(16, 23,),
+ array(47, 53,), array(27, 34,), array(27, 34,), array(27, 34,), array(47, 53,), array(14, 37,), array(47, 53,),
+ array(27, 34,), array(15, 55,), array(27, 34,), array(47, 53,), array(27, 34,), array(27, 34,), array(15, 55,),
+ array(27, 34,), array(15, 55,), array(27, 34,), array(18, 50,), array(27, 34,), array(10,), array(1,),
+ array(19,), array(1,), array(1,), array(1,), array(2,), array(1,), array(19,), array(37,), array(19,),
+ array(2,), array(), array(), array(), array(), array(), array(1, 2, 37, 39, 40, 41, 49, 56, 57, 58,),
+ array(12, 22, 24, 27, 34, 36, 38, 47,), array(12, 16, 27, 34, 37, 49,), array(37, 47, 49, 54,),
+ array(29, 37, 49,), array(14, 18, 51,), array(23, 42, 60,), array(23, 42, 54,), array(47, 54,), array(36, 54,),
+ array(18, 51,), array(22, 36,), array(36, 38,), array(23, 42,), array(16, 47,), array(37, 49,), array(36, 38,),
+ array(36, 38,), array(37, 49,), array(37, 49,), array(37,), array(18,), array(54,), array(16,), array(52,),
+ array(5,), array(18,), array(38,), array(18,), array(52,), array(18,), array(43,), array(12,), array(35,),
+ array(47,), array(18,), array(37,), array(18,), array(18,), array(18,), array(18,), array(35,), array(54,),
+ array(23,), array(24,), array(18,), array(), array(), array(), array(), array(), array(), array(), array(),
+ array(), array(), array(), array(), array(), array(), array(), array(), array(), array(), array(), array(),
+ array(), array(), array(), array(), array(), array(), array(), array(), array(), array(), array(), array(),
+ array(), array(), array(), array(), array(), array(), array(), array(), array(), array(), array(), array(),
+ array(), array(), array(), array(), array(), array(), array(), array(), array(), array(), array(), array(),
+ array(), array(), array(), array(), array(), array(), array(), array(), array(), array(), array(), array(),
+ array(), array(), array(), array(), array(), array(), array(), array(), array(), array(), array(), array(),
+ array(), array(), array(), array(), array(), array(), array(), array(), array(), array(), array(), array(),
+ array(), array(),);
+
+ static public $yy_default = array(334, 508, 523, 488, 488, 523, 488, 523, 523, 523, 523, 523, 523, 523, 523, 523,
+ 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523,
+ 523, 523, 523, 523, 523, 523, 523, 393, 360, 393, 357, 393, 369, 331, 523, 523, 523, 523, 523, 523, 398, 523,
+ 523, 523, 523, 523, 414, 431, 405, 400, 511, 395, 509, 486, 487, 374, 398, 404, 510, 419, 420, 407, 523, 393,
+ 523, 523, 393, 393, 393, 393, 393, 393, 523, 500, 523, 383, 421, 421, 407, 407, 407, 523, 454, 444, 444, 523,
+ 523, 407, 393, 444, 371, 407, 393, 387, 454, 454, 523, 407, 523, 389, 422, 407, 410, 497, 417, 423, 444, 424,
+ 411, 495, 443, 443, 443, 443, 443, 443, 523, 470, 456, 361, 378, 372, 362, 364, 377, 451, 523, 454, 356, 370,
+ 480, 481, 373, 447, 449, 448, 523, 478, 367, 366, 368, 479, 454, 452, 358, 523, 380, 450, 376, 354, 523, 382,
+ 523, 379, 523, 381, 348, 384, 498, 390, 413, 388, 489, 438, 475, 454, 501, 490, 494, 494, 454, 494, 454, 431,
+ 427, 431, 431, 431, 455, 421, 421, 427, 523, 523, 523, 523, 421, 427, 439, 523, 523, 431, 523, 499, 523, 523,
+ 523, 523, 339, 523, 523, 523, 523, 523, 433, 523, 523, 427, 523, 470, 523, 523, 523, 523, 429, 434, 421, 401,
+ 523, 464, 483, 375, 461, 484, 406, 463, 469, 462, 433, 474, 394, 402, 496, 470, 460, 332, 445, 491, 492, 425,
+ 386, 493, 392, 472, 473, 426, 428, 457, 458, 459, 453, 409, 430, 432, 408, 363, 391, 341, 340, 342, 338, 337,
+ 333, 335, 336, 343, 344, 350, 351, 352, 349, 347, 345, 346, 434, 435, 512, 513, 514, 385, 476, 485, 519, 520,
+ 517, 516, 505, 507, 506, 515, 522, 518, 521, 471, 477, 467, 465, 468, 440, 437, 436, 415, 416, 502, 503, 442,
+ 466, 446, 441, 418, 504, 412, 482,);
+
+ const YYNOCODE = 106;
+
+ const YYSTACKDEPTH = 500;
+
+ const YYNSTATE = 331;
+
+ const YYNRULE = 192;
+
+ const YYERRORSYMBOL = 61;
+
+ const YYERRSYMDT = 'yy0';
+
+ const YYFALLBACK = 0;
+
+ public static $yyFallback = array();
+
+ public function Trace($TraceFILE, $zTracePrompt) {
+ if (!$TraceFILE) {
+ $zTracePrompt = 0;
+ } elseif (!$zTracePrompt) {
+ $TraceFILE = 0;
+ }
+ $this->yyTraceFILE = $TraceFILE;
+ $this->yyTracePrompt = $zTracePrompt;
+ }
+
+ public function PrintTrace() {
+ $this->yyTraceFILE = fopen('php://output', 'w');
+ $this->yyTracePrompt = '<br>';
+ }
+
+ public $yyTraceFILE;
+
+ public $yyTracePrompt;
+
+ public $yyidx; /* Index of top element in stack */
+ public $yyerrcnt; /* Shifts left before out of the error */
+ public $yystack = array(); /* The parser's stack */
+
+ public $yyTokenName = array('$', 'VERT', 'COLON', 'PHP', 'NOCACHE', 'TEXT', 'STRIPON', 'STRIPOFF', 'BLOCKSOURCE',
+ 'LITERALSTART', 'LITERALEND', 'LITERAL', 'RDEL', 'SIMPLEOUTPUT', 'LDEL', 'DOLLARID', 'EQUAL', 'SIMPLETAG', 'ID',
+ 'PTR', 'LDELIF', 'LDELFOR', 'SEMICOLON', 'INCDEC', 'TO', 'STEP', 'LDELFOREACH', 'SPACE', 'AS', 'APTR',
+ 'LDELSETFILTER', 'SMARTYBLOCKCHILDPARENT', 'CLOSETAG', 'LDELSLASH', 'ATTR', 'INTEGER', 'COMMA', 'OPENP',
+ 'CLOSEP', 'MATH', 'UNIMATH', 'ISIN', 'INSTANCEOF', 'QMARK', 'NOT', 'TYPECAST', 'HEX', 'DOT',
+ 'SINGLEQUOTESTRING', 'DOUBLECOLON', 'NAMESPACE', 'AT', 'HATCH', 'OPENB', 'CLOSEB', 'DOLLAR', 'LOGOP', 'TLOGOP',
+ 'SINGLECOND', 'QUOTE', 'BACKTICK', 'error', 'start', 'template', 'template_element', 'smartytag', 'literal',
+ 'text_content', 'literal_elements', 'literal_element', 'tag', 'variable', 'attributes', 'value', 'expr',
+ 'varindexed', 'modifierlist', 'statement', 'statements', 'foraction', 'varvar', 'modparameters', 'attribute',
+ 'ternary', 'array', 'lop', 'scond', 'ns1', 'function', 'doublequoted_with_quotes', 'static_class_access',
+ 'object', 'arrayindex', 'indexdef', 'varvarele', 'objectchain', 'objectelement', 'method', 'params', 'modifier',
+ 'modparameter', 'arrayelements', 'arrayelement', 'doublequoted', 'doublequotedcontent',);
+
+ public static $yyRuleName = array('start ::= template', 'template ::= template_element',
+ 'template ::= template template_element', 'template ::=', 'template_element ::= smartytag',
+ 'template_element ::= literal', 'template_element ::= PHP', 'template_element ::= NOCACHE',
+ 'template_element ::= text_content', 'text_content ::= TEXT', 'text_content ::= text_content TEXT',
+ 'template_element ::= STRIPON', 'template_element ::= STRIPOFF', 'template_element ::= BLOCKSOURCE',
+ 'literal ::= LITERALSTART LITERALEND', 'literal ::= LITERALSTART literal_elements LITERALEND',
+ 'literal_elements ::= literal_elements literal_element', 'literal_elements ::=', 'literal_element ::= literal',
+ 'literal_element ::= LITERAL', 'smartytag ::= tag RDEL', 'smartytag ::= SIMPLEOUTPUT', 'tag ::= LDEL variable',
+ 'tag ::= LDEL variable attributes', 'tag ::= LDEL value', 'tag ::= LDEL value attributes', 'tag ::= LDEL expr',
+ 'tag ::= LDEL expr attributes', 'tag ::= LDEL DOLLARID EQUAL value', 'tag ::= LDEL DOLLARID EQUAL expr',
+ 'tag ::= LDEL DOLLARID EQUAL expr attributes', 'tag ::= LDEL varindexed EQUAL expr attributes',
+ 'smartytag ::= SIMPLETAG', 'tag ::= LDEL ID attributes', 'tag ::= LDEL ID',
+ 'tag ::= LDEL ID modifierlist attributes', 'tag ::= LDEL ID PTR ID attributes',
+ 'tag ::= LDEL ID PTR ID modifierlist attributes', 'tag ::= LDELIF expr', 'tag ::= LDELIF expr attributes',
+ 'tag ::= LDELIF statement', 'tag ::= LDELIF statement attributes',
+ 'tag ::= LDELFOR statements SEMICOLON expr SEMICOLON varindexed foraction attributes',
+ 'foraction ::= EQUAL expr', 'foraction ::= INCDEC', 'tag ::= LDELFOR statement TO expr attributes',
+ 'tag ::= LDELFOR statement TO expr STEP expr attributes', 'tag ::= LDELFOREACH attributes',
+ 'tag ::= LDELFOREACH SPACE value AS varvar attributes',
+ 'tag ::= LDELFOREACH SPACE value AS varvar APTR varvar attributes',
+ 'tag ::= LDELFOREACH SPACE expr AS varvar attributes',
+ 'tag ::= LDELFOREACH SPACE expr AS varvar APTR varvar attributes', 'tag ::= LDELSETFILTER ID modparameters',
+ 'tag ::= LDELSETFILTER ID modparameters modifierlist', 'tag ::= LDEL SMARTYBLOCKCHILDPARENT',
+ 'smartytag ::= CLOSETAG', 'tag ::= LDELSLASH ID', 'tag ::= LDELSLASH ID modifierlist',
+ 'tag ::= LDELSLASH ID PTR ID', 'tag ::= LDELSLASH ID PTR ID modifierlist',
+ 'attributes ::= attributes attribute', 'attributes ::= attribute', 'attributes ::=',
+ 'attribute ::= SPACE ID EQUAL ID', 'attribute ::= ATTR expr', 'attribute ::= ATTR value',
+ 'attribute ::= SPACE ID', 'attribute ::= SPACE expr', 'attribute ::= SPACE value',
+ 'attribute ::= SPACE INTEGER EQUAL expr', 'statements ::= statement',
+ 'statements ::= statements COMMA statement', 'statement ::= DOLLARID EQUAL INTEGER',
+ 'statement ::= DOLLARID EQUAL expr', 'statement ::= varindexed EQUAL expr',
+ 'statement ::= OPENP statement CLOSEP', 'expr ::= value', 'expr ::= ternary', 'expr ::= DOLLARID COLON ID',
+ 'expr ::= expr MATH value', 'expr ::= expr UNIMATH value', 'expr ::= array', 'expr ::= expr modifierlist',
+ 'expr ::= expr lop expr', 'expr ::= expr scond', 'expr ::= expr ISIN array', 'expr ::= expr ISIN value',
+ 'expr ::= variable INSTANCEOF ns1', 'ternary ::= OPENP expr CLOSEP QMARK DOLLARID COLON expr',
+ 'ternary ::= OPENP expr CLOSEP QMARK expr COLON expr', 'value ::= variable', 'value ::= UNIMATH value',
+ 'value ::= NOT value', 'value ::= TYPECAST value', 'value ::= variable INCDEC', 'value ::= HEX',
+ 'value ::= INTEGER', 'value ::= INTEGER DOT INTEGER', 'value ::= INTEGER DOT', 'value ::= DOT INTEGER',
+ 'value ::= ID', 'value ::= function', 'value ::= OPENP expr CLOSEP', 'value ::= SINGLEQUOTESTRING',
+ 'value ::= doublequoted_with_quotes', 'value ::= varindexed DOUBLECOLON static_class_access',
+ 'value ::= smartytag', 'value ::= value modifierlist', 'value ::= NAMESPACE',
+ 'value ::= ns1 DOUBLECOLON static_class_access', 'ns1 ::= ID', 'ns1 ::= NAMESPACE', 'variable ::= DOLLARID',
+ 'variable ::= varindexed', 'variable ::= varvar AT ID', 'variable ::= object', 'variable ::= HATCH ID HATCH',
+ 'variable ::= HATCH ID HATCH arrayindex', 'variable ::= HATCH variable HATCH',
+ 'variable ::= HATCH variable HATCH arrayindex', 'varindexed ::= DOLLARID arrayindex',
+ 'varindexed ::= varvar arrayindex', 'arrayindex ::= arrayindex indexdef', 'arrayindex ::=',
+ 'indexdef ::= DOT DOLLARID', 'indexdef ::= DOT varvar', 'indexdef ::= DOT varvar AT ID', 'indexdef ::= DOT ID',
+ 'indexdef ::= DOT INTEGER', 'indexdef ::= DOT LDEL expr RDEL', 'indexdef ::= OPENB ID CLOSEB',
+ 'indexdef ::= OPENB ID DOT ID CLOSEB', 'indexdef ::= OPENB SINGLEQUOTESTRING CLOSEB',
+ 'indexdef ::= OPENB INTEGER CLOSEB', 'indexdef ::= OPENB DOLLARID CLOSEB', 'indexdef ::= OPENB variable CLOSEB',
+ 'indexdef ::= OPENB value CLOSEB', 'indexdef ::= OPENB expr CLOSEB', 'indexdef ::= OPENB CLOSEB',
+ 'varvar ::= DOLLARID', 'varvar ::= DOLLAR', 'varvar ::= varvar varvarele', 'varvarele ::= ID',
+ 'varvarele ::= LDEL expr RDEL', 'object ::= varindexed objectchain', 'objectchain ::= objectelement',
+ 'objectchain ::= objectchain objectelement', 'objectelement ::= PTR ID arrayindex',
+ 'objectelement ::= PTR varvar arrayindex', 'objectelement ::= PTR LDEL expr RDEL arrayindex',
+ 'objectelement ::= PTR ID LDEL expr RDEL arrayindex', 'objectelement ::= PTR method',
+ 'function ::= ns1 OPENP params CLOSEP', 'method ::= ID OPENP params CLOSEP',
+ 'method ::= DOLLARID OPENP params CLOSEP', 'params ::= params COMMA expr', 'params ::= expr', 'params ::=',
+ 'modifierlist ::= modifierlist modifier modparameters', 'modifierlist ::= modifier modparameters',
+ 'modifier ::= VERT AT ID', 'modifier ::= VERT ID', 'modparameters ::= modparameters modparameter',
+ 'modparameters ::=', 'modparameter ::= COLON value', 'modparameter ::= COLON array',
+ 'static_class_access ::= method', 'static_class_access ::= method objectchain', 'static_class_access ::= ID',
+ 'static_class_access ::= DOLLARID arrayindex', 'static_class_access ::= DOLLARID arrayindex objectchain',
+ 'lop ::= LOGOP', 'lop ::= TLOGOP', 'scond ::= SINGLECOND', 'array ::= OPENB arrayelements CLOSEB',
+ 'arrayelements ::= arrayelement', 'arrayelements ::= arrayelements COMMA arrayelement', 'arrayelements ::=',
+ 'arrayelement ::= value APTR expr', 'arrayelement ::= ID APTR expr', 'arrayelement ::= expr',
+ 'doublequoted_with_quotes ::= QUOTE QUOTE', 'doublequoted_with_quotes ::= QUOTE doublequoted QUOTE',
+ 'doublequoted ::= doublequoted doublequotedcontent', 'doublequoted ::= doublequotedcontent',
+ 'doublequotedcontent ::= BACKTICK variable BACKTICK', 'doublequotedcontent ::= BACKTICK expr BACKTICK',
+ 'doublequotedcontent ::= DOLLARID', 'doublequotedcontent ::= LDEL variable RDEL',
+ 'doublequotedcontent ::= LDEL expr RDEL', 'doublequotedcontent ::= smartytag', 'doublequotedcontent ::= TEXT',);
+
+ public function tokenName($tokenType) {
+ if ($tokenType === 0) {
+ return 'End of Input';
+ }
+ if ($tokenType > 0 && $tokenType < count($this->yyTokenName)) {
+ return $this->yyTokenName[$tokenType];
+ } else {
+ return "Unknown";
+ }
+ }
+
+ public static function yy_destructor($yymajor, $yypminor) {
+ switch ($yymajor) {
+ default:
+ break; /* If no destructor action specified: do nothing */
+ }
+ }
+
+ public function yy_pop_parser_stack() {
+ if (empty($this->yystack)) {
+ return;
+ }
+ $yytos = array_pop($this->yystack);
+ if ($this->yyTraceFILE && $this->yyidx >= 0) {
+ fwrite($this->yyTraceFILE, $this->yyTracePrompt . 'Popping ' . $this->yyTokenName[$yytos->major] . "\n");
+ }
+ $yymajor = $yytos->major;
+ self::yy_destructor($yymajor, $yytos->minor);
+ $this->yyidx--;
+
+ return $yymajor;
+ }
+
+ public function __destruct() {
+ while ($this->yystack !== Array()) {
+ $this->yy_pop_parser_stack();
+ }
+ if (is_resource($this->yyTraceFILE)) {
+ fclose($this->yyTraceFILE);
+ }
+ }
+
+ public function yy_get_expected_tokens($token) {
+ static $res3 = array();
+ static $res4 = array();
+ $state = $this->yystack[$this->yyidx]->stateno;
+ $expected = self::$yyExpectedTokens[$state];
+ if (isset($res3[$state][$token])) {
+ if ($res3[$state][$token]) {
+ return $expected;
+ }
+ } else {
+ if ($res3[$state][$token] = in_array($token, self::$yyExpectedTokens[$state], true)) {
+ return $expected;
+ }
+ }
+ $stack = $this->yystack;
+ $yyidx = $this->yyidx;
+ do {
+ $yyact = $this->yy_find_shift_action($token);
+ if ($yyact >= self::YYNSTATE && $yyact < self::YYNSTATE + self::YYNRULE) {
+ // reduce action
+ $done = 0;
+ do {
+ if ($done++ == 100) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ // too much recursion prevents proper detection
+ // so give up
+ return array_unique($expected);
+ }
+ $yyruleno = $yyact - self::YYNSTATE;
+ $this->yyidx -= self::$yyRuleInfo[$yyruleno][1];
+ $nextstate = $this->yy_find_reduce_action($this->yystack[$this->yyidx]->stateno, self::$yyRuleInfo[$yyruleno][0]);
+ if (isset(self::$yyExpectedTokens[$nextstate])) {
+ $expected = array_merge($expected, self::$yyExpectedTokens[$nextstate]);
+ if (isset($res4[$nextstate][$token])) {
+ if ($res4[$nextstate][$token]) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ return array_unique($expected);
+ }
+ } else {
+ if ($res4[$nextstate][$token] = in_array($token, self::$yyExpectedTokens[$nextstate], true)) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ return array_unique($expected);
+ }
+ }
+ }
+ if ($nextstate < self::YYNSTATE) {
+ // we need to shift a non-terminal
+ $this->yyidx++;
+ $x = new TP_yyStackEntry;
+ $x->stateno = $nextstate;
+ $x->major = self::$yyRuleInfo[$yyruleno][0];
+ $this->yystack[$this->yyidx] = $x;
+ continue 2;
+ } elseif ($nextstate == self::YYNSTATE + self::YYNRULE + 1) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ // the last token was just ignored, we can't accept
+ // by ignoring input, this is in essence ignoring a
+ // syntax error!
+ return array_unique($expected);
+ } elseif ($nextstate === self::YY_NO_ACTION) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ // input accepted, but not shifted (I guess)
+ return $expected;
+ } else {
+ $yyact = $nextstate;
+ }
+ } while (true);
+ }
+ break;
+ } while (true);
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+
+ return array_unique($expected);
+ }
+
+ public function yy_is_expected_token($token) {
+ static $res = array();
+ static $res2 = array();
+ if ($token === 0) {
+ return true; // 0 is not part of this
+ }
+ $state = $this->yystack[$this->yyidx]->stateno;
+ if (isset($res[$state][$token])) {
+ if ($res[$state][$token]) {
+ return true;
+ }
+ } else {
+ if ($res[$state][$token] = in_array($token, self::$yyExpectedTokens[$state], true)) {
+ return true;
+ }
+ }
+ $stack = $this->yystack;
+ $yyidx = $this->yyidx;
+ do {
+ $yyact = $this->yy_find_shift_action($token);
+ if ($yyact >= self::YYNSTATE && $yyact < self::YYNSTATE + self::YYNRULE) {
+ // reduce action
+ $done = 0;
+ do {
+ if ($done++ == 100) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ // too much recursion prevents proper detection
+ // so give up
+ return true;
+ }
+ $yyruleno = $yyact - self::YYNSTATE;
+ $this->yyidx -= self::$yyRuleInfo[$yyruleno][1];
+ $nextstate = $this->yy_find_reduce_action($this->yystack[$this->yyidx]->stateno, self::$yyRuleInfo[$yyruleno][0]);
+ if (isset($res2[$nextstate][$token])) {
+ if ($res2[$nextstate][$token]) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ return true;
+ }
+ } else {
+ if ($res2[$nextstate][$token] = (isset(self::$yyExpectedTokens[$nextstate]) && in_array($token, self::$yyExpectedTokens[$nextstate], true))) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ return true;
+ }
+ }
+ if ($nextstate < self::YYNSTATE) {
+ // we need to shift a non-terminal
+ $this->yyidx++;
+ $x = new TP_yyStackEntry;
+ $x->stateno = $nextstate;
+ $x->major = self::$yyRuleInfo[$yyruleno][0];
+ $this->yystack[$this->yyidx] = $x;
+ continue 2;
+ } elseif ($nextstate == self::YYNSTATE + self::YYNRULE + 1) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ if (!$token) {
+ // end of input: this is valid
+ return true;
+ }
+ // the last token was just ignored, we can't accept
+ // by ignoring input, this is in essence ignoring a
+ // syntax error!
+ return false;
+ } elseif ($nextstate === self::YY_NO_ACTION) {
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+ // input accepted, but not shifted (I guess)
+ return true;
+ } else {
+ $yyact = $nextstate;
+ }
+ } while (true);
+ }
+ break;
+ } while (true);
+ $this->yyidx = $yyidx;
+ $this->yystack = $stack;
+
+ return true;
+ }
+
+ public function yy_find_shift_action($iLookAhead) {
+ $stateno = $this->yystack[$this->yyidx]->stateno;
+
+ /* if ($this->yyidx < 0) return self::YY_NO_ACTION; */
+ if (!isset(self::$yy_shift_ofst[$stateno])) {
+ // no shift actions
+ return self::$yy_default[$stateno];
+ }
+ $i = self::$yy_shift_ofst[$stateno];
+ if ($i === self::YY_SHIFT_USE_DFLT) {
+ return self::$yy_default[$stateno];
+ }
+ if ($iLookAhead == self::YYNOCODE) {
+ return self::YY_NO_ACTION;
+ }
+ $i += $iLookAhead;
+ if ($i < 0 || $i >= self::YY_SZ_ACTTAB || self::$yy_lookahead[$i] != $iLookAhead) {
+ if (count(self::$yyFallback) && $iLookAhead < count(self::$yyFallback) && ($iFallback = self::$yyFallback[$iLookAhead]) != 0) {
+ if ($this->yyTraceFILE) {
+ fwrite($this->yyTraceFILE, $this->yyTracePrompt . "FALLBACK " . $this->yyTokenName[$iLookAhead] . " => " . $this->yyTokenName[$iFallback] . "\n");
+ }
+
+ return $this->yy_find_shift_action($iFallback);
+ }
+
+ return self::$yy_default[$stateno];
+ } else {
+ return self::$yy_action[$i];
+ }
+ }
+
+ public function yy_find_reduce_action($stateno, $iLookAhead) {
+ /* $stateno = $this->yystack[$this->yyidx]->stateno; */
+
+ if (!isset(self::$yy_reduce_ofst[$stateno])) {
+ return self::$yy_default[$stateno];
+ }
+ $i = self::$yy_reduce_ofst[$stateno];
+ if ($i == self::YY_REDUCE_USE_DFLT) {
+ return self::$yy_default[$stateno];
+ }
+ if ($iLookAhead == self::YYNOCODE) {
+ return self::YY_NO_ACTION;
+ }
+ $i += $iLookAhead;
+ if ($i < 0 || $i >= self::YY_SZ_ACTTAB || self::$yy_lookahead[$i] != $iLookAhead) {
+ return self::$yy_default[$stateno];
+ } else {
+ return self::$yy_action[$i];
+ }
+ }
+
+ public function yy_shift($yyNewState, $yyMajor, $yypMinor) {
+ $this->yyidx++;
+ if ($this->yyidx >= self::YYSTACKDEPTH) {
+ $this->yyidx--;
+ if ($this->yyTraceFILE) {
+ fprintf($this->yyTraceFILE, "%sStack Overflow!\n", $this->yyTracePrompt);
+ }
+ while ($this->yyidx >= 0) {
+ $this->yy_pop_parser_stack();
+ }
+ #line 190 "../smarty/lexer/smarty_internal_templateparser.y"
+
+ $this->internalError = true;
+ $this->compiler->trigger_template_error("Stack overflow in template parser");
+
+ return;
+ }
+ $yytos = new TP_yyStackEntry;
+ $yytos->stateno = $yyNewState;
+ $yytos->major = $yyMajor;
+ $yytos->minor = $yypMinor;
+ $this->yystack[] = $yytos;
+ if ($this->yyTraceFILE && $this->yyidx > 0) {
+ fprintf($this->yyTraceFILE, "%sShift %d\n", $this->yyTracePrompt, $yyNewState);
+ fprintf($this->yyTraceFILE, "%sStack:", $this->yyTracePrompt);
+ for ($i = 1; $i <= $this->yyidx; $i++) {
+ fprintf($this->yyTraceFILE, " %s", $this->yyTokenName[$this->yystack[$i]->major]);
+ }
+ fwrite($this->yyTraceFILE, "\n");
+ }
+ }
+
+ public static $yyRuleInfo = array(array(0 => 62, 1 => 1), array(0 => 63, 1 => 1), array(0 => 63, 1 => 2),
+ array(0 => 63, 1 => 0), array(0 => 64, 1 => 1), array(0 => 64, 1 => 1), array(0 => 64, 1 => 1),
+ array(0 => 64, 1 => 1), array(0 => 64, 1 => 1), array(0 => 67, 1 => 1), array(0 => 67, 1 => 2),
+ array(0 => 64, 1 => 1), array(0 => 64, 1 => 1), array(0 => 64, 1 => 1), array(0 => 66, 1 => 2),
+ array(0 => 66, 1 => 3), array(0 => 68, 1 => 2), array(0 => 68, 1 => 0), array(0 => 69, 1 => 1),
+ array(0 => 69, 1 => 1), array(0 => 65, 1 => 2), array(0 => 65, 1 => 1), array(0 => 70, 1 => 2),
+ array(0 => 70, 1 => 3), array(0 => 70, 1 => 2), array(0 => 70, 1 => 3), array(0 => 70, 1 => 2),
+ array(0 => 70, 1 => 3), array(0 => 70, 1 => 4), array(0 => 70, 1 => 4), array(0 => 70, 1 => 5),
+ array(0 => 70, 1 => 5), array(0 => 65, 1 => 1), array(0 => 70, 1 => 3), array(0 => 70, 1 => 2),
+ array(0 => 70, 1 => 4), array(0 => 70, 1 => 5), array(0 => 70, 1 => 6), array(0 => 70, 1 => 2),
+ array(0 => 70, 1 => 3), array(0 => 70, 1 => 2), array(0 => 70, 1 => 3), array(0 => 70, 1 => 8),
+ array(0 => 79, 1 => 2), array(0 => 79, 1 => 1), array(0 => 70, 1 => 5), array(0 => 70, 1 => 7),
+ array(0 => 70, 1 => 2), array(0 => 70, 1 => 6), array(0 => 70, 1 => 8), array(0 => 70, 1 => 6),
+ array(0 => 70, 1 => 8), array(0 => 70, 1 => 3), array(0 => 70, 1 => 4), array(0 => 70, 1 => 2),
+ array(0 => 65, 1 => 1), array(0 => 70, 1 => 2), array(0 => 70, 1 => 3), array(0 => 70, 1 => 4),
+ array(0 => 70, 1 => 5), array(0 => 72, 1 => 2), array(0 => 72, 1 => 1), array(0 => 72, 1 => 0),
+ array(0 => 82, 1 => 4), array(0 => 82, 1 => 2), array(0 => 82, 1 => 2), array(0 => 82, 1 => 2),
+ array(0 => 82, 1 => 2), array(0 => 82, 1 => 2), array(0 => 82, 1 => 4), array(0 => 78, 1 => 1),
+ array(0 => 78, 1 => 3), array(0 => 77, 1 => 3), array(0 => 77, 1 => 3), array(0 => 77, 1 => 3),
+ array(0 => 77, 1 => 3), array(0 => 74, 1 => 1), array(0 => 74, 1 => 1), array(0 => 74, 1 => 3),
+ array(0 => 74, 1 => 3), array(0 => 74, 1 => 3), array(0 => 74, 1 => 1), array(0 => 74, 1 => 2),
+ array(0 => 74, 1 => 3), array(0 => 74, 1 => 2), array(0 => 74, 1 => 3), array(0 => 74, 1 => 3),
+ array(0 => 74, 1 => 3), array(0 => 83, 1 => 7), array(0 => 83, 1 => 7), array(0 => 73, 1 => 1),
+ array(0 => 73, 1 => 2), array(0 => 73, 1 => 2), array(0 => 73, 1 => 2), array(0 => 73, 1 => 2),
+ array(0 => 73, 1 => 1), array(0 => 73, 1 => 1), array(0 => 73, 1 => 3), array(0 => 73, 1 => 2),
+ array(0 => 73, 1 => 2), array(0 => 73, 1 => 1), array(0 => 73, 1 => 1), array(0 => 73, 1 => 3),
+ array(0 => 73, 1 => 1), array(0 => 73, 1 => 1), array(0 => 73, 1 => 3), array(0 => 73, 1 => 1),
+ array(0 => 73, 1 => 2), array(0 => 73, 1 => 1), array(0 => 73, 1 => 3), array(0 => 87, 1 => 1),
+ array(0 => 87, 1 => 1), array(0 => 71, 1 => 1), array(0 => 71, 1 => 1), array(0 => 71, 1 => 3),
+ array(0 => 71, 1 => 1), array(0 => 71, 1 => 3), array(0 => 71, 1 => 4), array(0 => 71, 1 => 3),
+ array(0 => 71, 1 => 4), array(0 => 75, 1 => 2), array(0 => 75, 1 => 2), array(0 => 92, 1 => 2),
+ array(0 => 92, 1 => 0), array(0 => 93, 1 => 2), array(0 => 93, 1 => 2), array(0 => 93, 1 => 4),
+ array(0 => 93, 1 => 2), array(0 => 93, 1 => 2), array(0 => 93, 1 => 4), array(0 => 93, 1 => 3),
+ array(0 => 93, 1 => 5), array(0 => 93, 1 => 3), array(0 => 93, 1 => 3), array(0 => 93, 1 => 3),
+ array(0 => 93, 1 => 3), array(0 => 93, 1 => 3), array(0 => 93, 1 => 3), array(0 => 93, 1 => 2),
+ array(0 => 80, 1 => 1), array(0 => 80, 1 => 1), array(0 => 80, 1 => 2), array(0 => 94, 1 => 1),
+ array(0 => 94, 1 => 3), array(0 => 91, 1 => 2), array(0 => 95, 1 => 1), array(0 => 95, 1 => 2),
+ array(0 => 96, 1 => 3), array(0 => 96, 1 => 3), array(0 => 96, 1 => 5), array(0 => 96, 1 => 6),
+ array(0 => 96, 1 => 2), array(0 => 88, 1 => 4), array(0 => 97, 1 => 4), array(0 => 97, 1 => 4),
+ array(0 => 98, 1 => 3), array(0 => 98, 1 => 1), array(0 => 98, 1 => 0), array(0 => 76, 1 => 3),
+ array(0 => 76, 1 => 2), array(0 => 99, 1 => 3), array(0 => 99, 1 => 2), array(0 => 81, 1 => 2),
+ array(0 => 81, 1 => 0), array(0 => 100, 1 => 2), array(0 => 100, 1 => 2), array(0 => 90, 1 => 1),
+ array(0 => 90, 1 => 2), array(0 => 90, 1 => 1), array(0 => 90, 1 => 2), array(0 => 90, 1 => 3),
+ array(0 => 85, 1 => 1), array(0 => 85, 1 => 1), array(0 => 86, 1 => 1), array(0 => 84, 1 => 3),
+ array(0 => 101, 1 => 1), array(0 => 101, 1 => 3), array(0 => 101, 1 => 0), array(0 => 102, 1 => 3),
+ array(0 => 102, 1 => 3), array(0 => 102, 1 => 1), array(0 => 89, 1 => 2), array(0 => 89, 1 => 3),
+ array(0 => 103, 1 => 2), array(0 => 103, 1 => 1), array(0 => 104, 1 => 3), array(0 => 104, 1 => 3),
+ array(0 => 104, 1 => 1), array(0 => 104, 1 => 3), array(0 => 104, 1 => 3), array(0 => 104, 1 => 1),
+ array(0 => 104, 1 => 1),);
+
+ public static $yyReduceMap = array(0 => 0, 1 => 1, 2 => 2, 4 => 4, 5 => 5, 6 => 6, 7 => 7, 8 => 8, 9 => 9,
+ 18 => 9, 19 => 9, 44 => 9, 67 => 9, 68 => 9, 76 => 9, 77 => 9, 81 => 9, 90 => 9,
+ 95 => 9, 96 => 9, 101 => 9, 103 => 9, 104 => 9, 108 => 9, 110 => 9, 111 => 9,
+ 115 => 9, 175 => 9, 180 => 9, 10 => 10, 11 => 11, 12 => 12, 13 => 13, 14 => 14,
+ 17 => 14, 15 => 15, 75 => 15, 16 => 16, 91 => 16, 93 => 16, 94 => 16, 122 => 16,
+ 20 => 20, 21 => 21, 22 => 22, 24 => 22, 26 => 22, 23 => 23, 25 => 23, 27 => 23,
+ 28 => 28, 29 => 28, 30 => 30, 31 => 31, 32 => 32, 33 => 33, 34 => 34, 35 => 35,
+ 36 => 36, 37 => 37, 38 => 38, 39 => 39, 41 => 39, 40 => 40, 42 => 42, 43 => 43,
+ 45 => 45, 46 => 46, 47 => 47, 48 => 48, 50 => 48, 49 => 49, 51 => 49, 52 => 52,
+ 53 => 53, 54 => 54, 55 => 55, 56 => 56, 57 => 57, 58 => 58, 59 => 59, 60 => 60,
+ 61 => 61, 70 => 61, 156 => 61, 160 => 61, 164 => 61, 165 => 61, 62 => 62,
+ 157 => 62, 163 => 62, 63 => 63, 64 => 64, 65 => 64, 66 => 66, 142 => 66,
+ 69 => 69, 71 => 71, 72 => 72, 73 => 72, 74 => 74, 78 => 78, 79 => 79, 80 => 79,
+ 82 => 82, 107 => 82, 83 => 83, 84 => 84, 85 => 85, 86 => 86, 87 => 87, 88 => 88,
+ 89 => 89, 92 => 92, 97 => 97, 98 => 98, 99 => 99, 100 => 100, 102 => 102,
+ 105 => 105, 106 => 106, 109 => 109, 112 => 112, 113 => 113, 114 => 114,
+ 116 => 116, 117 => 117, 118 => 118, 119 => 119, 120 => 120, 121 => 121,
+ 123 => 123, 177 => 123, 124 => 124, 125 => 125, 126 => 126, 127 => 127,
+ 128 => 128, 129 => 129, 137 => 129, 130 => 130, 131 => 131, 132 => 132,
+ 133 => 132, 135 => 132, 136 => 132, 134 => 134, 138 => 138, 139 => 139,
+ 140 => 140, 181 => 140, 141 => 141, 143 => 143, 144 => 144, 145 => 145,
+ 146 => 146, 147 => 147, 148 => 148, 149 => 149, 150 => 150, 151 => 151,
+ 152 => 152, 153 => 153, 154 => 154, 155 => 155, 158 => 158, 159 => 159,
+ 161 => 161, 162 => 162, 166 => 166, 167 => 167, 168 => 168, 169 => 169,
+ 170 => 170, 171 => 171, 172 => 172, 173 => 173, 174 => 174, 176 => 176,
+ 178 => 178, 179 => 179, 182 => 182, 183 => 183, 184 => 184, 185 => 185,
+ 186 => 185, 188 => 185, 187 => 187, 189 => 189, 190 => 190, 191 => 191,);
+
+ #line 201 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r0() {
+ $this->_retvalue = $this->root_buffer->to_smarty_php();
+ }
+
+ #line 209 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r1() {
+ if ($this->yystack[$this->yyidx + 0]->minor != null) {
+ $this->current_buffer->append_subtree($this->yystack[$this->yyidx + 0]->minor);
+ }
+ }
+
+ #line 216 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r2() {
+ if ($this->yystack[$this->yyidx + 0]->minor != null) {
+ // because of possible code injection
+ $this->current_buffer->append_subtree($this->yystack[$this->yyidx + 0]->minor);
+ }
+ }
+
+ #line 230 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r4() {
+ if ($this->compiler->has_code) {
+ $this->_retvalue = $this->mergePrefixCode($this->yystack[$this->yyidx + 0]->minor);
+ } else {
+ $this->_retvalue = null;
+ }
+ $this->compiler->has_variable_string = false;
+ $this->block_nesting_level = count($this->compiler->_tag_stack);
+ }
+
+ #line 241 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r5() {
+ $this->_retvalue = new Smarty_Internal_ParseTree_Text($this, $this->yystack[$this->yyidx + 0]->minor);
+ }
+
+ #line 245 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r6() {
+ $code = $this->compiler->compileTag('private_php', array(array('code' => $this->yystack[$this->yyidx + 0]->minor),
+ array('type' => $this->lex->phpType)), array());
+ if ($this->compiler->has_code && !empty($code)) {
+ $tmp = '';
+ foreach ($this->compiler->prefix_code as $code) {
+ $tmp .= $code;
+ }
+ $this->compiler->prefix_code = array();
+ $this->_retvalue = new Smarty_Internal_ParseTree_Tag($this, $this->compiler->processNocacheCode($tmp . $code, true));
+ } else {
+ $this->_retvalue = null;
+ }
+ }
+
+ #line 256 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r7() {
+ $this->compiler->tag_nocache = true;
+ $save = $this->template->has_nocache_code;
+ $this->_retvalue = new Smarty_Internal_ParseTree_Tag($this, $this->compiler->processNocacheCode("<?php echo '{$this->yystack[$this->yyidx + 0]->minor}';?>\n", $this->compiler, true));
+ $this->template->has_nocache_code = $save;
+ }
+
+ #line 263 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r8() {
+ $this->_retvalue = $this->compiler->processText($this->yystack[$this->yyidx + 0]->minor);
+ }
+
+ #line 267 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r9() {
+ $this->_retvalue = $this->yystack[$this->yyidx + 0]->minor;
+ }
+
+ #line 271 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r10() {
+ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor . $this->yystack[$this->yyidx + 0]->minor;
+ }
+
+ #line 276 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r11() {
+ $this->strip = true;
+ }
+
+ #line 280 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r12() {
+ $this->strip = false;
+ }
+
+ #line 284 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r13() {
+ if ($this->strip) {
+ SMARTY_INTERNAL_COMPILE_BLOCK::blockSource($this->compiler, preg_replace('![\t ]*[\r\n]+[\t ]*!', '', $this->yystack[$this->yyidx + 0]->minor));
+ } else {
+ SMARTY_INTERNAL_COMPILE_BLOCK::blockSource($this->compiler, $this->yystack[$this->yyidx + 0]->minor);
+ }
+ }
+
+ #line 293 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r14() {
+ $this->_retvalue = '';
+ }
+
+ #line 297 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r15() {
+ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor;
+ }
+
+ #line 301 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r16() {
+ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor . $this->yystack[$this->yyidx + 0]->minor;
+ }
+
+ #line 317 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r20() {
+ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor;
+ }
+
+ #line 323 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r21() {
+ $var = trim(substr($this->yystack[$this->yyidx + 0]->minor, $this->lex->ldel_length, -$this->lex->rdel_length), ' $');
+ if (preg_match('/^(.*)(\s+nocache)$/', $var, $match)) {
+ $this->_retvalue = $this->compiler->compileTag('private_print_expression', array('nocache'), array('value' => $this->compiler->compileVariable('\'' . $match[1] . '\'')));
+ } else {
+ $this->_retvalue = $this->compiler->compileTag('private_print_expression', array(), array('value' => $this->compiler->compileVariable('\'' . $var . '\'')));
+ }
+ }
+
+ #line 333 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r22() {
+ $this->_retvalue = $this->compiler->compileTag('private_print_expression', array(), array('value' => $this->yystack[$this->yyidx + 0]->minor));
+ }
+
+ #line 337 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r23() {
+ $this->_retvalue = $this->compiler->compileTag('private_print_expression', $this->yystack[$this->yyidx + 0]->minor, array('value' => $this->yystack[$this->yyidx + -1]->minor));
+ }
+
+ #line 360 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r28() {
+ $this->_retvalue = $this->compiler->compileTag('assign', array(array('value' => $this->yystack[$this->yyidx + 0]->minor),
+ array('var' => '\'' . substr($this->yystack[$this->yyidx + -2]->minor, 1) . '\'')));
+ }
+
+ #line 368 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r30() {
+ $this->_retvalue = $this->compiler->compileTag('assign', array_merge(array(array('value' => $this->yystack[$this->yyidx + -1]->minor),
+ array('var' => '\'' . substr($this->yystack[$this->yyidx + -3]->minor, 1) . '\'')), $this->yystack[$this->yyidx + 0]->minor));
+ }
+
+ #line 372 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r31() {
+ $this->_retvalue = $this->compiler->compileTag('assign', array_merge(array(array('value' => $this->yystack[$this->yyidx + -1]->minor),
+ array('var' => $this->yystack[$this->yyidx + -3]->minor['var'])), $this->yystack[$this->yyidx + 0]->minor), array('smarty_internal_index' => $this->yystack[$this->yyidx + -3]->minor['smarty_internal_index']));
+ }
+
+ #line 377 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r32() {
+ $tag = trim(substr($this->yystack[$this->yyidx + 0]->minor, $this->lex->ldel_length, -$this->lex->rdel_length));
+ if ($tag == 'strip') {
+ $this->strip = true;
+ $this->_retvalue = null;;
+ } else {
+ if (defined($tag)) {
+ if ($this->security) {
+ $this->security->isTrustedConstant($tag, $this->compiler);
+ }
+ $this->_retvalue = $this->compiler->compileTag('private_print_expression', array(), array('value' => $tag));
+ } else {
+ if (preg_match('/^(.*)(\s+nocache)$/', $tag, $match)) {
+ $this->_retvalue = $this->compiler->compileTag($match[1], array("'nocache'"));
+ } else {
+ $this->_retvalue = $this->compiler->compileTag($tag, array());
+ }
+ }
+ }
+ }
+
+ #line 399 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r33() {
+ if (defined($this->yystack[$this->yyidx + -1]->minor)) {
+ if ($this->security) {
+ $this->security->isTrustedConstant($this->yystack[$this->yyidx + -1]->minor, $this->compiler);
+ }
+ $this->_retvalue = $this->compiler->compileTag('private_print_expression', $this->yystack[$this->yyidx + 0]->minor, array('value' => $this->yystack[$this->yyidx + -1]->minor));
+ } else {
+ $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -1]->minor, $this->yystack[$this->yyidx + 0]->minor);
+ }
+ }
+
+ #line 409 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r34() {
+ if (defined($this->yystack[$this->yyidx + 0]->minor)) {
+ if ($this->security) {
+ $this->security->isTrustedConstant($this->yystack[$this->yyidx + 0]->minor, $this->compiler);
+ }
+ $this->_retvalue = $this->compiler->compileTag('private_print_expression', array(), array('value' => $this->yystack[$this->yyidx + 0]->minor));
+ } else {
+ $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + 0]->minor, array());
+ }
+ }
+
+ #line 422 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r35() {
+ if (defined($this->yystack[$this->yyidx + -2]->minor)) {
+ if ($this->security) {
+ $this->security->isTrustedConstant($this->yystack[$this->yyidx + -2]->minor, $this->compiler);
+ }
+ $this->_retvalue = $this->compiler->compileTag('private_print_expression', $this->yystack[$this->yyidx + 0]->minor, array('value' => $this->yystack[$this->yyidx + -2]->minor,
+ 'modifierlist' => $this->yystack[$this->yyidx + -1]->minor));
+ } else {
+ $this->_retvalue = '<?php ob_start();?>' . $this->compiler->compileTag($this->yystack[$this->yyidx + -2]->minor, $this->yystack[$this->yyidx + 0]->minor) . '<?php echo ';
+ $this->_retvalue .= $this->compiler->compileTag('private_modifier', array(), array('modifierlist' => $this->yystack[$this->yyidx + -1]->minor,
+ 'value' => 'ob_get_clean()')) . ';?>';
+ }
+ }
+
+ #line 435 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r36() {
+ $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -3]->minor, $this->yystack[$this->yyidx + 0]->minor, array('object_method' => $this->yystack[$this->yyidx + -1]->minor));
+ }
+
+ #line 440 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r37() {
+ $this->_retvalue = '<?php ob_start();?>' . $this->compiler->compileTag($this->yystack[$this->yyidx + -4]->minor, $this->yystack[$this->yyidx + 0]->minor, array('object_method' => $this->yystack[$this->yyidx + -2]->minor)) . '<?php echo ';
+ $this->_retvalue .= $this->compiler->compileTag('private_modifier', array(), array('modifierlist' => $this->yystack[$this->yyidx + -1]->minor,
+ 'value' => 'ob_get_clean()')) . ';?>';
+ }
+
+ #line 446 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r38() {
+ $tag = trim(substr($this->yystack[$this->yyidx + -1]->minor, $this->lex->ldel_length));
+ $this->_retvalue = $this->compiler->compileTag(($tag == 'else if') ? 'elseif' : $tag, array(), array('if condition' => $this->yystack[$this->yyidx + 0]->minor));
+ }
+
+ #line 451 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r39() {
+ $tag = trim(substr($this->yystack[$this->yyidx + -2]->minor, $this->lex->ldel_length));
+ $this->_retvalue = $this->compiler->compileTag(($tag == 'else if') ? 'elseif' : $tag, $this->yystack[$this->yyidx + 0]->minor, array('if condition' => $this->yystack[$this->yyidx + -1]->minor));
+ }
+
+ #line 456 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r40() {
+ $tag = trim(substr($this->yystack[$this->yyidx + -1]->minor, $this->lex->ldel_length));
+ $this->_retvalue = $this->compiler->compileTag(($tag == 'else if') ? 'elseif' : $tag, array(), array('if condition' => $this->yystack[$this->yyidx + 0]->minor));
+ }
+
+ #line 467 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r42() {
+ $this->_retvalue = $this->compiler->compileTag('for', array_merge($this->yystack[$this->yyidx + 0]->minor, array(array('start' => $this->yystack[$this->yyidx + -6]->minor),
+ array('ifexp' => $this->yystack[$this->yyidx + -4]->minor),
+ array('var' => $this->yystack[$this->yyidx + -2]->minor),
+ array('step' => $this->yystack[$this->yyidx + -1]->minor))), 1);
+ }
+
+ #line 471 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r43() {
+ $this->_retvalue = '=' . $this->yystack[$this->yyidx + 0]->minor;
+ }
+
+ #line 479 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r45() {
+ $this->_retvalue = $this->compiler->compileTag('for', array_merge($this->yystack[$this->yyidx + 0]->minor, array(array('start' => $this->yystack[$this->yyidx + -3]->minor),
+ array('to' => $this->yystack[$this->yyidx + -1]->minor))), 0);
+ }
+
+ #line 483 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r46() {
+ $this->_retvalue = $this->compiler->compileTag('for', array_merge($this->yystack[$this->yyidx + 0]->minor, array(array('start' => $this->yystack[$this->yyidx + -5]->minor),
+ array('to' => $this->yystack[$this->yyidx + -3]->minor),
+ array('step' => $this->yystack[$this->yyidx + -1]->minor))), 0);
+ }
+
+ #line 488 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r47() {
+ $this->_retvalue = $this->compiler->compileTag('foreach', $this->yystack[$this->yyidx + 0]->minor);
+ }
+
+ #line 493 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r48() {
+ $this->_retvalue = $this->compiler->compileTag('foreach', array_merge($this->yystack[$this->yyidx + 0]->minor, array(array('from' => $this->yystack[$this->yyidx + -3]->minor),
+ array('item' => $this->yystack[$this->yyidx + -1]->minor))));
+ }
+
+ #line 497 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r49() {
+ $this->_retvalue = $this->compiler->compileTag('foreach', array_merge($this->yystack[$this->yyidx + 0]->minor, array(array('from' => $this->yystack[$this->yyidx + -5]->minor),
+ array('item' => $this->yystack[$this->yyidx + -1]->minor),
+ array('key' => $this->yystack[$this->yyidx + -3]->minor))));
+ }
+
+ #line 510 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r52() {
+ $this->_retvalue = $this->compiler->compileTag('setfilter', array(), array('modifier_list' => array(array_merge(array($this->yystack[$this->yyidx + -1]->minor), $this->yystack[$this->yyidx + 0]->minor))));
+ }
+
+ #line 514 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r53() {
+ $this->_retvalue = $this->compiler->compileTag('setfilter', array(), array('modifier_list' => array_merge(array(array_merge(array($this->yystack[$this->yyidx + -2]->minor), $this->yystack[$this->yyidx + -1]->minor)), $this->yystack[$this->yyidx + 0]->minor)));
+ }
+
+ #line 519 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r54() {
+ $j = strrpos($this->yystack[$this->yyidx + 0]->minor, '.');
+ if ($this->yystack[$this->yyidx + 0]->minor[$j + 1] == 'c') {
+ // {$smarty.block.child}
+ $this->_retvalue = SMARTY_INTERNAL_COMPILE_BLOCK::compileChildBlock($this->compiler);
+ } else {
+ // {$smarty.block.parent}
+ $this->_retvalue = SMARTY_INTERNAL_COMPILE_BLOCK::compileParentBlock($this->compiler);
+ }
+ }
+
+ #line 532 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r55() {
+ $tag = trim(substr($this->yystack[$this->yyidx + 0]->minor, $this->lex->ldel_length, -$this->lex->rdel_length), ' /');
+ if ($tag == 'strip') {
+ $this->strip = false;
+ $this->_retvalue = null;
+ } else {
+ $this->_retvalue = $this->compiler->compileTag($tag . 'close', array());
+ }
+ }
+
+ #line 541 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r56() {
+ $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + 0]->minor . 'close', array());
+ }
+
+ #line 545 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r57() {
+ $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -1]->minor . 'close', array(), array('modifier_list' => $this->yystack[$this->yyidx + 0]->minor));
+ }
+
+ #line 550 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r58() {
+ $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -2]->minor . 'close', array(), array('object_method' => $this->yystack[$this->yyidx + 0]->minor));
+ }
+
+ #line 554 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r59() {
+ $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -3]->minor . 'close', array(), array('object_method' => $this->yystack[$this->yyidx + -1]->minor,
+ 'modifier_list' => $this->yystack[$this->yyidx + 0]->minor));
+ }
+
+ #line 562 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r60() {
+ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor;
+ $this->_retvalue[] = $this->yystack[$this->yyidx + 0]->minor;
+ }
+
+ #line 568 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r61() {
+ $this->_retvalue = array($this->yystack[$this->yyidx + 0]->minor);
+ }
+
+ #line 573 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r62() {
+ $this->_retvalue = array();
+ }
+
+ #line 578 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r63() {
+ if (defined($this->yystack[$this->yyidx + 0]->minor)) {
+ if ($this->security) {
+ $this->security->isTrustedConstant($this->yystack[$this->yyidx + 0]->minor, $this->compiler);
+ }
+ $this->_retvalue = array($this->yystack[$this->yyidx + -2]->minor => $this->yystack[$this->yyidx + 0]->minor);
+ } else {
+ $this->_retvalue = array($this->yystack[$this->yyidx + -2]->minor => '\'' . $this->yystack[$this->yyidx + 0]->minor . '\'');
+ }
+ }
+
+ #line 589 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r64() {
+ $this->_retvalue = array(trim($this->yystack[$this->yyidx + -1]->minor, " =\n\r\t") => $this->yystack[$this->yyidx + 0]->minor);
+ }
+
+ #line 597 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r66() {
+ $this->_retvalue = '\'' . $this->yystack[$this->yyidx + 0]->minor . '\'';
+ }
+
+ #line 609 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r69() {
+ $this->_retvalue = array($this->yystack[$this->yyidx + -2]->minor => $this->yystack[$this->yyidx + 0]->minor);
+ }
+
+ #line 622 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r71() {
+ $this->yystack[$this->yyidx + -2]->minor[] = $this->yystack[$this->yyidx + 0]->minor;
+ $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor;
+ }
+
+ #line 627 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r72() {
+ $this->_retvalue = array('var' => '\'' . substr($this->yystack[$this->yyidx + -2]->minor, 1) . '\'',
+ 'value' => $this->yystack[$this->yyidx + 0]->minor);
+ }
+
+ #line 634 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r74() {
+ $this->_retvalue = array('var' => $this->yystack[$this->yyidx + -2]->minor,
+ 'value' => $this->yystack[$this->yyidx + 0]->minor);
+ }
+
+ #line 658 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r78() {
+ $this->_retvalue = '$_smarty_tpl->getStreamVariable(\'' . substr($this->yystack[$this->yyidx + -2]->minor, 1) . '://' . $this->yystack[$this->yyidx + 0]->minor . '\')';
+ }
+
+ #line 663 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r79() {
+ $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor . trim($this->yystack[$this->yyidx + -1]->minor) . $this->yystack[$this->yyidx + 0]->minor;
+ }
+
+ #line 677 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r82() {
+ $this->_retvalue = $this->compiler->compileTag('private_modifier', array(), array('value' => $this->yystack[$this->yyidx + -1]->minor,
+ 'modifierlist' => $this->yystack[$this->yyidx + 0]->minor));
+ }
+
+ #line 683 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r83() {
+ $this->_retvalue = (isset($this->yystack[$this->yyidx + -1]->minor['pre']) ? $this->yystack[$this->yyidx + -1]->minor['pre'] : '') . $this->yystack[$this->yyidx + -2]->minor . $this->yystack[$this->yyidx + -1]->minor['op'] . $this->yystack[$this->yyidx + 0]->minor . (isset($this->yystack[$this->yyidx + -1]->minor['pre']) ? ')' : '');
+ }
+
+ #line 686 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r84() {
+ $this->_retvalue = $this->yystack[$this->yyidx + 0]->minor . $this->yystack[$this->yyidx + -1]->minor . ')';
+ }
+
+ #line 690 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r85() {
+ $this->_retvalue = 'in_array(' . $this->yystack[$this->yyidx + -2]->minor . ',' . $this->yystack[$this->yyidx + 0]->minor . ')';
+ }
+
+ #line 694 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r86() {
+ $this->_retvalue = 'in_array(' . $this->yystack[$this->yyidx + -2]->minor . ',(array)' . $this->yystack[$this->yyidx + 0]->minor . ')';
+ }
+
+ #line 698 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r87() {
+ $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor . $this->yystack[$this->yyidx + -1]->minor . $this->yystack[$this->yyidx + 0]->minor;
+ }
+
+ #line 706 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r88() {
+ $this->_retvalue = $this->yystack[$this->yyidx + -5]->minor . ' ? ' . $this->compiler->compileVariable('\'' . substr($this->yystack[$this->yyidx + -2]->minor, 1) . '\'') . ' : ' . $this->yystack[$this->yyidx + 0]->minor;
+ }
+
+ #line 710 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r89() {
+ $this->_retvalue = $this->yystack[$this->yyidx + -5]->minor . ' ? ' . $this->yystack[$this->yyidx + -2]->minor . ' : ' . $this->yystack[$this->yyidx + 0]->minor;
+ }
+
+ #line 725 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r92() {
+ $this->_retvalue = '!' . $this->yystack[$this->yyidx + 0]->minor;
+ }
+
+ #line 746 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r97() {
+ $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor . '.' . $this->yystack[$this->yyidx + 0]->minor;
+ }
+
+ #line 750 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r98() {
+ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor . '.';
+ }
+
+ #line 754 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r99() {
+ $this->_retvalue = '.' . $this->yystack[$this->yyidx + 0]->minor;
+ }
+
+ #line 759 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r100() {
+ if (defined($this->yystack[$this->yyidx + 0]->minor)) {
+ if ($this->security) {
+ $this->security->isTrustedConstant($this->yystack[$this->yyidx + 0]->minor, $this->compiler);
+ }
+ $this->_retvalue = $this->yystack[$this->yyidx + 0]->minor;
+ } else {
+ $this->_retvalue = '\'' . $this->yystack[$this->yyidx + 0]->minor . '\'';
+ }
+ }
+
+ #line 776 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r102() {
+ $this->_retvalue = "(" . $this->yystack[$this->yyidx + -1]->minor . ")";
+ }
+
+ #line 791 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r105() {
+ self::$prefix_number++;
+ if ($this->yystack[$this->yyidx + -2]->minor['var'] == '\'smarty\'') {
+ $this->compiler->prefix_code[] = '<?php $_tmp' . self::$prefix_number . ' = ' . $this->compiler->compileTag('private_special_variable', array(), $this->yystack[$this->yyidx + -2]->minor['smarty_internal_index']) . ';?>';
+ } else {
+ $this->compiler->prefix_code[] = '<?php $_tmp' . self::$prefix_number . ' = ' . $this->compiler->compileVariable($this->yystack[$this->yyidx + -2]->minor['var']) . $this->yystack[$this->yyidx + -2]->minor['smarty_internal_index'] . ';?>';
+ }
+ $this->_retvalue = '$_tmp' . self::$prefix_number . '::' . $this->yystack[$this->yyidx + 0]->minor[0] . $this->yystack[$this->yyidx + 0]->minor[1];
+ }
+
+ #line 802 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r106() {
+ self::$prefix_number++;
+ $tmp = $this->compiler->appendCode('<?php ob_start();?>', $this->yystack[$this->yyidx + 0]->minor);
+ $this->compiler->prefix_code[] = $this->compiler->appendCode($tmp, '<?php $_tmp' . self::$prefix_number . '=ob_get_clean();?>');
+ $this->_retvalue = '$_tmp' . self::$prefix_number;
+ }
+
+ #line 819 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r109() {
+ if (!in_array(strtolower($this->yystack[$this->yyidx + -2]->minor), array('self',
+ 'parent')) && (!$this->security || $this->security->isTrustedStaticClassAccess($this->yystack[$this->yyidx + -2]->minor, $this->yystack[$this->yyidx + 0]->minor, $this->compiler))
+ ) {
+ if (isset($this->smarty->registered_classes[$this->yystack[$this->yyidx + -2]->minor])) {
+ $this->_retvalue = $this->smarty->registered_classes[$this->yystack[$this->yyidx + -2]->minor] . '::' . $this->yystack[$this->yyidx + 0]->minor[0] . $this->yystack[$this->yyidx + 0]->minor[1];
+ } else {
+ $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor . '::' . $this->yystack[$this->yyidx + 0]->minor[0] . $this->yystack[$this->yyidx + 0]->minor[1];
+ }
+ } else {
+ $this->compiler->trigger_template_error("static class '" . $this->yystack[$this->yyidx + -2]->minor . "' is undefined or not allowed by security setting");
+ }
+ }
+
+ #line 853 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r112() {
+ $this->_retvalue = $this->compiler->compileVariable('\'' . substr($this->yystack[$this->yyidx + 0]->minor, 1) . '\'');
+ }
+
+ #line 856 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r113() {
+ if ($this->yystack[$this->yyidx + 0]->minor['var'] == '\'smarty\'') {
+ $smarty_var = $this->compiler->compileTag('private_special_variable', array(), $this->yystack[$this->yyidx + 0]->minor['smarty_internal_index']);
+ $this->_retvalue = $smarty_var;
+ } else {
+ // used for array reset,next,prev,end,current
+ $this->last_variable = $this->yystack[$this->yyidx + 0]->minor['var'];
+ $this->last_index = $this->yystack[$this->yyidx + 0]->minor['smarty_internal_index'];
+ $this->_retvalue = $this->compiler->compileVariable($this->yystack[$this->yyidx + 0]->minor['var']) . $this->yystack[$this->yyidx + 0]->minor['smarty_internal_index'];
+ }
+ }
+
+ #line 869 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r114() {
+ $this->_retvalue = '$_smarty_tpl->tpl_vars[' . $this->yystack[$this->yyidx + -2]->minor . ']->' . $this->yystack[$this->yyidx + 0]->minor;
+ }
+
+ #line 879 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r116() {
+ $this->_retvalue = '$_smarty_tpl->getConfigVariable( \'' . $this->yystack[$this->yyidx + -1]->minor . '\')';
+ }
+
+ #line 883 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r117() {
+ $this->_retvalue = '(is_array($tmp = $_smarty_tpl->getConfigVariable( \'' . $this->yystack[$this->yyidx + -2]->minor . '\')) ? $tmp' . $this->yystack[$this->yyidx + 0]->minor . ' :null)';
+ }
+
+ #line 887 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r118() {
+ $this->_retvalue = '$_smarty_tpl->getConfigVariable( ' . $this->yystack[$this->yyidx + -1]->minor . ')';
+ }
+
+ #line 891 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r119() {
+ $this->_retvalue = '(is_array($tmp = $_smarty_tpl->getConfigVariable( ' . $this->yystack[$this->yyidx + -2]->minor . ')) ? $tmp' . $this->yystack[$this->yyidx + 0]->minor . ' : null)';
+ }
+
+ #line 895 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r120() {
+ $this->_retvalue = array('var' => '\'' . substr($this->yystack[$this->yyidx + -1]->minor, 1) . '\'',
+ 'smarty_internal_index' => $this->yystack[$this->yyidx + 0]->minor);
+ }
+
+ #line 898 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r121() {
+ $this->_retvalue = array('var' => $this->yystack[$this->yyidx + -1]->minor,
+ 'smarty_internal_index' => $this->yystack[$this->yyidx + 0]->minor);
+ }
+
+ #line 911 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r123() {
+ return;
+ }
+
+ #line 917 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r124() {
+ $this->_retvalue = '[' . $this->compiler->compileVariable('\'' . substr($this->yystack[$this->yyidx + 0]->minor, 1) . '\'') . ']';
+ }
+
+ #line 920 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r125() {
+ $this->_retvalue = '[' . $this->compiler->compileVariable($this->yystack[$this->yyidx + 0]->minor) . ']';
+ }
+
+ #line 924 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r126() {
+ $this->_retvalue = '[' . $this->compiler->compileVariable($this->yystack[$this->yyidx + -2]->minor) . '->' . $this->yystack[$this->yyidx + 0]->minor . ']';
+ }
+
+ #line 928 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r127() {
+ if (defined($this->yystack[$this->yyidx + 0]->minor)) {
+ if ($this->security) {
+ $this->security->isTrustedConstant($this->yystack[$this->yyidx + 0]->minor, $this->compiler);
+ }
+ $this->_retvalue = '[' . $this->yystack[$this->yyidx + 0]->minor . ']';
+ } else {
+ $this->_retvalue = "['" . $this->yystack[$this->yyidx + 0]->minor . "']";
+ }
+ }
+
+ #line 939 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r128() {
+ $this->_retvalue = '[' . $this->yystack[$this->yyidx + 0]->minor . ']';
+ }
+
+ #line 943 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r129() {
+ $this->_retvalue = '[' . $this->yystack[$this->yyidx + -1]->minor . ']';
+ }
+
+ #line 948 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r130() {
+ $this->_retvalue = '[' . $this->compiler->compileTag('private_special_variable', array(), '[\'section\'][\'' . $this->yystack[$this->yyidx + -1]->minor . '\'][\'index\']') . ']';
+ }
+
+ #line 952 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r131() {
+ $this->_retvalue = '[' . $this->compiler->compileTag('private_special_variable', array(), '[\'section\'][\'' . $this->yystack[$this->yyidx + -3]->minor . '\'][\'' . $this->yystack[$this->yyidx + -1]->minor . '\']') . ']';
+ }
+
+ #line 955 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r132() {
+ $this->_retvalue = '[' . $this->yystack[$this->yyidx + -1]->minor . ']';
+ }
+
+ #line 961 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r134() {
+ $this->_retvalue = '[' . $this->compiler->compileVariable('\'' . substr($this->yystack[$this->yyidx + -1]->minor, 1) . '\'') . ']';;
+ }
+
+ #line 977 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r138() {
+ $this->_retvalue = '[]';
+ }
+
+ #line 987 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r139() {
+ $this->_retvalue = '\'' . substr($this->yystack[$this->yyidx + 0]->minor, 1) . '\'';
+ }
+
+ #line 991 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r140() {
+ $this->_retvalue = "''";
+ }
+
+ #line 996 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r141() {
+ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor . '.' . $this->yystack[$this->yyidx + 0]->minor;
+ }
+
+ #line 1006 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r143() {
+ $this->_retvalue = '(' . $this->yystack[$this->yyidx + -1]->minor . ')';
+ }
+
+ #line 1013 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r144() {
+ if ($this->yystack[$this->yyidx + -1]->minor['var'] == '\'smarty\'') {
+ $this->_retvalue = $this->compiler->compileTag('private_special_variable', array(), $this->yystack[$this->yyidx + -1]->minor['smarty_internal_index']) . $this->yystack[$this->yyidx + 0]->minor;
+ } else {
+ $this->_retvalue = $this->compiler->compileVariable($this->yystack[$this->yyidx + -1]->minor['var']) . $this->yystack[$this->yyidx + -1]->minor['smarty_internal_index'] . $this->yystack[$this->yyidx + 0]->minor;
+ }
+ }
+
+ #line 1022 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r145() {
+ $this->_retvalue = $this->yystack[$this->yyidx + 0]->minor;
+ }
+
+ #line 1027 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r146() {
+ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor . $this->yystack[$this->yyidx + 0]->minor;
+ }
+
+ #line 1032 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r147() {
+ if ($this->security && substr($this->yystack[$this->yyidx + -1]->minor, 0, 1) == '_') {
+ $this->compiler->trigger_template_error(self::Err1);
+ }
+ $this->_retvalue = '->' . $this->yystack[$this->yyidx + -1]->minor . $this->yystack[$this->yyidx + 0]->minor;
+ }
+
+ #line 1039 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r148() {
+ if ($this->security) {
+ $this->compiler->trigger_template_error(self::Err2);
+ }
+ $this->_retvalue = '->{' . $this->compiler->compileVariable($this->yystack[$this->yyidx + -1]->minor) . $this->yystack[$this->yyidx + 0]->minor . '}';
+ }
+
+ #line 1046 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r149() {
+ if ($this->security) {
+ $this->compiler->trigger_template_error(self::Err2);
+ }
+ $this->_retvalue = '->{' . $this->yystack[$this->yyidx + -2]->minor . $this->yystack[$this->yyidx + 0]->minor . '}';
+ }
+
+ #line 1053 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r150() {
+ if ($this->security) {
+ $this->compiler->trigger_template_error(self::Err2);
+ }
+ $this->_retvalue = '->{\'' . $this->yystack[$this->yyidx + -4]->minor . '\'.' . $this->yystack[$this->yyidx + -2]->minor . $this->yystack[$this->yyidx + 0]->minor . '}';
+ }
+
+ #line 1061 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r151() {
+ $this->_retvalue = '->' . $this->yystack[$this->yyidx + 0]->minor;
+ }
+
+ #line 1069 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r152() {
+ if (!$this->security || $this->security->isTrustedPhpFunction($this->yystack[$this->yyidx + -3]->minor, $this->compiler)) {
+ if (strcasecmp($this->yystack[$this->yyidx + -3]->minor, 'isset') === 0 || strcasecmp($this->yystack[$this->yyidx + -3]->minor, 'empty') === 0 || strcasecmp($this->yystack[$this->yyidx + -3]->minor, 'array') === 0 || is_callable($this->yystack[$this->yyidx + -3]->minor)) {
+ $func_name = strtolower($this->yystack[$this->yyidx + -3]->minor);
+ if ($func_name == 'isset') {
+ if (count($this->yystack[$this->yyidx + -1]->minor) == 0) {
+ $this->compiler->trigger_template_error('Illegal number of paramer in "isset()"');
+ }
+ $par = implode(',', $this->yystack[$this->yyidx + -1]->minor);
+ if (strncasecmp($par, '$_smarty_tpl->getConfigVariable', strlen('$_smarty_tpl->getConfigVariable')) === 0) {
+ self::$prefix_number++;
+ $this->compiler->prefix_code[] = '<?php $_tmp' . self::$prefix_number . '=' . str_replace(')', ', false)', $par) . ';?>';
+ $isset_par = '$_tmp' . self::$prefix_number;
+ } else {
+ $isset_par = str_replace("')->value", "',null,true,false)->value", $par);
+ }
+ $this->_retvalue = $this->yystack[$this->yyidx + -3]->minor . "(" . $isset_par . ")";
+ } elseif (in_array($func_name, array('empty', 'reset', 'current', 'end', 'prev', 'next'))) {
+ if (count($this->yystack[$this->yyidx + -1]->minor) != 1) {
+ $this->compiler->trigger_template_error('Illegal number of paramer in "empty()"');
+ }
+ if ($func_name == 'empty') {
+ $this->_retvalue = $func_name . '(' . str_replace("')->value", "',null,true,false)->value", $this->yystack[$this->yyidx + -1]->minor[0]) . ')';
+ } else {
+ $this->_retvalue = $func_name . '(' . $this->yystack[$this->yyidx + -1]->minor[0] . ')';
+ }
+ } else {
+ $this->_retvalue = $this->yystack[$this->yyidx + -3]->minor . "(" . implode(',', $this->yystack[$this->yyidx + -1]->minor) . ")";
+ }
+ } else {
+ $this->compiler->trigger_template_error("unknown function \"" . $this->yystack[$this->yyidx + -3]->minor . "\"");
+ }
+ }
+ }
+
+ #line 1108 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r153() {
+ if ($this->security && substr($this->yystack[$this->yyidx + -3]->minor, 0, 1) == '_') {
+ $this->compiler->trigger_template_error(self::Err1);
+ }
+ $this->_retvalue = $this->yystack[$this->yyidx + -3]->minor . "(" . implode(',', $this->yystack[$this->yyidx + -1]->minor) . ")";
+ }
+
+ #line 1115 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r154() {
+ if ($this->security) {
+ $this->compiler->trigger_template_error(self::Err2);
+ }
+ self::$prefix_number++;
+ $this->compiler->prefix_code[] = '<?php $_tmp' . self::$prefix_number . '=' . $this->compiler->compileVariable('\'' . substr($this->yystack[$this->yyidx + -3]->minor, 1) . '\'') . ';?>';
+ $this->_retvalue = '$_tmp' . self::$prefix_number . '(' . implode(',', $this->yystack[$this->yyidx + -1]->minor) . ')';
+ }
+
+ #line 1126 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r155() {
+ $this->_retvalue = array_merge($this->yystack[$this->yyidx + -2]->minor, array($this->yystack[$this->yyidx + 0]->minor));
+ }
+
+ #line 1143 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r158() {
+ $this->_retvalue = array_merge($this->yystack[$this->yyidx + -2]->minor, array(array_merge($this->yystack[$this->yyidx + -1]->minor, $this->yystack[$this->yyidx + 0]->minor)));
+ }
+
+ #line 1147 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r159() {
+ $this->_retvalue = array(array_merge($this->yystack[$this->yyidx + -1]->minor, $this->yystack[$this->yyidx + 0]->minor));
+ }
+
+ #line 1155 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r161() {
+ $this->_retvalue = array($this->yystack[$this->yyidx + 0]->minor);
+ }
+
+ #line 1163 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r162() {
+ $this->_retvalue = array_merge($this->yystack[$this->yyidx + -1]->minor, $this->yystack[$this->yyidx + 0]->minor);
+ }
+
+ #line 1182 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r166() {
+ $this->_retvalue = array($this->yystack[$this->yyidx + 0]->minor, '', 'method');
+ }
+
+ #line 1187 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r167() {
+ $this->_retvalue = array($this->yystack[$this->yyidx + -1]->minor, $this->yystack[$this->yyidx + 0]->minor,
+ 'method');
+ }
+
+ #line 1192 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r168() {
+ $this->_retvalue = array($this->yystack[$this->yyidx + 0]->minor, '');
+ }
+
+ #line 1197 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r169() {
+ $this->_retvalue = array($this->yystack[$this->yyidx + -1]->minor, $this->yystack[$this->yyidx + 0]->minor,
+ 'property');
+ }
+
+ #line 1202 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r170() {
+ $this->_retvalue = array($this->yystack[$this->yyidx + -2]->minor,
+ $this->yystack[$this->yyidx + -1]->minor . $this->yystack[$this->yyidx + 0]->minor, 'property');
+ }
+
+ #line 1208 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r171() {
+ $this->_retvalue['op'] = ' ' . trim($this->yystack[$this->yyidx + 0]->minor) . ' ';
+ }
+
+ #line 1212 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r172() {
+ static $lops = array('eq' => array('op' => ' == ', 'pre' => null),
+ 'ne' => array('op' => ' != ', 'pre' => null),
+ 'neq' => array('op' => ' != ', 'pre' => null),
+ 'gt' => array('op' => ' > ', 'pre' => null),
+ 'ge' => array('op' => ' >= ', 'pre' => null),
+ 'gte' => array('op' => ' >= ', 'pre' => null),
+ 'lt' => array('op' => ' < ', 'pre' => null),
+ 'le' => array('op' => ' <= ', 'pre' => null),
+ 'lte' => array('op' => ' <= ', 'pre' => null),
+ 'mod' => array('op' => ' % ', 'pre' => null),
+ 'and' => array('op' => ' && ', 'pre' => null),
+ 'or' => array('op' => ' || ', 'pre' => null),
+ 'xor' => array('op' => ' xor ', 'pre' => null),
+ 'isdivby' => array('op' => ' % ', 'pre' => '!('),
+ 'isnotdivby' => array('op' => ' % ', 'pre' => '('),
+ 'isevenby' => array('op' => ' / ', 'pre' => '!(1 & '),
+ 'isnotevenby' => array('op' => ' / ', 'pre' => '(1 & '),
+ 'isoddby' => array('op' => ' / ', 'pre' => '(1 & '),
+ 'isnotoddby' => array('op' => ' / ', 'pre' => '!(1 & '),);
+ $op = strtolower(preg_replace('/\s*/', '', $this->yystack[$this->yyidx + 0]->minor));
+ $this->_retvalue = $lops[$op];
+ }
+
+ #line 1238 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r173() {
+ static $scond = array('iseven' => '!(1 & ', 'isnoteven' => '(1 & ', 'isodd' => '(1 & ',
+ 'isnotodd' => '!(1 & ',);
+ $op = strtolower(str_replace(' ', '', $this->yystack[$this->yyidx + 0]->minor));
+ $this->_retvalue = $scond[$op];
+ }
+
+ #line 1252 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r174() {
+ $this->_retvalue = 'array(' . $this->yystack[$this->yyidx + -1]->minor . ')';
+ }
+
+ #line 1260 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r176() {
+ $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor . ',' . $this->yystack[$this->yyidx + 0]->minor;
+ }
+
+ #line 1268 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r178() {
+ $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor . '=>' . $this->yystack[$this->yyidx + 0]->minor;
+ }
+
+ #line 1272 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r179() {
+ $this->_retvalue = '\'' . $this->yystack[$this->yyidx + -2]->minor . '\'=>' . $this->yystack[$this->yyidx + 0]->minor;
+ }
+
+ #line 1288 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r182() {
+ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor->to_smarty_php();
+ }
+
+ #line 1293 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r183() {
+ $this->yystack[$this->yyidx + -1]->minor->append_subtree($this->yystack[$this->yyidx + 0]->minor);
+ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor;
+ }
+
+ #line 1298 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r184() {
+ $this->_retvalue = new Smarty_Internal_ParseTree_Dq($this, $this->yystack[$this->yyidx + 0]->minor);
+ }
+
+ #line 1302 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r185() {
+ $this->_retvalue = new Smarty_Internal_ParseTree_Code($this, '(string)' . $this->yystack[$this->yyidx + -1]->minor);
+ }
+
+ #line 1310 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r187() {
+ $this->_retvalue = new Smarty_Internal_ParseTree_Code($this, '(string)$_smarty_tpl->tpl_vars[\'' . substr($this->yystack[$this->yyidx + 0]->minor, 1) . '\']->value');
+ }
+
+ #line 1318 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r189() {
+ $this->_retvalue = new Smarty_Internal_ParseTree_Code($this, '(string)(' . $this->yystack[$this->yyidx + -1]->minor . ')');
+ }
+
+ #line 1322 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r190() {
+ $this->_retvalue = new Smarty_Internal_ParseTree_Tag($this, $this->yystack[$this->yyidx + 0]->minor);
+ }
+
+ #line 1326 "../smarty/lexer/smarty_internal_templateparser.y"
+ function yy_r191() {
+ $this->_retvalue = new Smarty_Internal_ParseTree_DqContent($this, $this->yystack[$this->yyidx + 0]->minor);
+ }
+
+ private $_retvalue;
+
+ public function yy_reduce($yyruleno) {
+ if ($this->yyTraceFILE && $yyruleno >= 0 && $yyruleno < count(self::$yyRuleName)) {
+ fprintf($this->yyTraceFILE, "%sReduce (%d) [%s].\n", $this->yyTracePrompt, $yyruleno, self::$yyRuleName[$yyruleno]);
+ }
+
+ $this->_retvalue = $yy_lefthand_side = null;
+ if (isset(self::$yyReduceMap[$yyruleno])) {
+ // call the action
+ $this->_retvalue = null;
+ $this->{'yy_r' . self::$yyReduceMap[$yyruleno]}();
+ $yy_lefthand_side = $this->_retvalue;
+ }
+ $yygoto = self::$yyRuleInfo[$yyruleno][0];
+ $yysize = self::$yyRuleInfo[$yyruleno][1];
+ $this->yyidx -= $yysize;
+ for ($i = $yysize; $i; $i--) {
+ // pop all of the right-hand side parameters
+ array_pop($this->yystack);
+ }
+ $yyact = $this->yy_find_reduce_action($this->yystack[$this->yyidx]->stateno, $yygoto);
+ if ($yyact < self::YYNSTATE) {
+ if (!$this->yyTraceFILE && $yysize) {
+ $this->yyidx++;
+ $x = new TP_yyStackEntry;
+ $x->stateno = $yyact;
+ $x->major = $yygoto;
+ $x->minor = $yy_lefthand_side;
+ $this->yystack[$this->yyidx] = $x;
+ } else {
+ $this->yy_shift($yyact, $yygoto, $yy_lefthand_side);
+ }
+ } elseif ($yyact == self::YYNSTATE + self::YYNRULE + 1) {
+ $this->yy_accept();
+ }
+ }
+
+ public function yy_parse_failed() {
+ if ($this->yyTraceFILE) {
+ fprintf($this->yyTraceFILE, "%sFail!\n", $this->yyTracePrompt);
+ }
+ while ($this->yyidx >= 0) {
+ $this->yy_pop_parser_stack();
+ }
+ }
+
+ public function yy_syntax_error($yymajor, $TOKEN) {
+ #line 183 "../smarty/lexer/smarty_internal_templateparser.y"
+
+ $this->internalError = true;
+ $this->yymajor = $yymajor;
+ $this->compiler->trigger_template_error();
+ }
+
+ public function yy_accept() {
+ if ($this->yyTraceFILE) {
+ fprintf($this->yyTraceFILE, "%sAccept!\n", $this->yyTracePrompt);
+ }
+ while ($this->yyidx >= 0) {
+ $this->yy_pop_parser_stack();
+ }
+ #line 176 "../smarty/lexer/smarty_internal_templateparser.y"
+
+ $this->successful = !$this->internalError;
+ $this->internalError = false;
+ $this->retvalue = $this->_retvalue;
+ }
+
+ public function doParse($yymajor, $yytokenvalue) {
+ $yyerrorhit = 0; /* True if yymajor has invoked an error */
+
+ if ($this->yyidx === null || $this->yyidx < 0) {
+ $this->yyidx = 0;
+ $this->yyerrcnt = -1;
+ $x = new TP_yyStackEntry;
+ $x->stateno = 0;
+ $x->major = 0;
+ $this->yystack = array();
+ $this->yystack[] = $x;
+ }
+ $yyendofinput = ($yymajor == 0);
+
+ if ($this->yyTraceFILE) {
+ fprintf($this->yyTraceFILE, "%sInput %s\n", $this->yyTracePrompt, $this->yyTokenName[$yymajor]);
+ }
+
+ do {
+ $yyact = $this->yy_find_shift_action($yymajor);
+ if ($yymajor < self::YYERRORSYMBOL && !$this->yy_is_expected_token($yymajor)) {
+ // force a syntax error
+ $yyact = self::YY_ERROR_ACTION;
+ }
+ if ($yyact < self::YYNSTATE) {
+ $this->yy_shift($yyact, $yymajor, $yytokenvalue);
+ $this->yyerrcnt--;
+ if ($yyendofinput && $this->yyidx >= 0) {
+ $yymajor = 0;
+ } else {
+ $yymajor = self::YYNOCODE;
+ }
+ } elseif ($yyact < self::YYNSTATE + self::YYNRULE) {
+ $this->yy_reduce($yyact - self::YYNSTATE);
+ } elseif ($yyact == self::YY_ERROR_ACTION) {
+ if ($this->yyTraceFILE) {
+ fprintf($this->yyTraceFILE, "%sSyntax Error!\n", $this->yyTracePrompt);
+ }
+ if (self::YYERRORSYMBOL) {
+ if ($this->yyerrcnt < 0) {
+ $this->yy_syntax_error($yymajor, $yytokenvalue);
+ }
+ $yymx = $this->yystack[$this->yyidx]->major;
+ if ($yymx == self::YYERRORSYMBOL || $yyerrorhit) {
+ if ($this->yyTraceFILE) {
+ fprintf($this->yyTraceFILE, "%sDiscard input token %s\n", $this->yyTracePrompt, $this->yyTokenName[$yymajor]);
+ }
+ $this->yy_destructor($yymajor, $yytokenvalue);
+ $yymajor = self::YYNOCODE;
+ } else {
+ while ($this->yyidx >= 0 && $yymx != self::YYERRORSYMBOL && ($yyact = $this->yy_find_shift_action(self::YYERRORSYMBOL)) >= self::YYNSTATE) {
+ $this->yy_pop_parser_stack();
+ }
+ if ($this->yyidx < 0 || $yymajor == 0) {
+ $this->yy_destructor($yymajor, $yytokenvalue);
+ $this->yy_parse_failed();
+ $yymajor = self::YYNOCODE;
+ } elseif ($yymx != self::YYERRORSYMBOL) {
+ $u2 = 0;
+ $this->yy_shift($yyact, self::YYERRORSYMBOL, $u2);
+ }
+ }
+ $this->yyerrcnt = 3;
+ $yyerrorhit = 1;
+ } else {
+ if ($this->yyerrcnt <= 0) {
+ $this->yy_syntax_error($yymajor, $yytokenvalue);
+ }
+ $this->yyerrcnt = 3;
+ $this->yy_destructor($yymajor, $yytokenvalue);
+ if ($yyendofinput) {
+ $this->yy_parse_failed();
+ }
+ $yymajor = self::YYNOCODE;
+ }
+ } else {
+ $this->yy_accept();
+ $yymajor = self::YYNOCODE;
+ }
+ } while ($yymajor != self::YYNOCODE && $this->yyidx >= 0);
+ }
+}
+
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_testinstall.php
@@ -0,0 +1,570 @@
+<?php
+/**
+ * Smarty Internal TestInstall
+ * Test Smarty installation
+ *
+ * @package Smarty
+ * @subpackage Utilities
+ * @author Uwe Tews
+ */
+
+/**
+ * TestInstall class
+ *
+ * @package Smarty
+ * @subpackage Utilities
+ */
+class Smarty_Internal_TestInstall {
+ /**
+ * diagnose Smarty setup
+ * If $errors is secified, the diagnostic report will be appended to the array, rather than being output.
+ *
+ * @param Smarty $smarty Smarty instance to test
+ * @param array $errors array to push results into rather than outputting them
+ *
+ * @return bool status, true if everything is fine, false else
+ */
+ public static function testInstall(Smarty $smarty, &$errors = null) {
+ $status = true;
+
+ if ($errors === null) {
+ echo "<PRE>\n";
+ echo "Smarty Installation test...\n";
+ echo "Testing template directory...\n";
+ }
+
+ $_stream_resolve_include_path = function_exists('stream_resolve_include_path');
+
+ // test if all registered template_dir are accessible
+ foreach ($smarty->getTemplateDir() as $template_dir) {
+ $_template_dir = $template_dir;
+ $template_dir = realpath($template_dir);
+ // resolve include_path or fail existence
+ if (!$template_dir) {
+ if ($smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_template_dir)) {
+ // try PHP include_path
+ if ($_stream_resolve_include_path) {
+ $template_dir = stream_resolve_include_path($_template_dir);
+ } else {
+ $template_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_template_dir);
+ }
+
+ if ($template_dir !== false) {
+ if ($errors === null) {
+ echo "$template_dir is OK.\n";
+ }
+
+ continue;
+ } else {
+ $status = false;
+ $message = "FAILED: $_template_dir does not exist (and couldn't be found in include_path either)";
+ if ($errors === null) {
+ echo $message . ".\n";
+ } else {
+ $errors['template_dir'] = $message;
+ }
+
+ continue;
+ }
+ } else {
+ $status = false;
+ $message = "FAILED: $_template_dir does not exist";
+ if ($errors === null) {
+ echo $message . ".\n";
+ } else {
+ $errors['template_dir'] = $message;
+ }
+
+ continue;
+ }
+ }
+
+ if (!is_dir($template_dir)) {
+ $status = false;
+ $message = "FAILED: $template_dir is not a directory";
+ if ($errors === null) {
+ echo $message . ".\n";
+ } else {
+ $errors['template_dir'] = $message;
+ }
+ } elseif (!is_readable($template_dir)) {
+ $status = false;
+ $message = "FAILED: $template_dir is not readable";
+ if ($errors === null) {
+ echo $message . ".\n";
+ } else {
+ $errors['template_dir'] = $message;
+ }
+ } else {
+ if ($errors === null) {
+ echo "$template_dir is OK.\n";
+ }
+ }
+ }
+
+ if ($errors === null) {
+ echo "Testing compile directory...\n";
+ }
+
+ // test if registered compile_dir is accessible
+ $__compile_dir = $smarty->getCompileDir();
+ $_compile_dir = realpath($__compile_dir);
+ if (!$_compile_dir) {
+ $status = false;
+ $message = "FAILED: {$__compile_dir} does not exist";
+ if ($errors === null) {
+ echo $message . ".\n";
+ } else {
+ $errors['compile_dir'] = $message;
+ }
+ } elseif (!is_dir($_compile_dir)) {
+ $status = false;
+ $message = "FAILED: {$_compile_dir} is not a directory";
+ if ($errors === null) {
+ echo $message . ".\n";
+ } else {
+ $errors['compile_dir'] = $message;
+ }
+ } elseif (!is_readable($_compile_dir)) {
+ $status = false;
+ $message = "FAILED: {$_compile_dir} is not readable";
+ if ($errors === null) {
+ echo $message . ".\n";
+ } else {
+ $errors['compile_dir'] = $message;
+ }
+ } elseif (!is_writable($_compile_dir)) {
+ $status = false;
+ $message = "FAILED: {$_compile_dir} is not writable";
+ if ($errors === null) {
+ echo $message . ".\n";
+ } else {
+ $errors['compile_dir'] = $message;
+ }
+ } else {
+ if ($errors === null) {
+ echo "{$_compile_dir} is OK.\n";
+ }
+ }
+
+ if ($errors === null) {
+ echo "Testing plugins directory...\n";
+ }
+
+ // test if all registered plugins_dir are accessible
+ // and if core plugins directory is still registered
+ $_core_plugins_dir = realpath(dirname(__FILE__) . '/../plugins');
+ $_core_plugins_available = false;
+ foreach ($smarty->getPluginsDir() as $plugin_dir) {
+ $_plugin_dir = $plugin_dir;
+ $plugin_dir = realpath($plugin_dir);
+ // resolve include_path or fail existence
+ if (!$plugin_dir) {
+ if ($smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_plugin_dir)) {
+ // try PHP include_path
+ if ($_stream_resolve_include_path) {
+ $plugin_dir = stream_resolve_include_path($_plugin_dir);
+ } else {
+ $plugin_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_plugin_dir);
+ }
+
+ if ($plugin_dir !== false) {
+ if ($errors === null) {
+ echo "$plugin_dir is OK.\n";
+ }
+
+ continue;
+ } else {
+ $status = false;
+ $message = "FAILED: $_plugin_dir does not exist (and couldn't be found in include_path either)";
+ if ($errors === null) {
+ echo $message . ".\n";
+ } else {
+ $errors['plugins_dir'] = $message;
+ }
+
+ continue;
+ }
+ } else {
+ $status = false;
+ $message = "FAILED: $_plugin_dir does not exist";
+ if ($errors === null) {
+ echo $message . ".\n";
+ } else {
+ $errors['plugins_dir'] = $message;
+ }
+
+ continue;
+ }
+ }
+
+ if (!is_dir($plugin_dir)) {
+ $status = false;
+ $message = "FAILED: $plugin_dir is not a directory";
+ if ($errors === null) {
+ echo $message . ".\n";
+ } else {
+ $errors['plugins_dir'] = $message;
+ }
+ } elseif (!is_readable($plugin_dir)) {
+ $status = false;
+ $message = "FAILED: $plugin_dir is not readable";
+ if ($errors === null) {
+ echo $message . ".\n";
+ } else {
+ $errors['plugins_dir'] = $message;
+ }
+ } elseif ($_core_plugins_dir && $_core_plugins_dir == realpath($plugin_dir)) {
+ $_core_plugins_available = true;
+ if ($errors === null) {
+ echo "$plugin_dir is OK.\n";
+ }
+ } else {
+ if ($errors === null) {
+ echo "$plugin_dir is OK.\n";
+ }
+ }
+ }
+ if (!$_core_plugins_available) {
+ $status = false;
+ $message = "WARNING: Smarty's own libs/plugins is not available";
+ if ($errors === null) {
+ echo $message . ".\n";
+ } elseif (!isset($errors['plugins_dir'])) {
+ $errors['plugins_dir'] = $message;
+ }
+ }
+
+ if ($errors === null) {
+ echo "Testing cache directory...\n";
+ }
+
+ // test if all registered cache_dir is accessible
+ $__cache_dir = $smarty->getCacheDir();
+ $_cache_dir = realpath($__cache_dir);
+ if (!$_cache_dir) {
+ $status = false;
+ $message = "FAILED: {$__cache_dir} does not exist";
+ if ($errors === null) {
+ echo $message . ".\n";
+ } else {
+ $errors['cache_dir'] = $message;
+ }
+ } elseif (!is_dir($_cache_dir)) {
+ $status = false;
+ $message = "FAILED: {$_cache_dir} is not a directory";
+ if ($errors === null) {
+ echo $message . ".\n";
+ } else {
+ $errors['cache_dir'] = $message;
+ }
+ } elseif (!is_readable($_cache_dir)) {
+ $status = false;
+ $message = "FAILED: {$_cache_dir} is not readable";
+ if ($errors === null) {
+ echo $message . ".\n";
+ } else {
+ $errors['cache_dir'] = $message;
+ }
+ } elseif (!is_writable($_cache_dir)) {
+ $status = false;
+ $message = "FAILED: {$_cache_dir} is not writable";
+ if ($errors === null) {
+ echo $message . ".\n";
+ } else {
+ $errors['cache_dir'] = $message;
+ }
+ } else {
+ if ($errors === null) {
+ echo "{$_cache_dir} is OK.\n";
+ }
+ }
+
+ if ($errors === null) {
+ echo "Testing configs directory...\n";
+ }
+
+ // test if all registered config_dir are accessible
+ foreach ($smarty->getConfigDir() as $config_dir) {
+ $_config_dir = $config_dir;
+ $config_dir = realpath($config_dir);
+ // resolve include_path or fail existence
+ if (!$config_dir) {
+ if ($smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_config_dir)) {
+ // try PHP include_path
+ if ($_stream_resolve_include_path) {
+ $config_dir = stream_resolve_include_path($_config_dir);
+ } else {
+ $config_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_config_dir);
+ }
+
+ if ($config_dir !== false) {
+ if ($errors === null) {
+ echo "$config_dir is OK.\n";
+ }
+
+ continue;
+ } else {
+ $status = false;
+ $message = "FAILED: $_config_dir does not exist (and couldn't be found in include_path either)";
+ if ($errors === null) {
+ echo $message . ".\n";
+ } else {
+ $errors['config_dir'] = $message;
+ }
+
+ continue;
+ }
+ } else {
+ $status = false;
+ $message = "FAILED: $_config_dir does not exist";
+ if ($errors === null) {
+ echo $message . ".\n";
+ } else {
+ $errors['config_dir'] = $message;
+ }
+
+ continue;
+ }
+ }
+
+ if (!is_dir($config_dir)) {
+ $status = false;
+ $message = "FAILED: $config_dir is not a directory";
+ if ($errors === null) {
+ echo $message . ".\n";
+ } else {
+ $errors['config_dir'] = $message;
+ }
+ } elseif (!is_readable($config_dir)) {
+ $status = false;
+ $message = "FAILED: $config_dir is not readable";
+ if ($errors === null) {
+ echo $message . ".\n";
+ } else {
+ $errors['config_dir'] = $message;
+ }
+ } else {
+ if ($errors === null) {
+ echo "$config_dir is OK.\n";
+ }
+ }
+ }
+
+ if ($errors === null) {
+ echo "Testing sysplugin files...\n";
+ }
+ // test if sysplugins are available
+ $source = SMARTY_SYSPLUGINS_DIR;
+ if (is_dir($source)) {
+ $expected = array(
+ "smarty_cacheresource.php" => true,
+ "smarty_cacheresource_custom.php" => true,
+ "smarty_cacheresource_keyvaluestore.php" => true,
+ "smarty_data.php" => true,
+ "smarty_internal_cacheresource_file.php" => true,
+ "smarty_internal_compile_append.php" => true,
+ "smarty_internal_compile_assign.php" => true,
+ "smarty_internal_compile_block.php" => true,
+ "smarty_internal_compile_break.php" => true,
+ "smarty_internal_compile_call.php" => true,
+ "smarty_internal_compile_capture.php" => true,
+ "smarty_internal_compile_config_load.php" => true,
+ "smarty_internal_compile_continue.php" => true,
+ "smarty_internal_compile_debug.php" => true,
+ "smarty_internal_compile_eval.php" => true,
+ "smarty_internal_compile_extends.php" => true,
+ "smarty_internal_compile_for.php" => true,
+ "smarty_internal_compile_foreach.php" => true,
+ "smarty_internal_compile_function.php" => true,
+ "smarty_internal_compile_if.php" => true,
+ "smarty_internal_compile_include.php" => true,
+ "smarty_internal_compile_include_php.php" => true,
+ "smarty_internal_compile_insert.php" => true,
+ "smarty_internal_compile_ldelim.php" => true,
+ "smarty_internal_compile_nocache.php" => true,
+ "smarty_internal_compile_private_block_plugin.php" => true,
+ "smarty_internal_compile_private_function_plugin.php" => true,
+ "smarty_internal_compile_private_modifier.php" => true,
+ "smarty_internal_compile_private_object_block_function.php" => true,
+ "smarty_internal_compile_private_object_function.php" => true,
+ "smarty_internal_compile_private_print_expression.php" => true,
+ "smarty_internal_compile_private_registered_block.php" => true,
+ "smarty_internal_compile_private_registered_function.php" => true,
+ "smarty_internal_compile_private_special_variable.php" => true,
+ "smarty_internal_compile_rdelim.php" => true,
+ "smarty_internal_compile_section.php" => true,
+ "smarty_internal_compile_setfilter.php" => true,
+ "smarty_internal_compile_while.php" => true,
+ "smarty_internal_compilebase.php" => true,
+ "smarty_internal_config_file_compiler.php" => true,
+ "smarty_internal_configfilelexer.php" => true,
+ "smarty_internal_configfileparser.php" => true,
+ "smarty_internal_data.php" => true,
+ "smarty_internal_debug.php" => true,
+ "smarty_internal_extension_codeframe.php" => true,
+ "smarty_internal_extension_config.php" => true,
+ "smarty_internal_extension_defaulttemplatehandler.php" => true,
+ "smarty_internal_filter_handler.php" => true,
+ "smarty_internal_function_call_handler.php" => true,
+ "smarty_internal_get_include_path.php" => true,
+ "smarty_internal_nocache_insert.php" => true,
+ "smarty_internal_parsetree.php" => true,
+ "smarty_internal_parsetree_code.php" => true,
+ "smarty_internal_parsetree_dq.php" => true,
+ "smarty_internal_parsetree_dqcontent.php" => true,
+ "smarty_internal_parsetree_tag.php" => true,
+ "smarty_internal_parsetree_template.php" => true,
+ "smarty_internal_parsetree_text.php" => true,
+ "smarty_internal_resource_eval.php" => true,
+ "smarty_internal_resource_extends.php" => true,
+ "smarty_internal_resource_file.php" => true,
+ "smarty_internal_resource_php.php" => true,
+ "smarty_internal_resource_registered.php" => true,
+ "smarty_internal_resource_stream.php" => true,
+ "smarty_internal_resource_string.php" => true,
+ "smarty_internal_smartytemplatecompiler.php" => true,
+ "smarty_internal_template.php" => true,
+ "smarty_internal_templatebase.php" => true,
+ "smarty_internal_templatecompilerbase.php" => true,
+ "smarty_internal_templatelexer.php" => true,
+ "smarty_internal_templateparser.php" => true,
+ "smarty_internal_utility.php" => true,
+ "smarty_internal_write_file.php" => true,
+ "smarty_resource.php" => true,
+ "smarty_resource_custom.php" => true,
+ "smarty_resource_recompiled.php" => true,
+ "smarty_resource_uncompiled.php" => true,
+ "smarty_security.php" => true,
+ "smarty_template_cached.php" => true,
+ "smarty_template_compiled.php" => true,
+ "smarty_template_config.php" => true,
+ "smarty_template_source.php" => true,
+ "smarty_undefined_variable.php" => true,
+ "smarty_variable.php" => true,
+ "smartycompilerexception.php" => true,
+ "smartyexception.php" => true,
+ );
+ $iterator = new DirectoryIterator($source);
+ foreach ($iterator as $file) {
+ if (!$file->isDot()) {
+ $filename = $file->getFilename();
+ if (isset($expected[$filename])) {
+ unset($expected[$filename]);
+ }
+ }
+ }
+ if ($expected) {
+ $status = false;
+ $message = "FAILED: files missing from libs/sysplugins: " . join(', ', array_keys($expected));
+ if ($errors === null) {
+ echo $message . ".\n";
+ } else {
+ $errors['sysplugins'] = $message;
+ }
+ } elseif ($errors === null) {
+ echo "... OK\n";
+ }
+ } else {
+ $status = false;
+ $message = "FAILED: " . SMARTY_SYSPLUGINS_DIR . ' is not a directory';
+ if ($errors === null) {
+ echo $message . ".\n";
+ } else {
+ $errors['sysplugins_dir_constant'] = $message;
+ }
+ }
+
+ if ($errors === null) {
+ echo "Testing plugin files...\n";
+ }
+ // test if core plugins are available
+ $source = SMARTY_PLUGINS_DIR;
+ if (is_dir($source)) {
+ $expected = array(
+ "block.textformat.php" => true,
+ "function.counter.php" => true,
+ "function.cycle.php" => true,
+ "function.fetch.php" => true,
+ "function.html_checkboxes.php" => true,
+ "function.html_image.php" => true,
+ "function.html_options.php" => true,
+ "function.html_radios.php" => true,
+ "function.html_select_date.php" => true,
+ "function.html_select_time.php" => true,
+ "function.html_table.php" => true,
+ "function.mailto.php" => true,
+ "function.math.php" => true,
+ "modifier.capitalize.php" => true,
+ "modifier.date_format.php" => true,
+ "modifier.debug_print_var.php" => true,
+ "modifier.escape.php" => true,
+ "modifier.regex_replace.php" => true,
+ "modifier.replace.php" => true,
+ "modifier.spacify.php" => true,
+ "modifier.truncate.php" => true,
+ "modifiercompiler.cat.php" => true,
+ "modifiercompiler.count_characters.php" => true,
+ "modifiercompiler.count_paragraphs.php" => true,
+ "modifiercompiler.count_sentences.php" => true,
+ "modifiercompiler.count_words.php" => true,
+ "modifiercompiler.default.php" => true,
+ "modifiercompiler.escape.php" => true,
+ "modifiercompiler.from_charset.php" => true,
+ "modifiercompiler.indent.php" => true,
+ "modifiercompiler.lower.php" => true,
+ "modifiercompiler.noprint.php" => true,
+ "modifiercompiler.string_format.php" => true,
+ "modifiercompiler.strip.php" => true,
+ "modifiercompiler.strip_tags.php" => true,
+ "modifiercompiler.to_charset.php" => true,
+ "modifiercompiler.unescape.php" => true,
+ "modifiercompiler.upper.php" => true,
+ "modifiercompiler.wordwrap.php" => true,
+ "outputfilter.trimwhitespace.php" => true,
+ "shared.escape_special_chars.php" => true,
+ "shared.literal_compiler_param.php" => true,
+ "shared.make_timestamp.php" => true,
+ "shared.mb_str_replace.php" => true,
+ "shared.mb_unicode.php" => true,
+ "shared.mb_wordwrap.php" => true,
+ "variablefilter.htmlspecialchars.php" => true,
+ );
+ $iterator = new DirectoryIterator($source);
+ foreach ($iterator as $file) {
+ if (!$file->isDot()) {
+ $filename = $file->getFilename();
+ if (isset($expected[$filename])) {
+ unset($expected[$filename]);
+ }
+ }
+ }
+ if ($expected) {
+ $status = false;
+ $message = "FAILED: files missing from libs/plugins: " . join(', ', array_keys($expected));
+ if ($errors === null) {
+ echo $message . ".\n";
+ } else {
+ $errors['plugins'] = $message;
+ }
+ } elseif ($errors === null) {
+ echo "... OK\n";
+ }
+ } else {
+ $status = false;
+ $message = "FAILED: " . SMARTY_PLUGINS_DIR . ' is not a directory';
+ if ($errors === null) {
+ echo $message . ".\n";
+ } else {
+ $errors['plugins_dir_constant'] = $message;
+ }
+ }
+
+ if ($errors === null) {
+ echo "Tests complete.\n";
+ echo "</PRE>\n";
+ }
+
+ return $status;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_utility.php
@@ -0,0 +1,294 @@
+<?php
+/**
+ * Project: Smarty: the PHP compiling template engine
+ * File: smarty_internal_utility.php
+ * SVN: $Id: $
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * For questions, help, comments, discussion, etc., please join the
+ * Smarty mailing list. Send a blank e-mail to
+ * smarty-discussion-subscribe@googlegroups.com
+ *
+ * @link http://www.smarty.net/
+ * @copyright 2008 New Digital Group, Inc.
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author Uwe Tews
+ * @package Smarty
+ * @subpackage PluginsInternal
+ * @version 3-SVN$Rev: 3286 $
+ */
+
+/**
+ * Utility class
+ *
+ * @package Smarty
+ * @subpackage Security
+ */
+class Smarty_Internal_Utility {
+ /**
+ * private constructor to prevent calls creation of new instances
+ */
+ final private function __construct() {
+ // intentionally left blank
+ }
+
+ /**
+ * Compile all template files
+ *
+ * @param string $extension template file name extension
+ * @param bool $force_compile force all to recompile
+ * @param int $time_limit set maximum execution time
+ * @param int $max_errors set maximum allowed errors
+ * @param Smarty $smarty Smarty instance
+ *
+ * @return integer number of template files compiled
+ */
+ public static function compileAllTemplates($extension, $force_compile, $time_limit, $max_errors, Smarty $smarty) {
+ // switch off time limit
+ if (function_exists('set_time_limit')) {
+ @set_time_limit($time_limit);
+ }
+ $smarty->force_compile = $force_compile;
+ $_count = 0;
+ $_error_count = 0;
+ // loop over array of template directories
+ foreach ($smarty->getTemplateDir() as $_dir) {
+ $_compileDirs = new RecursiveDirectoryIterator($_dir);
+ $_compile = new RecursiveIteratorIterator($_compileDirs);
+ foreach ($_compile as $_fileinfo) {
+ $_file = $_fileinfo->getFilename();
+ if (substr(basename($_fileinfo->getPathname()), 0, 1) == '.' || strpos($_file, '.svn') !== false) {
+ continue;
+ }
+ if (!substr_compare($_file, $extension, -strlen($extension)) == 0) {
+ continue;
+ }
+ if ($_fileinfo->getPath() == substr($_dir, 0, -1)) {
+ $_template_file = $_file;
+ } else {
+ $_template_file = substr($_fileinfo->getPath(), strlen($_dir)) . DS . $_file;
+ }
+ echo '<br>', $_dir, '---', $_template_file;
+ flush();
+ $_start_time = microtime(true);
+ try {
+ $_tpl = $smarty->createTemplate($_template_file, null, null, null, false);
+ if ($_tpl->mustCompile()) {
+ $_tpl->compileTemplateSource();
+ $_count++;
+ echo ' compiled in ', microtime(true) - $_start_time, ' seconds';
+ flush();
+ } else {
+ echo ' is up to date';
+ flush();
+ }
+ } catch (Exception $e) {
+ echo 'Error: ', $e->getMessage(), "<br><br>";
+ $_error_count++;
+ }
+ // free memory
+ $smarty->template_objects = array();
+ $_tpl->smarty->template_objects = array();
+ $_tpl = null;
+ if ($max_errors !== null && $_error_count == $max_errors) {
+ echo '<br><br>too many errors';
+ exit();
+ }
+ }
+ }
+
+ return $_count;
+ }
+
+ /**
+ * Compile all config files
+ *
+ * @param string $extension config file name extension
+ * @param bool $force_compile force all to recompile
+ * @param int $time_limit set maximum execution time
+ * @param int $max_errors set maximum allowed errors
+ * @param Smarty $smarty Smarty instance
+ *
+ * @return integer number of config files compiled
+ */
+ public static function compileAllConfig($extension, $force_compile, $time_limit, $max_errors, Smarty $smarty) {
+ // switch off time limit
+ if (function_exists('set_time_limit')) {
+ @set_time_limit($time_limit);
+ }
+ $smarty->force_compile = $force_compile;
+ $_count = 0;
+ $_error_count = 0;
+ // loop over array of template directories
+ foreach ($smarty->getConfigDir() as $_dir) {
+ $_compileDirs = new RecursiveDirectoryIterator($_dir);
+ $_compile = new RecursiveIteratorIterator($_compileDirs);
+ foreach ($_compile as $_fileinfo) {
+ $_file = $_fileinfo->getFilename();
+ if (substr(basename($_fileinfo->getPathname()), 0, 1) == '.' || strpos($_file, '.svn') !== false) {
+ continue;
+ }
+ if (!substr_compare($_file, $extension, -strlen($extension)) == 0) {
+ continue;
+ }
+ if ($_fileinfo->getPath() == substr($_dir, 0, -1)) {
+ $_config_file = $_file;
+ } else {
+ $_config_file = substr($_fileinfo->getPath(), strlen($_dir)) . DS . $_file;
+ }
+ echo '<br>', $_dir, '---', $_config_file;
+ flush();
+ $_start_time = microtime(true);
+ try {
+ $_config = new Smarty_Internal_Config($_config_file, $smarty);
+ if ($_config->mustCompile()) {
+ $_config->compileConfigSource();
+ $_count++;
+ echo ' compiled in ', microtime(true) - $_start_time, ' seconds';
+ flush();
+ } else {
+ echo ' is up to date';
+ flush();
+ }
+ } catch (Exception $e) {
+ echo 'Error: ', $e->getMessage(), "<br><br>";
+ $_error_count++;
+ }
+ if ($max_errors !== null && $_error_count == $max_errors) {
+ echo '<br><br>too many errors';
+ exit();
+ }
+ }
+ }
+
+ return $_count;
+ }
+
+ /**
+ * Delete compiled template file
+ *
+ * @param string $resource_name template name
+ * @param string $compile_id compile id
+ * @param integer $exp_time expiration time
+ * @param Smarty $smarty Smarty instance
+ *
+ * @return integer number of template files deleted
+ */
+ public static function clearCompiledTemplate($resource_name, $compile_id, $exp_time, Smarty $smarty) {
+ $_compile_dir = realpath($smarty->getCompileDir()) . '/';
+ if ($_compile_dir == '/') { //We should never want to delete this!
+ return 0;
+ }
+ $_compile_id = isset($compile_id) ? preg_replace('![^\w\|]+!', '_', $compile_id) : null;
+ $_dir_sep = $smarty->use_sub_dirs ? '/' : '^';
+ if (isset($resource_name)) {
+ $_save_stat = $smarty->caching;
+ $smarty->caching = false;
+ $tpl = new $smarty->template_class($resource_name, $smarty);
+ $smarty->caching = $_save_stat;
+
+ // remove from template cache
+ $tpl->source; // have the template registered before unset()
+ if ($smarty->allow_ambiguous_resources) {
+ $_templateId = $tpl->source->unique_resource . $tpl->cache_id . $tpl->compile_id;
+ } else {
+ $_templateId = $smarty->joined_template_dir . '#' . $resource_name . $tpl->cache_id . $tpl->compile_id;
+ }
+ if (isset($_templateId[150])) {
+ $_templateId = sha1($_templateId);
+ }
+ unset($smarty->template_objects[$_templateId]);
+
+ if ($tpl->source->exists) {
+ $_resource_part_1 = basename(str_replace('^', '/', $tpl->compiled->filepath));
+ $_resource_part_1_length = strlen($_resource_part_1);
+ } else {
+ return 0;
+ }
+
+ $_resource_part_2 = str_replace('.php', '.cache.php', $_resource_part_1);
+ $_resource_part_2_length = strlen($_resource_part_2);
+ }
+ $_dir = $_compile_dir;
+ if ($smarty->use_sub_dirs && isset($_compile_id)) {
+ $_dir .= $_compile_id . $_dir_sep;
+ }
+ if (isset($_compile_id)) {
+ $_compile_id_part = str_replace('\\', '/', $_compile_dir . $_compile_id . $_dir_sep);
+ $_compile_id_part_length = strlen($_compile_id_part);
+ }
+ $_count = 0;
+ try {
+ $_compileDirs = new RecursiveDirectoryIterator($_dir);
+ // NOTE: UnexpectedValueException thrown for PHP >= 5.3
+ } catch (Exception $e) {
+ return 0;
+ }
+ $_compile = new RecursiveIteratorIterator($_compileDirs, RecursiveIteratorIterator::CHILD_FIRST);
+ foreach ($_compile as $_file) {
+ if (substr(basename($_file->getPathname()), 0, 1) == '.' || strpos($_file, '.svn') !== false) {
+ continue;
+ }
+
+ $_filepath = str_replace('\\', '/', (string)$_file);
+
+ if ($_file->isDir()) {
+ if (!$_compile->isDot()) {
+ // delete folder if empty
+ @rmdir($_file->getPathname());
+ }
+ } else {
+ $unlink = false;
+ if ((!isset($_compile_id) || (isset($_filepath[$_compile_id_part_length]) && $a = !strncmp($_filepath, $_compile_id_part, $_compile_id_part_length)))
+ && (!isset($resource_name)
+ || (isset($_filepath[$_resource_part_1_length])
+ && substr_compare($_filepath, $_resource_part_1, -$_resource_part_1_length, $_resource_part_1_length) == 0)
+ || (isset($_filepath[$_resource_part_2_length])
+ && substr_compare($_filepath, $_resource_part_2, -$_resource_part_2_length, $_resource_part_2_length) == 0))
+ ) {
+ if (isset($exp_time)) {
+ if (time() - @filemtime($_filepath) >= $exp_time) {
+ $unlink = true;
+ }
+ } else {
+ $unlink = true;
+ }
+ }
+
+ if ($unlink && @unlink($_filepath)) {
+ $_count++;
+ }
+ }
+ }
+ // clear compiled cache
+ Smarty_Resource::$sources = array();
+ Smarty_Resource::$compileds = array();
+
+ return $_count;
+ }
+
+ /**
+ * Return array of tag/attributes of all tags used by an template
+ *
+ * @param Smarty_Internal_Template $template
+ *
+ * @throws Exception
+ * @throws SmartyException
+ * @return array of tag/attributes
+ */
+ public static function getTags(Smarty_Internal_Template $template) {
+ $template->smarty->get_used_tags = true;
+ $template->compileTemplateSource();
+
+ return $template->used_tags;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_internal_write_file.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ * Smarty write file plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsInternal
+ * @author Monte Ohrt
+ */
+
+/**
+ * Smarty Internal Write File Class
+ *
+ * @package Smarty
+ * @subpackage PluginsInternal
+ */
+class Smarty_Internal_Write_File {
+ /**
+ * Writes file in a safe way to disk
+ *
+ * @param string $_filepath complete filepath
+ * @param string $_contents file content
+ * @param Smarty $smarty smarty instance
+ *
+ * @throws SmartyException
+ * @return boolean true
+ */
+ public function writeFile($_filepath, $_contents, Smarty $smarty) {
+ $_error_reporting = error_reporting();
+ error_reporting($_error_reporting & ~E_NOTICE & ~E_WARNING);
+ if ($smarty->_file_perms !== null) {
+ $old_umask = umask(0);
+ }
+
+ $_dirpath = dirname($_filepath);
+ // if subdirs, create dir structure
+ if ($_dirpath !== '.' && !file_exists($_dirpath)) {
+ mkdir($_dirpath, $smarty->_dir_perms === null ? 0777 : $smarty->_dir_perms, true);
+ }
+
+ // write to tmp file, then move to overt file lock race condition
+ $_tmp_file = $_dirpath . DS . str_replace(array('.', ','), '_', uniqid('wrt', true));
+ if (!file_put_contents($_tmp_file, $_contents)) {
+ error_reporting($_error_reporting);
+ throw new SmartyException("unable to write file {$_tmp_file}");
+ }
+
+ /*
+ * Windows' rename() fails if the destination exists,
+ * Linux' rename() properly handles the overwrite.
+ * Simply unlink()ing a file might cause other processes
+ * currently reading that file to fail, but linux' rename()
+ * seems to be smart enough to handle that for us.
+ */
+ if (Smarty::$_IS_WINDOWS) {
+ // remove original file
+ if (is_file($_filepath)) {
+ @unlink($_filepath);
+ }
+ // rename tmp file
+ $success = @rename($_tmp_file, $_filepath);
+ } else {
+ // rename tmp file
+ $success = @rename($_tmp_file, $_filepath);
+ if (!$success) {
+ // remove original file
+ if (is_file($_filepath)) {
+ @unlink($_filepath);
+ }
+ // rename tmp file
+ $success = @rename($_tmp_file, $_filepath);
+ }
+ }
+ if (!$success) {
+ error_reporting($_error_reporting);
+ throw new SmartyException("unable to write file {$_filepath}");
+ }
+ if ($smarty->_file_perms !== null) {
+ // set file permissions
+ chmod($_filepath, $smarty->_file_perms);
+ umask($old_umask);
+ }
+ error_reporting($_error_reporting);
+
+ return true;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_resource.php
@@ -0,0 +1,276 @@
+<?php
+/**
+ * Smarty Resource Plugin
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Rodney Rehm
+ */
+
+/**
+ * Smarty Resource Plugin
+ * Base implementation for resource plugins
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ */
+abstract class Smarty_Resource {
+ /**
+ * Source is bypassing compiler
+ *
+ * @var boolean
+ */
+ public $uncompiled = false;
+
+ /**
+ * Source must be recompiled on every occasion
+ *
+ * @var boolean
+ */
+ public $recompiled = false;
+ /**
+ * resource handler object
+ *
+ * @var Smarty_Resource
+ */
+ public $handler = null;
+ /**
+ * cache for Smarty_Template_Source instances
+ *
+ * @var array
+ */
+ public static $sources = array();
+ /**
+ * cache for Smarty_Template_Compiled instances
+ *
+ * @var array
+ */
+ public static $compileds = array();
+ /**
+ * resource types provided by the core
+ *
+ * @var array
+ */
+ protected static $sysplugins = array(
+ 'file' => 'smarty_internal_resource_file.php',
+ 'string' => 'smarty_internal_resource_string.php',
+ 'extends' => 'smarty_internal_resource_extends.php',
+ 'stream' => 'smarty_internal_resource_stream.php',
+ 'eval' => 'smarty_internal_resource_eval.php',
+ 'php' => 'smarty_internal_resource_php.php'
+ );
+
+ /**
+ * Name of the Class to compile this resource's contents with
+ *
+ * @var string
+ */
+ public $compiler_class = 'Smarty_Internal_SmartyTemplateCompiler';
+
+ /**
+ * Name of the Class to tokenize this resource's contents with
+ *
+ * @var string
+ */
+ public $template_lexer_class = 'Smarty_Internal_Templatelexer';
+
+ /**
+ * Name of the Class to parse this resource's contents with
+ *
+ * @var string
+ */
+ public $template_parser_class = 'Smarty_Internal_Templateparser';
+
+ /**
+ * Load template's source into current template object
+ * {@internal The loaded source is assigned to $_template->source->content directly.}}
+ *
+ * @param Smarty_Template_Source $source source object
+ *
+ * @return string template source
+ * @throws SmartyException if source cannot be loaded
+ */
+ abstract public function getContent(Smarty_Template_Source $source);
+
+ /**
+ * populate Source Object with meta data from Resource
+ *
+ * @param Smarty_Template_Source $source source object
+ * @param Smarty_Internal_Template $_template template object
+ */
+ abstract public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template = null);
+
+ /**
+ * populate Source Object with timestamp and exists from Resource
+ *
+ * @param Smarty_Template_Source $source source object
+ */
+ public function populateTimestamp(Smarty_Template_Source $source) {
+ // intentionally left blank
+ }
+
+ /**
+ * modify resource_name according to resource handlers specifications
+ *
+ * @param Smarty $smarty Smarty instance
+ * @param string $resource_name resource_name to make unique
+ * @param boolean $isConfig flag for config resource
+ *
+ * @return string unique resource name
+ */
+ public function buildUniqueResourceName(Smarty $smarty, $resource_name, $isConfig = false) {
+ if ($isConfig) {
+ return get_class($this) . '#' . $smarty->joined_config_dir . '#' . $resource_name;
+ } else {
+ return get_class($this) . '#' . $smarty->joined_template_dir . '#' . $resource_name;
+ }
+ }
+
+ /**
+ * Determine basename for compiled filename
+ *
+ * @param Smarty_Template_Source $source source object
+ *
+ * @return string resource's basename
+ */
+ public function getBasename(Smarty_Template_Source $source) {
+ return null;
+ }
+
+ /**
+ * Load Resource Handler
+ *
+ * @param Smarty $smarty smarty object
+ * @param string $type name of the resource
+ *
+ * @throws SmartyException
+ * @return Smarty_Resource Resource Handler
+ */
+ public static function load(Smarty $smarty, $type) {
+ // try smarty's cache
+ if (isset($smarty->_resource_handlers[$type])) {
+ return $smarty->_resource_handlers[$type];
+ }
+
+ // try registered resource
+ if (isset($smarty->registered_resources[$type])) {
+ if ($smarty->registered_resources[$type] instanceof Smarty_Resource) {
+ $smarty->_resource_handlers[$type] = $smarty->registered_resources[$type];
+ } else {
+ $smarty->_resource_handlers[$type] = new Smarty_Internal_Resource_Registered();
+ }
+
+ return $smarty->_resource_handlers[$type];
+ }
+
+ // try sysplugins dir
+ if (isset(self::$sysplugins[$type])) {
+ $_resource_class = 'Smarty_Internal_Resource_' . ucfirst($type);
+ if (!class_exists($_resource_class, false)) {
+ require SMARTY_SYSPLUGINS_DIR . self::$sysplugins[$type];
+ }
+ return $smarty->_resource_handlers[$type] = new $_resource_class();
+ }
+
+ // try plugins dir
+ $_resource_class = 'Smarty_Resource_' . ucfirst($type);
+ if ($smarty->loadPlugin($_resource_class)) {
+ if (class_exists($_resource_class, false)) {
+ return $smarty->_resource_handlers[$type] = new $_resource_class();
+ } else {
+ $smarty->registerResource($type, array(
+ "smarty_resource_{$type}_source",
+ "smarty_resource_{$type}_timestamp",
+ "smarty_resource_{$type}_secure",
+ "smarty_resource_{$type}_trusted"
+ ));
+ // give it another try, now that the resource is registered properly
+ return self::load($smarty, $type);
+ }
+ }
+
+ // try streams
+ $_known_stream = stream_get_wrappers();
+ if (in_array($type, $_known_stream)) {
+ // is known stream
+ if (is_object($smarty->security_policy)) {
+ $smarty->security_policy->isTrustedStream($type);
+ }
+ return $smarty->_resource_handlers[$type] = new Smarty_Internal_Resource_Stream();;
+ }
+
+ // TODO: try default_(template|config)_handler
+
+ // give up
+ throw new SmartyException("Unknown resource type '{$type}'");
+ }
+
+ /**
+ * extract resource_type and resource_name from template_resource and config_resource
+ * @note "C:/foo.tpl" was forced to file resource up till Smarty 3.1.3 (including).
+ *
+ * @param string $resource_name template_resource or config_resource to parse
+ * @param string $default_resource the default resource_type defined in $smarty
+ *
+ * @return array with parsed resource name and type
+ */
+ public static function parseResourceName($resource_name, $default_resource) {
+ if (preg_match('/^([A-Za-z0-9_\-]{2,})[:]/', $resource_name, $match)) {
+ $type = $match[1];
+ $name = substr($resource_name, strlen($match[0]));
+ } else {
+ // no resource given, use default
+ // or single character before the colon is not a resource type, but part of the filepath
+ $type = $default_resource;
+ $name = $resource_name;
+
+ }
+ return array($name, $type);
+ }
+
+ /**
+ * modify resource_name according to resource handlers specifications
+ *
+ * @param Smarty $smarty Smarty instance
+ * @param string $resource_name resource_name to make unique
+ *
+ * @return string unique resource name
+ */
+
+ /**
+ * modify template_resource according to resource handlers specifications
+ *
+ * @param Smarty_Internal_template $template Smarty instance
+ * @param string $template_resource template_resource to extract resource handler and name of
+ *
+ * @return string unique resource name
+ */
+ public static function getUniqueTemplateName($template, $template_resource) {
+ $smarty = isset($template->smarty) ? $template->smarty : $template;
+ list($name, $type) = self::parseResourceName($template_resource, $smarty->default_resource_type);
+ // TODO: optimize for Smarty's internal resource types
+ $resource = Smarty_Resource::load($smarty, $type);
+ // go relative to a given template?
+ $_file_is_dotted = $name[0] == '.' && ($name[1] == '.' || $name[1] == '/');
+ if ($template instanceof Smarty_Internal_Template && $_file_is_dotted && ($template->source->type == 'file' || $template->parent->source->type == 'extends')) {
+ $name = dirname($template->source->filepath) . DS . $name;
+ }
+ return $resource->buildUniqueResourceName($smarty, $name);
+ }
+
+ /**
+ * initialize Source Object for given resource
+ * wrapper for backward compatibility to versions < 3.1.22
+ * Either [$_template] or [$smarty, $template_resource] must be specified
+ *
+ * @param Smarty_Internal_Template $_template template object
+ * @param Smarty $smarty smarty object
+ * @param string $template_resource resource identifier
+ *
+ * @return Smarty_Template_Source Source Object
+ */
+ public static function source(Smarty_Internal_Template $_template = null, Smarty $smarty = null, $template_resource = null) {
+ return Smarty_Template_Source::load($_template, $smarty, $template_resource);
+ }
+}
+
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_resource_custom.php
@@ -0,0 +1,90 @@
+<?php
+/**
+ * Smarty Resource Plugin
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Rodney Rehm
+ */
+
+/**
+ * Smarty Resource Plugin
+ * Wrapper Implementation for custom resource plugins
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ */
+abstract class Smarty_Resource_Custom extends Smarty_Resource {
+ /**
+ * fetch template and its modification time from data source
+ *
+ * @param string $name template name
+ * @param string &$source template source
+ * @param integer &$mtime template modification timestamp (epoch)
+ */
+ abstract protected function fetch($name, &$source, &$mtime);
+
+ /**
+ * Fetch template's modification timestamp from data source
+ * {@internal implementing this method is optional.
+ * Only implement it if modification times can be accessed faster than loading the complete template source.}}
+ *
+ * @param string $name template name
+ *
+ * @return integer|boolean timestamp (epoch) the template was modified, or false if not found
+ */
+ protected function fetchTimestamp($name) {
+ return null;
+ }
+
+ /**
+ * populate Source Object with meta data from Resource
+ *
+ * @param Smarty_Template_Source $source source object
+ * @param Smarty_Internal_Template $_template template object
+ */
+ public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template = null) {
+ $source->filepath = $source->type . ':' . $source->name;
+ $source->uid = sha1($source->type . ':' . $source->name);
+
+ $mtime = $this->fetchTimestamp($source->name);
+ if ($mtime !== null) {
+ $source->timestamp = $mtime;
+ } else {
+ $this->fetch($source->name, $content, $timestamp);
+ $source->timestamp = isset($timestamp) ? $timestamp : false;
+ if (isset($content)) {
+ $source->content = $content;
+ }
+ }
+ $source->exists = !!$source->timestamp;
+ }
+
+ /**
+ * Load template's source into current template object
+ *
+ * @param Smarty_Template_Source $source source object
+ *
+ * @return string template source
+ * @throws SmartyException if source cannot be loaded
+ */
+ public function getContent(Smarty_Template_Source $source) {
+ $this->fetch($source->name, $content, $timestamp);
+ if (isset($content)) {
+ return $content;
+ }
+
+ throw new SmartyException("Unable to read template {$source->type} '{$source->name}'");
+ }
+
+ /**
+ * Determine basename for compiled filename
+ *
+ * @param Smarty_Template_Source $source source object
+ *
+ * @return string resource's basename
+ */
+ public function getBasename(Smarty_Template_Source $source) {
+ return basename($source->name);
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_resource_recompiled.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Smarty Resource Plugin
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Rodney Rehm
+ */
+
+/**
+ * Smarty Resource Plugin
+ * Base implementation for resource plugins that don't compile cache
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ */
+abstract class Smarty_Resource_Recompiled extends Smarty_Resource {
+ /**
+ * Flag that it's an recompiled resource
+ *
+ * @var bool
+ */
+ public $recompiled = true;
+
+ /**
+ * populate Compiled Object with compiled filepath
+ *
+ * @param Smarty_Template_Compiled $compiled compiled object
+ * @param Smarty_Internal_Template $_template template object
+ *
+ * @return void
+ */
+ public function populateCompiledFilepath(Smarty_Template_Compiled $compiled, Smarty_Internal_Template $_template) {
+ $compiled->filepath = false;
+ $compiled->timestamp = false;
+ $compiled->exists = false;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_resource_uncompiled.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * Smarty Resource Plugin
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Rodney Rehm
+ */
+
+/**
+ * Smarty Resource Plugin
+ * Base implementation for resource plugins that don't use the compiler
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ */
+abstract class Smarty_Resource_Uncompiled extends Smarty_Resource {
+ /**
+ * Flag that it's an uncompiled resource
+ *
+ * @var bool
+ */
+ public $uncompiled = true;
+
+ /**
+ * Render and output the template (without using the compiler)
+ *
+ * @param Smarty_Template_Source $source source object
+ * @param Smarty_Internal_Template $_template template object
+ *
+ * @throws SmartyException on failure
+ */
+ abstract public function renderUncompiled(Smarty_Template_Source $source, Smarty_Internal_Template $_template);
+
+ /**
+ * populate compiled object with compiled filepath
+ *
+ * @param Smarty_Template_Compiled $compiled compiled object
+ * @param Smarty_Internal_Template $_template template object (is ignored)
+ */
+ public function populateCompiledFilepath(Smarty_Template_Compiled $compiled, Smarty_Internal_Template $_template) {
+ $compiled->filepath = false;
+ $compiled->timestamp = false;
+ $compiled->exists = false;
+ }
+
+ /**
+ * render compiled template code
+ *
+ * @param Smarty_Internal_Template $_template
+ *
+ * @return string
+ * @throws Exception
+ */
+ public function render($_template) {
+ $level = ob_get_level();
+ ob_start();
+ try {
+ $this->renderUncompiled($_template->source, $_template);
+ return ob_get_clean();
+ } catch (Exception $e) {
+ while (ob_get_level() > $level) {
+ ob_end_clean();
+ }
+ throw $e;
+ }
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_security.php
@@ -0,0 +1,628 @@
+<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage Security
+ * @author Uwe Tews
+ */
+
+/*
+ * FIXME: Smarty_Security API
+ * - getter and setter instead of public properties would allow cultivating an internal cache properly
+ * - current implementation of isTrustedResourceDir() assumes that Smarty::$template_dir and Smarty::$config_dir are immutable
+ * the cache is killed every time either of the variables change. That means that two distinct Smarty objects with differing
+ * $template_dir or $config_dir should NOT share the same Smarty_Security instance,
+ * as this would lead to (severe) performance penalty! how should this be handled?
+ */
+
+/**
+ * This class does contain the security settings
+ */
+class Smarty_Security {
+ /**
+ * This determines how Smarty handles "<?php ... ?>" tags in templates.
+ * possible values:
+ * <ul>
+ * <li>Smarty::PHP_PASSTHRU -> echo PHP tags as they are</li>
+ * <li>Smarty::PHP_QUOTE -> escape tags as entities</li>
+ * <li>Smarty::PHP_REMOVE -> remove php tags</li>
+ * <li>Smarty::PHP_ALLOW -> execute php tags</li>
+ * </ul>
+ *
+ * @var integer
+ */
+ public $php_handling = Smarty::PHP_PASSTHRU;
+ /**
+ * This is the list of template directories that are considered secure.
+ * $template_dir is in this list implicitly.
+ *
+ * @var array
+ */
+ public $secure_dir = array();
+ /**
+ * This is an array of directories where trusted php scripts reside.
+ * {@link $security} is disabled during their inclusion/execution.
+ *
+ * @var array
+ */
+ public $trusted_dir = array();
+ /**
+ * List of regular expressions (PCRE) that include trusted URIs
+ *
+ * @var array
+ */
+ public $trusted_uri = array();
+ /**
+ * List of trusted constants names
+ *
+ * @var array
+ */
+ public $trusted_constants = array();
+ /**
+ * This is an array of trusted static classes.
+ * If empty access to all static classes is allowed.
+ * If set to 'none' none is allowed.
+ *
+ * @var array
+ */
+ public $static_classes = array();
+
+ /**
+ * This is an nested array of trusted classes and static methods.
+ * If empty access to all static classes and methods is allowed.
+ * Format:
+ * array (
+ * 'class_1' => array('method_1', 'method_2'), // allowed methods listed
+ * 'class_2' => array(), // all methods of class allowed
+ * )
+ * If set to null none is allowed.
+ *
+ * @var array
+ */
+ public $trusted_static_methods = array();
+
+ /**
+ * This is an array of trusted static properties.
+ * If empty access to all static classes and properties is allowed.
+ * Format:
+ * array (
+ * 'class_1' => array('prop_1', 'prop_2'), // allowed properties listed
+ * 'class_2' => array(), // all properties of class allowed
+ * )
+ * If set to null none is allowed.
+ *
+ * @var array
+ */
+ public $trusted_static_properties = array();
+ /**
+ * This is an array of trusted PHP functions.
+ * If empty all functions are allowed.
+ * To disable all PHP functions set $php_functions = null.
+ *
+ * @var array
+ */
+ public $php_functions = array(
+ 'isset', 'empty',
+ 'count', 'sizeof',
+ 'in_array', 'is_array',
+ 'time',
+ );
+ /**
+ * This is an array of trusted PHP modifiers.
+ * If empty all modifiers are allowed.
+ * To disable all modifier set $php_modifiers = null.
+ *
+ * @var array
+ */
+ public $php_modifiers = array(
+ 'escape',
+ 'count',
+ 'nl2br',
+ );
+ /**
+ * This is an array of allowed tags.
+ * If empty no restriction by allowed_tags.
+ *
+ * @var array
+ */
+ public $allowed_tags = array();
+ /**
+ * This is an array of disabled tags.
+ * If empty no restriction by disabled_tags.
+ *
+ * @var array
+ */
+ public $disabled_tags = array();
+ /**
+ * This is an array of allowed modifier plugins.
+ * If empty no restriction by allowed_modifiers.
+ *
+ * @var array
+ */
+ public $allowed_modifiers = array();
+ /**
+ * This is an array of disabled modifier plugins.
+ * If empty no restriction by disabled_modifiers.
+ *
+ * @var array
+ */
+ public $disabled_modifiers = array();
+ /**
+ * This is an array of disabled special $smarty variables.
+ *
+ * @var array
+ */
+ public $disabled_special_smarty_vars = array();
+ /**
+ * This is an array of trusted streams.
+ * If empty all streams are allowed.
+ * To disable all streams set $streams = null.
+ *
+ * @var array
+ */
+ public $streams = array('file');
+ /**
+ * + flag if constants can be accessed from template
+ *
+ * @var boolean
+ */
+ public $allow_constants = true;
+ /**
+ * + flag if super globals can be accessed from template
+ *
+ * @var boolean
+ */
+ public $allow_super_globals = true;
+ /**
+ * max template nesting level
+ *
+ * @var int
+ */
+ public $max_template_nesting = 0;
+ /**
+ * current template nesting level
+ *
+ * @var int
+ */
+ private $_current_template_nesting = 0;
+ /**
+ * Cache for $resource_dir lookup
+ *
+ * @var array
+ */
+ protected $_resource_dir = null;
+ /**
+ * Cache for $template_dir lookup
+ *
+ * @var array
+ */
+ protected $_template_dir = null;
+ /**
+ * Cache for $config_dir lookup
+ *
+ * @var array
+ */
+ protected $_config_dir = null;
+ /**
+ * Cache for $secure_dir lookup
+ *
+ * @var array
+ */
+ protected $_secure_dir = null;
+ /**
+ * Cache for $php_resource_dir lookup
+ *
+ * @var array
+ */
+ protected $_php_resource_dir = null;
+ /**
+ * Cache for $trusted_dir lookup
+ *
+ * @var array
+ */
+ protected $_trusted_dir = null;
+
+ /**
+ * @param Smarty $smarty
+ */
+ public function __construct($smarty) {
+ $this->smarty = $smarty;
+ }
+
+ /**
+ * Check if PHP function is trusted.
+ *
+ * @param string $function_name
+ * @param object $compiler compiler object
+ *
+ * @return boolean true if function is trusted
+ * @throws SmartyCompilerException if php function is not trusted
+ */
+ public function isTrustedPhpFunction($function_name, $compiler) {
+ if (isset($this->php_functions) && (empty($this->php_functions) || in_array($function_name, $this->php_functions))) {
+ return true;
+ }
+
+ $compiler->trigger_template_error("PHP function '{$function_name}' not allowed by security setting");
+
+ return false; // should not, but who knows what happens to the compiler in the future?
+ }
+
+ /**
+ * Check if static class is trusted.
+ *
+ * @param string $class_name
+ * @param object $compiler compiler object
+ *
+ * @return boolean true if class is trusted
+ * @throws SmartyCompilerException if static class is not trusted
+ */
+ public function isTrustedStaticClass($class_name, $compiler) {
+ if (isset($this->static_classes) && (empty($this->static_classes) || in_array($class_name, $this->static_classes))) {
+ return true;
+ }
+
+ $compiler->trigger_template_error("access to static class '{$class_name}' not allowed by security setting");
+
+ return false; // should not, but who knows what happens to the compiler in the future?
+ }
+
+ /**
+ * Check if static class method/property is trusted.
+ *
+ * @param string $class_name
+ * @param string $params
+ * @param object $compiler compiler object
+ *
+ * @return boolean true if class method is trusted
+ * @throws SmartyCompilerException if static class method is not trusted
+ */
+ public function isTrustedStaticClassAccess($class_name, $params, $compiler) {
+ if (!isset($params[2])) {
+ // fall back
+ return $this->isTrustedStaticClass($class_name, $compiler);
+ }
+ if ($params[2] == 'method') {
+ $allowed = $this->trusted_static_methods;
+ $name = substr($params[0], 0, strpos($params[0], '('));
+ } else {
+ $allowed = $this->trusted_static_properties;
+ // strip '$'
+ $name = substr($params[0], 1);
+ }
+ if (isset($allowed)) {
+ if (empty($allowed)) {
+ // fall back
+ return $this->isTrustedStaticClass($class_name, $compiler);
+ }
+ if (isset($allowed[$class_name])
+ && (empty($allowed[$class_name])
+ || in_array($name, $allowed[$class_name]))
+ ) {
+ return true;
+ }
+ }
+ $compiler->trigger_template_error("access to static class '{$class_name}' {$params[2]} '{$name}' not allowed by security setting");
+ return false; // should not, but who knows what happens to the compiler in the future?
+ }
+
+ /**
+ * Check if PHP modifier is trusted.
+ *
+ * @param string $modifier_name
+ * @param object $compiler compiler object
+ *
+ * @return boolean true if modifier is trusted
+ * @throws SmartyCompilerException if modifier is not trusted
+ */
+ public function isTrustedPhpModifier($modifier_name, $compiler) {
+ if (isset($this->php_modifiers) && (empty($this->php_modifiers) || in_array($modifier_name, $this->php_modifiers))) {
+ return true;
+ }
+
+ $compiler->trigger_template_error("modifier '{$modifier_name}' not allowed by security setting");
+
+ return false; // should not, but who knows what happens to the compiler in the future?
+ }
+
+ /**
+ * Check if tag is trusted.
+ *
+ * @param string $tag_name
+ * @param object $compiler compiler object
+ *
+ * @return boolean true if tag is trusted
+ * @throws SmartyCompilerException if modifier is not trusted
+ */
+ public function isTrustedTag($tag_name, $compiler) {
+ // check for internal always required tags
+ if (in_array($tag_name, array('assign', 'call', 'private_filter', 'private_block_plugin', 'private_function_plugin', 'private_object_block_function',
+ 'private_object_function', 'private_registered_function', 'private_registered_block', 'private_special_variable', 'private_print_expression', 'private_modifier'))
+ ) {
+ return true;
+ }
+ // check security settings
+ if (empty($this->allowed_tags)) {
+ if (empty($this->disabled_tags) || !in_array($tag_name, $this->disabled_tags)) {
+ return true;
+ } else {
+ $compiler->trigger_template_error("tag '{$tag_name}' disabled by security setting", $compiler->lex->taglineno);
+ }
+ } elseif (in_array($tag_name, $this->allowed_tags) && !in_array($tag_name, $this->disabled_tags)) {
+ return true;
+ } else {
+ $compiler->trigger_template_error("tag '{$tag_name}' not allowed by security setting", $compiler->lex->taglineno);
+ }
+
+ return false; // should not, but who knows what happens to the compiler in the future?
+ }
+
+ /**
+ * Check if special $smarty variable is trusted.
+ *
+ * @param string $var_name
+ * @param object $compiler compiler object
+ *
+ * @return boolean true if tag is trusted
+ * @throws SmartyCompilerException if modifier is not trusted
+ */
+ public function isTrustedSpecialSmartyVar($var_name, $compiler) {
+ if (!in_array($var_name, $this->disabled_special_smarty_vars)) {
+ return true;
+ } else {
+ $compiler->trigger_template_error("special variable '\$smarty.{$var_name}' not allowed by security setting", $compiler->lex->taglineno);
+ }
+
+ return false; // should not, but who knows what happens to the compiler in the future?
+ }
+
+ /**
+ * Check if modifier plugin is trusted.
+ *
+ * @param string $modifier_name
+ * @param object $compiler compiler object
+ *
+ * @return boolean true if tag is trusted
+ * @throws SmartyCompilerException if modifier is not trusted
+ */
+ public function isTrustedModifier($modifier_name, $compiler) {
+ // check for internal always allowed modifier
+ if (in_array($modifier_name, array('default'))) {
+ return true;
+ }
+ // check security settings
+ if (empty($this->allowed_modifiers)) {
+ if (empty($this->disabled_modifiers) || !in_array($modifier_name, $this->disabled_modifiers)) {
+ return true;
+ } else {
+ $compiler->trigger_template_error("modifier '{$modifier_name}' disabled by security setting", $compiler->lex->taglineno);
+ }
+ } elseif (in_array($modifier_name, $this->allowed_modifiers) && !in_array($modifier_name, $this->disabled_modifiers)) {
+ return true;
+ } else {
+ $compiler->trigger_template_error("modifier '{$modifier_name}' not allowed by security setting", $compiler->lex->taglineno);
+ }
+
+ return false; // should not, but who knows what happens to the compiler in the future?
+ }
+
+ /**
+ * Check if constants are enabled or trusted
+ *
+ * @param string $const contant name
+ * @param object $compiler compiler object
+ *
+ * @return bool
+ */
+ public function isTrustedConstant($const, $compiler) {
+ if (in_array($const, array('true', 'false', 'null'))) {
+ return true;
+ }
+ if (!empty($this->trusted_constants)) {
+ if (!in_array($const, $this->trusted_constants)) {
+ $compiler->trigger_template_error("Security: access to constant '{$const}' not permitted");
+ return false;
+ }
+ return true;
+ }
+ if ($this->allow_constants) {
+ return true;
+ }
+ $compiler->trigger_template_error("Security: access to constants not permitted");
+ return false;
+ }
+
+ /**
+ * Check if stream is trusted.
+ *
+ * @param string $stream_name
+ *
+ * @return boolean true if stream is trusted
+ * @throws SmartyException if stream is not trusted
+ */
+ public function isTrustedStream($stream_name) {
+ if (isset($this->streams) && (empty($this->streams) || in_array($stream_name, $this->streams))) {
+ return true;
+ }
+
+ throw new SmartyException("stream '{$stream_name}' not allowed by security setting");
+ }
+
+ /**
+ * Check if directory of file resource is trusted.
+ *
+ * @param string $filepath
+ *
+ * @return boolean true if directory is trusted
+ * @throws SmartyException if directory is not trusted
+ */
+ public function isTrustedResourceDir($filepath) {
+ $_template = false;
+ $_config = false;
+ $_secure = false;
+
+ $_template_dir = $this->smarty->getTemplateDir();
+ $_config_dir = $this->smarty->getConfigDir();
+
+ // check if index is outdated
+ if ((!$this->_template_dir || $this->_template_dir !== $_template_dir)
+ || (!$this->_config_dir || $this->_config_dir !== $_config_dir)
+ || (!empty($this->secure_dir) && (!$this->_secure_dir || $this->_secure_dir !== $this->secure_dir))
+ ) {
+ $this->_resource_dir = array();
+ $_template = true;
+ $_config = true;
+ $_secure = !empty($this->secure_dir);
+ }
+
+ // rebuild template dir index
+ if ($_template) {
+ $this->_template_dir = $_template_dir;
+ foreach ($_template_dir as $directory) {
+ $directory = realpath($directory);
+ $this->_resource_dir[$directory] = true;
+ }
+ }
+
+ // rebuild config dir index
+ if ($_config) {
+ $this->_config_dir = $_config_dir;
+ foreach ($_config_dir as $directory) {
+ $directory = realpath($directory);
+ $this->_resource_dir[$directory] = true;
+ }
+ }
+
+ // rebuild secure dir index
+ if ($_secure) {
+ $this->_secure_dir = $this->secure_dir;
+ foreach ((array)$this->secure_dir as $directory) {
+ $directory = realpath($directory);
+ $this->_resource_dir[$directory] = true;
+ }
+ }
+
+ $_filepath = realpath($filepath);
+ $directory = dirname($_filepath);
+ $_directory = array();
+ while (true) {
+ // remember the directory to add it to _resource_dir in case we're successful
+ $_directory[$directory] = true;
+ // test if the directory is trusted
+ if (isset($this->_resource_dir[$directory])) {
+ // merge sub directories of current $directory into _resource_dir to speed up subsequent lookup
+ $this->_resource_dir = array_merge($this->_resource_dir, $_directory);
+
+ return true;
+ }
+ // abort if we've reached root
+ if (($pos = strrpos($directory, DS)) === false || !isset($directory[1])) {
+ break;
+ }
+ // bubble up one level
+ $directory = substr($directory, 0, $pos);
+ }
+
+ // give up
+ throw new SmartyException("directory '{$_filepath}' not allowed by security setting");
+ }
+
+ /**
+ * Check if URI (e.g. {fetch} or {html_image}) is trusted
+ * To simplify things, isTrustedUri() resolves all input to "{$PROTOCOL}://{$HOSTNAME}".
+ * So "http://username:password@hello.world.example.org:8080/some-path?some=query-string"
+ * is reduced to "http://hello.world.example.org" prior to applying the patters from {@link $trusted_uri}.
+ *
+ * @param string $uri
+ *
+ * @return boolean true if URI is trusted
+ * @throws SmartyException if URI is not trusted
+ * @uses $trusted_uri for list of patterns to match against $uri
+ */
+ public function isTrustedUri($uri) {
+ $_uri = parse_url($uri);
+ if (!empty($_uri['scheme']) && !empty($_uri['host'])) {
+ $_uri = $_uri['scheme'] . '://' . $_uri['host'];
+ foreach ($this->trusted_uri as $pattern) {
+ if (preg_match($pattern, $_uri)) {
+ return true;
+ }
+ }
+ }
+
+ throw new SmartyException("URI '{$uri}' not allowed by security setting");
+ }
+
+ /**
+ * Check if directory of file resource is trusted.
+ *
+ * @param string $filepath
+ *
+ * @return boolean true if directory is trusted
+ * @throws SmartyException if PHP directory is not trusted
+ */
+ public function isTrustedPHPDir($filepath) {
+ if (empty($this->trusted_dir)) {
+ throw new SmartyException("directory '{$filepath}' not allowed by security setting (no trusted_dir specified)");
+ }
+
+ // check if index is outdated
+ if (!$this->_trusted_dir || $this->_trusted_dir !== $this->trusted_dir) {
+ $this->_php_resource_dir = array();
+
+ $this->_trusted_dir = $this->trusted_dir;
+ foreach ((array)$this->trusted_dir as $directory) {
+ $directory = realpath($directory);
+ $this->_php_resource_dir[$directory] = true;
+ }
+ }
+
+ $_filepath = realpath($filepath);
+ $directory = dirname($_filepath);
+ $_directory = array();
+ while (true) {
+ // remember the directory to add it to _resource_dir in case we're successful
+ $_directory[] = $directory;
+ // test if the directory is trusted
+ if (isset($this->_php_resource_dir[$directory])) {
+ // merge sub directories of current $directory into _resource_dir to speed up subsequent lookup
+ $this->_php_resource_dir = array_merge($this->_php_resource_dir, $_directory);
+
+ return true;
+ }
+ // abort if we've reached root
+ if (($pos = strrpos($directory, DS)) === false || !isset($directory[2])) {
+ break;
+ }
+ // bubble up one level
+ $directory = substr($directory, 0, $pos);
+ }
+
+ throw new SmartyException("directory '{$_filepath}' not allowed by security setting");
+ }
+
+ /**
+ * Start template processing
+ *
+ * @param $template
+ *
+ * @throws SmartyException
+ */
+ public function startTemplate($template) {
+ if ($this->max_template_nesting > 0 && $this->_current_template_nesting++ >= $this->max_template_nesting) {
+ throw new SmartyException("maximum template nesting level of '{$this->max_template_nesting}' exceeded when calling '{$template->template_resource}'");
+ }
+ }
+
+ /**
+ * Exit template processing
+ *
+ * @param $template
+ */
+ public function exitTemplate($template) {
+ if ($this->max_template_nesting > 0) {
+ $this->_current_template_nesting--;
+ }
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_template_cached.php
@@ -0,0 +1,392 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: Uwe Tews
+ * Date: 04.12.2014
+ * Time: 06:08
+ */
+
+/**
+ * Smarty Resource Data Object
+ * Cache Data Container for Template Files
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Rodney Rehm
+ */
+class Smarty_Template_Cached {
+ /**
+ * Source Filepath
+ *
+ * @var string
+ */
+ public $filepath = false;
+
+ /**
+ * Source Content
+ *
+ * @var string
+ */
+ public $content = null;
+
+ /**
+ * Source Timestamp
+ *
+ * @var integer
+ */
+ public $timestamp = false;
+
+ /**
+ * Source Existence
+ *
+ * @var boolean
+ */
+ public $exists = false;
+
+ /**
+ * Cache Is Valid
+ *
+ * @var boolean
+ */
+ public $valid = null;
+
+ /**
+ * Cache was processed
+ *
+ * @var boolean
+ */
+ public $processed = false;
+
+ /**
+ * CacheResource Handler
+ *
+ * @var Smarty_CacheResource
+ */
+ public $handler = null;
+
+ /**
+ * Template Compile Id (Smarty_Internal_Template::$compile_id)
+ *
+ * @var string
+ */
+ public $compile_id = null;
+
+ /**
+ * Template Cache Id (Smarty_Internal_Template::$cache_id)
+ *
+ * @var string
+ */
+ public $cache_id = null;
+
+ /**
+ * Id for cache locking
+ *
+ * @var string
+ */
+ public $lock_id = null;
+
+ /**
+ * flag that cache is locked by this instance
+ *
+ * @var bool
+ */
+ public $is_locked = false;
+
+ /**
+ * Source Object
+ *
+ * @var Smarty_Template_Source
+ */
+ public $source = null;
+
+ /**
+ * create Cached Object container
+ *
+ * @param Smarty_Internal_Template $_template template object
+ */
+ public function __construct(Smarty_Internal_Template $_template) {
+ $this->compile_id = $_template->compile_id;
+ $this->cache_id = $_template->cache_id;
+ if (!isset($_template->source)) {
+ $_template->loadSource();
+ }
+ $this->source = $_template->source;
+ if (!class_exists('Smarty_CacheResource', false)) {
+ require SMARTY_SYSPLUGINS_DIR . 'smarty_cacheresource.php';
+ }
+ $this->handler = Smarty_CacheResource::load($_template->smarty);
+ }
+
+ /**
+ * @param Smarty_Internal_Template $_template
+ *
+ * @return Smarty_Template_Cached
+ */
+ static function load(Smarty_Internal_Template $_template) {
+ $_template->cached = $cached = new Smarty_Template_Cached($_template);
+ $cached->handler->populate($cached, $_template);
+ // caching enabled ?
+ if (!($_template->caching == Smarty::CACHING_LIFETIME_CURRENT || $_template->caching == Smarty::CACHING_LIFETIME_SAVED) || $_template->source->recompiled) {
+ $cached->valid = false;
+ }
+ return $cached;
+ }
+
+ /**
+ * Check if cache is valid, lock cache if required
+ *
+ * @param \Smarty_Internal_Template $_template
+ *
+ * @return bool flag true if cache is valid
+ */
+ public function isCached(Smarty_Internal_Template $_template) {
+ if ($this->valid !== null) {
+ return $this->valid;
+ }
+ while (true) {
+ while (true) {
+ if ($this->exists === false || $_template->smarty->force_compile || $_template->smarty->force_cache) {
+ $this->valid = false;
+ } else {
+ $this->valid = true;
+ }
+ if ($this->valid && $_template->caching == Smarty::CACHING_LIFETIME_CURRENT && $_template->cache_lifetime >= 0 && time() > ($this->timestamp + $_template->cache_lifetime)) {
+ // lifetime expired
+ $this->valid = false;
+ }
+ if ($this->valid && $_template->source->timestamp > $this->timestamp) {
+ $this->valid = false;
+ }
+ if ($this->valid || !$_template->smarty->cache_locking) {
+ break;
+ }
+ if (!$this->handler->locked($_template->smarty, $this)) {
+ $this->handler->acquireLock($_template->smarty, $this);
+ break 2;
+ }
+ $this->handler->populate($this, $_template);
+ }
+ if ($this->valid) {
+ if (!$_template->smarty->cache_locking || $this->handler->locked($_template->smarty, $this) === null) {
+ // load cache file for the following checks
+ if ($_template->smarty->debugging) {
+ Smarty_Internal_Debug::start_cache($_template);
+ }
+ if ($this->handler->process($_template, $this) === false) {
+ $this->valid = false;
+ } else {
+ $this->processed = true;
+ }
+ if ($_template->smarty->debugging) {
+ Smarty_Internal_Debug::end_cache($_template);
+ }
+ } else {
+ $this->is_locked = true;
+ continue;
+ }
+ } else {
+ return $this->valid;
+ }
+ if ($this->valid && $_template->caching === Smarty::CACHING_LIFETIME_SAVED && $_template->properties['cache_lifetime'] >= 0 && (time() > ($_template->cached->timestamp + $_template->properties['cache_lifetime']))) {
+ $this->valid = false;
+ }
+ if ($_template->smarty->cache_locking) {
+ if (!$this->valid) {
+ $this->handler->acquireLock($_template->smarty, $this);
+ } elseif ($this->is_locked) {
+ $this->handler->releaseLock($_template->smarty, $this);
+ }
+ }
+ return $this->valid;
+ }
+ return $this->valid;
+ }
+
+ /**
+ * Process cached template
+ *
+ * @param Smarty_Internal_Template $_template template object
+ */
+ public function process(Smarty_Internal_Template $_template) {
+ if ($this->handler->process($_template, $this) === false) {
+ $this->valid = false;
+ }
+ if ($this->valid) {
+ $this->processed = true;
+ } else {
+ $this->processed = false;
+ }
+ }
+
+ /**
+ * Render cached template
+ *
+ * @param Smarty_Internal_Template $_template
+ *
+ * @return string
+ * @throws Exception
+ */
+ public function render(Smarty_Internal_Template $_template) {
+ if (!$this->processed) {
+ $this->process($_template);
+ }
+ return $_template->getRenderedTemplateCode();
+ }
+
+ /**
+ * Write this cache object to handler
+ *
+ * @param Smarty_Internal_Template $_template template object
+ * @param string $content content to cache
+ *
+ * @return boolean success
+ */
+ public function write(Smarty_Internal_Template $_template, $content) {
+ if (!$_template->source->recompiled) {
+ if ($this->handler->writeCachedContent($_template, $content)) {
+ $this->content = null;
+ $this->timestamp = time();
+ $this->exists = true;
+ $this->valid = true;
+ $this->processed = false;
+ if ($_template->smarty->cache_locking) {
+ $this->handler->releaseLock($_template->smarty, $this);
+ }
+
+ return true;
+ }
+ $this->content = null;
+ $this->timestamp = false;
+ $this->exists = false;
+ $this->valid = false;
+ $this->processed = false;
+ }
+
+ return false;
+ }
+
+ /**
+ * Read cache content from handler
+ *
+ * @param Smarty_Internal_Template $_template template object
+ *
+ * @return string content
+ */
+ public function read(Smarty_Internal_Template $_template) {
+ if (!$_template->source->recompiled) {
+ return $this->handler->readCachedContent($_template);
+ }
+ return false;
+ }
+
+ /**
+ * Sanitize content and write it to cache resource
+ *
+ * @param Smarty_Internal_Template $_template
+ * @param string $content
+ * @param bool $no_output_filter
+ *
+ * @throws SmartyException
+ */
+ public function updateCache(Smarty_Internal_Template $_template, $content, $no_output_filter) {
+ $_template->properties['has_nocache_code'] = false;
+ // get text between non-cached items
+ $cache_split = preg_split("!/\*%%SmartyNocache:{$_template->properties['nocache_hash']}%%\*\/(.+?)/\*/%%SmartyNocache:{$_template->properties['nocache_hash']}%%\*/!s", $content);
+ // get non-cached items
+ preg_match_all("!/\*%%SmartyNocache:{$_template->properties['nocache_hash']}%%\*\/(.+?)/\*/%%SmartyNocache:{$_template->properties['nocache_hash']}%%\*/!s", $content, $cache_parts);
+ $output = '';
+ // loop over items, stitch back together
+ foreach ($cache_split as $curr_idx => $curr_split) {
+ // escape PHP tags in template content
+ $output .= preg_replace('/(<%|%>|<\?php|<\?|\?>|<script\s+language\s*=\s*[\"\']?\s*php\s*[\"\']?\s*>)/', "<?php echo '\$1'; ?>\n", $curr_split);
+ if (isset($cache_parts[0][$curr_idx])) {
+ $_template->properties['has_nocache_code'] = true;
+ $output .= $cache_parts[1][$curr_idx];
+ }
+ }
+ if (!$no_output_filter && !$_template->has_nocache_code && (isset($_template->smarty->autoload_filters['output']) || isset($_template->smarty->registered_filters['output']))) {
+ $output = Smarty_Internal_Filter_Handler::runFilter('output', $output, $_template);
+ }
+ // write cache file content
+ $this->writeCachedContent($_template, $output);
+ }
+
+ /**
+ * Writes the content to cache resource
+ *
+ * @param Smarty_Internal_Template $_template
+ * @param string $content
+ *
+ * @return bool
+ */
+ public function writeCachedContent(Smarty_Internal_Template $_template, $content) {
+ if ($_template->source->recompiled || !($_template->caching == Smarty::CACHING_LIFETIME_CURRENT || $_template->caching == Smarty::CACHING_LIFETIME_SAVED)) {
+ // don't write cache file
+ return false;
+ }
+ $_template->properties['cache_lifetime'] = $_template->cache_lifetime;
+ $_template->properties['unifunc'] = 'content_' . str_replace(array('.', ','), '_', uniqid('', true));
+ $content = Smarty_Internal_Extension_CodeFrame::create($_template, $content, true);
+ if (!empty($_template->properties['tpl_function'])) {
+ foreach ($_template->properties['tpl_function'] as $funcParam) {
+ if (is_file($funcParam['compiled_filepath'])) {
+ // read compiled file
+ $code = file_get_contents($funcParam['compiled_filepath']);
+ // grab template function
+ if (preg_match("/\/\* {$funcParam['call_name']} \*\/([\S\s]*?)\/\*\/ {$funcParam['call_name']} \*\//", $code, $match)) {
+ unset($code);
+ $content .= "<?php " . $match[0] . "?>\n";
+ }
+ }
+ }
+ }
+ return $this->write($_template, $content);
+ }
+
+ /**
+ * check client side cache
+ *
+ * @param Smarty_Internal_Template $_template
+ * @param string $content
+ */
+ public function cacheModifiedCheck(Smarty_Internal_Template $_template, $content) {
+ $_isCached = $_template->isCached() && !$_template->has_nocache_code;
+ $_last_modified_date = @substr($_SERVER['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_SERVER['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3);
+ if ($_isCached && $this->timestamp <= strtotime($_last_modified_date)) {
+ switch (PHP_SAPI) {
+ case 'cgi': // php-cgi < 5.3
+ case 'cgi-fcgi': // php-cgi >= 5.3
+ case 'fpm-fcgi': // php-fpm >= 5.3.3
+ header('Status: 304 Not Modified');
+ break;
+
+ case 'cli':
+ if ( /* ^phpunit */
+ !empty($_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS']) /* phpunit$ */
+ ) {
+ $_SERVER['SMARTY_PHPUNIT_HEADERS'][] = '304 Not Modified';
+ }
+ break;
+
+ default:
+ header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified');
+ break;
+ }
+ } else {
+ switch (PHP_SAPI) {
+ case 'cli':
+ if ( /* ^phpunit */
+ !empty($_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS']) /* phpunit$ */
+ ) {
+ $_SERVER['SMARTY_PHPUNIT_HEADERS'][] = 'Last-Modified: ' . gmdate('D, d M Y H:i:s', $this->timestamp) . ' GMT';
+ }
+ break;
+
+ default:
+ header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $this->timestamp) . ' GMT');
+ break;
+ }
+ echo $content;
+ }
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_template_compiled.php
@@ -0,0 +1,277 @@
+<?php
+
+/**
+ * Smarty Resource Data Object
+ * Meta Data Container for Template Files
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Rodney Rehm
+ * @property string $content compiled content
+ */
+class Smarty_Template_Compiled {
+ /**
+ * Compiled Filepath
+ *
+ * @var string
+ */
+ public $filepath = null;
+
+ /**
+ * Compiled Timestamp
+ *
+ * @var integer
+ */
+ public $timestamp = null;
+
+ /**
+ * Compiled Existence
+ *
+ * @var boolean
+ */
+ public $exists = false;
+
+ /**
+ * Compiled Content Loaded
+ *
+ * @var boolean
+ */
+ public $processed = false;
+ /**
+ * Code of recompiled template resource
+ *
+ * @var string|null
+ */
+ public $code = null;
+
+ /**
+ * create Compiled Object container
+ */
+ public function __construct() {
+ }
+
+ /**
+ * get a Compiled Object of this source
+ *
+ * @param Smarty_Internal_Template $_template template object
+ *
+ * @return Smarty_Template_Compiled compiled object
+ */
+ static function load($_template) {
+ if (!isset($_template->source)) {
+ $_template->loadSource();
+ }
+ // check runtime cache
+ if (!$_template->source->recompiled && $_template->smarty->resource_caching) {
+ $_cache_key = $_template->source->unique_resource . '#';
+ if ($_template->caching) {
+ $_cache_key .= 'caching#';
+ }
+ $_cache_key .= $_template->compile_id;
+ if (isset($_template->source->compileds[$_cache_key])) {
+ return $_template->source->compileds[$_cache_key];
+ }
+ }
+ $compiled = new Smarty_Template_Compiled();
+ if (method_exists($_template->source->handler, 'populateCompiledFilepath')) {
+ $_template->source->handler->populateCompiledFilepath($compiled, $_template);
+ } else {
+ $compiled->populateCompiledFilepath($_template);
+ }
+ // runtime cache
+ if (!$_template->source->recompiled && $_template->smarty->resource_caching) {
+ $_template->source->compileds[$_cache_key] = $compiled;
+ }
+ return $compiled;
+ }
+
+ /**
+ * populate Compiled Object with compiled filepath
+ *
+ * @param Smarty_Internal_Template $_template template object
+ **/
+ public function populateCompiledFilepath(Smarty_Internal_Template $_template) {
+ $_compile_id = isset($_template->compile_id) ? preg_replace('![^\w\|]+!', '_', $_template->compile_id) : null;
+ if ($_template->source->isConfig) {
+ $_flag = '_' . ((int)$_template->smarty->config_read_hidden + (int)$_template->smarty->config_booleanize * 2
+ + (int)$_template->smarty->config_overwrite * 4);
+ } else {
+ $_flag = '_' . ((int)$_template->smarty->merge_compiled_includes + (int)$_template->smarty->escape_html * 2);
+ }
+ $_filepath = $_template->source->uid . $_flag;
+ // if use_sub_dirs, break file into directories
+ if ($_template->smarty->use_sub_dirs) {
+ $_filepath = substr($_filepath, 0, 2) . DS
+ . substr($_filepath, 2, 2) . DS
+ . substr($_filepath, 4, 2) . DS
+ . $_filepath;
+ }
+ $_compile_dir_sep = $_template->smarty->use_sub_dirs ? DS : '^';
+ if (isset($_compile_id)) {
+ $_filepath = $_compile_id . $_compile_dir_sep . $_filepath;
+ }
+ // caching token
+ if ($_template->caching) {
+ $_cache = '.cache';
+ } else {
+ $_cache = '';
+ }
+ $_compile_dir = $_template->smarty->getCompileDir();
+ // set basename if not specified
+ $_basename = $_template->source->handler->getBasename($_template->source);
+ if ($_basename === null) {
+ $_basename = basename(preg_replace('![^\w\/]+!', '_', $_template->source->name));
+ }
+ // separate (optional) basename by dot
+ if ($_basename) {
+ $_basename = '.' . $_basename;
+ }
+
+ $this->filepath = $_compile_dir . $_filepath . '.' . $_template->source->type . $_basename . $_cache . '.php';
+ $this->timestamp = $this->exists = is_file($this->filepath);
+ if ($this->exists) {
+ $this->timestamp = @filemtime($this->filepath);
+ }
+ }
+
+ /**
+ * load compiled template or compile from source
+ *
+ * @param Smarty_Internal_Template $_template
+ *
+ * @throws Exception
+ */
+ public function process(Smarty_Internal_Template $_template) {
+ $_smarty_tpl = $_template;
+ if ($_template->source->recompiled || !$_template->compiled->exists || $_template->smarty->force_compile) {
+ $this->compileTemplateSource($_template);
+ $compileCheck = $_template->smarty->compile_check;
+ $_template->smarty->compile_check = false;
+ if ($_template->source->recompiled) {
+ $level = ob_get_level();
+ ob_start();
+ try {
+ eval("?>" . $this->code);
+ } catch (Exception $e) {
+ while (ob_get_level() > $level) {
+ ob_end_clean();
+ }
+ throw $e;
+ }
+ ob_get_clean();
+ $this->code = null;
+ } else {
+ include($_template->compiled->filepath);
+ }
+ $_template->smarty->compile_check = $compileCheck;
+ } else {
+ include($_template->compiled->filepath);
+ if ($_template->mustCompile) {
+ $this->compileTemplateSource($_template);
+ $compileCheck = $_template->smarty->compile_check;
+ $_template->smarty->compile_check = false;
+ include($_template->compiled->filepath);
+ $_template->smarty->compile_check = $compileCheck;
+ }
+ }
+ $this->unifunc = $_template->properties['unifunc'];
+ $this->processed = true;
+ }
+
+ /**
+ * render compiled template code
+ *
+ * @param Smarty_Internal_Template $_template
+ *
+ * @return string
+ * @throws Exception
+ */
+ public function render(Smarty_Internal_Template $_template) {
+
+ if (!$this->processed) {
+ $this->process($_template);
+ }
+ $_template->properties['unifunc'] = $this->unifunc;
+ return $_template->getRenderedTemplateCode();
+ }
+
+ /**
+ * compile template from source
+ *
+ * @param Smarty_Internal_Template $_template
+ *
+ * @return string
+ * @throws Exception
+ */
+ public function compileTemplateSource(Smarty_Internal_Template $_template) {
+ if (!$_template->source->recompiled) {
+ $_template->properties['file_dependency'] = array();
+ }
+ // compile locking
+ if (!$_template->source->recompiled) {
+ if ($saved_timestamp = $_template->compiled->timestamp) {
+ touch($_template->compiled->filepath);
+ }
+ }
+ // call compiler
+ try {
+ $code = $_template->compiler->compileTemplate($_template);
+ } catch (Exception $e) {
+ // restore old timestamp in case of error
+ if (!$_template->source->recompiled && $saved_timestamp) {
+ touch($_template->compiled->filepath, $saved_timestamp);
+ }
+ throw $e;
+ }
+ // compiling succeeded
+ if ($_template->compiler->write_compiled_code) {
+ // write compiled template
+ $this->write($_template, $code);
+ $code = '';
+ }
+ // release compiler object to free memory
+ unset($_template->compiler);
+ return $code;
+ }
+
+ /**
+ * Write compiled code by handler
+ *
+ * @param Smarty_Internal_Template $_template template object
+ * @param string $code compiled code
+ *
+ * @return boolean success
+ */
+ public function write(Smarty_Internal_Template $_template, $code) {
+ if (!$_template->source->recompiled) {
+ $obj = new Smarty_Internal_Write_File();
+ if ($obj->writeFile($this->filepath, $code, $_template->smarty) === true) {
+ $this->timestamp = $this->exists = is_file($this->filepath);
+ if ($this->exists) {
+ $this->timestamp = @filemtime($this->filepath);
+ return true;
+ }
+ }
+ return false;
+ } else {
+ $this->code = $code;
+ }
+ $this->timestamp = time();
+ $this->exists = true;
+ return true;
+ }
+
+ /**
+ * Read compiled content from handler
+ *
+ * @param Smarty_Internal_Template $_template template object
+ *
+ * @return string content
+ */
+ public function read(Smarty_Internal_Template $_template) {
+ if (!$_template->source->recompiled) {
+ return file_get_contents($this->filepath);
+ }
+ return isset($this->content) ? $this->content : false;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_template_config.php
@@ -0,0 +1,115 @@
+<?php
+/**
+ * Smarty Config Source Plugin
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Connfig Resource Data Object
+ * Meta Data Container for Template Files
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Uwe Tews
+ * @property integer $timestamp Source Timestamp
+ * @property boolean $exists Source Existence
+ * @property boolean $template Extended Template reference
+ * @property string $content Source Content
+ */
+class Smarty_Template_Config extends Smarty_Template_Source {
+ /**
+ * Name of the Class to compile this resource's contents with
+ *
+ * @var string
+ */
+ public $compiler_class = 'Smarty_Internal_Config_File_Compiler';
+
+ /**
+ * Name of the Class to tokenize this resource's contents with
+ *
+ * @var string
+ */
+ public $template_lexer_class = 'Smarty_Internal_Configfilelexer';
+
+ /**
+ * Name of the Class to parse this resource's contents with
+ *
+ * @var string
+ */
+ public $template_parser_class = 'Smarty_Internal_Configfileparser';
+
+ /**
+ * array of section names, single section or null
+ *
+ * @var null|string|array
+ */
+ public $config_sections = null;
+
+ /**
+ * scope into which the config variables shall be loaded
+ *
+ * @var string
+ */
+ public $scope = 'local';
+
+ /**
+ * Flag that source is a config file
+ *
+ * @var bool
+ */
+ public $isConfig = true;
+
+ /**
+ * create Source Object container
+ *
+ * @param Smarty_Resource $handler Resource Handler this source object communicates with
+ * @param Smarty $smarty Smarty instance this source object belongs to
+ * @param string $resource full template_resource
+ * @param string $type type of resource
+ * @param string $name resource name
+ */
+ public function __construct(Smarty_Resource $handler, Smarty $smarty, $resource, $type, $name) {
+ $this->handler = clone $handler; // Note: prone to circular references
+ $this->resource = $resource;
+ $this->type = $type;
+ $this->name = $name;
+ $this->smarty = $smarty;
+ }
+
+ /**
+ * initialize Source Object for given resource
+ * Either [$_template] or [$smarty, $template_resource] must be specified
+ *
+ * @param Smarty_Internal_Template $_template template object
+ * @param Smarty $smarty smarty object
+ * @param string $template_resource resource identifier
+ *
+ * @return Smarty_Template_Source Source Object
+ * @throws SmartyException
+ */
+ public static function load(Smarty_Internal_Template $_template = null, Smarty $smarty = null, $template_resource = null) {
+ static $_incompatible_resources = array('extends' => true, 'php' => true);
+ $smarty = $_template->smarty;
+ $template_resource = $_template->template_resource;
+ if (empty($template_resource)) {
+ throw new SmartyException('Missing config name');
+ }
+ // parse resource_name, load resource handler
+ list($name, $type) = Smarty_Resource::parseResourceName($template_resource, $smarty->default_config_type);
+ // make sure configs are not loaded via anything smarty can't handle
+ if (isset($_incompatible_resources[$type])) {
+ throw new SmartyException ("Unable to use resource '{$type}' for config");
+ }
+ $resource = Smarty_Resource::load($smarty, $type);
+ $source = new Smarty_Template_Config($resource, $smarty, $template_resource, $type, $name);
+ $resource->populate($source, $_template);
+ if ((!isset($source->exists) || !$source->exists) && isset($_template->smarty->default_config_handler_func)) {
+ Smarty_Internal_Extension_DefaultTemplateHandler::_getDefault($_template, $source, $resource);
+ }
+ $source->unique_resource = $resource->buildUniqueResourceName($smarty, $name, true);
+ return $source;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_template_source.php
@@ -0,0 +1,278 @@
+<?php
+
+/**
+ * Smarty Resource Data Object
+ * Meta Data Container for Template Files
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Rodney Rehm
+ * @property integer $timestamp Source Timestamp
+ * @property boolean $exists Source Existence
+ * @property boolean $template Extended Template reference
+ * @property string $content Source Content
+ */
+class Smarty_Template_Source {
+ /**
+ * Name of the Class to compile this resource's contents with
+ *
+ * @var string
+ */
+ public $compiler_class = null;
+
+ /**
+ * Name of the Class to tokenize this resource's contents with
+ *
+ * @var string
+ */
+ public $template_lexer_class = null;
+
+ /**
+ * Name of the Class to parse this resource's contents with
+ *
+ * @var string
+ */
+ public $template_parser_class = null;
+
+ /**
+ * Unique Template ID
+ *
+ * @var string
+ */
+ public $uid = null;
+
+ /**
+ * Template Resource (Smarty_Internal_Template::$template_resource)
+ *
+ * @var string
+ */
+ public $resource = null;
+
+ /**
+ * Resource Type
+ *
+ * @var string
+ */
+ public $type = null;
+
+ /**
+ * Resource Name
+ *
+ * @var string
+ */
+ public $name = null;
+
+ /**
+ * Unique Resource Name
+ *
+ * @var string
+ */
+ public $unique_resource = null;
+
+ /**
+ * Source Filepath
+ *
+ * @var string
+ */
+ public $filepath = null;
+ /**
+ * Source File Base name
+ *
+ * @var string
+ */
+ public $basename = null;
+
+ /**
+ * The Components an extended template is made of
+ *
+ * @var array
+ */
+ public $components = null;
+
+ /**
+ * Resource Handler
+ *
+ * @var Smarty_Resource
+ */
+ public $handler = null;
+
+ /**
+ * Smarty instance
+ *
+ * @var Smarty
+ */
+ public $smarty = null;
+ /**
+ * Resource is source
+ *
+ * @var bool
+ */
+ public $isConfig = false;
+ /**
+ * Source is bypassing compiler
+ *
+ * @var boolean
+ */
+ public $uncompiled = false;
+
+ /**
+ * Source must be recompiled on every occasion
+ *
+ * @var boolean
+ */
+ public $recompiled = false;
+ /**
+ * cache for Smarty_Template_Compiled instances
+ *
+ * @var array
+ */
+ public $compileds = array();
+
+ /**
+ * create Source Object container
+ *
+ * @param Smarty_Resource $handler Resource Handler this source object communicates with
+ * @param Smarty $smarty Smarty instance this source object belongs to
+ * @param string $resource full template_resource
+ * @param string $type type of resource
+ * @param string $name resource name
+ *
+ * @internal param string $unique_resource unique resource name
+ */
+ public function __construct(Smarty_Resource $handler, Smarty $smarty, $resource, $type, $name) {
+ $this->handler = $handler; // Note: prone to circular references
+
+ $this->recompiled = $handler->recompiled;
+ $this->uncompiled = $handler->uncompiled;
+ $this->compiler_class = $handler->compiler_class;
+ $this->template_lexer_class = $handler->template_lexer_class;
+ $this->template_parser_class = $handler->template_parser_class;
+
+ $this->smarty = $smarty;
+ $this->resource = $resource;
+ $this->type = $type;
+ $this->name = $name;
+ }
+
+ /**
+ * initialize Source Object for given resource
+ * Either [$_template] or [$smarty, $template_resource] must be specified
+ *
+ * @param Smarty_Internal_Template $_template template object
+ * @param Smarty $smarty smarty object
+ * @param string $template_resource resource identifier
+ *
+ * @return Smarty_Template_Source Source Object
+ * @throws SmartyException
+ */
+ public static function load(Smarty_Internal_Template $_template = null, Smarty $smarty = null, $template_resource = null) {
+ if ($_template) {
+ $smarty = $_template->smarty;
+ $template_resource = $_template->template_resource;
+ }
+ if (empty($template_resource)) {
+ throw new SmartyException('Missing template name');
+ }
+ // parse resource_name, load resource handler, identify unique resource name
+ list($name, $type) = Smarty_Resource::parseResourceName($template_resource, $smarty->default_resource_type);
+ $resource = Smarty_Resource::load($smarty, $type);
+ // if resource is not recompiling and resource name is not dotted we can check the source cache
+ if ($smarty->resource_caching && !$resource->recompiled && !(isset($name[1]) && $name[0] == '.' && ($name[1] == '.' || $name[1] == '/'))) {
+ $unique_resource = $resource->buildUniqueResourceName($smarty, $name);
+ if (isset($smarty->source_objects[$unique_resource])) {
+ return $smarty->source_objects[$unique_resource];
+ }
+ } else {
+ $unique_resource = null;
+ }
+ // create new source object
+ $source = new Smarty_Template_Source($resource, $smarty, $template_resource, $type, $name);
+ $resource->populate($source, $_template);
+ if ((!isset($source->exists) || !$source->exists) && isset($_template->smarty->default_template_handler_func)) {
+ Smarty_Internal_Extension_DefaultTemplateHandler::_getDefault($_template, $source, $resObj);
+ }
+ // on recompiling resources we are done
+ if ($smarty->resource_caching && !$resource->recompiled) {
+ // may by we have already $unique_resource
+ $is_relative = false;
+ if (!isset($unique_resource)) {
+ $is_relative = isset($name[1]) && $name[0] == '.' && ($name[1] == '.' || $name[1] == '/') &&
+ ($type == 'file' || (isset($_template->parent->source) && $_template->parent->source->type == 'extends'));
+ $unique_resource = $resource->buildUniqueResourceName($smarty, $is_relative ? $source->filepath . $name : $name);
+ }
+ $source->unique_resource = $unique_resource;
+ // save in runtime cache if not relative
+ if (!$is_relative) {
+ $smarty->source_objects[$unique_resource] = $source;
+ }
+ }
+ return $source;
+ }
+
+ /**
+ * render the uncompiled source
+ *
+ * @param Smarty_Internal_Template $_template template object
+ */
+ public function renderUncompiled(Smarty_Internal_Template $_template) {
+ $level = ob_get_level();
+ ob_start();
+ try {
+ $this->handler->renderUncompiled($_template->source, $_template);
+ return ob_get_clean();
+ } catch (Exception $e) {
+ while (ob_get_level() > $level) {
+ ob_end_clean();
+ }
+ throw $e;
+ }
+ }
+
+ /**
+ * <<magic>> Generic Setter.
+ *
+ * @param string $property_name valid: timestamp, exists, content, template
+ * @param mixed $value new value (is not checked)
+ *
+ * @throws SmartyException if $property_name is not valid
+ */
+ public function __set($property_name, $value) {
+ switch ($property_name) {
+ // regular attributes
+ case 'timestamp':
+ case 'exists':
+ case 'content':
+ // required for extends: only
+ case 'template':
+ $this->$property_name = $value;
+ break;
+
+ default:
+ throw new SmartyException("source property '$property_name' does not exist.");
+ }
+ }
+
+ /**
+ * <<magic>> Generic getter.
+ *
+ * @param string $property_name valid: timestamp, exists, content
+ *
+ * @return mixed
+ * @throws SmartyException if $property_name is not valid
+ */
+ public function __get($property_name) {
+ switch ($property_name) {
+ case 'timestamp':
+ case 'exists':
+ $this->handler->populateTimestamp($this);
+
+ return $this->$property_name;
+
+ case 'content':
+ return $this->content = $this->handler->getContent($this);
+
+ default:
+ throw new SmartyException("source property '$property_name' does not exist.");
+ }
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_undefined_variable.php
@@ -0,0 +1,34 @@
+<?php
+
+/**
+ * class for undefined variable object
+ * This class defines an object for undefined variable handling
+ *
+ * @package Smarty
+ * @subpackage Template
+ */
+class Smarty_Undefined_Variable {
+ /**
+ * Returns FALSE for 'nocache' and NULL otherwise.
+ *
+ * @param string $name
+ *
+ * @return bool
+ */
+ public function __get($name) {
+ if ($name == 'nocache') {
+ return false;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Always returns an empty string.
+ *
+ * @return string
+ */
+ public function __toString() {
+ return "";
+ }
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smarty_variable.php
@@ -0,0 +1,52 @@
+<?php
+
+/**
+ * class for the Smarty variable object
+ * This class defines the Smarty variable object
+ *
+ * @package Smarty
+ * @subpackage Template
+ */
+class Smarty_Variable {
+ /**
+ * template variable
+ *
+ * @var mixed
+ */
+ public $value = null;
+ /**
+ * if true any output of this variable will be not cached
+ *
+ * @var boolean
+ */
+ public $nocache = false;
+ /**
+ * the scope the variable will have (local,parent or root)
+ *
+ * @var int
+ */
+ public $scope = Smarty::SCOPE_LOCAL;
+
+ /**
+ * create Smarty variable object
+ *
+ * @param mixed $value the value to assign
+ * @param boolean $nocache if true any output of this variable will be not cached
+ * @param int $scope the scope the variable will have (local,parent or root)
+ */
+ public function __construct($value = null, $nocache = false, $scope = Smarty::SCOPE_LOCAL) {
+ $this->value = $value;
+ $this->nocache = $nocache;
+ $this->scope = $scope;
+ }
+
+ /**
+ * <<magic>> String conversion
+ *
+ * @return string
+ */
+ public function __toString() {
+ return (string)$this->value;
+ }
+}
+
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smartycompilerexception.php
@@ -0,0 +1,37 @@
+<?php
+
+/**
+ * Smarty compiler exception class
+ *
+ * @package Smarty
+ */
+class SmartyCompilerException extends SmartyException {
+ public function __toString() {
+ return ' --> Smarty Compiler: ' . $this->message . ' <-- ';
+ }
+
+ /**
+ * The line number of the template error
+ *
+ * @type int|null
+ */
+ public $line = null;
+ /**
+ * The template source snippet relating to the error
+ *
+ * @type string|null
+ */
+ public $source = null;
+ /**
+ * The raw text of the error message
+ *
+ * @type string|null
+ */
+ public $desc = null;
+ /**
+ * The resource identifier or template name
+ *
+ * @type string|null
+ */
+ public $template = null;
+}
new file mode 100644
--- /dev/null
+++ b/library/smarty/libs/sysplugins/smartyexception.php
@@ -0,0 +1,14 @@
+<?php
+
+/**
+ * Smarty exception class
+ *
+ * @package Smarty
+ */
+class SmartyException extends Exception {
+ public static $escape = false;
+
+ public function __toString() {
+ return ' --> Smarty: ' . (self::$escape ? htmlentities($this->message) : $this->message) . ' <-- ';
+ }
+}
new file mode 100644
--- /dev/null
+++ b/sql/init.sql
@@ -0,0 +1,397 @@
+-- phpMyAdmin SQL Dump
+-- version 4.4.14
+-- http://www.phpmyadmin.net
+--
+-- Host: 127.0.0.1
+-- Erstellungszeit: 09. Nov 2015 um 14:16
+-- Server-Version: 5.6.26
+-- PHP-Version: 5.6.12
+
+SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
+SET time_zone = "+00:00";
+
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8mb4 */;
+
+--
+-- Datenbank: `ticketsystem`
+--
+
+DELIMITER $$
+--
+-- Prozeduren
+--
+CREATE DEFINER=`root`@`localhost` PROCEDURE `update_history`(IN `tid` BIGINT, IN `aid` BIGINT, IN `uid` BIGINT, IN `sid` BIGINT, IN `s_text` VARCHAR(512), IN `m_text` VARCHAR(512), IN `si_locked` SMALLINT, IN `ts_last_access` TIMESTAMP)
+ COMMENT 'Simpler Update Trigger für die History-Log-Tabelle'
+BEGIN
+INSERT INTO
+ t_history(
+ id,
+ ticket_id,
+ action_id,
+ user_id,
+ status_id,
+ subject,
+ message,
+ locked,
+ last_access
+ ) VALUES(
+ NULL,
+ tid,
+ aid,
+ uid,
+ sid,
+ s_text,
+ m_text,
+ si_locked,
+ ts_last_access
+ );
+END$$
+
+DELIMITER ;
+
+-- --------------------------------------------------------
+
+--
+-- Tabellenstruktur für Tabelle `t_action`
+--
+
+CREATE TABLE IF NOT EXISTS `t_action` (
+ `id` bigint(20) unsigned NOT NULL,
+ `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT ''
+) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+
+--
+-- Daten für Tabelle `t_action`
+--
+
+INSERT INTO `t_action` (`id`, `name`) VALUES
+(1, 'System'),
+(2, 'ANGELEGT'),
+(3, 'GEÄNDERT'),
+(4, 'GELÖSCHT');
+
+-- --------------------------------------------------------
+
+--
+-- Tabellenstruktur für Tabelle `t_group`
+--
+
+CREATE TABLE IF NOT EXISTS `t_group` (
+ `id` bigint(20) unsigned NOT NULL,
+ `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT ''
+) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+
+--
+-- Daten für Tabelle `t_group`
+--
+
+INSERT INTO `t_group` (`id`, `name`) VALUES
+(1, 'System'),
+(2, 'Admin'),
+(3, 'Manager'),
+(4, 'Supporter'),
+(5, 'Gast');
+
+-- --------------------------------------------------------
+
+--
+-- Tabellenstruktur für Tabelle `t_history`
+--
+
+CREATE TABLE IF NOT EXISTS `t_history` (
+ `id` bigint(20) unsigned NOT NULL,
+ `ticket_id` bigint(11) unsigned NOT NULL DEFAULT '1',
+ `action_id` bigint(20) unsigned NOT NULL DEFAULT '1',
+ `user_id` bigint(20) unsigned NOT NULL DEFAULT '1',
+ `status_id` bigint(20) unsigned NOT NULL DEFAULT '1',
+ `subject` varchar(512) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
+ `message` varchar(512) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
+ `locked` tinyint(4) NOT NULL DEFAULT '0',
+ `last_access` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+
+--
+-- Daten für Tabelle `t_history`
+--
+
+INSERT INTO `t_history` (`id`, `ticket_id`, `action_id`, `user_id`, `status_id`, `subject`, `message`, `locked`, `last_access`) VALUES
+(1, 1, 1, 1, 1, 'Systemeintrag', 'Systemeintrag', 0, '2015-11-09 09:37:15'),
+(2, 2, 2, 1, 2, 'Ticket-1', 'Beschreibung-1', 0, '2015-11-09 13:15:27'),
+(3, 3, 2, 1, 2, 'Ticket-2', 'Beschreibung-2', 0, '2015-11-09 13:15:27'),
+(4, 4, 2, 1, 2, 'Ticket-3', 'Beschreibung-3', 0, '2015-11-09 13:15:27'),
+(5, 5, 2, 1, 2, 'Ticket-4', 'Beschreibung-4', 0, '2015-11-09 13:15:27'),
+(6, 6, 2, 1, 2, 'Ticket-5', 'Beschreibung-5', 0, '2015-11-09 13:15:27'),
+(7, 7, 2, 1, 2, 'Ticket-6', 'Beschreibung-6', 0, '2015-11-09 13:15:27'),
+(8, 8, 2, 1, 2, 'Ticket-7', 'Beschreibung-7', 0, '2015-11-09 13:15:27'),
+(9, 9, 2, 1, 2, 'Ticket-8', 'Beschreibung-8', 0, '2015-11-09 13:15:27'),
+(10, 10, 2, 1, 2, 'Ticket-9', 'Beschreibung-9', 0, '2015-11-09 13:15:27'),
+(11, 11, 2, 1, 2, 'Ticket-10', 'Beschreibung-10', 0, '2015-11-09 13:15:27');
+
+-- --------------------------------------------------------
+
+--
+-- Tabellenstruktur für Tabelle `t_status`
+--
+
+CREATE TABLE IF NOT EXISTS `t_status` (
+ `id` bigint(20) unsigned NOT NULL,
+ `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT ''
+) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+
+--
+-- Daten für Tabelle `t_status`
+--
+
+INSERT INTO `t_status` (`id`, `name`) VALUES
+(1, 'System'),
+(2, 'offen'),
+(3, 'geschlossen'),
+(4, 'abgelehnt'),
+(5, 'korrigiert'),
+(6, 'nicht korrigierbar');
+
+-- --------------------------------------------------------
+
+--
+-- Tabellenstruktur für Tabelle `t_text`
+--
+
+CREATE TABLE IF NOT EXISTS `t_text` (
+ `id` bigint(20) unsigned NOT NULL,
+ `user_id` bigint(20) unsigned NOT NULL DEFAULT '1',
+ `headline` text COLLATE utf8_unicode_ci NOT NULL,
+ `text` text COLLATE utf8_unicode_ci NOT NULL
+) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+
+--
+-- Daten für Tabelle `t_text`
+--
+
+INSERT INTO `t_text` (`id`, `user_id`, `headline`, `text`) VALUES
+(1, 1, '', 'Systemdatensatz'),
+(2, 2, 'Onscreen-Ticket System', 'Das ist ein simples Ticketsystem für dieses Unternehmen. Das Formatieren von HTML Text ist erst einmal deaktiviert und wird wohl auch niemals aktiviert.\r\n');
+
+-- --------------------------------------------------------
+
+--
+-- Tabellenstruktur für Tabelle `t_ticket`
+--
+
+CREATE TABLE IF NOT EXISTS `t_ticket` (
+ `id` bigint(20) unsigned NOT NULL,
+ `user_id` bigint(20) unsigned NOT NULL DEFAULT '1',
+ `status_id` bigint(20) unsigned NOT NULL DEFAULT '1',
+ `subject` varchar(512) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
+ `message` varchar(512) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
+ `locked` tinyint(1) NOT NULL DEFAULT '0',
+ `last_access` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
+) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+
+--
+-- Daten für Tabelle `t_ticket`
+--
+
+INSERT INTO `t_ticket` (`id`, `user_id`, `status_id`, `subject`, `message`, `locked`, `last_access`) VALUES
+(1, 1, 1, 'System', 'System', 0, '2015-11-02 15:37:14'),
+(2, 1, 2, 'Ticket-1', 'Beschreibung-1', 0, '2015-11-09 13:15:27'),
+(3, 1, 2, 'Ticket-2', 'Beschreibung-2', 0, '2015-11-09 13:15:27'),
+(4, 1, 2, 'Ticket-3', 'Beschreibung-3', 0, '2015-11-09 13:15:27'),
+(5, 1, 2, 'Ticket-4', 'Beschreibung-4', 0, '2015-11-09 13:15:27'),
+(6, 1, 2, 'Ticket-5', 'Beschreibung-5', 0, '2015-11-09 13:15:27'),
+(7, 1, 2, 'Ticket-6', 'Beschreibung-6', 0, '2015-11-09 13:15:27'),
+(8, 1, 2, 'Ticket-7', 'Beschreibung-7', 0, '2015-11-09 13:15:27'),
+(9, 1, 2, 'Ticket-8', 'Beschreibung-8', 0, '2015-11-09 13:15:27'),
+(10, 1, 2, 'Ticket-9', 'Beschreibung-9', 0, '2015-11-09 13:15:27'),
+(11, 1, 2, 'Ticket-10', 'Beschreibung-10', 0, '2015-11-09 13:15:27');
+
+--
+-- Trigger `t_ticket`
+--
+DELIMITER $$
+CREATE TRIGGER `t_ticket_after_delete` AFTER DELETE ON `t_ticket`
+ FOR EACH ROW BEGIN
+ call update_history(OLD.id, 4, OLD.user_id, OLD.status_id, OLD.subject, OLD.message, OLD.locked, OLD.last_access);
+END
+$$
+DELIMITER ;
+DELIMITER $$
+CREATE TRIGGER `t_ticket_after_insert` AFTER INSERT ON `t_ticket`
+ FOR EACH ROW BEGIN
+ call update_history(NEW.id, 2, NEW.user_id, NEW.status_id, NEW.subject, NEW.message, NEW.locked, NEW.last_access);
+END
+$$
+DELIMITER ;
+DELIMITER $$
+CREATE TRIGGER `t_ticket_after_update` AFTER UPDATE ON `t_ticket`
+ FOR EACH ROW BEGIN
+ call update_history(NEW.id, 3, NEW.user_id, NEW.status_id, NEW.subject, NEW.message, NEW.locked, NEW.last_access);
+END
+$$
+DELIMITER ;
+
+-- --------------------------------------------------------
+
+--
+-- Tabellenstruktur für Tabelle `t_user`
+--
+
+CREATE TABLE IF NOT EXISTS `t_user` (
+ `id` bigint(20) unsigned NOT NULL,
+ `group_id` bigint(20) unsigned NOT NULL DEFAULT '1',
+ `username` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
+ `password` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
+ `firstname` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
+ `lastname` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT ''
+) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+
+--
+-- Daten für Tabelle `t_user`
+--
+
+INSERT INTO `t_user` (`id`, `group_id`, `username`, `password`, `firstname`, `lastname`) VALUES
+(1, 1, 'system@onscreen.net', '098f6bcd4621d373cade4e832627b4f6', 'System', 'Datensatz'),
+(2, 2, 'broeker@onscreen.net', '098f6bcd4621d373cade4e832627b4f6', 'Markus', 'Bröker'),
+(3, 3, 'manager1@onscreen.net', '098f6bcd4621d373cade4e832627b4f6', 'Manager1', 'Onscreen'),
+(4, 4, 'supporter1@onscreen.net', '098f6bcd4621d373cade4e832627b4f6', 'supporter1', 'Onscreen'),
+(5, 4, 'supporter2@onscreen.net', '098f6bcd4621d373cade4e832627b4f6', 'supporter2', 'Onscreen'),
+(6, 4, 'supporter3@onscreen.net', '098f6bcd4621d373cade4e832627b4f6', 'supporter3', 'Onscreen'),
+(7, 4, 'supporter4@onscreen.net', '098f6bcd4621d373cade4e832627b4f6', 'supporter4', 'Onscreen'),
+(8, 4, 'supporter5@onscreen.net', '098f6bcd4621d373cade4e832627b4f6', 'supporter5', 'Onscreen'),
+(9, 4, 'supporter6@onscreen.net', '098f6bcd4621d373cade4e832627b4f6', 'supporter6', 'Onscreen'),
+(10, 4, 'supporter7@onscreen.net', '098f6bcd4621d373cade4e832627b4f6', 'supporter7', 'Onscreen'),
+(11, 4, 'supporter8@onscreen.net', '098f6bcd4621d373cade4e832627b4f6', 'supporter8', 'Onscreen'),
+(12, 4, 'supporter9@onscreen.net', '098f6bcd4621d373cade4e832627b4f6', 'supporter9', 'Onscreen'),
+(13, 4, 'supporter10@onscreen.net', '098f6bcd4621d373cade4e832627b4f6', 'supporter10', 'Onscreen');
+
+--
+-- Indizes der exportierten Tabellen
+--
+
+--
+-- Indizes für die Tabelle `t_action`
+--
+ALTER TABLE `t_action`
+ ADD UNIQUE KEY `id` (`id`);
+
+--
+-- Indizes für die Tabelle `t_group`
+--
+ALTER TABLE `t_group`
+ ADD UNIQUE KEY `id` (`id`);
+
+--
+-- Indizes für die Tabelle `t_history`
+--
+ALTER TABLE `t_history`
+ ADD UNIQUE KEY `id` (`id`),
+ ADD KEY `fk_history_ticked_id` (`ticket_id`),
+ ADD KEY `fk_history_action_id` (`action_id`),
+ ADD KEY `fk_history_user_id` (`user_id`),
+ ADD KEY `fk_history_status_id` (`status_id`);
+
+--
+-- Indizes für die Tabelle `t_status`
+--
+ALTER TABLE `t_status`
+ ADD UNIQUE KEY `id` (`id`);
+
+--
+-- Indizes für die Tabelle `t_text`
+--
+ALTER TABLE `t_text`
+ ADD UNIQUE KEY `id` (`id`),
+ ADD KEY `fk_t_user_text` (`user_id`);
+
+--
+-- Indizes für die Tabelle `t_ticket`
+--
+ALTER TABLE `t_ticket`
+ ADD UNIQUE KEY `id` (`id`),
+ ADD KEY `fk_t_status` (`status_id`),
+ ADD KEY `fk_t_user` (`user_id`);
+
+--
+-- Indizes für die Tabelle `t_user`
+--
+ALTER TABLE `t_user`
+ ADD UNIQUE KEY `id` (`id`),
+ ADD UNIQUE KEY `co_username` (`username`),
+ ADD KEY `fk_t_group` (`group_id`);
+
+--
+-- AUTO_INCREMENT für exportierte Tabellen
+--
+
+--
+-- AUTO_INCREMENT für Tabelle `t_action`
+--
+ALTER TABLE `t_action`
+ MODIFY `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=5;
+--
+-- AUTO_INCREMENT für Tabelle `t_group`
+--
+ALTER TABLE `t_group`
+ MODIFY `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=6;
+--
+-- AUTO_INCREMENT für Tabelle `t_history`
+--
+ALTER TABLE `t_history`
+ MODIFY `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=12;
+--
+-- AUTO_INCREMENT für Tabelle `t_status`
+--
+ALTER TABLE `t_status`
+ MODIFY `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=7;
+--
+-- AUTO_INCREMENT für Tabelle `t_text`
+--
+ALTER TABLE `t_text`
+ MODIFY `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=3;
+--
+-- AUTO_INCREMENT für Tabelle `t_ticket`
+--
+ALTER TABLE `t_ticket`
+ MODIFY `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=12;
+--
+-- AUTO_INCREMENT für Tabelle `t_user`
+--
+ALTER TABLE `t_user`
+ MODIFY `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=14;
+--
+-- Constraints der exportierten Tabellen
+--
+
+--
+-- Constraints der Tabelle `t_history`
+--
+ALTER TABLE `t_history`
+ ADD CONSTRAINT `fk_history_action_id` FOREIGN KEY (`action_id`) REFERENCES `t_action` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
+ ADD CONSTRAINT `fk_history_status_id` FOREIGN KEY (`status_id`) REFERENCES `t_status` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
+ ADD CONSTRAINT `fk_history_user_id` FOREIGN KEY (`user_id`) REFERENCES `t_user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION;
+
+--
+-- Constraints der Tabelle `t_text`
+--
+ALTER TABLE `t_text`
+ ADD CONSTRAINT `fk_t_user_text` FOREIGN KEY (`user_id`) REFERENCES `t_user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION;
+
+--
+-- Constraints der Tabelle `t_ticket`
+--
+ALTER TABLE `t_ticket`
+ ADD CONSTRAINT `fk_t_status` FOREIGN KEY (`status_id`) REFERENCES `t_status` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
+ ADD CONSTRAINT `fk_t_user` FOREIGN KEY (`user_id`) REFERENCES `t_user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION;
+
+--
+-- Constraints der Tabelle `t_user`
+--
+ALTER TABLE `t_user`
+ ADD CONSTRAINT `fk_t_group` FOREIGN KEY (`group_id`) REFERENCES `t_group` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION;
+
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
new file mode 100644
--- /dev/null
+++ b/templates/benutzerverwaltungs/anmelden.tpl
@@ -0,0 +1,31 @@
+<div class="container">
+ <div class="row">
+ <form action="" method="post">
+ <div class="col-lg-12">
+ <p>
+ <label for="usernameField">Benutzername:</label>
+ <input id="usernameField" type="email" name="username" value="{$request->post('username')}"/>
+ </p>
+
+ <p>
+ <label id="passwordField" for="passwordField">Passwort:</label>
+ <input type="password" name="password" value="{$request->post('password')}"/>
+ </p>
+ </div>
+
+ <div class="row">
+ <div class="col-lg-12">
+ <div class="col-lg-6">
+ <input type="button" onClick="route('/resetpasswort/')" value="Passwort zurück setzen"/>
+ </div>
+
+ <div class="col-lg-6">
+ <input type="submit" name="anmelden" value="anmelden"/>
+ </div>
+ </div>
+ </div>
+ </form>
+ </div>
+
+ {$request->printSession()}
+</div>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/templates/benutzerverwaltungs/benutzerverwaltung.tpl
@@ -0,0 +1,74 @@
+<h2 class="text-center">Benutzerverwaltung</h2>
+<hr/>
+
+<div class="container">
+ {foreach $users as $user}
+ <div class="row">
+ <div class="col-lg-12">
+ <form action="" method="post" autocomplete="off">
+ <div class="col-lg-4">
+ <p>
+ <label for="usernameField">Benutzername<span class="pull-right">({$user->getTicketCount()})</span></label>
+ <input id="usernameField" type="text" name="username" value="{$user->getUsername()}"/>
+ </p>
+ </div>
+
+ <div class="col-lg-3">
+ <p>
+ <label for="passwordField">Password</label>
+ <input id="passwordField" type="password" name="password" value="" autocomplete="off"/>
+ </p>
+ </div>
+
+ <div class="col-lg-3">
+ <p>
+ <label for="groupBox">Gruppenzugehörigkeit</label>
+ <select id="groupBox" name="groupbox">
+ {foreach $groups as $group}
+ {if $group->getId() == $user->getGroup_id()}
+ <option value="{$group->getId()}" selected="'selected'">{$group->getName()}</option>
+ {else}
+ <option value="{$group->getId()}">{$group->getName()}</option>
+ {/if}
+ {/foreach}
+ </select>
+ </p>
+ </div>
+
+ <div class="col-lg-1">
+ <label for="actionsKnopf1">Aktion</label>
+ <input id="aktionsKnopf1" type="submit" name="aendern" value="Ändern"/>
+ </div>
+
+ <div class="col-lg-1">
+ <label for="actionsKnopf2">Aktion</label>
+ <input id="aktionsKnopf2" type="submit" name="loeschen" value="Löschen"/>
+ </div>
+
+ <input type="hidden" name="uid" value="{$user->getId()}"/>
+
+ <br class="clearfix"/>
+ <hr/>
+ </form>
+ </div>
+ </div>
+ {/foreach}
+
+ <div class="row">
+ <hr/>
+ <div class="col-lg-12">
+ <div class="col-lg-6">
+ <div class="bold">
+ <a href="/?reset=1">Datenbank-Reset</a>
+ </div>
+ </div>
+
+ <div class="col-lg-6 text-right">
+ <div class="bold">
+ <a href="/?unit=1">Testeinträge aus CSV-Datei erzeugen</a>
+ </div>
+ </div>
+ </div>
+
+ </div>
+</div>
new file mode 100644
--- /dev/null
+++ b/templates/benutzerverwaltungs/meinprofil.tpl
@@ -0,0 +1,34 @@
+<h2 class="text-center">Mein Profil</h2>
+<hr/>
+
+<form action="" method="post">
+ <div class="container">
+ <div class="row">
+ <div class="col-lg-12">
+ <p>
+ <label for="usernameField">Benutzername</label>
+ <input id="usernameField" type="text" name="username" value="{$tUser->getUsername()}"/>
+ </p>
+
+ <p>
+ <label for="passwordField">Password</label>
+ <input id="passwordField" type="password" name="password" value=""/>
+ </p>
+
+ <p>
+ <label for="firstnameField">Vorname</label>
+ <input id="firstnameField" type="text" name="firstname" value="{$tUser->getFirstname()}"/>
+ </p>
+
+ <p>
+ <label for="lastnameField">Nachname</label>
+ <input id="lastnameField" type="text" name="lastname" value="{$tUser->getLastname()}"/>
+ </p>
+
+ <div class="pull-right">
+ <input type="submit" name="aendern" value="Ändern"/>
+ </div>
+ </div>
+ </div>
+ </div>
+</form>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/templates/benutzerverwaltungs/registrieren.tpl
@@ -0,0 +1,39 @@
+<h2 class="text-center">Benutzerregistrierung</h2>
+<hr/>
+
+<form action="" method="post">
+ <div class="container">
+ <div class="row">
+ <div class="col-lg-12">
+ <p>
+ <label for="usernameField">Benutzername</label>
+ <input id="usernameField" type="text" name="username" value="{$currentUser->getUsername()}"/>
+ </p>
+
+ <p>
+ <label for="passwordField1">Password</label>
+ <input id="passwordField1" type="password" name="password1" value=""/>
+ </p>
+
+ <p>
+ <label for="passwordField2">Password wiederholen</label>
+ <input id="passwordField2" type="password" name="password2" value=""/>
+ </p>
+
+ <p>
+ <label for="firstnameField">Vorname</label>
+ <input id="firstnameField" type="text" name="firstname" value="{$currentUser->getFirstname()}"/>
+ </p>
+
+ <p>
+ <label for="lastnameField">Nachname</label>
+ <input id="lastnameField" type="text" name="lastname" value="{$currentUser->getLastname()}"/>
+ </p>
+
+ <div class="pull-right">
+ <input type="submit" name="registrieren" value="neu registrieren"/>
+ </div>
+ </div>
+ </div>
+ </div>
+</form>
new file mode 100644
--- /dev/null
+++ b/templates/benutzerverwaltungs/resetpasswort.tpl
@@ -0,0 +1,25 @@
+<div class="container">
+ <div class="row">
+ <form action="/resetpasswort/" method="post">
+ <div class="col-lg-12">
+ <p>
+ <label for="usernameField">Benutzername:</label>
+ <input id="usernameField" type="email" name="username" value="{$request->post('username')}"/>
+ </p>
+ </div>
+
+ <div class="row">
+ <div class="col-lg-12">
+ <div class="col-lg-6">
+ <input type="submit" name="pw-reset" value="Passwort zurück setzten"/>
+ </div>
+ <div class="col-lg-6">
+ <input type="reset" name="verwerfen" value="Eingaben verwerfen"/>
+ </div>
+ </div>
+ </div>
+ </form>
+ </div>
+
+ {$request->printSession()}
+</div>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/templates/error/error.tpl
@@ -0,0 +1,11 @@
+<div class="container-fluid">
+ <div class="row">
+ <div class="col-lg-12">
+ <div class="text-center">
+ <p class="bold">Die gewünschte Seite '{$request->getUrl()}' ist derzeit nicht vorhanden.</p>
+
+ <p>Probieren Sie einen Eintrag aus dem Menü.</p>
+ </div>
+ </div>
+ </div>
+</div>
new file mode 100644
--- /dev/null
+++ b/templates/footer.tpl
@@ -0,0 +1,14 @@
+<div class="col-lg-12">
+ <div class="col-lg-4">
+ <p class="text-warning bold">{$smarty.session.prefix.msg}</p>
+ </div>
+
+ <div class="col-lg-4">
+ <p class="text-info bold">Ticket-System V1.0 / UID: {$smarty.session.prefix.user_id} /
+ GID: {$smarty.session.prefix.group_id} / HTTP-STATUS: {$response->getStatusCode()}</p>
+ </div>
+
+ <div class="col-lg-4">
+ <p class="text-danger bold">{$smarty.session.prefix.fehler}</p>
+ </div>
+</div>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/templates/header.tpl
@@ -0,0 +1,40 @@
+<nav class="navbar navbar-default">
+ <div class="container-fluid">
+ <div class="navbar-header">
+ <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#ticketbar" aria-expanded="false">
+ <span class="sr-only">Toggle navigation</span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ </button>
+ <a class="navbar-brand" href="/">Ticket-System</a>
+ </div>
+
+ <div class="collapse navbar-collapse" id="ticketbar">
+ {if $smarty.session.prefix.group_id == $tGroup::ADMIN || $smarty.session.prefix.group_id == $tGroup::MANAGER}
+ <ul class="nav navbar-nav">
+ <li class="active"><a href="/benutzerverwaltung/">Benutzerverwaltung <span class="sr-only">(current)</span></a></li>
+ </ul>
+ {/if}
+
+ <ul class="nav navbar-nav">
+ <li class="active"><a href="/tickets/">Tickets <span class="sr-only">(current)</span></a></li>
+ </ul>
+ <form class="navbar-form navbar-left" role="search" method="get" action="/tickets/">
+ <div class="form-group">
+ <input type="text" class="form-control" placeholder="Suchen..." name="tid" value="">
+ </div>
+ <button type="submit" class="btn btn-default">Ticket-Suche</button>
+ </form>
+ <ul class="nav navbar-nav navbar-right">
+ {if $request->getKey('isLoggedIn')}
+ <li><a href="/meinprofil/">{$tUser->getFirstname()} {$tUser->getLastname()}</a></li>
+ <li><a href="/abmelden/">abmelden</a></li>
+ {else}
+ <li><a href="/anmelden/">anmelden</a></li>
+ <li><a href="/registrieren/">registrieren</a></li>
+ {/if}
+ </ul>
+ </div>
+ </div>
+</nav>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/templates/history/historie.tpl
@@ -0,0 +1,35 @@
+<h2 class="text-center">Historie des Tickets Nr. {$ticket->getId()}</h2>
+<hr/>
+
+<table border="1" style="width: 100%">
+ <tr>
+ <th>Aktion</th>
+ <th>Status</th>
+ <th>Benutzer</th>
+ <th>Betreff</th>
+ <th>Nachricht</th>
+ <th>Gesperrt</th>
+ <th>Letzter Zugriff</th>
+ </tr>
+
+ {foreach $histories as $history}
+ {assign var="coloredRow" value=""}
+ {if $history->getLocked() == 1}
+ {assign var="coloredRow" value=" yellow-row"}
+ {/if}
+
+ {if $history->getStatus_Id() == $tStatus::GESCHLOSSEN}
+ {assign var="coloredRow" value=" red-row"}
+ {/if}
+ <tr class="clickable{$coloredRow}" id="tid{$ticket->getId()}">
+ <td>{$history->getActionName()}</td>
+ <td>{$history->getStatusName()}</td>
+ <td>{$history->getUsername()}</td>
+ <td>{$history->getSubject()}</td>
+ <td>{$history->getMessage()}</td>
+ <td>{$history->getLocked()}</td>
+ <td>{$history->getLast_Access()}</td>
+ </tr>
+ {/foreach}
+</table>
+
new file mode 100644
--- /dev/null
+++ b/templates/home/home.tpl
@@ -0,0 +1,40 @@
+<div class="container-fluid">
+ <div class="row">
+ <div class="col-lg-12">
+ <div class="text-center">
+ <h4>
+ {html_entity_decode($text->getHeadline())}
+ </h4>
+
+ <hr/>
+
+ <p>
+ {html_entity_decode($text->getText())}
+ </p>
+ </div>
+ </div>
+ </div>
+
+ {if $group_id == $tGroup::ADMIN}
+ <div class="row">
+ <div class="col-lg-12">
+ <form action="" method="post">
+ <p>
+ <label for="text">Überschrift</label>
+ <textarea id="headline" name="headline">{$text->getHeadline()}</textarea>
+ </p>
+
+ <p>
+ <label for="text">Nachricht</label>
+ <textarea id="text" name="text">{$text->getText()}</textarea>
+ </p>
+
+ <p>
+ <input type="submit" name="eintragen" value="eintragen"/>
+ <input type="hidden" name="tid" value="{$text->getId()}"/>
+ </p>
+ </form>
+ </div>
+ </div>
+ {/if}
+</div>
new file mode 100644
--- /dev/null
+++ b/templates/layout.tpl
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html lang="de">
+<head>
+ <meta charset="utf-8"/>
+ <title>Ticket-System-Demo</title>
+
+ <link href="/js/bootstrap/css/bootstrap.min.css" rel="stylesheet" type="text/css"/>
+
+ <link href="/css/main.css" rel="stylesheet" type="text/css"/>
+
+ <script type="text/javascript" src="/js/jquery-1.11.3.min.js"></script>
+ <script type="text/javascript" src="/js/bootstrap/bootstrap.js"></script>
+
+ <script type="text/javascript" src="//tinymce.cachefly.net/4.2/tinymce.min.js"></script>
+ <script type="text/javascript" src="/js/main.js"></script>
+</head>
+<body>
+<div id="page">
+ {include file="header.tpl"}
+ <div class="content">
+ {include file="{$page}.tpl"}
+ </div>
+
+ <div class="footer-area">
+ <div class="footer">
+ {include file="footer.tpl"}
+ </div>
+
+ <br class="clearfix"/>
+ </div>
+</div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/templates/tickets/ticketanlegen.tpl
@@ -0,0 +1,53 @@
+<h4 class="text-center">{if $currentTicket->getId() == NULL}Neues Ticket{else}Ticket Nr. {$currentTicket->getId()}{/if}</h4>
+<hr/>
+
+<div class="container-fluid">
+ <div class="row">
+ <div class="col-lg-12">
+ <form action="/tickets/" method="post">
+ <p>
+ <label for="subjectId">Betreff</label>
+ <input id="subjectId" type="text" name="subject" value="{$currentTicket->getSubject()}"/>
+ </p>
+
+ <p>
+ <label for="messageId">Nachricht</label>
+ <textarea id="messageId" name="message">{$currentTicket->getMessage()}</textarea>
+ </p>
+
+ <p>
+ <label for="statusId">Status</label>
+ <select id="statusId" name="status">
+ {foreach $statusItems as $status}
+ {if $status->getId() == $currentTicket->getStatus_Id()}
+ <option value="{$status->getId()}" selected="selected">{$status->getName()}</option>
+ {else}
+ <option value="{$status->getId()}">{$status->getName()}</option>
+ {/if}
+ {/foreach}
+ </select>
+ </p>
+
+ {if $smarty.session.prefix.group_id == $tGroup::ADMIN || $smarty.session.prefix.group_id == $tGroup::MANAGER}
+ <p>
+ <label for="userId">Bearbeiter</label>
+ <select id="userId" name="user_id">
+ {foreach $users as $user}
+ {if $user->getId() == $currentTicket->getUser_Id()}
+ <option value="{$user->getId()}" selected="selected">{$tUser->getFormattedUsername($user->getId())}</option>
+ {else}
+ <option value="{$user->getId()}">{$tUser->getFormattedUsername($user->getId())}</option>
+ {/if}
+ {/foreach}
+ </select>
+ </p>
+ {/if}
+
+ <p>
+ <input type="submit" name="eintragen" value="eintragen"/>
+ <input type="hidden" name="tid" value="{$currentTicket->getId()}"/>
+ </p>
+ </form>
+ </div>
+ </div>
+</div>
new file mode 100644
--- /dev/null
+++ b/templates/tickets/tickets.tpl
@@ -0,0 +1,78 @@
+<h2 class="text-center">Ticketverwaltung</h2>
+<hr/>
+
+<div class="container-fluid">
+ <div class="row">
+ <div class="col-lg-12">
+ {include file="tickets/ticketanlegen.tpl"}
+ </div>
+
+ <br class="clearfix"/>
+ </div>
+</div>
+
+{if $tickets != null}
+ <br class="clearfix"/>
+ <div class="container-fluid">
+ <div class="row">
+ <div class="col-lg-12">
+ <table class="achtel">
+ <tr>
+ <th>Nummer</th>
+ <th>Besitzer</th>
+ <th>Betreff</th>
+ <th>Nachricht</th>
+ <th>Status</th>
+ <th>Aktion1</th>
+ <th>Aktion2</th>
+ <th>Aktion3</th>
+ </tr>
+ </table>
+ </div>
+ </div>
+
+ <div class="row">
+ {foreach $tickets as $ticket}
+ <div class="col-lg-12">
+ <form action="/tickets/" method="post">
+ <table class="achtel">
+ {assign var="coloredRow" value=""}
+ {if $ticket->getLocked()}
+ {assign var="coloredRow" value="yellow-row"}
+ {/if}
+
+ {if $ticket->getStatus_Id() == $tStatus::GESCHLOSSEN}
+ {assign var="coloredRow" value="red-row"}
+ {/if}
+
+ <tr class="{$coloredRow}">
+ <td><input readonly='readonly' type="text" name="tid" value="{$ticket->getId()}"/></td>
+ <td><input readonly='readonly' type="text" name="username" value="{$tUser->getFormattedUsername($ticket->getUser_Id())}"/></td>
+ <td><input readonly='readonly' type="text" name="subject" value="{$ticket->getSubject()}"/></td>
+ <td><input readonly='readonly' type="text" name="message" value="{strip_tags(html_entity_decode($ticket->getMessage()))}"/></td>
+ <td><input readonly='readonly' type="text" name="status" value="{$tStatus->getFormattedStatus($ticket->getStatus_Id())}"/></td>
+
+ {if $group_id != $tGroup::GUEST}
+ {if $group_id == $tGroup::SUPPORTER && $ticket->getLocked() == 0}
+ <td><input type="submit" name="laden" value="annehmen"/></td>
+ {else}
+ <td><input type="submit" name="laden" value="laden"/></td>
+ {/if}
+ {else}
+ <td>Bearbeiten ist gesperrt</td>
+ {/if}
+
+ {if $group_id == $tGroup::MANAGER || $group_id == $tGroup::ADMIN}
+ <td><input type="submit" name="loeschen" value="löschen"/></td>
+ {else}
+ <td>Löschen ist gesperrt</td>
+ {/if}
+ <td><input type="submit" name="historie" value="Historie"/></td>
+ </tr>
+ </table>
+ </form>
+ </div>
+ {/foreach}
+ </div>
+ </div>
+{/if}
\ No newline at end of file