Created
December 16, 2012 14:24
-
-
Save Gonzih/4307784 to your computer and use it in GitHub Desktop.
4 Course PHP KR
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| db/table*.data | |
| uploads/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| $mysql_host = 'localhost'; | |
| $mysql_user = 'root'; | |
| $mysql_pass = '447750'; | |
| $mysql_db = 'php_kr_development'; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| function dbconn($mysql_host, $mysql_user, $mysql_pass, $mysql_db) { | |
| if (!@mysql_connect($mysql_host, $mysql_user, $mysql_pass)) { | |
| debug(mysql_error()); | |
| } | |
| if (!mysql_select_db($mysql_db)) { | |
| debug(mysql_error()); | |
| } | |
| register_shutdown_function("mysql_close"); | |
| } | |
| function sql_query($query) { | |
| $result = mysql_query($query); | |
| if (!$result) { | |
| debug(mysql_error()); | |
| } | |
| return $result; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| $table_name = 'soltan_mv_users'; | |
| $fields = Array( | |
| 'firstname' => 'char(255)', | |
| 'secondname' => 'char(255)', | |
| 'lastname' => 'char(255)', | |
| 'phone' => 'char(255)', | |
| 'email' => 'char(255)', | |
| 'country' => 'char(255)', | |
| 'city' => 'char(255)', | |
| 'street' => 'char(255)', | |
| 'street_n' => 'char(255)', | |
| 'additional_info' => 'char(255)', | |
| ); | |
| $field_titles = Array( | |
| 'firstname' => 'First Name', | |
| 'secondname' => 'Second Name', | |
| 'lastname' => 'Last Name', | |
| 'phone' => 'Phone Numbrer', | |
| 'email' => 'Email address', | |
| 'country' => 'Country', | |
| 'city' => 'City', | |
| 'street' => 'Street', | |
| 'street_n' => 'Streen Number', | |
| 'additional_info' => 'Additional information', | |
| ); | |
| $field_types = Array( | |
| 'firstname' => array('type' => 'text'), | |
| 'secondname' => array('type' => 'text'), | |
| 'lastname' => array('type' => 'text'), | |
| 'phone' => array('type' => 'radio', 'options' => array('Mobile', 'None')), | |
| 'email' => array('type' => 'email', 'required' => true), | |
| 'country' => array('type' => 'select', 'options' => array('BY', 'EN', 'US')), | |
| 'city' => array('type' => 'text'), | |
| 'street' => array('type' => 'text'), | |
| 'street_n' => array('type' => 'text'), | |
| 'additional_info' => array('type' => 'textarea'), | |
| ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| $table_name = 'soltan_mv_phones'; | |
| $fields = Array( | |
| 'release_year' => 'char(255)', | |
| 'type' => 'char(255)', | |
| 'os' => 'char(255)', | |
| 'processor' => 'char(255)', | |
| 'number_of_cores' => 'char(255)', | |
| 'size' => 'char(255)', | |
| 'weight' => 'char(255)', | |
| 'producer' => 'char(255)', | |
| 'model' => 'char(255)', | |
| 'price' => 'char(255)', | |
| ); | |
| $field_titles = Array( | |
| 'release_year' => 'Release Year', | |
| 'type' => 'Type', | |
| 'os' => 'Operating System', | |
| 'processor' => 'Processor', | |
| 'number_of_cores' => 'Number of cores', | |
| 'size' => 'Size', | |
| 'weight' => 'Weight', | |
| 'producer' => 'Producer', | |
| 'model' => 'Model', | |
| 'price' => 'Price', | |
| ); | |
| $field_types = Array( | |
| 'release_year' => array('type' => 'text'), | |
| 'type' => array('type' => 'radio', 'options' => array('Smartphone', 'Meh')), | |
| 'os' => array('type' => 'text'), | |
| 'processor' => array('type' => 'text'), | |
| 'number_of_cores' => array('type' => 'select', 'options' => array(1, 2, 3, 4, 5, 6, 7)), | |
| 'size' => array('type' => 'text'), | |
| 'weight' => array('type' => 'text'), | |
| 'producer' => array('type' => 'text'), | |
| 'model' => array('type' => 'text'), | |
| 'price' => array('type' => 'text'), | |
| ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| class DatabaseStorage { | |
| function __construct($table_name) { | |
| $this->table_name = $table_name; | |
| } | |
| public function all_records($query = null) { | |
| if (!$query) $query = "SELECT * FROM `{$this->table_name}`;"; | |
| $result = mysql_query($query); | |
| debug(mysql_error()); | |
| while(($result_array[] = mysql_fetch_assoc($result)) || array_pop($result_array)); | |
| return $result_array; | |
| } | |
| public function find_records($params, $fields) { | |
| $args = array(); | |
| foreach ($fields as $field => $type) { | |
| $filter_value = mysql_real_escape_string($params['filter_' . $field]); | |
| if ($filter_value) { | |
| $args[] = "`$field` LIKE '%$filter_value%'"; | |
| } | |
| } | |
| if (count($args) > 0) { | |
| $query = "SELECT * FROM `{$this->table_name}` WHERE " . join(' && ', $args) . ';'; | |
| return $this->all_records($query); | |
| } else { | |
| return $this->all_records(); | |
| } | |
| } | |
| public function create_record($params, $fields) { | |
| $f_list = array(); | |
| $v_list = array(); | |
| foreach ($fields as $field => $type) { | |
| $value = mysql_real_escape_string($params[$field]); | |
| $f_list[] = "`$field`"; | |
| $v_list[] = "'$value'"; | |
| } | |
| if (count($f_list) > 0) { | |
| $query = "INSERT INTO `{$this->table_name}` (" . join(' ,', $f_list) . ") values (" . join(" ,", $v_list) . ");"; | |
| $result = mysql_query($query); | |
| debug(mysql_error()); | |
| } | |
| } | |
| public function find_record($params) { | |
| if ($params['id']) { | |
| $id = mysql_real_escape_string($params['id']); | |
| $query = "SELECT * FROM `{$this->table_name}` WHERE `id` = $id;"; | |
| $result = mysql_query($query); | |
| debug(mysql_error()); | |
| return mysql_fetch_assoc($result); | |
| } else { | |
| throw new Exception('RecordNotFound'); | |
| } | |
| } | |
| public function update_record($params, $fields) { | |
| if ($params['id']) { | |
| $id = mysql_real_escape_string($params['id']); | |
| $args = array(); | |
| foreach ($fields as $field => $type) { | |
| $value = mysql_real_escape_string($params[$field]); | |
| $args[] = "`$field`='$value'"; | |
| } | |
| if (count($args) > 0) { | |
| $query = "UPDATE `{$this->table_name}` SET " . join(', ', $args) . " WHERE `id` = $id;"; | |
| mysql_query($query); | |
| debug(mysql_error()); | |
| } | |
| } else { | |
| throw new Exception('RecordNotFound'); | |
| } | |
| } | |
| public function delete_record($params) { | |
| if ($params['id']) { | |
| $id = mysql_real_escape_string($params['id']); | |
| $query = "DELETE FROM `{$this->table_name}` WHERE `id` = $id;"; | |
| $result = mysql_query($query); | |
| debug(mysql_error()); | |
| } else { | |
| throw new Exception('RecordNotFound'); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| $debug = true; | |
| function debug($string) { | |
| global $debug; | |
| if ($string && $debug) { | |
| echo '<pre>'; | |
| print_r($string); | |
| echo '</pre>'; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| class FileStorage { | |
| function __construct($file_name) { | |
| $this->file_name = $file_name; | |
| } | |
| function last_id() { | |
| $key = key(array_slice($this->db, -1, 1, TRUE)); | |
| if ($key) $key = 0; | |
| return $key; | |
| } | |
| function save() { | |
| file_put_contents($this->file_name, serialize($this->db), FILE_USE_INCLUDE_PATH); | |
| } | |
| function load() { | |
| $this->db = unserialize(file_get_contents($this->file_name, FILE_USE_INCLUDE_PATH)); | |
| if (!$this->db) $this->db = array(); | |
| } | |
| public function all_records($query = null) { | |
| $this->load(); | |
| return $this->db; | |
| } | |
| public function find_records($params, $fields) { | |
| $this->load(); | |
| $records = array(); | |
| foreach ($this->db as $record) { | |
| $out = true; | |
| foreach ($fields as $field => $type) { | |
| $filter_value = $params['filter_' . $field]; | |
| if ($filter_value && $out) { | |
| if (strpos($record[$field], $filter_value) === false) $out = false; | |
| } | |
| } | |
| if ($out) $records[] = $record; | |
| } | |
| return $records; | |
| } | |
| public function create_record($params, $fields) { | |
| $record = array(); | |
| foreach ($fields as $field => $type) { | |
| $value = $params[$field]; | |
| $record[$field] = $value; | |
| } | |
| if (count($record) > 0) { | |
| $this->load(); | |
| $this->db[] = $record; | |
| $this->save(); | |
| } | |
| } | |
| public function find_record($params) { | |
| if ($params['id'] != '') { | |
| $this->load(); | |
| $id = $params['id']; | |
| return $this->db[$id]; | |
| } else { | |
| throw new Exception('RecordNotFound'); | |
| } | |
| } | |
| public function update_record($params, $fields) { | |
| if ($params['id'] != '') { | |
| $id = $params['id']; | |
| $record = array(); | |
| foreach ($fields as $field => $type) { | |
| $value = $params[$field]; | |
| $record[$field] = $value; | |
| } | |
| if (count($record) > 0) { | |
| $this->load(); | |
| $this->db[$id] = $record; | |
| $this->save(); | |
| } | |
| } else { | |
| throw new Exception('RecordNotFound'); | |
| } | |
| } | |
| public function delete_record($params) { | |
| if ($params['id'] != '') { | |
| $this->load(); | |
| $id = $params['id']; | |
| unset($this->db[$id]); | |
| $this->save(); | |
| } else { | |
| throw new Exception('RecordNotFound'); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div class="span5"> | |
| {% if error %} | |
| <div class="alert alert-error"> | |
| {{ error }} | |
| </div> | |
| {% endif %} | |
| {% if success %} | |
| <div class="alert alert-success"> | |
| {{ success }} | |
| </div> | |
| {% endif %} | |
| <form class="form-horizontal" action="{{ prefix }}{{ submit_path }}" method="post" enctype="multipart/form-data"> | |
| <fieldset> | |
| <div class="control-group"> | |
| <label class="control-label" for="file">File</label> | |
| <div class="controls"> | |
| <input type="file" name="file" id="file"> | |
| </div> | |
| </div> | |
| <div class="control-group"> | |
| <div class="controls"> | |
| <button type="submit" class="btn btn-success">Upload</button> | |
| <button type="reset" class="btn">Reset</button> | |
| </div> | |
| </div> | |
| </fieldset> | |
| </form> | |
| <table class="table table-stripped"> | |
| <thead> | |
| <tr><td> Uploaded Images </td></tr> | |
| </thead> | |
| <tbody> | |
| {% for file in files %} | |
| <tr><td> | |
| <img src="{{ prefix }}uploads/{{ file }}"/> | |
| </td></tr> | |
| {% endfor %} | |
| </tbody> | |
| </table> | |
| </div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div class="span5"> | |
| <form class="form-horizontal" action="{{ prefix }}{{ submit_path }}"> | |
| <fieldset> | |
| <input type="hidden" name="action" value="filter"> | |
| {% for field, title in titles %} | |
| {{ views.render_field(types[field], filter_key(field), title, params[filter_key(field)], false) }} | |
| {% endfor %} | |
| <div class="control-group"> | |
| <div class="controls"> | |
| <button type="submit" class="btn btn-info">Filter</button> | |
| <a class="btn" href="{{ prefix }}{{ submit_path }}">Reset</a> | |
| </div> | |
| </div> | |
| </fieldset> | |
| </form> | |
| </div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div class="span5"> | |
| <form class="form-horizontal" action="{{ prefix }}{{ submit_path }}"> | |
| <fieldset> | |
| {% if action == 'update' %} | |
| <input type="hidden" name="id" value="{% if record['id'] %}{{ record['id'] }}{% else %}{{ params['id'] }}{% endif %}"> | |
| {% endif %} | |
| <input type="hidden" name="action" value="{{ action }}"> | |
| {% for field, title in titles %} | |
| {{ views.render_field(types[field], field, title, record[field], true) }} | |
| {% endfor %} | |
| <div class="control-group"> | |
| <div class="controls"> | |
| {% if action == 'update' %} | |
| <button type="submit" class="btn btn-primary">Update</button> | |
| <a class="btn" href="{{ prefix }}{{ submit_path }}">Reset</a> | |
| {% else %} | |
| <button type="submit" class="btn btn-success">Create</button> | |
| <button type="reset" class="btn">Reset</button> | |
| {% endif %} | |
| </div> | |
| </div> | |
| </fieldset> | |
| </form> | |
| </div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| function filter_key($key) { | |
| return 'filter_' . $key; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div class="span10"> | |
| <hr/> | |
| </div> | |
| <div class="span10"> | |
| <table class="table table-stripped"> | |
| <thead> | |
| <tr> | |
| <td> # </td> | |
| {% for field, title in titles %} | |
| <td>{{ title }}</td> | |
| {% endfor %} | |
| <td>Edit</td> | |
| <td>Delete</td> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| {% for id, record in records %} | |
| <tr> | |
| <td> | |
| {% if record['id'] %} {{ record['id'] }} {% else %} {{ id + 1 }} {% endif %} | |
| </td> | |
| {% for field, title in titles %} | |
| <td>{{ record[field] | e }}</td> | |
| {% endfor %} | |
| <td> | |
| <a class="btn btn-warning" href="{{ prefix }}{{ submit_path }}?action=edit&id={% if record['id'] %}{{ record['id'] }}{% else %}{{ id }}{% endif %}"><i class="icon-edit"></i></a> | |
| </td> | |
| <td> | |
| <a class="btn btn-danger" href="{{ prefix }}{{ submit_path }}?action=delete&id={% if record['id'] %}{{ record['id'] }}{% else %}{{ id }}{% endif %}"><i class="icon-remove"></i></a> | |
| </td> | |
| </tr> | |
| {% endfor %} | |
| </tbody> | |
| </table> | |
| </div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| $action = $_REQUEST['action']; | |
| function index($views, $fields, $titles, $storage, $controller_path, $field_types) { | |
| $records = $storage->all_records(); | |
| echo $views->render_multiple(array('_form', '_filter', '_index'), array( | |
| 'fields' => $fields, | |
| 'types' => $field_types, | |
| 'titles' => $titles, | |
| 'submit_path' => $controller_path, | |
| 'records' => $records, | |
| 'params' => array(), | |
| 'record' => array(), | |
| 'action' => 'create')); | |
| } | |
| function filter($views, $fields, $titles, $storage, $params, $controller_path, $field_types) { | |
| $records = $storage->find_records($params, $fields); | |
| echo $views->render_multiple(array('_form', '_filter', '_index'), array( | |
| 'fields' => $fields, | |
| 'types' => $field_types, | |
| 'titles' => $titles, | |
| 'submit_path' => $controller_path, | |
| 'records' => $records, | |
| 'params' => $params, | |
| 'record' => array(), | |
| 'action' => 'create')); | |
| } | |
| function create($views, $fields, $titles, $storage, $params, $controller_path, $field_types) { | |
| $storage->create_record($params, $fields); | |
| $records = $storage->all_records(); | |
| echo $views->render_multiple(array('_form', '_filter', '_index'), array( | |
| 'fields' => $fields, | |
| 'types' => $field_types, | |
| 'titles' => $titles, | |
| 'submit_path' => $controller_path, | |
| 'records' => $records, | |
| 'params' => $params, | |
| 'record' => array(), | |
| 'action' => 'create')); | |
| } | |
| function edit($views, $fields, $titles, $storage, $params, $controller_path, $field_types) { | |
| $records = $storage->all_records(); | |
| $record = $storage->find_record($params); | |
| echo $views->render_multiple(array('_form', '_filter', '_index'), array( | |
| 'fields' => $fields, | |
| 'types' => $field_types, | |
| 'titles' => $titles, | |
| 'submit_path' => $controller_path, | |
| 'records' => $records, | |
| 'params' => $params, | |
| 'record' => $record, | |
| 'action' => 'update')); | |
| } | |
| function update($views, $fields, $titles, $storage, $params, $controller_path, $field_types) { | |
| $storage->update_record($params, $fields); | |
| $records = $storage->all_records(); | |
| echo $views->render_multiple(array('_form', '_filter', '_index'), array( | |
| 'fields' => $fields, | |
| 'types' => $field_types, | |
| 'titles' => $titles, | |
| 'submit_path' => $controller_path, | |
| 'records' => $records, | |
| 'params' => $params, | |
| 'record' => array(), | |
| 'action' => 'create')); | |
| } | |
| function delete($views, $fields, $titles, $storage, $params, $controller_path, $field_types) { | |
| $storage->delete_record($params); | |
| $records = $storage->all_records(); | |
| echo $views->render_multiple(array('_form', '_filter', '_index'), array( | |
| 'fields' => $fields, | |
| 'types' => $field_types, | |
| 'titles' => $titles, | |
| 'submit_path' => $controller_path, | |
| 'records' => $records, | |
| 'params' => $params, | |
| 'record' => array(), | |
| 'action' => 'create')); | |
| } | |
| switch ($action) { | |
| case 'filter': | |
| filter($views, $fields, $field_titles, $storage, $_REQUEST, $controller_path, $field_types); | |
| break; | |
| case 'create': | |
| create($views, $fields, $field_titles, $storage, $_REQUEST, $controller_path, $field_types); | |
| break; | |
| case 'edit': | |
| edit($views, $fields, $field_titles, $storage, $_REQUEST, $controller_path, $field_types); | |
| break; | |
| case 'update': | |
| update($views, $fields, $field_titles, $storage, $_REQUEST, $controller_path, $field_types); | |
| break; | |
| case 'delete': | |
| delete($views, $fields, $field_titles, $storage, $_REQUEST, $controller_path, $field_types); | |
| break; | |
| default: | |
| index($views, $fields, $field_titles, $storage, $controller_path, $field_types); | |
| break; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| class Views { | |
| function __construct() { | |
| Twig_Autoloader::register(); | |
| $loader = new Twig_Loader_Filesystem('views'); | |
| //$this->prefix = '/~soltan_mv_09/'; | |
| $this->prefix = '/'; | |
| $this->twig = new Twig_Environment($loader, array('autoescape' => false)); | |
| $this->init_helpers(); | |
| } | |
| function init_helpers() { | |
| $this->twig->addFunction('filter_key', new Twig_Function_Function('filter_key')); | |
| } | |
| public function render_multiple($files = array(), $args = array()) { | |
| $content = ''; | |
| foreach($files as $file) { | |
| $content = $content . $this->render($file, $args); | |
| } | |
| $args['content'] = $content; | |
| return $this->twig->render('application.html', $args); | |
| } | |
| public function render($file, $args = array()) { | |
| $path = $file . '.html'; | |
| $args['views'] = $this; | |
| $args['prefix'] = $this->prefix; | |
| return $this->twig->render($path, $args); | |
| } | |
| public function render_with_layout($file, $args = array()) { | |
| return $this->render_multiple(array($file), $args); | |
| } | |
| public function render_field($type, $field, $title, $value, $required) { | |
| return $this->render('fields/' . $type['type'], array( | |
| 'title' => $title, | |
| 'type' => $type, | |
| 'field' => $field, | |
| 'value' => $value, | |
| 'required' => $required, | |
| )); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Binary_Add extends Twig_Node_Expression_Binary | |
| { | |
| public function operator(Twig_Compiler $compiler) | |
| { | |
| return $compiler->raw('+'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Binary_And extends Twig_Node_Expression_Binary | |
| { | |
| public function operator(Twig_Compiler $compiler) | |
| { | |
| return $compiler->raw('&&'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html xmlns='http://www.w3.org/1999/xhtml'> | |
| <head> | |
| <title>PHP</title> | |
| <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> | |
| <link href='{{ prefix }}bootstrap/css/bootstrap.css' rel='stylesheet'> | |
| <link href='{{ prefix }}css/styles.css' rel='stylesheet'> | |
| </head> | |
| <body> | |
| <div class="container-fluid"> | |
| <div class="row-fluid"> | |
| <div class="span2"> | |
| <ul class="nav nav-pills nav-stacked"> | |
| <li> | |
| <a href={{ prefix }}table1_file.php>Table 1 File</a> | |
| </li> | |
| <li> | |
| <a href={{ prefix }}table2_file.php>Table 2 File</a> | |
| </li> | |
| <li> | |
| <a href={{ prefix }}migrate_up_table1.php>Migraion Up Table 1</a> | |
| </li> | |
| <li> | |
| <a href={{ prefix }}migrate_down_table1.php>Migraion Down Table 1</a> | |
| </li> | |
| <li> | |
| <a href={{ prefix }}migrate_up_table2.php>Migraion Up Table 2</a> | |
| </li> | |
| <li> | |
| <a href={{ prefix }}migrate_down_table2.php>Migraion Down Table 2</a> | |
| </li> | |
| <li> | |
| <a href={{ prefix }}table1_db.php>Table 1 DB</a> | |
| </li> | |
| <li> | |
| <a href={{ prefix }}table2_db.php>Table 2 DB</a> | |
| </li> | |
| <li> | |
| <a href={{ prefix }}file_upload.php>File Upload</a> | |
| </li> | |
| </ul> | |
| </div> | |
| <div class="span10"> | |
| {{ content }} | |
| </div> | |
| </div> | |
| </div> | |
| </body> | |
| </html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Loads a template from an array. | |
| * | |
| * When using this loader with a cache mechanism, you should know that a new cache | |
| * key is generated each time a template content "changes" (the cache key being the | |
| * source code of the template). If you don't want to see your cache grows out of | |
| * control, you need to take care of clearing the old cache file by yourself. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterface | |
| { | |
| protected $templates; | |
| /** | |
| * Constructor. | |
| * | |
| * @param array $templates An array of templates (keys are the names, and values are the source code) | |
| * | |
| * @see Twig_Loader | |
| */ | |
| public function __construct(array $templates) | |
| { | |
| $this->templates = array(); | |
| foreach ($templates as $name => $template) { | |
| $this->templates[$name] = $template; | |
| } | |
| } | |
| /** | |
| * Adds or overrides a template. | |
| * | |
| * @param string $name The template name | |
| * @param string $template The template source | |
| */ | |
| public function setTemplate($name, $template) | |
| { | |
| $this->templates[(string) $name] = $template; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function getSource($name) | |
| { | |
| $name = (string) $name; | |
| if (!isset($this->templates[$name])) { | |
| throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name)); | |
| } | |
| return $this->templates[$name]; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function exists($name) | |
| { | |
| return isset($this->templates[(string) $name]); | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function getCacheKey($name) | |
| { | |
| $name = (string) $name; | |
| if (!isset($this->templates[$name])) { | |
| throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name)); | |
| } | |
| return $this->templates[$name]; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function isFresh($name, $time) | |
| { | |
| $name = (string) $name; | |
| if (!isset($this->templates[$name])) { | |
| throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name)); | |
| } | |
| return true; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Array extends Twig_Node_Expression | |
| { | |
| protected $index; | |
| public function __construct(array $elements, $lineno) | |
| { | |
| parent::__construct($elements, array(), $lineno); | |
| $this->index = -1; | |
| foreach ($this->getKeyValuePairs() as $pair) { | |
| if ($pair['key'] instanceof Twig_Node_Expression_Constant && ctype_digit((string) $pair['key']->getAttribute('value')) && $pair['key']->getAttribute('value') > $this->index) { | |
| $this->index = $pair['key']->getAttribute('value'); | |
| } | |
| } | |
| } | |
| public function getKeyValuePairs() | |
| { | |
| $pairs = array(); | |
| foreach (array_chunk($this->nodes, 2) as $pair) { | |
| $pairs[] = array( | |
| 'key' => $pair[0], | |
| 'value' => $pair[1], | |
| ); | |
| } | |
| return $pairs; | |
| } | |
| public function hasElement(Twig_Node_Expression $key) | |
| { | |
| foreach ($this->getKeyValuePairs() as $pair) { | |
| // we compare the string representation of the keys | |
| // to avoid comparing the line numbers which are not relevant here. | |
| if ((string) $key == (string) $pair['key']) { | |
| return true; | |
| } | |
| } | |
| return false; | |
| } | |
| public function addElement(Twig_Node_Expression $value, Twig_Node_Expression $key = null) | |
| { | |
| if (null === $key) { | |
| $key = new Twig_Node_Expression_Constant(++$this->index, $value->getLine()); | |
| } | |
| array_push($this->nodes, $key, $value); | |
| } | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler->raw('array('); | |
| $first = true; | |
| foreach ($this->getKeyValuePairs() as $pair) { | |
| if (!$first) { | |
| $compiler->raw(', '); | |
| } | |
| $first = false; | |
| $compiler | |
| ->subcompile($pair['key']) | |
| ->raw(' => ') | |
| ->subcompile($pair['value']) | |
| ; | |
| } | |
| $compiler->raw(')'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_AssignName extends Twig_Node_Expression_Name | |
| { | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->raw('$context[') | |
| ->string($this->getAttribute('name')) | |
| ->raw(']') | |
| ; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents an autoescape node. | |
| * | |
| * The value is the escaping strategy (can be html, js, ...) | |
| * | |
| * The true value is equivalent to html. | |
| * | |
| * If autoescaping is disabled, then the value is false. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_AutoEscape extends Twig_Node | |
| { | |
| public function __construct($value, Twig_NodeInterface $body, $lineno, $tag = 'autoescape') | |
| { | |
| parent::__construct(array('body' => $body), array('value' => $value), $lineno, $tag); | |
| } | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler->subcompile($this->getNode('body')); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Marks a section of a template to be escaped or not. | |
| * | |
| * <pre> | |
| * {% autoescape true %} | |
| * Everything will be automatically escaped in this block | |
| * {% endautoescape %} | |
| * | |
| * {% autoescape false %} | |
| * Everything will be outputed as is in this block | |
| * {% endautoescape %} | |
| * | |
| * {% autoescape true js %} | |
| * Everything will be automatically escaped in this block | |
| * using the js escaping strategy | |
| * {% endautoescape %} | |
| * </pre> | |
| */ | |
| class Twig_TokenParser_AutoEscape extends Twig_TokenParser | |
| { | |
| /** | |
| * Parses a token and returns a node. | |
| * | |
| * @param Twig_Token $token A Twig_Token instance | |
| * | |
| * @return Twig_NodeInterface A Twig_NodeInterface instance | |
| */ | |
| public function parse(Twig_Token $token) | |
| { | |
| $lineno = $token->getLine(); | |
| $stream = $this->parser->getStream(); | |
| if ($stream->test(Twig_Token::BLOCK_END_TYPE)) { | |
| $value = 'html'; | |
| } else { | |
| $expr = $this->parser->getExpressionParser()->parseExpression(); | |
| if (!$expr instanceof Twig_Node_Expression_Constant) { | |
| throw new Twig_Error_Syntax('An escaping strategy must be a string or a Boolean.', $stream->getCurrent()->getLine(), $stream->getFilename()); | |
| } | |
| $value = $expr->getAttribute('value'); | |
| $compat = true === $value || false === $value; | |
| if (true === $value) { | |
| $value = 'html'; | |
| } | |
| if ($compat && $stream->test(Twig_Token::NAME_TYPE)) { | |
| if (false === $value) { | |
| throw new Twig_Error_Syntax('Unexpected escaping strategy as you set autoescaping to false.', $stream->getCurrent()->getLine(), $stream->getFilename()); | |
| } | |
| $value = $stream->next()->getValue(); | |
| } | |
| } | |
| $stream->expect(Twig_Token::BLOCK_END_TYPE); | |
| $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true); | |
| $stream->expect(Twig_Token::BLOCK_END_TYPE); | |
| return new Twig_Node_AutoEscape($value, $body, $lineno, $this->getTag()); | |
| } | |
| public function decideBlockEnd(Twig_Token $token) | |
| { | |
| return $token->test('endautoescape'); | |
| } | |
| /** | |
| * Gets the tag name associated with this token parser. | |
| * | |
| * @return string The tag name | |
| */ | |
| public function getTag() | |
| { | |
| return 'autoescape'; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| require_once 'lib/Twig/Autoloader.php'; | |
| require_once 'lib/_debug.php'; | |
| require_once 'lib/_config.php'; | |
| require_once 'lib/_db.php'; | |
| require_once 'lib/_db_storage.php'; | |
| require_once 'lib/_file_storage.php'; | |
| require_once 'lib/_helpers.php'; | |
| require_once 'lib/_views.php'; | |
| dbconn($mysql_host, $mysql_user, $mysql_pass, $mysql_db); | |
| $views = new Views(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Autoloads Twig classes. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Autoloader | |
| { | |
| /** | |
| * Registers Twig_Autoloader as an SPL autoloader. | |
| */ | |
| public static function register() | |
| { | |
| ini_set('unserialize_callback_func', 'spl_autoload_call'); | |
| spl_autoload_register(array(new self, 'autoload')); | |
| } | |
| /** | |
| * Handles autoloading of classes. | |
| * | |
| * @param string $class A class name. | |
| */ | |
| public static function autoload($class) | |
| { | |
| if (0 !== strpos($class, 'Twig')) { | |
| return; | |
| } | |
| if (is_file($file = dirname(__FILE__).'/../'.str_replace(array('_', "\0"), array('/', ''), $class).'.php')) { | |
| require $file; | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| abstract class Twig_Node_Expression_Binary extends Twig_Node_Expression | |
| { | |
| public function __construct(Twig_NodeInterface $left, Twig_NodeInterface $right, $lineno) | |
| { | |
| parent::__construct(array('left' => $left, 'right' => $right), array(), $lineno); | |
| } | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->raw('(') | |
| ->subcompile($this->getNode('left')) | |
| ->raw(' ') | |
| ; | |
| $this->operator($compiler); | |
| $compiler | |
| ->raw(' ') | |
| ->subcompile($this->getNode('right')) | |
| ->raw(')') | |
| ; | |
| } | |
| abstract public function operator(Twig_Compiler $compiler); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Binary_BitwiseAnd extends Twig_Node_Expression_Binary | |
| { | |
| public function operator(Twig_Compiler $compiler) | |
| { | |
| return $compiler->raw('&'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Binary_BitwiseOr extends Twig_Node_Expression_Binary | |
| { | |
| public function operator(Twig_Compiler $compiler) | |
| { | |
| return $compiler->raw('|'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Binary_BitwiseXor extends Twig_Node_Expression_Binary | |
| { | |
| public function operator(Twig_Compiler $compiler) | |
| { | |
| return $compiler->raw('^'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a block node. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_Block extends Twig_Node | |
| { | |
| public function __construct($name, Twig_NodeInterface $body, $lineno, $tag = null) | |
| { | |
| parent::__construct(array('body' => $body), array('name' => $name), $lineno, $tag); | |
| } | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->addDebugInfo($this) | |
| ->write(sprintf("public function block_%s(\$context, array \$blocks = array())\n", $this->getAttribute('name')), "{\n") | |
| ->indent() | |
| ; | |
| $compiler | |
| ->subcompile($this->getNode('body')) | |
| ->outdent() | |
| ->write("}\n\n") | |
| ; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Marks a section of a template as being reusable. | |
| * | |
| * <pre> | |
| * {% block head %} | |
| * <link rel="stylesheet" href="style.css" /> | |
| * <title>{% block title %}{% endblock %} - My Webpage</title> | |
| * {% endblock %} | |
| * </pre> | |
| */ | |
| class Twig_TokenParser_Block extends Twig_TokenParser | |
| { | |
| /** | |
| * Parses a token and returns a node. | |
| * | |
| * @param Twig_Token $token A Twig_Token instance | |
| * | |
| * @return Twig_NodeInterface A Twig_NodeInterface instance | |
| */ | |
| public function parse(Twig_Token $token) | |
| { | |
| $lineno = $token->getLine(); | |
| $stream = $this->parser->getStream(); | |
| $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); | |
| if ($this->parser->hasBlock($name)) { | |
| throw new Twig_Error_Syntax(sprintf("The block '$name' has already been defined line %d", $this->parser->getBlock($name)->getLine()), $stream->getCurrent()->getLine(), $stream->getFilename()); | |
| } | |
| $this->parser->setBlock($name, $block = new Twig_Node_Block($name, new Twig_Node(array()), $lineno)); | |
| $this->parser->pushLocalScope(); | |
| $this->parser->pushBlockStack($name); | |
| if ($stream->test(Twig_Token::BLOCK_END_TYPE)) { | |
| $stream->next(); | |
| $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true); | |
| if ($stream->test(Twig_Token::NAME_TYPE)) { | |
| $value = $stream->next()->getValue(); | |
| if ($value != $name) { | |
| throw new Twig_Error_Syntax(sprintf("Expected endblock for block '$name' (but %s given)", $value), $stream->getCurrent()->getLine(), $stream->getFilename()); | |
| } | |
| } | |
| } else { | |
| $body = new Twig_Node(array( | |
| new Twig_Node_Print($this->parser->getExpressionParser()->parseExpression(), $lineno), | |
| )); | |
| } | |
| $stream->expect(Twig_Token::BLOCK_END_TYPE); | |
| $block->setNode('body', $body); | |
| $this->parser->popBlockStack(); | |
| $this->parser->popLocalScope(); | |
| return new Twig_Node_BlockReference($name, $lineno, $this->getTag()); | |
| } | |
| public function decideBlockEnd(Twig_Token $token) | |
| { | |
| return $token->test('endblock'); | |
| } | |
| /** | |
| * Gets the tag name associated with this token parser. | |
| * | |
| * @return string The tag name | |
| */ | |
| public function getTag() | |
| { | |
| return 'block'; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a block call node. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_BlockReference extends Twig_Node implements Twig_NodeOutputInterface | |
| { | |
| public function __construct($name, $lineno, $tag = null) | |
| { | |
| parent::__construct(array(), array('name' => $name), $lineno, $tag); | |
| } | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->addDebugInfo($this) | |
| ->write(sprintf("\$this->displayBlock('%s', \$context, \$blocks);\n", $this->getAttribute('name'))) | |
| ; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a block call node. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_Expression_BlockReference extends Twig_Node_Expression | |
| { | |
| public function __construct(Twig_NodeInterface $name, $asString = false, $lineno, $tag = null) | |
| { | |
| parent::__construct(array('name' => $name), array('as_string' => $asString, 'output' => false), $lineno, $tag); | |
| } | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| if ($this->getAttribute('as_string')) { | |
| $compiler->raw('(string) '); | |
| } | |
| if ($this->getAttribute('output')) { | |
| $compiler | |
| ->addDebugInfo($this) | |
| ->write("\$this->displayBlock(") | |
| ->subcompile($this->getNode('name')) | |
| ->raw(", \$context, \$blocks);\n") | |
| ; | |
| } else { | |
| $compiler | |
| ->raw("\$this->renderBlock(") | |
| ->subcompile($this->getNode('name')) | |
| ->raw(", \$context, \$blocks)") | |
| ; | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2011 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a body node. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_Body extends Twig_Node | |
| { | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /*! | |
| * Bootstrap Responsive v2.2.2 | |
| * | |
| * Copyright 2012 Twitter, Inc | |
| * Licensed under the Apache License v2.0 | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Designed and built with all the love in the world @twitter by @mdo and @fat. | |
| */ | |
| @-ms-viewport { | |
| width: device-width; | |
| } | |
| .clearfix { | |
| *zoom: 1; | |
| } | |
| .clearfix:before, | |
| .clearfix:after { | |
| display: table; | |
| line-height: 0; | |
| content: ""; | |
| } | |
| .clearfix:after { | |
| clear: both; | |
| } | |
| .hide-text { | |
| font: 0/0 a; | |
| color: transparent; | |
| text-shadow: none; | |
| background-color: transparent; | |
| border: 0; | |
| } | |
| .input-block-level { | |
| display: block; | |
| width: 100%; | |
| min-height: 30px; | |
| -webkit-box-sizing: border-box; | |
| -moz-box-sizing: border-box; | |
| box-sizing: border-box; | |
| } | |
| .hidden { | |
| display: none; | |
| visibility: hidden; | |
| } | |
| .visible-phone { | |
| display: none !important; | |
| } | |
| .visible-tablet { | |
| display: none !important; | |
| } | |
| .hidden-desktop { | |
| display: none !important; | |
| } | |
| .visible-desktop { | |
| display: inherit !important; | |
| } | |
| @media (min-width: 768px) and (max-width: 979px) { | |
| .hidden-desktop { | |
| display: inherit !important; | |
| } | |
| .visible-desktop { | |
| display: none !important ; | |
| } | |
| .visible-tablet { | |
| display: inherit !important; | |
| } | |
| .hidden-tablet { | |
| display: none !important; | |
| } | |
| } | |
| @media (max-width: 767px) { | |
| .hidden-desktop { | |
| display: inherit !important; | |
| } | |
| .visible-desktop { | |
| display: none !important; | |
| } | |
| .visible-phone { | |
| display: inherit !important; | |
| } | |
| .hidden-phone { | |
| display: none !important; | |
| } | |
| } | |
| @media (min-width: 1200px) { | |
| .row { | |
| margin-left: -30px; | |
| *zoom: 1; | |
| } | |
| .row:before, | |
| .row:after { | |
| display: table; | |
| line-height: 0; | |
| content: ""; | |
| } | |
| .row:after { | |
| clear: both; | |
| } | |
| [class*="span"] { | |
| float: left; | |
| min-height: 1px; | |
| margin-left: 30px; | |
| } | |
| .container, | |
| .navbar-static-top .container, | |
| .navbar-fixed-top .container, | |
| .navbar-fixed-bottom .container { | |
| width: 1170px; | |
| } | |
| .span12 { | |
| width: 1170px; | |
| } | |
| .span11 { | |
| width: 1070px; | |
| } | |
| .span10 { | |
| width: 970px; | |
| } | |
| .span9 { | |
| width: 870px; | |
| } | |
| .span8 { | |
| width: 770px; | |
| } | |
| .span7 { | |
| width: 670px; | |
| } | |
| .span6 { | |
| width: 570px; | |
| } | |
| .span5 { | |
| width: 470px; | |
| } | |
| .span4 { | |
| width: 370px; | |
| } | |
| .span3 { | |
| width: 270px; | |
| } | |
| .span2 { | |
| width: 170px; | |
| } | |
| .span1 { | |
| width: 70px; | |
| } | |
| .offset12 { | |
| margin-left: 1230px; | |
| } | |
| .offset11 { | |
| margin-left: 1130px; | |
| } | |
| .offset10 { | |
| margin-left: 1030px; | |
| } | |
| .offset9 { | |
| margin-left: 930px; | |
| } | |
| .offset8 { | |
| margin-left: 830px; | |
| } | |
| .offset7 { | |
| margin-left: 730px; | |
| } | |
| .offset6 { | |
| margin-left: 630px; | |
| } | |
| .offset5 { | |
| margin-left: 530px; | |
| } | |
| .offset4 { | |
| margin-left: 430px; | |
| } | |
| .offset3 { | |
| margin-left: 330px; | |
| } | |
| .offset2 { | |
| margin-left: 230px; | |
| } | |
| .offset1 { | |
| margin-left: 130px; | |
| } | |
| .row-fluid { | |
| width: 100%; | |
| *zoom: 1; | |
| } | |
| .row-fluid:before, | |
| .row-fluid:after { | |
| display: table; | |
| line-height: 0; | |
| content: ""; | |
| } | |
| .row-fluid:after { | |
| clear: both; | |
| } | |
| .row-fluid [class*="span"] { | |
| display: block; | |
| float: left; | |
| width: 100%; | |
| min-height: 30px; | |
| margin-left: 2.564102564102564%; | |
| *margin-left: 2.5109110747408616%; | |
| -webkit-box-sizing: border-box; | |
| -moz-box-sizing: border-box; | |
| box-sizing: border-box; | |
| } | |
| .row-fluid [class*="span"]:first-child { | |
| margin-left: 0; | |
| } | |
| .row-fluid .controls-row [class*="span"] + [class*="span"] { | |
| margin-left: 2.564102564102564%; | |
| } | |
| .row-fluid .span12 { | |
| width: 100%; | |
| *width: 99.94680851063829%; | |
| } | |
| .row-fluid .span11 { | |
| width: 91.45299145299145%; | |
| *width: 91.39979996362975%; | |
| } | |
| .row-fluid .span10 { | |
| width: 82.90598290598291%; | |
| *width: 82.8527914166212%; | |
| } | |
| .row-fluid .span9 { | |
| width: 74.35897435897436%; | |
| *width: 74.30578286961266%; | |
| } | |
| .row-fluid .span8 { | |
| width: 65.81196581196582%; | |
| *width: 65.75877432260411%; | |
| } | |
| .row-fluid .span7 { | |
| width: 57.26495726495726%; | |
| *width: 57.21176577559556%; | |
| } | |
| .row-fluid .span6 { | |
| width: 48.717948717948715%; | |
| *width: 48.664757228587014%; | |
| } | |
| .row-fluid .span5 { | |
| width: 40.17094017094017%; | |
| *width: 40.11774868157847%; | |
| } | |
| .row-fluid .span4 { | |
| width: 31.623931623931625%; | |
| *width: 31.570740134569924%; | |
| } | |
| .row-fluid .span3 { | |
| width: 23.076923076923077%; | |
| *width: 23.023731587561375%; | |
| } | |
| .row-fluid .span2 { | |
| width: 14.52991452991453%; | |
| *width: 14.476723040552828%; | |
| } | |
| .row-fluid .span1 { | |
| width: 5.982905982905983%; | |
| *width: 5.929714493544281%; | |
| } | |
| .row-fluid .offset12 { | |
| margin-left: 105.12820512820512%; | |
| *margin-left: 105.02182214948171%; | |
| } | |
| .row-fluid .offset12:first-child { | |
| margin-left: 102.56410256410257%; | |
| *margin-left: 102.45771958537915%; | |
| } | |
| .row-fluid .offset11 { | |
| margin-left: 96.58119658119658%; | |
| *margin-left: 96.47481360247316%; | |
| } | |
| .row-fluid .offset11:first-child { | |
| margin-left: 94.01709401709402%; | |
| *margin-left: 93.91071103837061%; | |
| } | |
| .row-fluid .offset10 { | |
| margin-left: 88.03418803418803%; | |
| *margin-left: 87.92780505546462%; | |
| } | |
| .row-fluid .offset10:first-child { | |
| margin-left: 85.47008547008548%; | |
| *margin-left: 85.36370249136206%; | |
| } | |
| .row-fluid .offset9 { | |
| margin-left: 79.48717948717949%; | |
| *margin-left: 79.38079650845607%; | |
| } | |
| .row-fluid .offset9:first-child { | |
| margin-left: 76.92307692307693%; | |
| *margin-left: 76.81669394435352%; | |
| } | |
| .row-fluid .offset8 { | |
| margin-left: 70.94017094017094%; | |
| *margin-left: 70.83378796144753%; | |
| } | |
| .row-fluid .offset8:first-child { | |
| margin-left: 68.37606837606839%; | |
| *margin-left: 68.26968539734497%; | |
| } | |
| .row-fluid .offset7 { | |
| margin-left: 62.393162393162385%; | |
| *margin-left: 62.28677941443899%; | |
| } | |
| .row-fluid .offset7:first-child { | |
| margin-left: 59.82905982905982%; | |
| *margin-left: 59.72267685033642%; | |
| } | |
| .row-fluid .offset6 { | |
| margin-left: 53.84615384615384%; | |
| *margin-left: 53.739770867430444%; | |
| } | |
| .row-fluid .offset6:first-child { | |
| margin-left: 51.28205128205128%; | |
| *margin-left: 51.175668303327875%; | |
| } | |
| .row-fluid .offset5 { | |
| margin-left: 45.299145299145295%; | |
| *margin-left: 45.1927623204219%; | |
| } | |
| .row-fluid .offset5:first-child { | |
| margin-left: 42.73504273504273%; | |
| *margin-left: 42.62865975631933%; | |
| } | |
| .row-fluid .offset4 { | |
| margin-left: 36.75213675213675%; | |
| *margin-left: 36.645753773413354%; | |
| } | |
| .row-fluid .offset4:first-child { | |
| margin-left: 34.18803418803419%; | |
| *margin-left: 34.081651209310785%; | |
| } | |
| .row-fluid .offset3 { | |
| margin-left: 28.205128205128204%; | |
| *margin-left: 28.0987452264048%; | |
| } | |
| .row-fluid .offset3:first-child { | |
| margin-left: 25.641025641025642%; | |
| *margin-left: 25.53464266230224%; | |
| } | |
| .row-fluid .offset2 { | |
| margin-left: 19.65811965811966%; | |
| *margin-left: 19.551736679396257%; | |
| } | |
| .row-fluid .offset2:first-child { | |
| margin-left: 17.094017094017094%; | |
| *margin-left: 16.98763411529369%; | |
| } | |
| .row-fluid .offset1 { | |
| margin-left: 11.11111111111111%; | |
| *margin-left: 11.004728132387708%; | |
| } | |
| .row-fluid .offset1:first-child { | |
| margin-left: 8.547008547008547%; | |
| *margin-left: 8.440625568285142%; | |
| } | |
| input, | |
| textarea, | |
| .uneditable-input { | |
| margin-left: 0; | |
| } | |
| .controls-row [class*="span"] + [class*="span"] { | |
| margin-left: 30px; | |
| } | |
| input.span12, | |
| textarea.span12, | |
| .uneditable-input.span12 { | |
| width: 1156px; | |
| } | |
| input.span11, | |
| textarea.span11, | |
| .uneditable-input.span11 { | |
| width: 1056px; | |
| } | |
| input.span10, | |
| textarea.span10, | |
| .uneditable-input.span10 { | |
| width: 956px; | |
| } | |
| input.span9, | |
| textarea.span9, | |
| .uneditable-input.span9 { | |
| width: 856px; | |
| } | |
| input.span8, | |
| textarea.span8, | |
| .uneditable-input.span8 { | |
| width: 756px; | |
| } | |
| input.span7, | |
| textarea.span7, | |
| .uneditable-input.span7 { | |
| width: 656px; | |
| } | |
| input.span6, | |
| textarea.span6, | |
| .uneditable-input.span6 { | |
| width: 556px; | |
| } | |
| input.span5, | |
| textarea.span5, | |
| .uneditable-input.span5 { | |
| width: 456px; | |
| } | |
| input.span4, | |
| textarea.span4, | |
| .uneditable-input.span4 { | |
| width: 356px; | |
| } | |
| input.span3, | |
| textarea.span3, | |
| .uneditable-input.span3 { | |
| width: 256px; | |
| } | |
| input.span2, | |
| textarea.span2, | |
| .uneditable-input.span2 { | |
| width: 156px; | |
| } | |
| input.span1, | |
| textarea.span1, | |
| .uneditable-input.span1 { | |
| width: 56px; | |
| } | |
| .thumbnails { | |
| margin-left: -30px; | |
| } | |
| .thumbnails > li { | |
| margin-left: 30px; | |
| } | |
| .row-fluid .thumbnails { | |
| margin-left: 0; | |
| } | |
| } | |
| @media (min-width: 768px) and (max-width: 979px) { | |
| .row { | |
| margin-left: -20px; | |
| *zoom: 1; | |
| } | |
| .row:before, | |
| .row:after { | |
| display: table; | |
| line-height: 0; | |
| content: ""; | |
| } | |
| .row:after { | |
| clear: both; | |
| } | |
| [class*="span"] { | |
| float: left; | |
| min-height: 1px; | |
| margin-left: 20px; | |
| } | |
| .container, | |
| .navbar-static-top .container, | |
| .navbar-fixed-top .container, | |
| .navbar-fixed-bottom .container { | |
| width: 724px; | |
| } | |
| .span12 { | |
| width: 724px; | |
| } | |
| .span11 { | |
| width: 662px; | |
| } | |
| .span10 { | |
| width: 600px; | |
| } | |
| .span9 { | |
| width: 538px; | |
| } | |
| .span8 { | |
| width: 476px; | |
| } | |
| .span7 { | |
| width: 414px; | |
| } | |
| .span6 { | |
| width: 352px; | |
| } | |
| .span5 { | |
| width: 290px; | |
| } | |
| .span4 { | |
| width: 228px; | |
| } | |
| .span3 { | |
| width: 166px; | |
| } | |
| .span2 { | |
| width: 104px; | |
| } | |
| .span1 { | |
| width: 42px; | |
| } | |
| .offset12 { | |
| margin-left: 764px; | |
| } | |
| .offset11 { | |
| margin-left: 702px; | |
| } | |
| .offset10 { | |
| margin-left: 640px; | |
| } | |
| .offset9 { | |
| margin-left: 578px; | |
| } | |
| .offset8 { | |
| margin-left: 516px; | |
| } | |
| .offset7 { | |
| margin-left: 454px; | |
| } | |
| .offset6 { | |
| margin-left: 392px; | |
| } | |
| .offset5 { | |
| margin-left: 330px; | |
| } | |
| .offset4 { | |
| margin-left: 268px; | |
| } | |
| .offset3 { | |
| margin-left: 206px; | |
| } | |
| .offset2 { | |
| margin-left: 144px; | |
| } | |
| .offset1 { | |
| margin-left: 82px; | |
| } | |
| .row-fluid { | |
| width: 100%; | |
| *zoom: 1; | |
| } | |
| .row-fluid:before, | |
| .row-fluid:after { | |
| display: table; | |
| line-height: 0; | |
| content: ""; | |
| } | |
| .row-fluid:after { | |
| clear: both; | |
| } | |
| .row-fluid [class*="span"] { | |
| display: block; | |
| float: left; | |
| width: 100%; | |
| min-height: 30px; | |
| margin-left: 2.7624309392265194%; | |
| *margin-left: 2.709239449864817%; | |
| -webkit-box-sizing: border-box; | |
| -moz-box-sizing: border-box; | |
| box-sizing: border-box; | |
| } | |
| .row-fluid [class*="span"]:first-child { | |
| margin-left: 0; | |
| } | |
| .row-fluid .controls-row [class*="span"] + [class*="span"] { | |
| margin-left: 2.7624309392265194%; | |
| } | |
| .row-fluid .span12 { | |
| width: 100%; | |
| *width: 99.94680851063829%; | |
| } | |
| .row-fluid .span11 { | |
| width: 91.43646408839778%; | |
| *width: 91.38327259903608%; | |
| } | |
| .row-fluid .span10 { | |
| width: 82.87292817679558%; | |
| *width: 82.81973668743387%; | |
| } | |
| .row-fluid .span9 { | |
| width: 74.30939226519337%; | |
| *width: 74.25620077583166%; | |
| } | |
| .row-fluid .span8 { | |
| width: 65.74585635359117%; | |
| *width: 65.69266486422946%; | |
| } | |
| .row-fluid .span7 { | |
| width: 57.18232044198895%; | |
| *width: 57.12912895262725%; | |
| } | |
| .row-fluid .span6 { | |
| width: 48.61878453038674%; | |
| *width: 48.56559304102504%; | |
| } | |
| .row-fluid .span5 { | |
| width: 40.05524861878453%; | |
| *width: 40.00205712942283%; | |
| } | |
| .row-fluid .span4 { | |
| width: 31.491712707182323%; | |
| *width: 31.43852121782062%; | |
| } | |
| .row-fluid .span3 { | |
| width: 22.92817679558011%; | |
| *width: 22.87498530621841%; | |
| } | |
| .row-fluid .span2 { | |
| width: 14.3646408839779%; | |
| *width: 14.311449394616199%; | |
| } | |
| .row-fluid .span1 { | |
| width: 5.801104972375691%; | |
| *width: 5.747913483013988%; | |
| } | |
| .row-fluid .offset12 { | |
| margin-left: 105.52486187845304%; | |
| *margin-left: 105.41847889972962%; | |
| } | |
| .row-fluid .offset12:first-child { | |
| margin-left: 102.76243093922652%; | |
| *margin-left: 102.6560479605031%; | |
| } | |
| .row-fluid .offset11 { | |
| margin-left: 96.96132596685082%; | |
| *margin-left: 96.8549429881274%; | |
| } | |
| .row-fluid .offset11:first-child { | |
| margin-left: 94.1988950276243%; | |
| *margin-left: 94.09251204890089%; | |
| } | |
| .row-fluid .offset10 { | |
| margin-left: 88.39779005524862%; | |
| *margin-left: 88.2914070765252%; | |
| } | |
| .row-fluid .offset10:first-child { | |
| margin-left: 85.6353591160221%; | |
| *margin-left: 85.52897613729868%; | |
| } | |
| .row-fluid .offset9 { | |
| margin-left: 79.8342541436464%; | |
| *margin-left: 79.72787116492299%; | |
| } | |
| .row-fluid .offset9:first-child { | |
| margin-left: 77.07182320441989%; | |
| *margin-left: 76.96544022569647%; | |
| } | |
| .row-fluid .offset8 { | |
| margin-left: 71.2707182320442%; | |
| *margin-left: 71.16433525332079%; | |
| } | |
| .row-fluid .offset8:first-child { | |
| margin-left: 68.50828729281768%; | |
| *margin-left: 68.40190431409427%; | |
| } | |
| .row-fluid .offset7 { | |
| margin-left: 62.70718232044199%; | |
| *margin-left: 62.600799341718584%; | |
| } | |
| .row-fluid .offset7:first-child { | |
| margin-left: 59.94475138121547%; | |
| *margin-left: 59.838368402492065%; | |
| } | |
| .row-fluid .offset6 { | |
| margin-left: 54.14364640883978%; | |
| *margin-left: 54.037263430116376%; | |
| } | |
| .row-fluid .offset6:first-child { | |
| margin-left: 51.38121546961326%; | |
| *margin-left: 51.27483249088986%; | |
| } | |
| .row-fluid .offset5 { | |
| margin-left: 45.58011049723757%; | |
| *margin-left: 45.47372751851417%; | |
| } | |
| .row-fluid .offset5:first-child { | |
| margin-left: 42.81767955801105%; | |
| *margin-left: 42.71129657928765%; | |
| } | |
| .row-fluid .offset4 { | |
| margin-left: 37.01657458563536%; | |
| *margin-left: 36.91019160691196%; | |
| } | |
| .row-fluid .offset4:first-child { | |
| margin-left: 34.25414364640884%; | |
| *margin-left: 34.14776066768544%; | |
| } | |
| .row-fluid .offset3 { | |
| margin-left: 28.45303867403315%; | |
| *margin-left: 28.346655695309746%; | |
| } | |
| .row-fluid .offset3:first-child { | |
| margin-left: 25.69060773480663%; | |
| *margin-left: 25.584224756083227%; | |
| } | |
| .row-fluid .offset2 { | |
| margin-left: 19.88950276243094%; | |
| *margin-left: 19.783119783707537%; | |
| } | |
| .row-fluid .offset2:first-child { | |
| margin-left: 17.12707182320442%; | |
| *margin-left: 17.02068884448102%; | |
| } | |
| .row-fluid .offset1 { | |
| margin-left: 11.32596685082873%; | |
| *margin-left: 11.219583872105325%; | |
| } | |
| .row-fluid .offset1:first-child { | |
| margin-left: 8.56353591160221%; | |
| *margin-left: 8.457152932878806%; | |
| } | |
| input, | |
| textarea, | |
| .uneditable-input { | |
| margin-left: 0; | |
| } | |
| .controls-row [class*="span"] + [class*="span"] { | |
| margin-left: 20px; | |
| } | |
| input.span12, | |
| textarea.span12, | |
| .uneditable-input.span12 { | |
| width: 710px; | |
| } | |
| input.span11, | |
| textarea.span11, | |
| .uneditable-input.span11 { | |
| width: 648px; | |
| } | |
| input.span10, | |
| textarea.span10, | |
| .uneditable-input.span10 { | |
| width: 586px; | |
| } | |
| input.span9, | |
| textarea.span9, | |
| .uneditable-input.span9 { | |
| width: 524px; | |
| } | |
| input.span8, | |
| textarea.span8, | |
| .uneditable-input.span8 { | |
| width: 462px; | |
| } | |
| input.span7, | |
| textarea.span7, | |
| .uneditable-input.span7 { | |
| width: 400px; | |
| } | |
| input.span6, | |
| textarea.span6, | |
| .uneditable-input.span6 { | |
| width: 338px; | |
| } | |
| input.span5, | |
| textarea.span5, | |
| .uneditable-input.span5 { | |
| width: 276px; | |
| } | |
| input.span4, | |
| textarea.span4, | |
| .uneditable-input.span4 { | |
| width: 214px; | |
| } | |
| input.span3, | |
| textarea.span3, | |
| .uneditable-input.span3 { | |
| width: 152px; | |
| } | |
| input.span2, | |
| textarea.span2, | |
| .uneditable-input.span2 { | |
| width: 90px; | |
| } | |
| input.span1, | |
| textarea.span1, | |
| .uneditable-input.span1 { | |
| width: 28px; | |
| } | |
| } | |
| @media (max-width: 767px) { | |
| body { | |
| padding-right: 20px; | |
| padding-left: 20px; | |
| } | |
| .navbar-fixed-top, | |
| .navbar-fixed-bottom, | |
| .navbar-static-top { | |
| margin-right: -20px; | |
| margin-left: -20px; | |
| } | |
| .container-fluid { | |
| padding: 0; | |
| } | |
| .dl-horizontal dt { | |
| float: none; | |
| width: auto; | |
| clear: none; | |
| text-align: left; | |
| } | |
| .dl-horizontal dd { | |
| margin-left: 0; | |
| } | |
| .container { | |
| width: auto; | |
| } | |
| .row-fluid { | |
| width: 100%; | |
| } | |
| .row, | |
| .thumbnails { | |
| margin-left: 0; | |
| } | |
| .thumbnails > li { | |
| float: none; | |
| margin-left: 0; | |
| } | |
| [class*="span"], | |
| .uneditable-input[class*="span"], | |
| .row-fluid [class*="span"] { | |
| display: block; | |
| float: none; | |
| width: 100%; | |
| margin-left: 0; | |
| -webkit-box-sizing: border-box; | |
| -moz-box-sizing: border-box; | |
| box-sizing: border-box; | |
| } | |
| .span12, | |
| .row-fluid .span12 { | |
| width: 100%; | |
| -webkit-box-sizing: border-box; | |
| -moz-box-sizing: border-box; | |
| box-sizing: border-box; | |
| } | |
| .row-fluid [class*="offset"]:first-child { | |
| margin-left: 0; | |
| } | |
| .input-large, | |
| .input-xlarge, | |
| .input-xxlarge, | |
| input[class*="span"], | |
| select[class*="span"], | |
| textarea[class*="span"], | |
| .uneditable-input { | |
| display: block; | |
| width: 100%; | |
| min-height: 30px; | |
| -webkit-box-sizing: border-box; | |
| -moz-box-sizing: border-box; | |
| box-sizing: border-box; | |
| } | |
| .input-prepend input, | |
| .input-append input, | |
| .input-prepend input[class*="span"], | |
| .input-append input[class*="span"] { | |
| display: inline-block; | |
| width: auto; | |
| } | |
| .controls-row [class*="span"] + [class*="span"] { | |
| margin-left: 0; | |
| } | |
| .modal { | |
| position: fixed; | |
| top: 20px; | |
| right: 20px; | |
| left: 20px; | |
| width: auto; | |
| margin: 0; | |
| } | |
| .modal.fade { | |
| top: -100px; | |
| } | |
| .modal.fade.in { | |
| top: 20px; | |
| } | |
| } | |
| @media (max-width: 480px) { | |
| .nav-collapse { | |
| -webkit-transform: translate3d(0, 0, 0); | |
| } | |
| .page-header h1 small { | |
| display: block; | |
| line-height: 20px; | |
| } | |
| input[type="checkbox"], | |
| input[type="radio"] { | |
| border: 1px solid #ccc; | |
| } | |
| .form-horizontal .control-label { | |
| float: none; | |
| width: auto; | |
| padding-top: 0; | |
| text-align: left; | |
| } | |
| .form-horizontal .controls { | |
| margin-left: 0; | |
| } | |
| .form-horizontal .control-list { | |
| padding-top: 0; | |
| } | |
| .form-horizontal .form-actions { | |
| padding-right: 10px; | |
| padding-left: 10px; | |
| } | |
| .media .pull-left, | |
| .media .pull-right { | |
| display: block; | |
| float: none; | |
| margin-bottom: 10px; | |
| } | |
| .media-object { | |
| margin-right: 0; | |
| margin-left: 0; | |
| } | |
| .modal { | |
| top: 10px; | |
| right: 10px; | |
| left: 10px; | |
| } | |
| .modal-header .close { | |
| padding: 10px; | |
| margin: -10px; | |
| } | |
| .carousel-caption { | |
| position: static; | |
| } | |
| } | |
| @media (max-width: 979px) { | |
| body { | |
| padding-top: 0; | |
| } | |
| .navbar-fixed-top, | |
| .navbar-fixed-bottom { | |
| position: static; | |
| } | |
| .navbar-fixed-top { | |
| margin-bottom: 20px; | |
| } | |
| .navbar-fixed-bottom { | |
| margin-top: 20px; | |
| } | |
| .navbar-fixed-top .navbar-inner, | |
| .navbar-fixed-bottom .navbar-inner { | |
| padding: 5px; | |
| } | |
| .navbar .container { | |
| width: auto; | |
| padding: 0; | |
| } | |
| .navbar .brand { | |
| padding-right: 10px; | |
| padding-left: 10px; | |
| margin: 0 0 0 -5px; | |
| } | |
| .nav-collapse { | |
| clear: both; | |
| } | |
| .nav-collapse .nav { | |
| float: none; | |
| margin: 0 0 10px; | |
| } | |
| .nav-collapse .nav > li { | |
| float: none; | |
| } | |
| .nav-collapse .nav > li > a { | |
| margin-bottom: 2px; | |
| } | |
| .nav-collapse .nav > .divider-vertical { | |
| display: none; | |
| } | |
| .nav-collapse .nav .nav-header { | |
| color: #777777; | |
| text-shadow: none; | |
| } | |
| .nav-collapse .nav > li > a, | |
| .nav-collapse .dropdown-menu a { | |
| padding: 9px 15px; | |
| font-weight: bold; | |
| color: #777777; | |
| -webkit-border-radius: 3px; | |
| -moz-border-radius: 3px; | |
| border-radius: 3px; | |
| } | |
| .nav-collapse .btn { | |
| padding: 4px 10px 4px; | |
| font-weight: normal; | |
| -webkit-border-radius: 4px; | |
| -moz-border-radius: 4px; | |
| border-radius: 4px; | |
| } | |
| .nav-collapse .dropdown-menu li + li a { | |
| margin-bottom: 2px; | |
| } | |
| .nav-collapse .nav > li > a:hover, | |
| .nav-collapse .dropdown-menu a:hover { | |
| background-color: #f2f2f2; | |
| } | |
| .navbar-inverse .nav-collapse .nav > li > a, | |
| .navbar-inverse .nav-collapse .dropdown-menu a { | |
| color: #999999; | |
| } | |
| .navbar-inverse .nav-collapse .nav > li > a:hover, | |
| .navbar-inverse .nav-collapse .dropdown-menu a:hover { | |
| background-color: #111111; | |
| } | |
| .nav-collapse.in .btn-group { | |
| padding: 0; | |
| margin-top: 5px; | |
| } | |
| .nav-collapse .dropdown-menu { | |
| position: static; | |
| top: auto; | |
| left: auto; | |
| display: none; | |
| float: none; | |
| max-width: none; | |
| padding: 0; | |
| margin: 0 15px; | |
| background-color: transparent; | |
| border: none; | |
| -webkit-border-radius: 0; | |
| -moz-border-radius: 0; | |
| border-radius: 0; | |
| -webkit-box-shadow: none; | |
| -moz-box-shadow: none; | |
| box-shadow: none; | |
| } | |
| .nav-collapse .open > .dropdown-menu { | |
| display: block; | |
| } | |
| .nav-collapse .dropdown-menu:before, | |
| .nav-collapse .dropdown-menu:after { | |
| display: none; | |
| } | |
| .nav-collapse .dropdown-menu .divider { | |
| display: none; | |
| } | |
| .nav-collapse .nav > li > .dropdown-menu:before, | |
| .nav-collapse .nav > li > .dropdown-menu:after { | |
| display: none; | |
| } | |
| .nav-collapse .navbar-form, | |
| .nav-collapse .navbar-search { | |
| float: none; | |
| padding: 10px 15px; | |
| margin: 10px 0; | |
| border-top: 1px solid #f2f2f2; | |
| border-bottom: 1px solid #f2f2f2; | |
| -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); | |
| -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); | |
| box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); | |
| } | |
| .navbar-inverse .nav-collapse .navbar-form, | |
| .navbar-inverse .nav-collapse .navbar-search { | |
| border-top-color: #111111; | |
| border-bottom-color: #111111; | |
| } | |
| .navbar .nav-collapse .nav.pull-right { | |
| float: none; | |
| margin-left: 0; | |
| } | |
| .nav-collapse, | |
| .nav-collapse.collapse { | |
| height: 0; | |
| overflow: hidden; | |
| } | |
| .navbar .btn-navbar { | |
| display: block; | |
| } | |
| .navbar-static .navbar-inner { | |
| padding-right: 10px; | |
| padding-left: 10px; | |
| } | |
| } | |
| @media (min-width: 980px) { | |
| .nav-collapse.collapse { | |
| height: auto !important; | |
| overflow: visible !important; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /*! | |
| * Bootstrap Responsive v2.2.2 | |
| * | |
| * Copyright 2012 Twitter, Inc | |
| * Licensed under the Apache License v2.0 | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Designed and built with all the love in the world @twitter by @mdo and @fat. | |
| */@-ms-viewport{width:device-width}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}.visible-desktop{display:inherit!important}@media(min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}}@media(max-width:767px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-phone{display:inherit!important}.hidden-phone{display:none!important}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:30px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%}.row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%}.row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%}.row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%}.row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%}.row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%}.row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%}.row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%}.row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%}.row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%}.row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%}.row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%}.row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%}.row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%}.row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%}.row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%}.row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%}.row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%}.row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%}.row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%}.row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%}.row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%}.row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%}.row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%}.row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%}.row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%}.row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%}.row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%}.row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%}.row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%}.row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%}.row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%}.row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%}.row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%}.row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:30px}input.span12,textarea.span12,.uneditable-input.span12{width:1156px}input.span11,textarea.span11,.uneditable-input.span11{width:1056px}input.span10,textarea.span10,.uneditable-input.span10{width:956px}input.span9,textarea.span9,.uneditable-input.span9{width:856px}input.span8,textarea.span8,.uneditable-input.span8{width:756px}input.span7,textarea.span7,.uneditable-input.span7{width:656px}input.span6,textarea.span6,.uneditable-input.span6{width:556px}input.span5,textarea.span5,.uneditable-input.span5{width:456px}input.span4,textarea.span4,.uneditable-input.span4{width:356px}input.span3,textarea.span3,.uneditable-input.span3{width:256px}input.span2,textarea.span2,.uneditable-input.span2{width:156px}input.span1,textarea.span1,.uneditable-input.span1{width:56px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%}.row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%}.row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%}.row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%}.row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%}.row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%}.row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%}.row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%}.row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%}.row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%}.row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%}.row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%}.row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%}.row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%}.row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%}.row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%}.row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%}.row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%}.row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%}.row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%}.row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%}.row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%}.row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%}.row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%}.row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%}.row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%}.row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%}.row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%}.row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%}.row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%}.row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%}.row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%}.row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%}.row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%}.row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:710px}input.span11,textarea.span11,.uneditable-input.span11{width:648px}input.span10,textarea.span10,.uneditable-input.span10{width:586px}input.span9,textarea.span9,.uneditable-input.span9{width:524px}input.span8,textarea.span8,.uneditable-input.span8{width:462px}input.span7,textarea.span7,.uneditable-input.span7{width:400px}input.span6,textarea.span6,.uneditable-input.span6{width:338px}input.span5,textarea.span5,.uneditable-input.span5{width:276px}input.span4,textarea.span4,.uneditable-input.span4{width:214px}input.span3,textarea.span3,.uneditable-input.span3{width:152px}input.span2,textarea.span2,.uneditable-input.span2{width:90px}input.span1,textarea.span1,.uneditable-input.span1{width:28px}}@media(max-width:767px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-right:-20px;margin-left:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;width:auto;clear:none;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}.thumbnails>li{float:none;margin-left:0}[class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{display:block;float:none;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="offset"]:first-child{margin-left:0}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}.controls-row [class*="span"]+[class*="span"]{margin-left:0}.modal{position:fixed;top:20px;right:20px;left:20px;width:auto;margin:0}.modal.fade{top:-100px}.modal.fade.in{top:20px}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:20px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-right:10px;padding-left:10px}.media .pull-left,.media .pull-right{display:block;float:none;margin-bottom:10px}.media-object{margin-right:0;margin-left:0}.modal{top:10px;right:10px;left:10px}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:20px}.navbar-fixed-bottom{margin-top:20px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-right:10px;padding-left:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 10px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#777;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .dropdown-menu a:hover{background-color:#f2f2f2}.navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999}.navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:hover{background-color:#111}.nav-collapse.in .btn-group{padding:0;margin-top:5px}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;display:none;float:none;max-width:none;padding:0;margin:0 15px;background-color:transparent;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .open>.dropdown-menu{display:block}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111;border-bottom-color:#111}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{height:0;overflow:hidden}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-right:10px;padding-left:10px}}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /*! | |
| * Bootstrap v2.2.2 | |
| * | |
| * Copyright 2012 Twitter, Inc | |
| * Licensed under the Apache License v2.0 | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Designed and built with all the love in the world @twitter by @mdo and @fat. | |
| */ | |
| article, | |
| aside, | |
| details, | |
| figcaption, | |
| figure, | |
| footer, | |
| header, | |
| hgroup, | |
| nav, | |
| section { | |
| display: block; | |
| } | |
| audio, | |
| canvas, | |
| video { | |
| display: inline-block; | |
| *display: inline; | |
| *zoom: 1; | |
| } | |
| audio:not([controls]) { | |
| display: none; | |
| } | |
| html { | |
| font-size: 100%; | |
| -webkit-text-size-adjust: 100%; | |
| -ms-text-size-adjust: 100%; | |
| } | |
| a:focus { | |
| outline: thin dotted #333; | |
| outline: 5px auto -webkit-focus-ring-color; | |
| outline-offset: -2px; | |
| } | |
| a:hover, | |
| a:active { | |
| outline: 0; | |
| } | |
| sub, | |
| sup { | |
| position: relative; | |
| font-size: 75%; | |
| line-height: 0; | |
| vertical-align: baseline; | |
| } | |
| sup { | |
| top: -0.5em; | |
| } | |
| sub { | |
| bottom: -0.25em; | |
| } | |
| img { | |
| width: auto\9; | |
| height: auto; | |
| max-width: 100%; | |
| vertical-align: middle; | |
| border: 0; | |
| -ms-interpolation-mode: bicubic; | |
| } | |
| #map_canvas img, | |
| .google-maps img { | |
| max-width: none; | |
| } | |
| button, | |
| input, | |
| select, | |
| textarea { | |
| margin: 0; | |
| font-size: 100%; | |
| vertical-align: middle; | |
| } | |
| button, | |
| input { | |
| *overflow: visible; | |
| line-height: normal; | |
| } | |
| button::-moz-focus-inner, | |
| input::-moz-focus-inner { | |
| padding: 0; | |
| border: 0; | |
| } | |
| button, | |
| html input[type="button"], | |
| input[type="reset"], | |
| input[type="submit"] { | |
| cursor: pointer; | |
| -webkit-appearance: button; | |
| } | |
| label, | |
| select, | |
| button, | |
| input[type="button"], | |
| input[type="reset"], | |
| input[type="submit"], | |
| input[type="radio"], | |
| input[type="checkbox"] { | |
| cursor: pointer; | |
| } | |
| 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-decoration, | |
| input[type="search"]::-webkit-search-cancel-button { | |
| -webkit-appearance: none; | |
| } | |
| textarea { | |
| overflow: auto; | |
| vertical-align: top; | |
| } | |
| @media print { | |
| * { | |
| color: #000 !important; | |
| text-shadow: none !important; | |
| background: transparent !important; | |
| box-shadow: none !important; | |
| } | |
| a, | |
| a:visited { | |
| text-decoration: underline; | |
| } | |
| a[href]:after { | |
| content: " (" attr(href) ")"; | |
| } | |
| abbr[title]:after { | |
| content: " (" attr(title) ")"; | |
| } | |
| .ir a:after, | |
| a[href^="javascript:"]:after, | |
| a[href^="#"]: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; | |
| } | |
| @page { | |
| margin: 0.5cm; | |
| } | |
| p, | |
| h2, | |
| h3 { | |
| orphans: 3; | |
| widows: 3; | |
| } | |
| h2, | |
| h3 { | |
| page-break-after: avoid; | |
| } | |
| } | |
| .clearfix { | |
| *zoom: 1; | |
| } | |
| .clearfix:before, | |
| .clearfix:after { | |
| display: table; | |
| line-height: 0; | |
| content: ""; | |
| } | |
| .clearfix:after { | |
| clear: both; | |
| } | |
| .hide-text { | |
| font: 0/0 a; | |
| color: transparent; | |
| text-shadow: none; | |
| background-color: transparent; | |
| border: 0; | |
| } | |
| .input-block-level { | |
| display: block; | |
| width: 100%; | |
| min-height: 30px; | |
| -webkit-box-sizing: border-box; | |
| -moz-box-sizing: border-box; | |
| box-sizing: border-box; | |
| } | |
| body { | |
| margin: 0; | |
| font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; | |
| font-size: 14px; | |
| line-height: 20px; | |
| color: #333333; | |
| background-color: #ffffff; | |
| } | |
| a { | |
| color: #0088cc; | |
| text-decoration: none; | |
| } | |
| a:hover { | |
| color: #005580; | |
| text-decoration: underline; | |
| } | |
| .img-rounded { | |
| -webkit-border-radius: 6px; | |
| -moz-border-radius: 6px; | |
| border-radius: 6px; | |
| } | |
| .img-polaroid { | |
| padding: 4px; | |
| background-color: #fff; | |
| border: 1px solid #ccc; | |
| border: 1px solid rgba(0, 0, 0, 0.2); | |
| -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); | |
| -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); | |
| box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); | |
| } | |
| .img-circle { | |
| -webkit-border-radius: 500px; | |
| -moz-border-radius: 500px; | |
| border-radius: 500px; | |
| } | |
| .row { | |
| margin-left: -20px; | |
| *zoom: 1; | |
| } | |
| .row:before, | |
| .row:after { | |
| display: table; | |
| line-height: 0; | |
| content: ""; | |
| } | |
| .row:after { | |
| clear: both; | |
| } | |
| [class*="span"] { | |
| float: left; | |
| min-height: 1px; | |
| margin-left: 20px; | |
| } | |
| .container, | |
| .navbar-static-top .container, | |
| .navbar-fixed-top .container, | |
| .navbar-fixed-bottom .container { | |
| width: 940px; | |
| } | |
| .span12 { | |
| width: 940px; | |
| } | |
| .span11 { | |
| width: 860px; | |
| } | |
| .span10 { | |
| width: 780px; | |
| } | |
| .span9 { | |
| width: 700px; | |
| } | |
| .span8 { | |
| width: 620px; | |
| } | |
| .span7 { | |
| width: 540px; | |
| } | |
| .span6 { | |
| width: 460px; | |
| } | |
| .span5 { | |
| width: 380px; | |
| } | |
| .span4 { | |
| width: 300px; | |
| } | |
| .span3 { | |
| width: 220px; | |
| } | |
| .span2 { | |
| width: 140px; | |
| } | |
| .span1 { | |
| width: 60px; | |
| } | |
| .offset12 { | |
| margin-left: 980px; | |
| } | |
| .offset11 { | |
| margin-left: 900px; | |
| } | |
| .offset10 { | |
| margin-left: 820px; | |
| } | |
| .offset9 { | |
| margin-left: 740px; | |
| } | |
| .offset8 { | |
| margin-left: 660px; | |
| } | |
| .offset7 { | |
| margin-left: 580px; | |
| } | |
| .offset6 { | |
| margin-left: 500px; | |
| } | |
| .offset5 { | |
| margin-left: 420px; | |
| } | |
| .offset4 { | |
| margin-left: 340px; | |
| } | |
| .offset3 { | |
| margin-left: 260px; | |
| } | |
| .offset2 { | |
| margin-left: 180px; | |
| } | |
| .offset1 { | |
| margin-left: 100px; | |
| } | |
| .row-fluid { | |
| width: 100%; | |
| *zoom: 1; | |
| } | |
| .row-fluid:before, | |
| .row-fluid:after { | |
| display: table; | |
| line-height: 0; | |
| content: ""; | |
| } | |
| .row-fluid:after { | |
| clear: both; | |
| } | |
| .row-fluid [class*="span"] { | |
| display: block; | |
| float: left; | |
| width: 100%; | |
| min-height: 30px; | |
| margin-left: 2.127659574468085%; | |
| *margin-left: 2.074468085106383%; | |
| -webkit-box-sizing: border-box; | |
| -moz-box-sizing: border-box; | |
| box-sizing: border-box; | |
| } | |
| .row-fluid [class*="span"]:first-child { | |
| margin-left: 0; | |
| } | |
| .row-fluid .controls-row [class*="span"] + [class*="span"] { | |
| margin-left: 2.127659574468085%; | |
| } | |
| .row-fluid .span12 { | |
| width: 100%; | |
| *width: 99.94680851063829%; | |
| } | |
| .row-fluid .span11 { | |
| width: 91.48936170212765%; | |
| *width: 91.43617021276594%; | |
| } | |
| .row-fluid .span10 { | |
| width: 82.97872340425532%; | |
| *width: 82.92553191489361%; | |
| } | |
| .row-fluid .span9 { | |
| width: 74.46808510638297%; | |
| *width: 74.41489361702126%; | |
| } | |
| .row-fluid .span8 { | |
| width: 65.95744680851064%; | |
| *width: 65.90425531914893%; | |
| } | |
| .row-fluid .span7 { | |
| width: 57.44680851063829%; | |
| *width: 57.39361702127659%; | |
| } | |
| .row-fluid .span6 { | |
| width: 48.93617021276595%; | |
| *width: 48.88297872340425%; | |
| } | |
| .row-fluid .span5 { | |
| width: 40.42553191489362%; | |
| *width: 40.37234042553192%; | |
| } | |
| .row-fluid .span4 { | |
| width: 31.914893617021278%; | |
| *width: 31.861702127659576%; | |
| } | |
| .row-fluid .span3 { | |
| width: 23.404255319148934%; | |
| *width: 23.351063829787233%; | |
| } | |
| .row-fluid .span2 { | |
| width: 14.893617021276595%; | |
| *width: 14.840425531914894%; | |
| } | |
| .row-fluid .span1 { | |
| width: 6.382978723404255%; | |
| *width: 6.329787234042553%; | |
| } | |
| .row-fluid .offset12 { | |
| margin-left: 104.25531914893617%; | |
| *margin-left: 104.14893617021275%; | |
| } | |
| .row-fluid .offset12:first-child { | |
| margin-left: 102.12765957446808%; | |
| *margin-left: 102.02127659574467%; | |
| } | |
| .row-fluid .offset11 { | |
| margin-left: 95.74468085106382%; | |
| *margin-left: 95.6382978723404%; | |
| } | |
| .row-fluid .offset11:first-child { | |
| margin-left: 93.61702127659574%; | |
| *margin-left: 93.51063829787232%; | |
| } | |
| .row-fluid .offset10 { | |
| margin-left: 87.23404255319149%; | |
| *margin-left: 87.12765957446807%; | |
| } | |
| .row-fluid .offset10:first-child { | |
| margin-left: 85.1063829787234%; | |
| *margin-left: 84.99999999999999%; | |
| } | |
| .row-fluid .offset9 { | |
| margin-left: 78.72340425531914%; | |
| *margin-left: 78.61702127659572%; | |
| } | |
| .row-fluid .offset9:first-child { | |
| margin-left: 76.59574468085106%; | |
| *margin-left: 76.48936170212764%; | |
| } | |
| .row-fluid .offset8 { | |
| margin-left: 70.2127659574468%; | |
| *margin-left: 70.10638297872339%; | |
| } | |
| .row-fluid .offset8:first-child { | |
| margin-left: 68.08510638297872%; | |
| *margin-left: 67.9787234042553%; | |
| } | |
| .row-fluid .offset7 { | |
| margin-left: 61.70212765957446%; | |
| *margin-left: 61.59574468085106%; | |
| } | |
| .row-fluid .offset7:first-child { | |
| margin-left: 59.574468085106375%; | |
| *margin-left: 59.46808510638297%; | |
| } | |
| .row-fluid .offset6 { | |
| margin-left: 53.191489361702125%; | |
| *margin-left: 53.085106382978715%; | |
| } | |
| .row-fluid .offset6:first-child { | |
| margin-left: 51.063829787234035%; | |
| *margin-left: 50.95744680851063%; | |
| } | |
| .row-fluid .offset5 { | |
| margin-left: 44.68085106382979%; | |
| *margin-left: 44.57446808510638%; | |
| } | |
| .row-fluid .offset5:first-child { | |
| margin-left: 42.5531914893617%; | |
| *margin-left: 42.4468085106383%; | |
| } | |
| .row-fluid .offset4 { | |
| margin-left: 36.170212765957444%; | |
| *margin-left: 36.06382978723405%; | |
| } | |
| .row-fluid .offset4:first-child { | |
| margin-left: 34.04255319148936%; | |
| *margin-left: 33.93617021276596%; | |
| } | |
| .row-fluid .offset3 { | |
| margin-left: 27.659574468085104%; | |
| *margin-left: 27.5531914893617%; | |
| } | |
| .row-fluid .offset3:first-child { | |
| margin-left: 25.53191489361702%; | |
| *margin-left: 25.425531914893618%; | |
| } | |
| .row-fluid .offset2 { | |
| margin-left: 19.148936170212764%; | |
| *margin-left: 19.04255319148936%; | |
| } | |
| .row-fluid .offset2:first-child { | |
| margin-left: 17.02127659574468%; | |
| *margin-left: 16.914893617021278%; | |
| } | |
| .row-fluid .offset1 { | |
| margin-left: 10.638297872340425%; | |
| *margin-left: 10.53191489361702%; | |
| } | |
| .row-fluid .offset1:first-child { | |
| margin-left: 8.51063829787234%; | |
| *margin-left: 8.404255319148938%; | |
| } | |
| [class*="span"].hide, | |
| .row-fluid [class*="span"].hide { | |
| display: none; | |
| } | |
| [class*="span"].pull-right, | |
| .row-fluid [class*="span"].pull-right { | |
| float: right; | |
| } | |
| .container { | |
| margin-right: auto; | |
| margin-left: auto; | |
| *zoom: 1; | |
| } | |
| .container:before, | |
| .container:after { | |
| display: table; | |
| line-height: 0; | |
| content: ""; | |
| } | |
| .container:after { | |
| clear: both; | |
| } | |
| .container-fluid { | |
| padding-right: 20px; | |
| padding-left: 20px; | |
| *zoom: 1; | |
| } | |
| .container-fluid:before, | |
| .container-fluid:after { | |
| display: table; | |
| line-height: 0; | |
| content: ""; | |
| } | |
| .container-fluid:after { | |
| clear: both; | |
| } | |
| p { | |
| margin: 0 0 10px; | |
| } | |
| .lead { | |
| margin-bottom: 20px; | |
| font-size: 21px; | |
| font-weight: 200; | |
| line-height: 30px; | |
| } | |
| small { | |
| font-size: 85%; | |
| } | |
| strong { | |
| font-weight: bold; | |
| } | |
| em { | |
| font-style: italic; | |
| } | |
| cite { | |
| font-style: normal; | |
| } | |
| .muted { | |
| color: #999999; | |
| } | |
| a.muted:hover { | |
| color: #808080; | |
| } | |
| .text-warning { | |
| color: #c09853; | |
| } | |
| a.text-warning:hover { | |
| color: #a47e3c; | |
| } | |
| .text-error { | |
| color: #b94a48; | |
| } | |
| a.text-error:hover { | |
| color: #953b39; | |
| } | |
| .text-info { | |
| color: #3a87ad; | |
| } | |
| a.text-info:hover { | |
| color: #2d6987; | |
| } | |
| .text-success { | |
| color: #468847; | |
| } | |
| a.text-success:hover { | |
| color: #356635; | |
| } | |
| h1, | |
| h2, | |
| h3, | |
| h4, | |
| h5, | |
| h6 { | |
| margin: 10px 0; | |
| font-family: inherit; | |
| font-weight: bold; | |
| line-height: 20px; | |
| color: inherit; | |
| text-rendering: optimizelegibility; | |
| } | |
| h1 small, | |
| h2 small, | |
| h3 small, | |
| h4 small, | |
| h5 small, | |
| h6 small { | |
| font-weight: normal; | |
| line-height: 1; | |
| color: #999999; | |
| } | |
| h1, | |
| h2, | |
| h3 { | |
| line-height: 40px; | |
| } | |
| h1 { | |
| font-size: 38.5px; | |
| } | |
| h2 { | |
| font-size: 31.5px; | |
| } | |
| h3 { | |
| font-size: 24.5px; | |
| } | |
| h4 { | |
| font-size: 17.5px; | |
| } | |
| h5 { | |
| font-size: 14px; | |
| } | |
| h6 { | |
| font-size: 11.9px; | |
| } | |
| h1 small { | |
| font-size: 24.5px; | |
| } | |
| h2 small { | |
| font-size: 17.5px; | |
| } | |
| h3 small { | |
| font-size: 14px; | |
| } | |
| h4 small { | |
| font-size: 14px; | |
| } | |
| .page-header { | |
| padding-bottom: 9px; | |
| margin: 20px 0 30px; | |
| border-bottom: 1px solid #eeeeee; | |
| } | |
| ul, | |
| ol { | |
| padding: 0; | |
| margin: 0 0 10px 25px; | |
| } | |
| ul ul, | |
| ul ol, | |
| ol ol, | |
| ol ul { | |
| margin-bottom: 0; | |
| } | |
| li { | |
| line-height: 20px; | |
| } | |
| ul.unstyled, | |
| ol.unstyled { | |
| margin-left: 0; | |
| list-style: none; | |
| } | |
| ul.inline, | |
| ol.inline { | |
| margin-left: 0; | |
| list-style: none; | |
| } | |
| ul.inline > li, | |
| ol.inline > li { | |
| display: inline-block; | |
| padding-right: 5px; | |
| padding-left: 5px; | |
| } | |
| dl { | |
| margin-bottom: 20px; | |
| } | |
| dt, | |
| dd { | |
| line-height: 20px; | |
| } | |
| dt { | |
| font-weight: bold; | |
| } | |
| dd { | |
| margin-left: 10px; | |
| } | |
| .dl-horizontal { | |
| *zoom: 1; | |
| } | |
| .dl-horizontal:before, | |
| .dl-horizontal:after { | |
| display: table; | |
| line-height: 0; | |
| content: ""; | |
| } | |
| .dl-horizontal:after { | |
| clear: both; | |
| } | |
| .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; | |
| } | |
| hr { | |
| margin: 20px 0; | |
| border: 0; | |
| border-top: 1px solid #eeeeee; | |
| border-bottom: 1px solid #ffffff; | |
| } | |
| abbr[title], | |
| abbr[data-original-title] { | |
| cursor: help; | |
| border-bottom: 1px dotted #999999; | |
| } | |
| abbr.initialism { | |
| font-size: 90%; | |
| text-transform: uppercase; | |
| } | |
| blockquote { | |
| padding: 0 0 0 15px; | |
| margin: 0 0 20px; | |
| border-left: 5px solid #eeeeee; | |
| } | |
| blockquote p { | |
| margin-bottom: 0; | |
| font-size: 16px; | |
| font-weight: 300; | |
| line-height: 25px; | |
| } | |
| blockquote small { | |
| display: block; | |
| line-height: 20px; | |
| color: #999999; | |
| } | |
| blockquote small:before { | |
| content: '\2014 \00A0'; | |
| } | |
| blockquote.pull-right { | |
| float: right; | |
| padding-right: 15px; | |
| padding-left: 0; | |
| border-right: 5px solid #eeeeee; | |
| border-left: 0; | |
| } | |
| blockquote.pull-right p, | |
| blockquote.pull-right small { | |
| text-align: right; | |
| } | |
| blockquote.pull-right small:before { | |
| content: ''; | |
| } | |
| blockquote.pull-right small:after { | |
| content: '\00A0 \2014'; | |
| } | |
| q:before, | |
| q:after, | |
| blockquote:before, | |
| blockquote:after { | |
| content: ""; | |
| } | |
| address { | |
| display: block; | |
| margin-bottom: 20px; | |
| font-style: normal; | |
| line-height: 20px; | |
| } | |
| code, | |
| pre { | |
| padding: 0 3px 2px; | |
| font-family: Monaco, Menlo, Consolas, "Courier New", monospace; | |
| font-size: 12px; | |
| color: #333333; | |
| -webkit-border-radius: 3px; | |
| -moz-border-radius: 3px; | |
| border-radius: 3px; | |
| } | |
| code { | |
| padding: 2px 4px; | |
| color: #d14; | |
| white-space: nowrap; | |
| background-color: #f7f7f9; | |
| border: 1px solid #e1e1e8; | |
| } | |
| pre { | |
| display: block; | |
| padding: 9.5px; | |
| margin: 0 0 10px; | |
| font-size: 13px; | |
| line-height: 20px; | |
| word-break: break-all; | |
| word-wrap: break-word; | |
| white-space: pre; | |
| white-space: pre-wrap; | |
| background-color: #f5f5f5; | |
| border: 1px solid #ccc; | |
| border: 1px solid rgba(0, 0, 0, 0.15); | |
| -webkit-border-radius: 4px; | |
| -moz-border-radius: 4px; | |
| border-radius: 4px; | |
| } | |
| pre.prettyprint { | |
| margin-bottom: 20px; | |
| } | |
| pre code { | |
| padding: 0; | |
| color: inherit; | |
| white-space: pre; | |
| white-space: pre-wrap; | |
| background-color: transparent; | |
| border: 0; | |
| } | |
| .pre-scrollable { | |
| max-height: 340px; | |
| overflow-y: scroll; | |
| } | |
| form { | |
| margin: 0 0 20px; | |
| } | |
| fieldset { | |
| padding: 0; | |
| margin: 0; | |
| border: 0; | |
| } | |
| legend { | |
| display: block; | |
| width: 100%; | |
| padding: 0; | |
| margin-bottom: 20px; | |
| font-size: 21px; | |
| line-height: 40px; | |
| color: #333333; | |
| border: 0; | |
| border-bottom: 1px solid #e5e5e5; | |
| } | |
| legend small { | |
| font-size: 15px; | |
| color: #999999; | |
| } | |
| label, | |
| input, | |
| button, | |
| select, | |
| textarea { | |
| font-size: 14px; | |
| font-weight: normal; | |
| line-height: 20px; | |
| } | |
| input, | |
| button, | |
| select, | |
| textarea { | |
| font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; | |
| } | |
| label { | |
| display: block; | |
| margin-bottom: 5px; | |
| } | |
| select, | |
| textarea, | |
| input[type="text"], | |
| input[type="password"], | |
| input[type="datetime"], | |
| input[type="datetime-local"], | |
| input[type="date"], | |
| input[type="month"], | |
| input[type="time"], | |
| input[type="week"], | |
| input[type="number"], | |
| input[type="email"], | |
| input[type="url"], | |
| input[type="search"], | |
| input[type="tel"], | |
| input[type="color"], | |
| .uneditable-input { | |
| display: inline-block; | |
| height: 20px; | |
| padding: 4px 6px; | |
| margin-bottom: 10px; | |
| font-size: 14px; | |
| line-height: 20px; | |
| color: #555555; | |
| vertical-align: middle; | |
| -webkit-border-radius: 4px; | |
| -moz-border-radius: 4px; | |
| border-radius: 4px; | |
| } | |
| input, | |
| textarea, | |
| .uneditable-input { | |
| width: 206px; | |
| } | |
| textarea { | |
| height: auto; | |
| } | |
| textarea, | |
| input[type="text"], | |
| input[type="password"], | |
| input[type="datetime"], | |
| input[type="datetime-local"], | |
| input[type="date"], | |
| input[type="month"], | |
| input[type="time"], | |
| input[type="week"], | |
| input[type="number"], | |
| input[type="email"], | |
| input[type="url"], | |
| input[type="search"], | |
| input[type="tel"], | |
| input[type="color"], | |
| .uneditable-input { | |
| background-color: #ffffff; | |
| border: 1px solid #cccccc; | |
| -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); | |
| -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); | |
| box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); | |
| -webkit-transition: border linear 0.2s, box-shadow linear 0.2s; | |
| -moz-transition: border linear 0.2s, box-shadow linear 0.2s; | |
| -o-transition: border linear 0.2s, box-shadow linear 0.2s; | |
| transition: border linear 0.2s, box-shadow linear 0.2s; | |
| } | |
| textarea:focus, | |
| input[type="text"]:focus, | |
| input[type="password"]:focus, | |
| input[type="datetime"]:focus, | |
| input[type="datetime-local"]:focus, | |
| input[type="date"]:focus, | |
| input[type="month"]:focus, | |
| input[type="time"]:focus, | |
| input[type="week"]:focus, | |
| input[type="number"]:focus, | |
| input[type="email"]:focus, | |
| input[type="url"]:focus, | |
| input[type="search"]:focus, | |
| input[type="tel"]:focus, | |
| input[type="color"]:focus, | |
| .uneditable-input:focus { | |
| border-color: rgba(82, 168, 236, 0.8); | |
| outline: 0; | |
| outline: thin dotted \9; | |
| /* IE6-9 */ | |
| -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); | |
| -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); | |
| box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); | |
| } | |
| input[type="radio"], | |
| input[type="checkbox"] { | |
| margin: 4px 0 0; | |
| margin-top: 1px \9; | |
| *margin-top: 0; | |
| line-height: normal; | |
| } | |
| input[type="file"], | |
| input[type="image"], | |
| input[type="submit"], | |
| input[type="reset"], | |
| input[type="button"], | |
| input[type="radio"], | |
| input[type="checkbox"] { | |
| width: auto; | |
| } | |
| select, | |
| input[type="file"] { | |
| height: 30px; | |
| /* In IE7, the height of the select element cannot be changed by height, only font-size */ | |
| *margin-top: 4px; | |
| /* For IE7, add top margin to align select with labels */ | |
| line-height: 30px; | |
| } | |
| select { | |
| width: 220px; | |
| background-color: #ffffff; | |
| border: 1px solid #cccccc; | |
| } | |
| select[multiple], | |
| select[size] { | |
| height: auto; | |
| } | |
| select:focus, | |
| input[type="file"]:focus, | |
| input[type="radio"]:focus, | |
| input[type="checkbox"]:focus { | |
| outline: thin dotted #333; | |
| outline: 5px auto -webkit-focus-ring-color; | |
| outline-offset: -2px; | |
| } | |
| .uneditable-input, | |
| .uneditable-textarea { | |
| color: #999999; | |
| cursor: not-allowed; | |
| background-color: #fcfcfc; | |
| border-color: #cccccc; | |
| -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); | |
| -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); | |
| box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); | |
| } | |
| .uneditable-input { | |
| overflow: hidden; | |
| white-space: nowrap; | |
| } | |
| .uneditable-textarea { | |
| width: auto; | |
| height: auto; | |
| } | |
| input:-moz-placeholder, | |
| textarea:-moz-placeholder { | |
| color: #999999; | |
| } | |
| input:-ms-input-placeholder, | |
| textarea:-ms-input-placeholder { | |
| color: #999999; | |
| } | |
| input::-webkit-input-placeholder, | |
| textarea::-webkit-input-placeholder { | |
| color: #999999; | |
| } | |
| .radio, | |
| .checkbox { | |
| min-height: 20px; | |
| padding-left: 20px; | |
| } | |
| .radio input[type="radio"], | |
| .checkbox input[type="checkbox"] { | |
| float: left; | |
| margin-left: -20px; | |
| } | |
| .controls > .radio:first-child, | |
| .controls > .checkbox:first-child { | |
| padding-top: 5px; | |
| } | |
| .radio.inline, | |
| .checkbox.inline { | |
| display: inline-block; | |
| padding-top: 5px; | |
| margin-bottom: 0; | |
| vertical-align: middle; | |
| } | |
| .radio.inline + .radio.inline, | |
| .checkbox.inline + .checkbox.inline { | |
| margin-left: 10px; | |
| } | |
| .input-mini { | |
| width: 60px; | |
| } | |
| .input-small { | |
| width: 90px; | |
| } | |
| .input-medium { | |
| width: 150px; | |
| } | |
| .input-large { | |
| width: 210px; | |
| } | |
| .input-xlarge { | |
| width: 270px; | |
| } | |
| .input-xxlarge { | |
| width: 530px; | |
| } | |
| input[class*="span"], | |
| select[class*="span"], | |
| textarea[class*="span"], | |
| .uneditable-input[class*="span"], | |
| .row-fluid input[class*="span"], | |
| .row-fluid select[class*="span"], | |
| .row-fluid textarea[class*="span"], | |
| .row-fluid .uneditable-input[class*="span"] { | |
| float: none; | |
| margin-left: 0; | |
| } | |
| .input-append input[class*="span"], | |
| .input-append .uneditable-input[class*="span"], | |
| .input-prepend input[class*="span"], | |
| .input-prepend .uneditable-input[class*="span"], | |
| .row-fluid input[class*="span"], | |
| .row-fluid select[class*="span"], | |
| .row-fluid textarea[class*="span"], | |
| .row-fluid .uneditable-input[class*="span"], | |
| .row-fluid .input-prepend [class*="span"], | |
| .row-fluid .input-append [class*="span"] { | |
| display: inline-block; | |
| } | |
| input, | |
| textarea, | |
| .uneditable-input { | |
| margin-left: 0; | |
| } | |
| .controls-row [class*="span"] + [class*="span"] { | |
| margin-left: 20px; | |
| } | |
| input.span12, | |
| textarea.span12, | |
| .uneditable-input.span12 { | |
| width: 926px; | |
| } | |
| input.span11, | |
| textarea.span11, | |
| .uneditable-input.span11 { | |
| width: 846px; | |
| } | |
| input.span10, | |
| textarea.span10, | |
| .uneditable-input.span10 { | |
| width: 766px; | |
| } | |
| input.span9, | |
| textarea.span9, | |
| .uneditable-input.span9 { | |
| width: 686px; | |
| } | |
| input.span8, | |
| textarea.span8, | |
| .uneditable-input.span8 { | |
| width: 606px; | |
| } | |
| input.span7, | |
| textarea.span7, | |
| .uneditable-input.span7 { | |
| width: 526px; | |
| } | |
| input.span6, | |
| textarea.span6, | |
| .uneditable-input.span6 { | |
| width: 446px; | |
| } | |
| input.span5, | |
| textarea.span5, | |
| .uneditable-input.span5 { | |
| width: 366px; | |
| } | |
| input.span4, | |
| textarea.span4, | |
| .uneditable-input.span4 { | |
| width: 286px; | |
| } | |
| input.span3, | |
| textarea.span3, | |
| .uneditable-input.span3 { | |
| width: 206px; | |
| } | |
| input.span2, | |
| textarea.span2, | |
| .uneditable-input.span2 { | |
| width: 126px; | |
| } | |
| input.span1, | |
| textarea.span1, | |
| .uneditable-input.span1 { | |
| width: 46px; | |
| } | |
| .controls-row { | |
| *zoom: 1; | |
| } | |
| .controls-row:before, | |
| .controls-row:after { | |
| display: table; | |
| line-height: 0; | |
| content: ""; | |
| } | |
| .controls-row:after { | |
| clear: both; | |
| } | |
| .controls-row [class*="span"], | |
| .row-fluid .controls-row [class*="span"] { | |
| float: left; | |
| } | |
| .controls-row .checkbox[class*="span"], | |
| .controls-row .radio[class*="span"] { | |
| padding-top: 5px; | |
| } | |
| input[disabled], | |
| select[disabled], | |
| textarea[disabled], | |
| input[readonly], | |
| select[readonly], | |
| textarea[readonly] { | |
| cursor: not-allowed; | |
| background-color: #eeeeee; | |
| } | |
| input[type="radio"][disabled], | |
| input[type="checkbox"][disabled], | |
| input[type="radio"][readonly], | |
| input[type="checkbox"][readonly] { | |
| background-color: transparent; | |
| } | |
| .control-group.warning .control-label, | |
| .control-group.warning .help-block, | |
| .control-group.warning .help-inline { | |
| color: #c09853; | |
| } | |
| .control-group.warning .checkbox, | |
| .control-group.warning .radio, | |
| .control-group.warning input, | |
| .control-group.warning select, | |
| .control-group.warning textarea { | |
| color: #c09853; | |
| } | |
| .control-group.warning input, | |
| .control-group.warning select, | |
| .control-group.warning textarea { | |
| border-color: #c09853; | |
| -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); | |
| -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); | |
| box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); | |
| } | |
| .control-group.warning input:focus, | |
| .control-group.warning select:focus, | |
| .control-group.warning textarea:focus { | |
| border-color: #a47e3c; | |
| -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; | |
| -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; | |
| box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; | |
| } | |
| .control-group.warning .input-prepend .add-on, | |
| .control-group.warning .input-append .add-on { | |
| color: #c09853; | |
| background-color: #fcf8e3; | |
| border-color: #c09853; | |
| } | |
| .control-group.error .control-label, | |
| .control-group.error .help-block, | |
| .control-group.error .help-inline { | |
| color: #b94a48; | |
| } | |
| .control-group.error .checkbox, | |
| .control-group.error .radio, | |
| .control-group.error input, | |
| .control-group.error select, | |
| .control-group.error textarea { | |
| color: #b94a48; | |
| } | |
| .control-group.error input, | |
| .control-group.error select, | |
| .control-group.error textarea { | |
| border-color: #b94a48; | |
| -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); | |
| -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); | |
| box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); | |
| } | |
| .control-group.error input:focus, | |
| .control-group.error select:focus, | |
| .control-group.error textarea:focus { | |
| border-color: #953b39; | |
| -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; | |
| -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; | |
| box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; | |
| } | |
| .control-group.error .input-prepend .add-on, | |
| .control-group.error .input-append .add-on { | |
| color: #b94a48; | |
| background-color: #f2dede; | |
| border-color: #b94a48; | |
| } | |
| .control-group.success .control-label, | |
| .control-group.success .help-block, | |
| .control-group.success .help-inline { | |
| color: #468847; | |
| } | |
| .control-group.success .checkbox, | |
| .control-group.success .radio, | |
| .control-group.success input, | |
| .control-group.success select, | |
| .control-group.success textarea { | |
| color: #468847; | |
| } | |
| .control-group.success input, | |
| .control-group.success select, | |
| .control-group.success textarea { | |
| border-color: #468847; | |
| -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); | |
| -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); | |
| box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); | |
| } | |
| .control-group.success input:focus, | |
| .control-group.success select:focus, | |
| .control-group.success textarea:focus { | |
| border-color: #356635; | |
| -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; | |
| -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; | |
| box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; | |
| } | |
| .control-group.success .input-prepend .add-on, | |
| .control-group.success .input-append .add-on { | |
| color: #468847; | |
| background-color: #dff0d8; | |
| border-color: #468847; | |
| } | |
| .control-group.info .control-label, | |
| .control-group.info .help-block, | |
| .control-group.info .help-inline { | |
| color: #3a87ad; | |
| } | |
| .control-group.info .checkbox, | |
| .control-group.info .radio, | |
| .control-group.info input, | |
| .control-group.info select, | |
| .control-group.info textarea { | |
| color: #3a87ad; | |
| } | |
| .control-group.info input, | |
| .control-group.info select, | |
| .control-group.info textarea { | |
| border-color: #3a87ad; | |
| -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); | |
| -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); | |
| box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); | |
| } | |
| .control-group.info input:focus, | |
| .control-group.info select:focus, | |
| .control-group.info textarea:focus { | |
| border-color: #2d6987; | |
| -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; | |
| -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; | |
| box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; | |
| } | |
| .control-group.info .input-prepend .add-on, | |
| .control-group.info .input-append .add-on { | |
| color: #3a87ad; | |
| background-color: #d9edf7; | |
| border-color: #3a87ad; | |
| } | |
| input:focus:invalid, | |
| textarea:focus:invalid, | |
| select:focus:invalid { | |
| color: #b94a48; | |
| border-color: #ee5f5b; | |
| } | |
| input:focus:invalid:focus, | |
| textarea:focus:invalid:focus, | |
| select:focus:invalid:focus { | |
| border-color: #e9322d; | |
| -webkit-box-shadow: 0 0 6px #f8b9b7; | |
| -moz-box-shadow: 0 0 6px #f8b9b7; | |
| box-shadow: 0 0 6px #f8b9b7; | |
| } | |
| .form-actions { | |
| padding: 19px 20px 20px; | |
| margin-top: 20px; | |
| margin-bottom: 20px; | |
| background-color: #f5f5f5; | |
| border-top: 1px solid #e5e5e5; | |
| *zoom: 1; | |
| } | |
| .form-actions:before, | |
| .form-actions:after { | |
| display: table; | |
| line-height: 0; | |
| content: ""; | |
| } | |
| .form-actions:after { | |
| clear: both; | |
| } | |
| .help-block, | |
| .help-inline { | |
| color: #595959; | |
| } | |
| .help-block { | |
| display: block; | |
| margin-bottom: 10px; | |
| } | |
| .help-inline { | |
| display: inline-block; | |
| *display: inline; | |
| padding-left: 5px; | |
| vertical-align: middle; | |
| *zoom: 1; | |
| } | |
| .input-append, | |
| .input-prepend { | |
| margin-bottom: 5px; | |
| font-size: 0; | |
| white-space: nowrap; | |
| } | |
| .input-append input, | |
| .input-prepend input, | |
| .input-append select, | |
| .input-prepend select, | |
| .input-append .uneditable-input, | |
| .input-prepend .uneditable-input, | |
| .input-append .dropdown-menu, | |
| .input-prepend .dropdown-menu { | |
| font-size: 14px; | |
| } | |
| .input-append input, | |
| .input-prepend input, | |
| .input-append select, | |
| .input-prepend select, | |
| .input-append .uneditable-input, | |
| .input-prepend .uneditable-input { | |
| position: relative; | |
| margin-bottom: 0; | |
| *margin-left: 0; | |
| vertical-align: top; | |
| -webkit-border-radius: 0 4px 4px 0; | |
| -moz-border-radius: 0 4px 4px 0; | |
| border-radius: 0 4px 4px 0; | |
| } | |
| .input-append input:focus, | |
| .input-prepend input:focus, | |
| .input-append select:focus, | |
| .input-prepend select:focus, | |
| .input-append .uneditable-input:focus, | |
| .input-prepend .uneditable-input:focus { | |
| z-index: 2; | |
| } | |
| .input-append .add-on, | |
| .input-prepend .add-on { | |
| display: inline-block; | |
| width: auto; | |
| height: 20px; | |
| min-width: 16px; | |
| padding: 4px 5px; | |
| font-size: 14px; | |
| font-weight: normal; | |
| line-height: 20px; | |
| text-align: center; | |
| text-shadow: 0 1px 0 #ffffff; | |
| background-color: #eeeeee; | |
| border: 1px solid #ccc; | |
| } | |
| .input-append .add-on, | |
| .input-prepend .add-on, | |
| .input-append .btn, | |
| .input-prepend .btn, | |
| .input-append .btn-group > .dropdown-toggle, | |
| .input-prepend .btn-group > .dropdown-toggle { | |
| vertical-align: top; | |
| -webkit-border-radius: 0; | |
| -moz-border-radius: 0; | |
| border-radius: 0; | |
| } | |
| .input-append .active, | |
| .input-prepend .active { | |
| background-color: #a9dba9; | |
| border-color: #46a546; | |
| } | |
| .input-prepend .add-on, | |
| .input-prepend .btn { | |
| margin-right: -1px; | |
| } | |
| .input-prepend .add-on:first-child, | |
| .input-prepend .btn:first-child { | |
| -webkit-border-radius: 4px 0 0 4px; | |
| -moz-border-radius: 4px 0 0 4px; | |
| border-radius: 4px 0 0 4px; | |
| } | |
| .input-append input, | |
| .input-append select, | |
| .input-append .uneditable-input { | |
| -webkit-border-radius: 4px 0 0 4px; | |
| -moz-border-radius: 4px 0 0 4px; | |
| border-radius: 4px 0 0 4px; | |
| } | |
| .input-append input + .btn-group .btn:last-child, | |
| .input-append select + .btn-group .btn:last-child, | |
| .input-append .uneditable-input + .btn-group .btn:last-child { | |
| -webkit-border-radius: 0 4px 4px 0; | |
| -moz-border-radius: 0 4px 4px 0; | |
| border-radius: 0 4px 4px 0; | |
| } | |
| .input-append .add-on, | |
| .input-append .btn, | |
| .input-append .btn-group { | |
| margin-left: -1px; | |
| } | |
| .input-append .add-on:last-child, | |
| .input-append .btn:last-child, | |
| .input-append .btn-group:last-child > .dropdown-toggle { | |
| -webkit-border-radius: 0 4px 4px 0; | |
| -moz-border-radius: 0 4px 4px 0; | |
| border-radius: 0 4px 4px 0; | |
| } | |
| .input-prepend.input-append input, | |
| .input-prepend.input-append select, | |
| .input-prepend.input-append .uneditable-input { | |
| -webkit-border-radius: 0; | |
| -moz-border-radius: 0; | |
| border-radius: 0; | |
| } | |
| .input-prepend.input-append input + .btn-group .btn, | |
| .input-prepend.input-append select + .btn-group .btn, | |
| .input-prepend.input-append .uneditable-input + .btn-group .btn { | |
| -webkit-border-radius: 0 4px 4px 0; | |
| -moz-border-radius: 0 4px 4px 0; | |
| border-radius: 0 4px 4px 0; | |
| } | |
| .input-prepend.input-append .add-on:first-child, | |
| .input-prepend.input-append .btn:first-child { | |
| margin-right: -1px; | |
| -webkit-border-radius: 4px 0 0 4px; | |
| -moz-border-radius: 4px 0 0 4px; | |
| border-radius: 4px 0 0 4px; | |
| } | |
| .input-prepend.input-append .add-on:last-child, | |
| .input-prepend.input-append .btn:last-child { | |
| margin-left: -1px; | |
| -webkit-border-radius: 0 4px 4px 0; | |
| -moz-border-radius: 0 4px 4px 0; | |
| border-radius: 0 4px 4px 0; | |
| } | |
| .input-prepend.input-append .btn-group:first-child { | |
| margin-left: 0; | |
| } | |
| input.search-query { | |
| padding-right: 14px; | |
| padding-right: 4px \9; | |
| padding-left: 14px; | |
| padding-left: 4px \9; | |
| /* IE7-8 doesn't have border-radius, so don't indent the padding */ | |
| margin-bottom: 0; | |
| -webkit-border-radius: 15px; | |
| -moz-border-radius: 15px; | |
| border-radius: 15px; | |
| } | |
| /* Allow for input prepend/append in search forms */ | |
| .form-search .input-append .search-query, | |
| .form-search .input-prepend .search-query { | |
| -webkit-border-radius: 0; | |
| -moz-border-radius: 0; | |
| border-radius: 0; | |
| } | |
| .form-search .input-append .search-query { | |
| -webkit-border-radius: 14px 0 0 14px; | |
| -moz-border-radius: 14px 0 0 14px; | |
| border-radius: 14px 0 0 14px; | |
| } | |
| .form-search .input-append .btn { | |
| -webkit-border-radius: 0 14px 14px 0; | |
| -moz-border-radius: 0 14px 14px 0; | |
| border-radius: 0 14px 14px 0; | |
| } | |
| .form-search .input-prepend .search-query { | |
| -webkit-border-radius: 0 14px 14px 0; | |
| -moz-border-radius: 0 14px 14px 0; | |
| border-radius: 0 14px 14px 0; | |
| } | |
| .form-search .input-prepend .btn { | |
| -webkit-border-radius: 14px 0 0 14px; | |
| -moz-border-radius: 14px 0 0 14px; | |
| border-radius: 14px 0 0 14px; | |
| } | |
| .form-search input, | |
| .form-inline input, | |
| .form-horizontal input, | |
| .form-search textarea, | |
| .form-inline textarea, | |
| .form-horizontal textarea, | |
| .form-search select, | |
| .form-inline select, | |
| .form-horizontal select, | |
| .form-search .help-inline, | |
| .form-inline .help-inline, | |
| .form-horizontal .help-inline, | |
| .form-search .uneditable-input, | |
| .form-inline .uneditable-input, | |
| .form-horizontal .uneditable-input, | |
| .form-search .input-prepend, | |
| .form-inline .input-prepend, | |
| .form-horizontal .input-prepend, | |
| .form-search .input-append, | |
| .form-inline .input-append, | |
| .form-horizontal .input-append { | |
| display: inline-block; | |
| *display: inline; | |
| margin-bottom: 0; | |
| vertical-align: middle; | |
| *zoom: 1; | |
| } | |
| .form-search .hide, | |
| .form-inline .hide, | |
| .form-horizontal .hide { | |
| display: none; | |
| } | |
| .form-search label, | |
| .form-inline label, | |
| .form-search .btn-group, | |
| .form-inline .btn-group { | |
| display: inline-block; | |
| } | |
| .form-search .input-append, | |
| .form-inline .input-append, | |
| .form-search .input-prepend, | |
| .form-inline .input-prepend { | |
| margin-bottom: 0; | |
| } | |
| .form-search .radio, | |
| .form-search .checkbox, | |
| .form-inline .radio, | |
| .form-inline .checkbox { | |
| padding-left: 0; | |
| margin-bottom: 0; | |
| vertical-align: middle; | |
| } | |
| .form-search .radio input[type="radio"], | |
| .form-search .checkbox input[type="checkbox"], | |
| .form-inline .radio input[type="radio"], | |
| .form-inline .checkbox input[type="checkbox"] { | |
| float: left; | |
| margin-right: 3px; | |
| margin-left: 0; | |
| } | |
| .control-group { | |
| margin-bottom: 10px; | |
| } | |
| legend + .control-group { | |
| margin-top: 20px; | |
| -webkit-margin-top-collapse: separate; | |
| } | |
| .form-horizontal .control-group { | |
| margin-bottom: 20px; | |
| *zoom: 1; | |
| } | |
| .form-horizontal .control-group:before, | |
| .form-horizontal .control-group:after { | |
| display: table; | |
| line-height: 0; | |
| content: ""; | |
| } | |
| .form-horizontal .control-group:after { | |
| clear: both; | |
| } | |
| .form-horizontal .control-label { | |
| float: left; | |
| width: 160px; | |
| padding-top: 5px; | |
| text-align: right; | |
| } | |
| .form-horizontal .controls { | |
| *display: inline-block; | |
| *padding-left: 20px; | |
| margin-left: 180px; | |
| *margin-left: 0; | |
| } | |
| .form-horizontal .controls:first-child { | |
| *padding-left: 180px; | |
| } | |
| .form-horizontal .help-block { | |
| margin-bottom: 0; | |
| } | |
| .form-horizontal input + .help-block, | |
| .form-horizontal select + .help-block, | |
| .form-horizontal textarea + .help-block, | |
| .form-horizontal .uneditable-input + .help-block, | |
| .form-horizontal .input-prepend + .help-block, | |
| .form-horizontal .input-append + .help-block { | |
| margin-top: 10px; | |
| } | |
| .form-horizontal .form-actions { | |
| padding-left: 180px; | |
| } | |
| table { | |
| max-width: 100%; | |
| background-color: transparent; | |
| border-collapse: collapse; | |
| border-spacing: 0; | |
| } | |
| .table { | |
| width: 100%; | |
| margin-bottom: 20px; | |
| } | |
| .table th, | |
| .table td { | |
| padding: 8px; | |
| line-height: 20px; | |
| text-align: left; | |
| vertical-align: top; | |
| border-top: 1px solid #dddddd; | |
| } | |
| .table th { | |
| font-weight: bold; | |
| } | |
| .table thead th { | |
| vertical-align: bottom; | |
| } | |
| .table caption + thead tr:first-child th, | |
| .table caption + thead tr:first-child td, | |
| .table colgroup + thead tr:first-child th, | |
| .table colgroup + thead tr:first-child td, | |
| .table thead:first-child tr:first-child th, | |
| .table thead:first-child tr:first-child td { | |
| border-top: 0; | |
| } | |
| .table tbody + tbody { | |
| border-top: 2px solid #dddddd; | |
| } | |
| .table .table { | |
| background-color: #ffffff; | |
| } | |
| .table-condensed th, | |
| .table-condensed td { | |
| padding: 4px 5px; | |
| } | |
| .table-bordered { | |
| border: 1px solid #dddddd; | |
| border-collapse: separate; | |
| *border-collapse: collapse; | |
| border-left: 0; | |
| -webkit-border-radius: 4px; | |
| -moz-border-radius: 4px; | |
| border-radius: 4px; | |
| } | |
| .table-bordered th, | |
| .table-bordered td { | |
| border-left: 1px solid #dddddd; | |
| } | |
| .table-bordered caption + thead tr:first-child th, | |
| .table-bordered caption + tbody tr:first-child th, | |
| .table-bordered caption + tbody tr:first-child td, | |
| .table-bordered colgroup + thead tr:first-child th, | |
| .table-bordered colgroup + tbody tr:first-child th, | |
| .table-bordered colgroup + tbody tr:first-child td, | |
| .table-bordered thead:first-child tr:first-child th, | |
| .table-bordered tbody:first-child tr:first-child th, | |
| .table-bordered tbody:first-child tr:first-child td { | |
| border-top: 0; | |
| } | |
| .table-bordered thead:first-child tr:first-child > th:first-child, | |
| .table-bordered tbody:first-child tr:first-child > td:first-child { | |
| -webkit-border-top-left-radius: 4px; | |
| border-top-left-radius: 4px; | |
| -moz-border-radius-topleft: 4px; | |
| } | |
| .table-bordered thead:first-child tr:first-child > th:last-child, | |
| .table-bordered tbody:first-child tr:first-child > td:last-child { | |
| -webkit-border-top-right-radius: 4px; | |
| border-top-right-radius: 4px; | |
| -moz-border-radius-topright: 4px; | |
| } | |
| .table-bordered thead:last-child tr:last-child > th:first-child, | |
| .table-bordered tbody:last-child tr:last-child > td:first-child, | |
| .table-bordered tfoot:last-child tr:last-child > td:first-child { | |
| -webkit-border-bottom-left-radius: 4px; | |
| border-bottom-left-radius: 4px; | |
| -moz-border-radius-bottomleft: 4px; | |
| } | |
| .table-bordered thead:last-child tr:last-child > th:last-child, | |
| .table-bordered tbody:last-child tr:last-child > td:last-child, | |
| .table-bordered tfoot:last-child tr:last-child > td:last-child { | |
| -webkit-border-bottom-right-radius: 4px; | |
| border-bottom-right-radius: 4px; | |
| -moz-border-radius-bottomright: 4px; | |
| } | |
| .table-bordered tfoot + tbody:last-child tr:last-child td:first-child { | |
| -webkit-border-bottom-left-radius: 0; | |
| border-bottom-left-radius: 0; | |
| -moz-border-radius-bottomleft: 0; | |
| } | |
| .table-bordered tfoot + tbody:last-child tr:last-child td:last-child { | |
| -webkit-border-bottom-right-radius: 0; | |
| border-bottom-right-radius: 0; | |
| -moz-border-radius-bottomright: 0; | |
| } | |
| .table-bordered caption + thead tr:first-child th:first-child, | |
| .table-bordered caption + tbody tr:first-child td:first-child, | |
| .table-bordered colgroup + thead tr:first-child th:first-child, | |
| .table-bordered colgroup + tbody tr:first-child td:first-child { | |
| -webkit-border-top-left-radius: 4px; | |
| border-top-left-radius: 4px; | |
| -moz-border-radius-topleft: 4px; | |
| } | |
| .table-bordered caption + thead tr:first-child th:last-child, | |
| .table-bordered caption + tbody tr:first-child td:last-child, | |
| .table-bordered colgroup + thead tr:first-child th:last-child, | |
| .table-bordered colgroup + tbody tr:first-child td:last-child { | |
| -webkit-border-top-right-radius: 4px; | |
| border-top-right-radius: 4px; | |
| -moz-border-radius-topright: 4px; | |
| } | |
| .table-striped tbody > tr:nth-child(odd) > td, | |
| .table-striped tbody > tr:nth-child(odd) > th { | |
| background-color: #f9f9f9; | |
| } | |
| .table-hover tbody tr:hover td, | |
| .table-hover tbody tr:hover th { | |
| background-color: #f5f5f5; | |
| } | |
| table td[class*="span"], | |
| table th[class*="span"], | |
| .row-fluid table td[class*="span"], | |
| .row-fluid table th[class*="span"] { | |
| display: table-cell; | |
| float: none; | |
| margin-left: 0; | |
| } | |
| .table td.span1, | |
| .table th.span1 { | |
| float: none; | |
| width: 44px; | |
| margin-left: 0; | |
| } | |
| .table td.span2, | |
| .table th.span2 { | |
| float: none; | |
| width: 124px; | |
| margin-left: 0; | |
| } | |
| .table td.span3, | |
| .table th.span3 { | |
| float: none; | |
| width: 204px; | |
| margin-left: 0; | |
| } | |
| .table td.span4, | |
| .table th.span4 { | |
| float: none; | |
| width: 284px; | |
| margin-left: 0; | |
| } | |
| .table td.span5, | |
| .table th.span5 { | |
| float: none; | |
| width: 364px; | |
| margin-left: 0; | |
| } | |
| .table td.span6, | |
| .table th.span6 { | |
| float: none; | |
| width: 444px; | |
| margin-left: 0; | |
| } | |
| .table td.span7, | |
| .table th.span7 { | |
| float: none; | |
| width: 524px; | |
| margin-left: 0; | |
| } | |
| .table td.span8, | |
| .table th.span8 { | |
| float: none; | |
| width: 604px; | |
| margin-left: 0; | |
| } | |
| .table td.span9, | |
| .table th.span9 { | |
| float: none; | |
| width: 684px; | |
| margin-left: 0; | |
| } | |
| .table td.span10, | |
| .table th.span10 { | |
| float: none; | |
| width: 764px; | |
| margin-left: 0; | |
| } | |
| .table td.span11, | |
| .table th.span11 { | |
| float: none; | |
| width: 844px; | |
| margin-left: 0; | |
| } | |
| .table td.span12, | |
| .table th.span12 { | |
| float: none; | |
| width: 924px; | |
| margin-left: 0; | |
| } | |
| .table tbody tr.success td { | |
| background-color: #dff0d8; | |
| } | |
| .table tbody tr.error td { | |
| background-color: #f2dede; | |
| } | |
| .table tbody tr.warning td { | |
| background-color: #fcf8e3; | |
| } | |
| .table tbody tr.info td { | |
| background-color: #d9edf7; | |
| } | |
| .table-hover tbody tr.success:hover td { | |
| background-color: #d0e9c6; | |
| } | |
| .table-hover tbody tr.error:hover td { | |
| background-color: #ebcccc; | |
| } | |
| .table-hover tbody tr.warning:hover td { | |
| background-color: #faf2cc; | |
| } | |
| .table-hover tbody tr.info:hover td { | |
| background-color: #c4e3f3; | |
| } | |
| [class^="icon-"], | |
| [class*=" icon-"] { | |
| display: inline-block; | |
| width: 14px; | |
| height: 14px; | |
| margin-top: 1px; | |
| *margin-right: .3em; | |
| line-height: 14px; | |
| vertical-align: text-top; | |
| background-image: url("../img/glyphicons-halflings.png"); | |
| background-position: 14px 14px; | |
| background-repeat: no-repeat; | |
| } | |
| /* White icons with optional class, or on hover/active states of certain elements */ | |
| .icon-white, | |
| .nav-pills > .active > a > [class^="icon-"], | |
| .nav-pills > .active > a > [class*=" icon-"], | |
| .nav-list > .active > a > [class^="icon-"], | |
| .nav-list > .active > a > [class*=" icon-"], | |
| .navbar-inverse .nav > .active > a > [class^="icon-"], | |
| .navbar-inverse .nav > .active > a > [class*=" icon-"], | |
| .dropdown-menu > li > a:hover > [class^="icon-"], | |
| .dropdown-menu > li > a:hover > [class*=" icon-"], | |
| .dropdown-menu > .active > a > [class^="icon-"], | |
| .dropdown-menu > .active > a > [class*=" icon-"], | |
| .dropdown-submenu:hover > a > [class^="icon-"], | |
| .dropdown-submenu:hover > a > [class*=" icon-"] { | |
| background-image: url("../img/glyphicons-halflings-white.png"); | |
| } | |
| .icon-glass { | |
| background-position: 0 0; | |
| } | |
| .icon-music { | |
| background-position: -24px 0; | |
| } | |
| .icon-search { | |
| background-position: -48px 0; | |
| } | |
| .icon-envelope { | |
| background-position: -72px 0; | |
| } | |
| .icon-heart { | |
| background-position: -96px 0; | |
| } | |
| .icon-star { | |
| background-position: -120px 0; | |
| } | |
| .icon-star-empty { | |
| background-position: -144px 0; | |
| } | |
| .icon-user { | |
| background-position: -168px 0; | |
| } | |
| .icon-film { | |
| background-position: -192px 0; | |
| } | |
| .icon-th-large { | |
| background-position: -216px 0; | |
| } | |
| .icon-th { | |
| background-position: -240px 0; | |
| } | |
| .icon-th-list { | |
| background-position: -264px 0; | |
| } | |
| .icon-ok { | |
| background-position: -288px 0; | |
| } | |
| .icon-remove { | |
| background-position: -312px 0; | |
| } | |
| .icon-zoom-in { | |
| background-position: -336px 0; | |
| } | |
| .icon-zoom-out { | |
| background-position: -360px 0; | |
| } | |
| .icon-off { | |
| background-position: -384px 0; | |
| } | |
| .icon-signal { | |
| background-position: -408px 0; | |
| } | |
| .icon-cog { | |
| background-position: -432px 0; | |
| } | |
| .icon-trash { | |
| background-position: -456px 0; | |
| } | |
| .icon-home { | |
| background-position: 0 -24px; | |
| } | |
| .icon-file { | |
| background-position: -24px -24px; | |
| } | |
| .icon-time { | |
| background-position: -48px -24px; | |
| } | |
| .icon-road { | |
| background-position: -72px -24px; | |
| } | |
| .icon-download-alt { | |
| background-position: -96px -24px; | |
| } | |
| .icon-download { | |
| background-position: -120px -24px; | |
| } | |
| .icon-upload { | |
| background-position: -144px -24px; | |
| } | |
| .icon-inbox { | |
| background-position: -168px -24px; | |
| } | |
| .icon-play-circle { | |
| background-position: -192px -24px; | |
| } | |
| .icon-repeat { | |
| background-position: -216px -24px; | |
| } | |
| .icon-refresh { | |
| background-position: -240px -24px; | |
| } | |
| .icon-list-alt { | |
| background-position: -264px -24px; | |
| } | |
| .icon-lock { | |
| background-position: -287px -24px; | |
| } | |
| .icon-flag { | |
| background-position: -312px -24px; | |
| } | |
| .icon-headphones { | |
| background-position: -336px -24px; | |
| } | |
| .icon-volume-off { | |
| background-position: -360px -24px; | |
| } | |
| .icon-volume-down { | |
| background-position: -384px -24px; | |
| } | |
| .icon-volume-up { | |
| background-position: -408px -24px; | |
| } | |
| .icon-qrcode { | |
| background-position: -432px -24px; | |
| } | |
| .icon-barcode { | |
| background-position: -456px -24px; | |
| } | |
| .icon-tag { | |
| background-position: 0 -48px; | |
| } | |
| .icon-tags { | |
| background-position: -25px -48px; | |
| } | |
| .icon-book { | |
| background-position: -48px -48px; | |
| } | |
| .icon-bookmark { | |
| background-position: -72px -48px; | |
| } | |
| .icon-print { | |
| background-position: -96px -48px; | |
| } | |
| .icon-camera { | |
| background-position: -120px -48px; | |
| } | |
| .icon-font { | |
| background-position: -144px -48px; | |
| } | |
| .icon-bold { | |
| background-position: -167px -48px; | |
| } | |
| .icon-italic { | |
| background-position: -192px -48px; | |
| } | |
| .icon-text-height { | |
| background-position: -216px -48px; | |
| } | |
| .icon-text-width { | |
| background-position: -240px -48px; | |
| } | |
| .icon-align-left { | |
| background-position: -264px -48px; | |
| } | |
| .icon-align-center { | |
| background-position: -288px -48px; | |
| } | |
| .icon-align-right { | |
| background-position: -312px -48px; | |
| } | |
| .icon-align-justify { | |
| background-position: -336px -48px; | |
| } | |
| .icon-list { | |
| background-position: -360px -48px; | |
| } | |
| .icon-indent-left { | |
| background-position: -384px -48px; | |
| } | |
| .icon-indent-right { | |
| background-position: -408px -48px; | |
| } | |
| .icon-facetime-video { | |
| background-position: -432px -48px; | |
| } | |
| .icon-picture { | |
| background-position: -456px -48px; | |
| } | |
| .icon-pencil { | |
| background-position: 0 -72px; | |
| } | |
| .icon-map-marker { | |
| background-position: -24px -72px; | |
| } | |
| .icon-adjust { | |
| background-position: -48px -72px; | |
| } | |
| .icon-tint { | |
| background-position: -72px -72px; | |
| } | |
| .icon-edit { | |
| background-position: -96px -72px; | |
| } | |
| .icon-share { | |
| background-position: -120px -72px; | |
| } | |
| .icon-check { | |
| background-position: -144px -72px; | |
| } | |
| .icon-move { | |
| background-position: -168px -72px; | |
| } | |
| .icon-step-backward { | |
| background-position: -192px -72px; | |
| } | |
| .icon-fast-backward { | |
| background-position: -216px -72px; | |
| } | |
| .icon-backward { | |
| background-position: -240px -72px; | |
| } | |
| .icon-play { | |
| background-position: -264px -72px; | |
| } | |
| .icon-pause { | |
| background-position: -288px -72px; | |
| } | |
| .icon-stop { | |
| background-position: -312px -72px; | |
| } | |
| .icon-forward { | |
| background-position: -336px -72px; | |
| } | |
| .icon-fast-forward { | |
| background-position: -360px -72px; | |
| } | |
| .icon-step-forward { | |
| background-position: -384px -72px; | |
| } | |
| .icon-eject { | |
| background-position: -408px -72px; | |
| } | |
| .icon-chevron-left { | |
| background-position: -432px -72px; | |
| } | |
| .icon-chevron-right { | |
| background-position: -456px -72px; | |
| } | |
| .icon-plus-sign { | |
| background-position: 0 -96px; | |
| } | |
| .icon-minus-sign { | |
| background-position: -24px -96px; | |
| } | |
| .icon-remove-sign { | |
| background-position: -48px -96px; | |
| } | |
| .icon-ok-sign { | |
| background-position: -72px -96px; | |
| } | |
| .icon-question-sign { | |
| background-position: -96px -96px; | |
| } | |
| .icon-info-sign { | |
| background-position: -120px -96px; | |
| } | |
| .icon-screenshot { | |
| background-position: -144px -96px; | |
| } | |
| .icon-remove-circle { | |
| background-position: -168px -96px; | |
| } | |
| .icon-ok-circle { | |
| background-position: -192px -96px; | |
| } | |
| .icon-ban-circle { | |
| background-position: -216px -96px; | |
| } | |
| .icon-arrow-left { | |
| background-position: -240px -96px; | |
| } | |
| .icon-arrow-right { | |
| background-position: -264px -96px; | |
| } | |
| .icon-arrow-up { | |
| background-position: -289px -96px; | |
| } | |
| .icon-arrow-down { | |
| background-position: -312px -96px; | |
| } | |
| .icon-share-alt { | |
| background-position: -336px -96px; | |
| } | |
| .icon-resize-full { | |
| background-position: -360px -96px; | |
| } | |
| .icon-resize-small { | |
| background-position: -384px -96px; | |
| } | |
| .icon-plus { | |
| background-position: -408px -96px; | |
| } | |
| .icon-minus { | |
| background-position: -433px -96px; | |
| } | |
| .icon-asterisk { | |
| background-position: -456px -96px; | |
| } | |
| .icon-exclamation-sign { | |
| background-position: 0 -120px; | |
| } | |
| .icon-gift { | |
| background-position: -24px -120px; | |
| } | |
| .icon-leaf { | |
| background-position: -48px -120px; | |
| } | |
| .icon-fire { | |
| background-position: -72px -120px; | |
| } | |
| .icon-eye-open { | |
| background-position: -96px -120px; | |
| } | |
| .icon-eye-close { | |
| background-position: -120px -120px; | |
| } | |
| .icon-warning-sign { | |
| background-position: -144px -120px; | |
| } | |
| .icon-plane { | |
| background-position: -168px -120px; | |
| } | |
| .icon-calendar { | |
| background-position: -192px -120px; | |
| } | |
| .icon-random { | |
| width: 16px; | |
| background-position: -216px -120px; | |
| } | |
| .icon-comment { | |
| background-position: -240px -120px; | |
| } | |
| .icon-magnet { | |
| background-position: -264px -120px; | |
| } | |
| .icon-chevron-up { | |
| background-position: -288px -120px; | |
| } | |
| .icon-chevron-down { | |
| background-position: -313px -119px; | |
| } | |
| .icon-retweet { | |
| background-position: -336px -120px; | |
| } | |
| .icon-shopping-cart { | |
| background-position: -360px -120px; | |
| } | |
| .icon-folder-close { | |
| background-position: -384px -120px; | |
| } | |
| .icon-folder-open { | |
| width: 16px; | |
| background-position: -408px -120px; | |
| } | |
| .icon-resize-vertical { | |
| background-position: -432px -119px; | |
| } | |
| .icon-resize-horizontal { | |
| background-position: -456px -118px; | |
| } | |
| .icon-hdd { | |
| background-position: 0 -144px; | |
| } | |
| .icon-bullhorn { | |
| background-position: -24px -144px; | |
| } | |
| .icon-bell { | |
| background-position: -48px -144px; | |
| } | |
| .icon-certificate { | |
| background-position: -72px -144px; | |
| } | |
| .icon-thumbs-up { | |
| background-position: -96px -144px; | |
| } | |
| .icon-thumbs-down { | |
| background-position: -120px -144px; | |
| } | |
| .icon-hand-right { | |
| background-position: -144px -144px; | |
| } | |
| .icon-hand-left { | |
| background-position: -168px -144px; | |
| } | |
| .icon-hand-up { | |
| background-position: -192px -144px; | |
| } | |
| .icon-hand-down { | |
| background-position: -216px -144px; | |
| } | |
| .icon-circle-arrow-right { | |
| background-position: -240px -144px; | |
| } | |
| .icon-circle-arrow-left { | |
| background-position: -264px -144px; | |
| } | |
| .icon-circle-arrow-up { | |
| background-position: -288px -144px; | |
| } | |
| .icon-circle-arrow-down { | |
| background-position: -312px -144px; | |
| } | |
| .icon-globe { | |
| background-position: -336px -144px; | |
| } | |
| .icon-wrench { | |
| background-position: -360px -144px; | |
| } | |
| .icon-tasks { | |
| background-position: -384px -144px; | |
| } | |
| .icon-filter { | |
| background-position: -408px -144px; | |
| } | |
| .icon-briefcase { | |
| background-position: -432px -144px; | |
| } | |
| .icon-fullscreen { | |
| background-position: -456px -144px; | |
| } | |
| .dropup, | |
| .dropdown { | |
| position: relative; | |
| } | |
| .dropdown-toggle { | |
| *margin-bottom: -3px; | |
| } | |
| .dropdown-toggle:active, | |
| .open .dropdown-toggle { | |
| outline: 0; | |
| } | |
| .caret { | |
| display: inline-block; | |
| width: 0; | |
| height: 0; | |
| vertical-align: top; | |
| border-top: 4px solid #000000; | |
| border-right: 4px solid transparent; | |
| border-left: 4px solid transparent; | |
| content: ""; | |
| } | |
| .dropdown .caret { | |
| margin-top: 8px; | |
| margin-left: 2px; | |
| } | |
| .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; | |
| list-style: none; | |
| background-color: #ffffff; | |
| border: 1px solid #ccc; | |
| border: 1px solid rgba(0, 0, 0, 0.2); | |
| *border-right-width: 2px; | |
| *border-bottom-width: 2px; | |
| -webkit-border-radius: 6px; | |
| -moz-border-radius: 6px; | |
| border-radius: 6px; | |
| -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); | |
| -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); | |
| box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); | |
| -webkit-background-clip: padding-box; | |
| -moz-background-clip: padding; | |
| background-clip: padding-box; | |
| } | |
| .dropdown-menu.pull-right { | |
| right: 0; | |
| left: auto; | |
| } | |
| .dropdown-menu .divider { | |
| *width: 100%; | |
| height: 1px; | |
| margin: 9px 1px; | |
| *margin: -5px 0 5px; | |
| overflow: hidden; | |
| background-color: #e5e5e5; | |
| border-bottom: 1px solid #ffffff; | |
| } | |
| .dropdown-menu li > a { | |
| display: block; | |
| padding: 3px 20px; | |
| clear: both; | |
| font-weight: normal; | |
| line-height: 20px; | |
| color: #333333; | |
| white-space: nowrap; | |
| } | |
| .dropdown-menu li > a:hover, | |
| .dropdown-menu li > a:focus, | |
| .dropdown-submenu:hover > a { | |
| color: #ffffff; | |
| text-decoration: none; | |
| background-color: #0081c2; | |
| background-image: -moz-linear-gradient(top, #0088cc, #0077b3); | |
| background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); | |
| background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); | |
| background-image: -o-linear-gradient(top, #0088cc, #0077b3); | |
| background-image: linear-gradient(to bottom, #0088cc, #0077b3); | |
| background-repeat: repeat-x; | |
| filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); | |
| } | |
| .dropdown-menu .active > a, | |
| .dropdown-menu .active > a:hover { | |
| color: #ffffff; | |
| text-decoration: none; | |
| background-color: #0081c2; | |
| background-image: -moz-linear-gradient(top, #0088cc, #0077b3); | |
| background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); | |
| background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); | |
| background-image: -o-linear-gradient(top, #0088cc, #0077b3); | |
| background-image: linear-gradient(to bottom, #0088cc, #0077b3); | |
| background-repeat: repeat-x; | |
| outline: 0; | |
| filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); | |
| } | |
| .dropdown-menu .disabled > a, | |
| .dropdown-menu .disabled > a:hover { | |
| color: #999999; | |
| } | |
| .dropdown-menu .disabled > a:hover { | |
| text-decoration: none; | |
| cursor: default; | |
| background-color: transparent; | |
| background-image: none; | |
| filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); | |
| } | |
| .open { | |
| *z-index: 1000; | |
| } | |
| .open > .dropdown-menu { | |
| display: block; | |
| } | |
| .pull-right > .dropdown-menu { | |
| right: 0; | |
| left: auto; | |
| } | |
| .dropup .caret, | |
| .navbar-fixed-bottom .dropdown .caret { | |
| border-top: 0; | |
| border-bottom: 4px solid #000000; | |
| content: ""; | |
| } | |
| .dropup .dropdown-menu, | |
| .navbar-fixed-bottom .dropdown .dropdown-menu { | |
| top: auto; | |
| bottom: 100%; | |
| margin-bottom: 1px; | |
| } | |
| .dropdown-submenu { | |
| position: relative; | |
| } | |
| .dropdown-submenu > .dropdown-menu { | |
| top: 0; | |
| left: 100%; | |
| margin-top: -6px; | |
| margin-left: -1px; | |
| -webkit-border-radius: 0 6px 6px 6px; | |
| -moz-border-radius: 0 6px 6px 6px; | |
| border-radius: 0 6px 6px 6px; | |
| } | |
| .dropdown-submenu:hover > .dropdown-menu { | |
| display: block; | |
| } | |
| .dropup .dropdown-submenu > .dropdown-menu { | |
| top: auto; | |
| bottom: 0; | |
| margin-top: 0; | |
| margin-bottom: -2px; | |
| -webkit-border-radius: 5px 5px 5px 0; | |
| -moz-border-radius: 5px 5px 5px 0; | |
| border-radius: 5px 5px 5px 0; | |
| } | |
| .dropdown-submenu > a:after { | |
| display: block; | |
| float: right; | |
| width: 0; | |
| height: 0; | |
| margin-top: 5px; | |
| margin-right: -10px; | |
| border-color: transparent; | |
| border-left-color: #cccccc; | |
| border-style: solid; | |
| border-width: 5px 0 5px 5px; | |
| content: " "; | |
| } | |
| .dropdown-submenu:hover > a:after { | |
| border-left-color: #ffffff; | |
| } | |
| .dropdown-submenu.pull-left { | |
| float: none; | |
| } | |
| .dropdown-submenu.pull-left > .dropdown-menu { | |
| left: -100%; | |
| margin-left: 10px; | |
| -webkit-border-radius: 6px 0 6px 6px; | |
| -moz-border-radius: 6px 0 6px 6px; | |
| border-radius: 6px 0 6px 6px; | |
| } | |
| .dropdown .dropdown-menu .nav-header { | |
| padding-right: 20px; | |
| padding-left: 20px; | |
| } | |
| .typeahead { | |
| z-index: 1051; | |
| margin-top: 2px; | |
| -webkit-border-radius: 4px; | |
| -moz-border-radius: 4px; | |
| border-radius: 4px; | |
| } | |
| .well { | |
| min-height: 20px; | |
| padding: 19px; | |
| margin-bottom: 20px; | |
| background-color: #f5f5f5; | |
| border: 1px solid #e3e3e3; | |
| -webkit-border-radius: 4px; | |
| -moz-border-radius: 4px; | |
| border-radius: 4px; | |
| -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); | |
| -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); | |
| box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); | |
| } | |
| .well blockquote { | |
| border-color: #ddd; | |
| border-color: rgba(0, 0, 0, 0.15); | |
| } | |
| .well-large { | |
| padding: 24px; | |
| -webkit-border-radius: 6px; | |
| -moz-border-radius: 6px; | |
| border-radius: 6px; | |
| } | |
| .well-small { | |
| padding: 9px; | |
| -webkit-border-radius: 3px; | |
| -moz-border-radius: 3px; | |
| border-radius: 3px; | |
| } | |
| .fade { | |
| opacity: 0; | |
| -webkit-transition: opacity 0.15s linear; | |
| -moz-transition: opacity 0.15s linear; | |
| -o-transition: opacity 0.15s linear; | |
| transition: opacity 0.15s linear; | |
| } | |
| .fade.in { | |
| opacity: 1; | |
| } | |
| .collapse { | |
| position: relative; | |
| height: 0; | |
| overflow: hidden; | |
| -webkit-transition: height 0.35s ease; | |
| -moz-transition: height 0.35s ease; | |
| -o-transition: height 0.35s ease; | |
| transition: height 0.35s ease; | |
| } | |
| .collapse.in { | |
| height: auto; | |
| } | |
| .close { | |
| float: right; | |
| font-size: 20px; | |
| font-weight: bold; | |
| line-height: 20px; | |
| color: #000000; | |
| text-shadow: 0 1px 0 #ffffff; | |
| opacity: 0.2; | |
| filter: alpha(opacity=20); | |
| } | |
| .close:hover { | |
| color: #000000; | |
| text-decoration: none; | |
| cursor: pointer; | |
| opacity: 0.4; | |
| filter: alpha(opacity=40); | |
| } | |
| button.close { | |
| padding: 0; | |
| cursor: pointer; | |
| background: transparent; | |
| border: 0; | |
| -webkit-appearance: none; | |
| } | |
| .btn { | |
| display: inline-block; | |
| *display: inline; | |
| padding: 4px 12px; | |
| margin-bottom: 0; | |
| *margin-left: .3em; | |
| font-size: 14px; | |
| line-height: 20px; | |
| color: #333333; | |
| text-align: center; | |
| text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); | |
| vertical-align: middle; | |
| cursor: pointer; | |
| background-color: #f5f5f5; | |
| *background-color: #e6e6e6; | |
| background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); | |
| background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); | |
| background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); | |
| background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); | |
| background-image: linear-gradient(to bottom, #ffffff, #e6e6e6); | |
| background-repeat: repeat-x; | |
| border: 1px solid #bbbbbb; | |
| *border: 0; | |
| border-color: #e6e6e6 #e6e6e6 #bfbfbf; | |
| border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); | |
| border-bottom-color: #a2a2a2; | |
| -webkit-border-radius: 4px; | |
| -moz-border-radius: 4px; | |
| border-radius: 4px; | |
| filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); | |
| filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); | |
| *zoom: 1; | |
| -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); | |
| -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); | |
| box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); | |
| } | |
| .btn:hover, | |
| .btn:active, | |
| .btn.active, | |
| .btn.disabled, | |
| .btn[disabled] { | |
| color: #333333; | |
| background-color: #e6e6e6; | |
| *background-color: #d9d9d9; | |
| } | |
| .btn:active, | |
| .btn.active { | |
| background-color: #cccccc \9; | |
| } | |
| .btn:first-child { | |
| *margin-left: 0; | |
| } | |
| .btn:hover { | |
| color: #333333; | |
| text-decoration: none; | |
| background-position: 0 -15px; | |
| -webkit-transition: background-position 0.1s linear; | |
| -moz-transition: background-position 0.1s linear; | |
| -o-transition: background-position 0.1s linear; | |
| transition: background-position 0.1s linear; | |
| } | |
| .btn:focus { | |
| outline: thin dotted #333; | |
| outline: 5px auto -webkit-focus-ring-color; | |
| outline-offset: -2px; | |
| } | |
| .btn.active, | |
| .btn:active { | |
| background-image: none; | |
| outline: 0; | |
| -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); | |
| -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); | |
| box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); | |
| } | |
| .btn.disabled, | |
| .btn[disabled] { | |
| cursor: default; | |
| background-image: none; | |
| opacity: 0.65; | |
| filter: alpha(opacity=65); | |
| -webkit-box-shadow: none; | |
| -moz-box-shadow: none; | |
| box-shadow: none; | |
| } | |
| .btn-large { | |
| padding: 11px 19px; | |
| font-size: 17.5px; | |
| -webkit-border-radius: 6px; | |
| -moz-border-radius: 6px; | |
| border-radius: 6px; | |
| } | |
| .btn-large [class^="icon-"], | |
| .btn-large [class*=" icon-"] { | |
| margin-top: 4px; | |
| } | |
| .btn-small { | |
| padding: 2px 10px; | |
| font-size: 11.9px; | |
| -webkit-border-radius: 3px; | |
| -moz-border-radius: 3px; | |
| border-radius: 3px; | |
| } | |
| .btn-small [class^="icon-"], | |
| .btn-small [class*=" icon-"] { | |
| margin-top: 0; | |
| } | |
| .btn-mini [class^="icon-"], | |
| .btn-mini [class*=" icon-"] { | |
| margin-top: -1px; | |
| } | |
| .btn-mini { | |
| padding: 0 6px; | |
| font-size: 10.5px; | |
| -webkit-border-radius: 3px; | |
| -moz-border-radius: 3px; | |
| border-radius: 3px; | |
| } | |
| .btn-block { | |
| display: block; | |
| width: 100%; | |
| padding-right: 0; | |
| padding-left: 0; | |
| -webkit-box-sizing: border-box; | |
| -moz-box-sizing: border-box; | |
| box-sizing: border-box; | |
| } | |
| .btn-block + .btn-block { | |
| margin-top: 5px; | |
| } | |
| input[type="submit"].btn-block, | |
| input[type="reset"].btn-block, | |
| input[type="button"].btn-block { | |
| width: 100%; | |
| } | |
| .btn-primary.active, | |
| .btn-warning.active, | |
| .btn-danger.active, | |
| .btn-success.active, | |
| .btn-info.active, | |
| .btn-inverse.active { | |
| color: rgba(255, 255, 255, 0.75); | |
| } | |
| .btn { | |
| border-color: #c5c5c5; | |
| border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25); | |
| } | |
| .btn-primary { | |
| color: #ffffff; | |
| text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); | |
| background-color: #006dcc; | |
| *background-color: #0044cc; | |
| background-image: -moz-linear-gradient(top, #0088cc, #0044cc); | |
| background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); | |
| background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); | |
| background-image: -o-linear-gradient(top, #0088cc, #0044cc); | |
| background-image: linear-gradient(to bottom, #0088cc, #0044cc); | |
| background-repeat: repeat-x; | |
| border-color: #0044cc #0044cc #002a80; | |
| border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); | |
| filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0); | |
| filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); | |
| } | |
| .btn-primary:hover, | |
| .btn-primary:active, | |
| .btn-primary.active, | |
| .btn-primary.disabled, | |
| .btn-primary[disabled] { | |
| color: #ffffff; | |
| background-color: #0044cc; | |
| *background-color: #003bb3; | |
| } | |
| .btn-primary:active, | |
| .btn-primary.active { | |
| background-color: #003399 \9; | |
| } | |
| .btn-warning { | |
| color: #ffffff; | |
| text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); | |
| background-color: #faa732; | |
| *background-color: #f89406; | |
| background-image: -moz-linear-gradient(top, #fbb450, #f89406); | |
| background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); | |
| background-image: -webkit-linear-gradient(top, #fbb450, #f89406); | |
| background-image: -o-linear-gradient(top, #fbb450, #f89406); | |
| background-image: linear-gradient(to bottom, #fbb450, #f89406); | |
| background-repeat: repeat-x; | |
| border-color: #f89406 #f89406 #ad6704; | |
| border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); | |
| filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); | |
| filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); | |
| } | |
| .btn-warning:hover, | |
| .btn-warning:active, | |
| .btn-warning.active, | |
| .btn-warning.disabled, | |
| .btn-warning[disabled] { | |
| color: #ffffff; | |
| background-color: #f89406; | |
| *background-color: #df8505; | |
| } | |
| .btn-warning:active, | |
| .btn-warning.active { | |
| background-color: #c67605 \9; | |
| } | |
| .btn-danger { | |
| color: #ffffff; | |
| text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); | |
| background-color: #da4f49; | |
| *background-color: #bd362f; | |
| background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f); | |
| background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f)); | |
| background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f); | |
| background-image: -o-linear-gradient(top, #ee5f5b, #bd362f); | |
| background-image: linear-gradient(to bottom, #ee5f5b, #bd362f); | |
| background-repeat: repeat-x; | |
| border-color: #bd362f #bd362f #802420; | |
| border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); | |
| filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0); | |
| filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); | |
| } | |
| .btn-danger:hover, | |
| .btn-danger:active, | |
| .btn-danger.active, | |
| .btn-danger.disabled, | |
| .btn-danger[disabled] { | |
| color: #ffffff; | |
| background-color: #bd362f; | |
| *background-color: #a9302a; | |
| } | |
| .btn-danger:active, | |
| .btn-danger.active { | |
| background-color: #942a25 \9; | |
| } | |
| .btn-success { | |
| color: #ffffff; | |
| text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); | |
| background-color: #5bb75b; | |
| *background-color: #51a351; | |
| background-image: -moz-linear-gradient(top, #62c462, #51a351); | |
| background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351)); | |
| background-image: -webkit-linear-gradient(top, #62c462, #51a351); | |
| background-image: -o-linear-gradient(top, #62c462, #51a351); | |
| background-image: linear-gradient(to bottom, #62c462, #51a351); | |
| background-repeat: repeat-x; | |
| border-color: #51a351 #51a351 #387038; | |
| border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); | |
| filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0); | |
| filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); | |
| } | |
| .btn-success:hover, | |
| .btn-success:active, | |
| .btn-success.active, | |
| .btn-success.disabled, | |
| .btn-success[disabled] { | |
| color: #ffffff; | |
| background-color: #51a351; | |
| *background-color: #499249; | |
| } | |
| .btn-success:active, | |
| .btn-success.active { | |
| background-color: #408140 \9; | |
| } | |
| .btn-info { | |
| color: #ffffff; | |
| text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); | |
| background-color: #49afcd; | |
| *background-color: #2f96b4; | |
| background-image: -moz-linear-gradient(top, #5bc0de, #2f96b4); | |
| background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4)); | |
| background-image: -webkit-linear-gradient(top, #5bc0de, #2f96b4); | |
| background-image: -o-linear-gradient(top, #5bc0de, #2f96b4); | |
| background-image: linear-gradient(to bottom, #5bc0de, #2f96b4); | |
| background-repeat: repeat-x; | |
| border-color: #2f96b4 #2f96b4 #1f6377; | |
| border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); | |
| filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0); | |
| filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); | |
| } | |
| .btn-info:hover, | |
| .btn-info:active, | |
| .btn-info.active, | |
| .btn-info.disabled, | |
| .btn-info[disabled] { | |
| color: #ffffff; | |
| background-color: #2f96b4; | |
| *background-color: #2a85a0; | |
| } | |
| .btn-info:active, | |
| .btn-info.active { | |
| background-color: #24748c \9; | |
| } | |
| .btn-inverse { | |
| color: #ffffff; | |
| text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); | |
| background-color: #363636; | |
| *background-color: #222222; | |
| background-image: -moz-linear-gradient(top, #444444, #222222); | |
| background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222)); | |
| background-image: -webkit-linear-gradient(top, #444444, #222222); | |
| background-image: -o-linear-gradient(top, #444444, #222222); | |
| background-image: linear-gradient(to bottom, #444444, #222222); | |
| background-repeat: repeat-x; | |
| border-color: #222222 #222222 #000000; | |
| border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); | |
| filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0); | |
| filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); | |
| } | |
| .btn-inverse:hover, | |
| .btn-inverse:active, | |
| .btn-inverse.active, | |
| .btn-inverse.disabled, | |
| .btn-inverse[disabled] { | |
| color: #ffffff; | |
| background-color: #222222; | |
| *background-color: #151515; | |
| } | |
| .btn-inverse:active, | |
| .btn-inverse.active { | |
| background-color: #080808 \9; | |
| } | |
| button.btn, | |
| input[type="submit"].btn { | |
| *padding-top: 3px; | |
| *padding-bottom: 3px; | |
| } | |
| button.btn::-moz-focus-inner, | |
| input[type="submit"].btn::-moz-focus-inner { | |
| padding: 0; | |
| border: 0; | |
| } | |
| button.btn.btn-large, | |
| input[type="submit"].btn.btn-large { | |
| *padding-top: 7px; | |
| *padding-bottom: 7px; | |
| } | |
| button.btn.btn-small, | |
| input[type="submit"].btn.btn-small { | |
| *padding-top: 3px; | |
| *padding-bottom: 3px; | |
| } | |
| button.btn.btn-mini, | |
| input[type="submit"].btn.btn-mini { | |
| *padding-top: 1px; | |
| *padding-bottom: 1px; | |
| } | |
| .btn-link, | |
| .btn-link:active, | |
| .btn-link[disabled] { | |
| background-color: transparent; | |
| background-image: none; | |
| -webkit-box-shadow: none; | |
| -moz-box-shadow: none; | |
| box-shadow: none; | |
| } | |
| .btn-link { | |
| color: #0088cc; | |
| cursor: pointer; | |
| border-color: transparent; | |
| -webkit-border-radius: 0; | |
| -moz-border-radius: 0; | |
| border-radius: 0; | |
| } | |
| .btn-link:hover { | |
| color: #005580; | |
| text-decoration: underline; | |
| background-color: transparent; | |
| } | |
| .btn-link[disabled]:hover { | |
| color: #333333; | |
| text-decoration: none; | |
| } | |
| .btn-group { | |
| position: relative; | |
| display: inline-block; | |
| *display: inline; | |
| *margin-left: .3em; | |
| font-size: 0; | |
| white-space: nowrap; | |
| vertical-align: middle; | |
| *zoom: 1; | |
| } | |
| .btn-group:first-child { | |
| *margin-left: 0; | |
| } | |
| .btn-group + .btn-group { | |
| margin-left: 5px; | |
| } | |
| .btn-toolbar { | |
| margin-top: 10px; | |
| margin-bottom: 10px; | |
| font-size: 0; | |
| } | |
| .btn-toolbar > .btn + .btn, | |
| .btn-toolbar > .btn-group + .btn, | |
| .btn-toolbar > .btn + .btn-group { | |
| margin-left: 5px; | |
| } | |
| .btn-group > .btn { | |
| position: relative; | |
| -webkit-border-radius: 0; | |
| -moz-border-radius: 0; | |
| border-radius: 0; | |
| } | |
| .btn-group > .btn + .btn { | |
| margin-left: -1px; | |
| } | |
| .btn-group > .btn, | |
| .btn-group > .dropdown-menu, | |
| .btn-group > .popover { | |
| font-size: 14px; | |
| } | |
| .btn-group > .btn-mini { | |
| font-size: 10.5px; | |
| } | |
| .btn-group > .btn-small { | |
| font-size: 11.9px; | |
| } | |
| .btn-group > .btn-large { | |
| font-size: 17.5px; | |
| } | |
| .btn-group > .btn:first-child { | |
| margin-left: 0; | |
| -webkit-border-bottom-left-radius: 4px; | |
| border-bottom-left-radius: 4px; | |
| -webkit-border-top-left-radius: 4px; | |
| border-top-left-radius: 4px; | |
| -moz-border-radius-bottomleft: 4px; | |
| -moz-border-radius-topleft: 4px; | |
| } | |
| .btn-group > .btn:last-child, | |
| .btn-group > .dropdown-toggle { | |
| -webkit-border-top-right-radius: 4px; | |
| border-top-right-radius: 4px; | |
| -webkit-border-bottom-right-radius: 4px; | |
| border-bottom-right-radius: 4px; | |
| -moz-border-radius-topright: 4px; | |
| -moz-border-radius-bottomright: 4px; | |
| } | |
| .btn-group > .btn.large:first-child { | |
| margin-left: 0; | |
| -webkit-border-bottom-left-radius: 6px; | |
| border-bottom-left-radius: 6px; | |
| -webkit-border-top-left-radius: 6px; | |
| border-top-left-radius: 6px; | |
| -moz-border-radius-bottomleft: 6px; | |
| -moz-border-radius-topleft: 6px; | |
| } | |
| .btn-group > .btn.large:last-child, | |
| .btn-group > .large.dropdown-toggle { | |
| -webkit-border-top-right-radius: 6px; | |
| border-top-right-radius: 6px; | |
| -webkit-border-bottom-right-radius: 6px; | |
| border-bottom-right-radius: 6px; | |
| -moz-border-radius-topright: 6px; | |
| -moz-border-radius-bottomright: 6px; | |
| } | |
| .btn-group > .btn:hover, | |
| .btn-group > .btn:focus, | |
| .btn-group > .btn:active, | |
| .btn-group > .btn.active { | |
| z-index: 2; | |
| } | |
| .btn-group .dropdown-toggle:active, | |
| .btn-group.open .dropdown-toggle { | |
| outline: 0; | |
| } | |
| .btn-group > .btn + .dropdown-toggle { | |
| *padding-top: 5px; | |
| padding-right: 8px; | |
| *padding-bottom: 5px; | |
| padding-left: 8px; | |
| -webkit-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); | |
| -moz-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); | |
| box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); | |
| } | |
| .btn-group > .btn-mini + .dropdown-toggle { | |
| *padding-top: 2px; | |
| padding-right: 5px; | |
| *padding-bottom: 2px; | |
| padding-left: 5px; | |
| } | |
| .btn-group > .btn-small + .dropdown-toggle { | |
| *padding-top: 5px; | |
| *padding-bottom: 4px; | |
| } | |
| .btn-group > .btn-large + .dropdown-toggle { | |
| *padding-top: 7px; | |
| padding-right: 12px; | |
| *padding-bottom: 7px; | |
| padding-left: 12px; | |
| } | |
| .btn-group.open .dropdown-toggle { | |
| background-image: none; | |
| -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); | |
| -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); | |
| box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); | |
| } | |
| .btn-group.open .btn.dropdown-toggle { | |
| background-color: #e6e6e6; | |
| } | |
| .btn-group.open .btn-primary.dropdown-toggle { | |
| background-color: #0044cc; | |
| } | |
| .btn-group.open .btn-warning.dropdown-toggle { | |
| background-color: #f89406; | |
| } | |
| .btn-group.open .btn-danger.dropdown-toggle { | |
| background-color: #bd362f; | |
| } | |
| .btn-group.open .btn-success.dropdown-toggle { | |
| background-color: #51a351; | |
| } | |
| .btn-group.open .btn-info.dropdown-toggle { | |
| background-color: #2f96b4; | |
| } | |
| .btn-group.open .btn-inverse.dropdown-toggle { | |
| background-color: #222222; | |
| } | |
| .btn .caret { | |
| margin-top: 8px; | |
| margin-left: 0; | |
| } | |
| .btn-mini .caret, | |
| .btn-small .caret, | |
| .btn-large .caret { | |
| margin-top: 6px; | |
| } | |
| .btn-large .caret { | |
| border-top-width: 5px; | |
| border-right-width: 5px; | |
| border-left-width: 5px; | |
| } | |
| .dropup .btn-large .caret { | |
| border-bottom-width: 5px; | |
| } | |
| .btn-primary .caret, | |
| .btn-warning .caret, | |
| .btn-danger .caret, | |
| .btn-info .caret, | |
| .btn-success .caret, | |
| .btn-inverse .caret { | |
| border-top-color: #ffffff; | |
| border-bottom-color: #ffffff; | |
| } | |
| .btn-group-vertical { | |
| display: inline-block; | |
| *display: inline; | |
| /* IE7 inline-block hack */ | |
| *zoom: 1; | |
| } | |
| .btn-group-vertical > .btn { | |
| display: block; | |
| float: none; | |
| max-width: 100%; | |
| -webkit-border-radius: 0; | |
| -moz-border-radius: 0; | |
| border-radius: 0; | |
| } | |
| .btn-group-vertical > .btn + .btn { | |
| margin-top: -1px; | |
| margin-left: 0; | |
| } | |
| .btn-group-vertical > .btn:first-child { | |
| -webkit-border-radius: 4px 4px 0 0; | |
| -moz-border-radius: 4px 4px 0 0; | |
| border-radius: 4px 4px 0 0; | |
| } | |
| .btn-group-vertical > .btn:last-child { | |
| -webkit-border-radius: 0 0 4px 4px; | |
| -moz-border-radius: 0 0 4px 4px; | |
| border-radius: 0 0 4px 4px; | |
| } | |
| .btn-group-vertical > .btn-large:first-child { | |
| -webkit-border-radius: 6px 6px 0 0; | |
| -moz-border-radius: 6px 6px 0 0; | |
| border-radius: 6px 6px 0 0; | |
| } | |
| .btn-group-vertical > .btn-large:last-child { | |
| -webkit-border-radius: 0 0 6px 6px; | |
| -moz-border-radius: 0 0 6px 6px; | |
| border-radius: 0 0 6px 6px; | |
| } | |
| .alert { | |
| padding: 8px 35px 8px 14px; | |
| margin-bottom: 20px; | |
| text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); | |
| background-color: #fcf8e3; | |
| border: 1px solid #fbeed5; | |
| -webkit-border-radius: 4px; | |
| -moz-border-radius: 4px; | |
| border-radius: 4px; | |
| } | |
| .alert, | |
| .alert h4 { | |
| color: #c09853; | |
| } | |
| .alert h4 { | |
| margin: 0; | |
| } | |
| .alert .close { | |
| position: relative; | |
| top: -2px; | |
| right: -21px; | |
| line-height: 20px; | |
| } | |
| .alert-success { | |
| color: #468847; | |
| background-color: #dff0d8; | |
| border-color: #d6e9c6; | |
| } | |
| .alert-success h4 { | |
| color: #468847; | |
| } | |
| .alert-danger, | |
| .alert-error { | |
| color: #b94a48; | |
| background-color: #f2dede; | |
| border-color: #eed3d7; | |
| } | |
| .alert-danger h4, | |
| .alert-error h4 { | |
| color: #b94a48; | |
| } | |
| .alert-info { | |
| color: #3a87ad; | |
| background-color: #d9edf7; | |
| border-color: #bce8f1; | |
| } | |
| .alert-info h4 { | |
| color: #3a87ad; | |
| } | |
| .alert-block { | |
| padding-top: 14px; | |
| padding-bottom: 14px; | |
| } | |
| .alert-block > p, | |
| .alert-block > ul { | |
| margin-bottom: 0; | |
| } | |
| .alert-block p + p { | |
| margin-top: 5px; | |
| } | |
| .nav { | |
| margin-bottom: 20px; | |
| margin-left: 0; | |
| list-style: none; | |
| } | |
| .nav > li > a { | |
| display: block; | |
| } | |
| .nav > li > a:hover { | |
| text-decoration: none; | |
| background-color: #eeeeee; | |
| } | |
| .nav > li > a > img { | |
| max-width: none; | |
| } | |
| .nav > .pull-right { | |
| float: right; | |
| } | |
| .nav-header { | |
| display: block; | |
| padding: 3px 15px; | |
| font-size: 11px; | |
| font-weight: bold; | |
| line-height: 20px; | |
| color: #999999; | |
| text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); | |
| text-transform: uppercase; | |
| } | |
| .nav li + .nav-header { | |
| margin-top: 9px; | |
| } | |
| .nav-list { | |
| padding-right: 15px; | |
| padding-left: 15px; | |
| margin-bottom: 0; | |
| } | |
| .nav-list > li > a, | |
| .nav-list .nav-header { | |
| margin-right: -15px; | |
| margin-left: -15px; | |
| text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); | |
| } | |
| .nav-list > li > a { | |
| padding: 3px 15px; | |
| } | |
| .nav-list > .active > a, | |
| .nav-list > .active > a:hover { | |
| color: #ffffff; | |
| text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2); | |
| background-color: #0088cc; | |
| } | |
| .nav-list [class^="icon-"], | |
| .nav-list [class*=" icon-"] { | |
| margin-right: 2px; | |
| } | |
| .nav-list .divider { | |
| *width: 100%; | |
| height: 1px; | |
| margin: 9px 1px; | |
| *margin: -5px 0 5px; | |
| overflow: hidden; | |
| background-color: #e5e5e5; | |
| border-bottom: 1px solid #ffffff; | |
| } | |
| .nav-tabs, | |
| .nav-pills { | |
| *zoom: 1; | |
| } | |
| .nav-tabs:before, | |
| .nav-pills:before, | |
| .nav-tabs:after, | |
| .nav-pills:after { | |
| display: table; | |
| line-height: 0; | |
| content: ""; | |
| } | |
| .nav-tabs:after, | |
| .nav-pills:after { | |
| clear: both; | |
| } | |
| .nav-tabs > li, | |
| .nav-pills > li { | |
| float: left; | |
| } | |
| .nav-tabs > li > a, | |
| .nav-pills > li > a { | |
| padding-right: 12px; | |
| padding-left: 12px; | |
| margin-right: 2px; | |
| line-height: 14px; | |
| } | |
| .nav-tabs { | |
| border-bottom: 1px solid #ddd; | |
| } | |
| .nav-tabs > li { | |
| margin-bottom: -1px; | |
| } | |
| .nav-tabs > li > a { | |
| padding-top: 8px; | |
| padding-bottom: 8px; | |
| line-height: 20px; | |
| border: 1px solid transparent; | |
| -webkit-border-radius: 4px 4px 0 0; | |
| -moz-border-radius: 4px 4px 0 0; | |
| border-radius: 4px 4px 0 0; | |
| } | |
| .nav-tabs > li > a:hover { | |
| border-color: #eeeeee #eeeeee #dddddd; | |
| } | |
| .nav-tabs > .active > a, | |
| .nav-tabs > .active > a:hover { | |
| color: #555555; | |
| cursor: default; | |
| background-color: #ffffff; | |
| border: 1px solid #ddd; | |
| border-bottom-color: transparent; | |
| } | |
| .nav-pills > li > a { | |
| padding-top: 8px; | |
| padding-bottom: 8px; | |
| margin-top: 2px; | |
| margin-bottom: 2px; | |
| -webkit-border-radius: 5px; | |
| -moz-border-radius: 5px; | |
| border-radius: 5px; | |
| } | |
| .nav-pills > .active > a, | |
| .nav-pills > .active > a:hover { | |
| color: #ffffff; | |
| background-color: #0088cc; | |
| } | |
| .nav-stacked > li { | |
| float: none; | |
| } | |
| .nav-stacked > li > a { | |
| margin-right: 0; | |
| } | |
| .nav-tabs.nav-stacked { | |
| border-bottom: 0; | |
| } | |
| .nav-tabs.nav-stacked > li > a { | |
| border: 1px solid #ddd; | |
| -webkit-border-radius: 0; | |
| -moz-border-radius: 0; | |
| border-radius: 0; | |
| } | |
| .nav-tabs.nav-stacked > li:first-child > a { | |
| -webkit-border-top-right-radius: 4px; | |
| border-top-right-radius: 4px; | |
| -webkit-border-top-left-radius: 4px; | |
| border-top-left-radius: 4px; | |
| -moz-border-radius-topright: 4px; | |
| -moz-border-radius-topleft: 4px; | |
| } | |
| .nav-tabs.nav-stacked > li:last-child > a { | |
| -webkit-border-bottom-right-radius: 4px; | |
| border-bottom-right-radius: 4px; | |
| -webkit-border-bottom-left-radius: 4px; | |
| border-bottom-left-radius: 4px; | |
| -moz-border-radius-bottomright: 4px; | |
| -moz-border-radius-bottomleft: 4px; | |
| } | |
| .nav-tabs.nav-stacked > li > a:hover { | |
| z-index: 2; | |
| border-color: #ddd; | |
| } | |
| .nav-pills.nav-stacked > li > a { | |
| margin-bottom: 3px; | |
| } | |
| .nav-pills.nav-stacked > li:last-child > a { | |
| margin-bottom: 1px; | |
| } | |
| .nav-tabs .dropdown-menu { | |
| -webkit-border-radius: 0 0 6px 6px; | |
| -moz-border-radius: 0 0 6px 6px; | |
| border-radius: 0 0 6px 6px; | |
| } | |
| .nav-pills .dropdown-menu { | |
| -webkit-border-radius: 6px; | |
| -moz-border-radius: 6px; | |
| border-radius: 6px; | |
| } | |
| .nav .dropdown-toggle .caret { | |
| margin-top: 6px; | |
| border-top-color: #0088cc; | |
| border-bottom-color: #0088cc; | |
| } | |
| .nav .dropdown-toggle:hover .caret { | |
| border-top-color: #005580; | |
| border-bottom-color: #005580; | |
| } | |
| /* move down carets for tabs */ | |
| .nav-tabs .dropdown-toggle .caret { | |
| margin-top: 8px; | |
| } | |
| .nav .active .dropdown-toggle .caret { | |
| border-top-color: #fff; | |
| border-bottom-color: #fff; | |
| } | |
| .nav-tabs .active .dropdown-toggle .caret { | |
| border-top-color: #555555; | |
| border-bottom-color: #555555; | |
| } | |
| .nav > .dropdown.active > a:hover { | |
| cursor: pointer; | |
| } | |
| .nav-tabs .open .dropdown-toggle, | |
| .nav-pills .open .dropdown-toggle, | |
| .nav > li.dropdown.open.active > a:hover { | |
| color: #ffffff; | |
| background-color: #999999; | |
| border-color: #999999; | |
| } | |
| .nav li.dropdown.open .caret, | |
| .nav li.dropdown.open.active .caret, | |
| .nav li.dropdown.open a:hover .caret { | |
| border-top-color: #ffffff; | |
| border-bottom-color: #ffffff; | |
| opacity: 1; | |
| filter: alpha(opacity=100); | |
| } | |
| .tabs-stacked .open > a:hover { | |
| border-color: #999999; | |
| } | |
| .tabbable { | |
| *zoom: 1; | |
| } | |
| .tabbable:before, | |
| .tabbable:after { | |
| display: table; | |
| line-height: 0; | |
| content: ""; | |
| } | |
| .tabbable:after { | |
| clear: both; | |
| } | |
| .tab-content { | |
| overflow: auto; | |
| } | |
| .tabs-below > .nav-tabs, | |
| .tabs-right > .nav-tabs, | |
| .tabs-left > .nav-tabs { | |
| border-bottom: 0; | |
| } | |
| .tab-content > .tab-pane, | |
| .pill-content > .pill-pane { | |
| display: none; | |
| } | |
| .tab-content > .active, | |
| .pill-content > .active { | |
| display: block; | |
| } | |
| .tabs-below > .nav-tabs { | |
| border-top: 1px solid #ddd; | |
| } | |
| .tabs-below > .nav-tabs > li { | |
| margin-top: -1px; | |
| margin-bottom: 0; | |
| } | |
| .tabs-below > .nav-tabs > li > a { | |
| -webkit-border-radius: 0 0 4px 4px; | |
| -moz-border-radius: 0 0 4px 4px; | |
| border-radius: 0 0 4px 4px; | |
| } | |
| .tabs-below > .nav-tabs > li > a:hover { | |
| border-top-color: #ddd; | |
| border-bottom-color: transparent; | |
| } | |
| .tabs-below > .nav-tabs > .active > a, | |
| .tabs-below > .nav-tabs > .active > a:hover { | |
| border-color: transparent #ddd #ddd #ddd; | |
| } | |
| .tabs-left > .nav-tabs > li, | |
| .tabs-right > .nav-tabs > li { | |
| float: none; | |
| } | |
| .tabs-left > .nav-tabs > li > a, | |
| .tabs-right > .nav-tabs > li > a { | |
| min-width: 74px; | |
| margin-right: 0; | |
| margin-bottom: 3px; | |
| } | |
| .tabs-left > .nav-tabs { | |
| float: left; | |
| margin-right: 19px; | |
| border-right: 1px solid #ddd; | |
| } | |
| .tabs-left > .nav-tabs > li > a { | |
| margin-right: -1px; | |
| -webkit-border-radius: 4px 0 0 4px; | |
| -moz-border-radius: 4px 0 0 4px; | |
| border-radius: 4px 0 0 4px; | |
| } | |
| .tabs-left > .nav-tabs > li > a:hover { | |
| border-color: #eeeeee #dddddd #eeeeee #eeeeee; | |
| } | |
| .tabs-left > .nav-tabs .active > a, | |
| .tabs-left > .nav-tabs .active > a:hover { | |
| border-color: #ddd transparent #ddd #ddd; | |
| *border-right-color: #ffffff; | |
| } | |
| .tabs-right > .nav-tabs { | |
| float: right; | |
| margin-left: 19px; | |
| border-left: 1px solid #ddd; | |
| } | |
| .tabs-right > .nav-tabs > li > a { | |
| margin-left: -1px; | |
| -webkit-border-radius: 0 4px 4px 0; | |
| -moz-border-radius: 0 4px 4px 0; | |
| border-radius: 0 4px 4px 0; | |
| } | |
| .tabs-right > .nav-tabs > li > a:hover { | |
| border-color: #eeeeee #eeeeee #eeeeee #dddddd; | |
| } | |
| .tabs-right > .nav-tabs .active > a, | |
| .tabs-right > .nav-tabs .active > a:hover { | |
| border-color: #ddd #ddd #ddd transparent; | |
| *border-left-color: #ffffff; | |
| } | |
| .nav > .disabled > a { | |
| color: #999999; | |
| } | |
| .nav > .disabled > a:hover { | |
| text-decoration: none; | |
| cursor: default; | |
| background-color: transparent; | |
| } | |
| .navbar { | |
| *position: relative; | |
| *z-index: 2; | |
| margin-bottom: 20px; | |
| overflow: visible; | |
| } | |
| .navbar-inner { | |
| min-height: 40px; | |
| padding-right: 20px; | |
| padding-left: 20px; | |
| background-color: #fafafa; | |
| background-image: -moz-linear-gradient(top, #ffffff, #f2f2f2); | |
| background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2)); | |
| background-image: -webkit-linear-gradient(top, #ffffff, #f2f2f2); | |
| background-image: -o-linear-gradient(top, #ffffff, #f2f2f2); | |
| background-image: linear-gradient(to bottom, #ffffff, #f2f2f2); | |
| background-repeat: repeat-x; | |
| border: 1px solid #d4d4d4; | |
| -webkit-border-radius: 4px; | |
| -moz-border-radius: 4px; | |
| border-radius: 4px; | |
| filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0); | |
| *zoom: 1; | |
| -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); | |
| -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); | |
| box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); | |
| } | |
| .navbar-inner:before, | |
| .navbar-inner:after { | |
| display: table; | |
| line-height: 0; | |
| content: ""; | |
| } | |
| .navbar-inner:after { | |
| clear: both; | |
| } | |
| .navbar .container { | |
| width: auto; | |
| } | |
| .nav-collapse.collapse { | |
| height: auto; | |
| overflow: visible; | |
| } | |
| .navbar .brand { | |
| display: block; | |
| float: left; | |
| padding: 10px 20px 10px; | |
| margin-left: -20px; | |
| font-size: 20px; | |
| font-weight: 200; | |
| color: #777777; | |
| text-shadow: 0 1px 0 #ffffff; | |
| } | |
| .navbar .brand:hover { | |
| text-decoration: none; | |
| } | |
| .navbar-text { | |
| margin-bottom: 0; | |
| line-height: 40px; | |
| color: #777777; | |
| } | |
| .navbar-link { | |
| color: #777777; | |
| } | |
| .navbar-link:hover { | |
| color: #333333; | |
| } | |
| .navbar .divider-vertical { | |
| height: 40px; | |
| margin: 0 9px; | |
| border-right: 1px solid #ffffff; | |
| border-left: 1px solid #f2f2f2; | |
| } | |
| .navbar .btn, | |
| .navbar .btn-group { | |
| margin-top: 5px; | |
| } | |
| .navbar .btn-group .btn, | |
| .navbar .input-prepend .btn, | |
| .navbar .input-append .btn { | |
| margin-top: 0; | |
| } | |
| .navbar-form { | |
| margin-bottom: 0; | |
| *zoom: 1; | |
| } | |
| .navbar-form:before, | |
| .navbar-form:after { | |
| display: table; | |
| line-height: 0; | |
| content: ""; | |
| } | |
| .navbar-form:after { | |
| clear: both; | |
| } | |
| .navbar-form input, | |
| .navbar-form select, | |
| .navbar-form .radio, | |
| .navbar-form .checkbox { | |
| margin-top: 5px; | |
| } | |
| .navbar-form input, | |
| .navbar-form select, | |
| .navbar-form .btn { | |
| display: inline-block; | |
| margin-bottom: 0; | |
| } | |
| .navbar-form input[type="image"], | |
| .navbar-form input[type="checkbox"], | |
| .navbar-form input[type="radio"] { | |
| margin-top: 3px; | |
| } | |
| .navbar-form .input-append, | |
| .navbar-form .input-prepend { | |
| margin-top: 5px; | |
| white-space: nowrap; | |
| } | |
| .navbar-form .input-append input, | |
| .navbar-form .input-prepend input { | |
| margin-top: 0; | |
| } | |
| .navbar-search { | |
| position: relative; | |
| float: left; | |
| margin-top: 5px; | |
| margin-bottom: 0; | |
| } | |
| .navbar-search .search-query { | |
| padding: 4px 14px; | |
| margin-bottom: 0; | |
| font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; | |
| font-size: 13px; | |
| font-weight: normal; | |
| line-height: 1; | |
| -webkit-border-radius: 15px; | |
| -moz-border-radius: 15px; | |
| border-radius: 15px; | |
| } | |
| .navbar-static-top { | |
| position: static; | |
| margin-bottom: 0; | |
| } | |
| .navbar-static-top .navbar-inner { | |
| -webkit-border-radius: 0; | |
| -moz-border-radius: 0; | |
| border-radius: 0; | |
| } | |
| .navbar-fixed-top, | |
| .navbar-fixed-bottom { | |
| position: fixed; | |
| right: 0; | |
| left: 0; | |
| z-index: 1030; | |
| margin-bottom: 0; | |
| } | |
| .navbar-fixed-top .navbar-inner, | |
| .navbar-static-top .navbar-inner { | |
| border-width: 0 0 1px; | |
| } | |
| .navbar-fixed-bottom .navbar-inner { | |
| border-width: 1px 0 0; | |
| } | |
| .navbar-fixed-top .navbar-inner, | |
| .navbar-fixed-bottom .navbar-inner { | |
| padding-right: 0; | |
| padding-left: 0; | |
| -webkit-border-radius: 0; | |
| -moz-border-radius: 0; | |
| border-radius: 0; | |
| } | |
| .navbar-static-top .container, | |
| .navbar-fixed-top .container, | |
| .navbar-fixed-bottom .container { | |
| width: 940px; | |
| } | |
| .navbar-fixed-top { | |
| top: 0; | |
| } | |
| .navbar-fixed-top .navbar-inner, | |
| .navbar-static-top .navbar-inner { | |
| -webkit-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); | |
| -moz-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); | |
| box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); | |
| } | |
| .navbar-fixed-bottom { | |
| bottom: 0; | |
| } | |
| .navbar-fixed-bottom .navbar-inner { | |
| -webkit-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); | |
| -moz-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); | |
| box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); | |
| } | |
| .navbar .nav { | |
| position: relative; | |
| left: 0; | |
| display: block; | |
| float: left; | |
| margin: 0 10px 0 0; | |
| } | |
| .navbar .nav.pull-right { | |
| float: right; | |
| margin-right: 0; | |
| } | |
| .navbar .nav > li { | |
| float: left; | |
| } | |
| .navbar .nav > li > a { | |
| float: none; | |
| padding: 10px 15px 10px; | |
| color: #777777; | |
| text-decoration: none; | |
| text-shadow: 0 1px 0 #ffffff; | |
| } | |
| .navbar .nav .dropdown-toggle .caret { | |
| margin-top: 8px; | |
| } | |
| .navbar .nav > li > a:focus, | |
| .navbar .nav > li > a:hover { | |
| color: #333333; | |
| text-decoration: none; | |
| background-color: transparent; | |
| } | |
| .navbar .nav > .active > a, | |
| .navbar .nav > .active > a:hover, | |
| .navbar .nav > .active > a:focus { | |
| color: #555555; | |
| text-decoration: none; | |
| background-color: #e5e5e5; | |
| -webkit-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); | |
| -moz-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); | |
| box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); | |
| } | |
| .navbar .btn-navbar { | |
| display: none; | |
| float: right; | |
| padding: 7px 10px; | |
| margin-right: 5px; | |
| margin-left: 5px; | |
| color: #ffffff; | |
| text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); | |
| background-color: #ededed; | |
| *background-color: #e5e5e5; | |
| background-image: -moz-linear-gradient(top, #f2f2f2, #e5e5e5); | |
| background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e5e5e5)); | |
| background-image: -webkit-linear-gradient(top, #f2f2f2, #e5e5e5); | |
| background-image: -o-linear-gradient(top, #f2f2f2, #e5e5e5); | |
| background-image: linear-gradient(to bottom, #f2f2f2, #e5e5e5); | |
| background-repeat: repeat-x; | |
| border-color: #e5e5e5 #e5e5e5 #bfbfbf; | |
| border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); | |
| filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffe5e5e5', GradientType=0); | |
| filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); | |
| -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); | |
| -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); | |
| box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); | |
| } | |
| .navbar .btn-navbar:hover, | |
| .navbar .btn-navbar:active, | |
| .navbar .btn-navbar.active, | |
| .navbar .btn-navbar.disabled, | |
| .navbar .btn-navbar[disabled] { | |
| color: #ffffff; | |
| background-color: #e5e5e5; | |
| *background-color: #d9d9d9; | |
| } | |
| .navbar .btn-navbar:active, | |
| .navbar .btn-navbar.active { | |
| background-color: #cccccc \9; | |
| } | |
| .navbar .btn-navbar .icon-bar { | |
| display: block; | |
| width: 18px; | |
| height: 2px; | |
| background-color: #f5f5f5; | |
| -webkit-border-radius: 1px; | |
| -moz-border-radius: 1px; | |
| border-radius: 1px; | |
| -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); | |
| -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); | |
| box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); | |
| } | |
| .btn-navbar .icon-bar + .icon-bar { | |
| margin-top: 3px; | |
| } | |
| .navbar .nav > li > .dropdown-menu:before { | |
| position: absolute; | |
| top: -7px; | |
| left: 9px; | |
| display: inline-block; | |
| border-right: 7px solid transparent; | |
| border-bottom: 7px solid #ccc; | |
| border-left: 7px solid transparent; | |
| border-bottom-color: rgba(0, 0, 0, 0.2); | |
| content: ''; | |
| } | |
| .navbar .nav > li > .dropdown-menu:after { | |
| position: absolute; | |
| top: -6px; | |
| left: 10px; | |
| display: inline-block; | |
| border-right: 6px solid transparent; | |
| border-bottom: 6px solid #ffffff; | |
| border-left: 6px solid transparent; | |
| content: ''; | |
| } | |
| .navbar-fixed-bottom .nav > li > .dropdown-menu:before { | |
| top: auto; | |
| bottom: -7px; | |
| border-top: 7px solid #ccc; | |
| border-bottom: 0; | |
| border-top-color: rgba(0, 0, 0, 0.2); | |
| } | |
| .navbar-fixed-bottom .nav > li > .dropdown-menu:after { | |
| top: auto; | |
| bottom: -6px; | |
| border-top: 6px solid #ffffff; | |
| border-bottom: 0; | |
| } | |
| .navbar .nav li.dropdown > a:hover .caret { | |
| border-top-color: #555555; | |
| border-bottom-color: #555555; | |
| } | |
| .navbar .nav li.dropdown.open > .dropdown-toggle, | |
| .navbar .nav li.dropdown.active > .dropdown-toggle, | |
| .navbar .nav li.dropdown.open.active > .dropdown-toggle { | |
| color: #555555; | |
| background-color: #e5e5e5; | |
| } | |
| .navbar .nav li.dropdown > .dropdown-toggle .caret { | |
| border-top-color: #777777; | |
| border-bottom-color: #777777; | |
| } | |
| .navbar .nav li.dropdown.open > .dropdown-toggle .caret, | |
| .navbar .nav li.dropdown.active > .dropdown-toggle .caret, | |
| .navbar .nav li.dropdown.open.active > .dropdown-toggle .caret { | |
| border-top-color: #555555; | |
| border-bottom-color: #555555; | |
| } | |
| .navbar .pull-right > li > .dropdown-menu, | |
| .navbar .nav > li > .dropdown-menu.pull-right { | |
| right: 0; | |
| left: auto; | |
| } | |
| .navbar .pull-right > li > .dropdown-menu:before, | |
| .navbar .nav > li > .dropdown-menu.pull-right:before { | |
| right: 12px; | |
| left: auto; | |
| } | |
| .navbar .pull-right > li > .dropdown-menu:after, | |
| .navbar .nav > li > .dropdown-menu.pull-right:after { | |
| right: 13px; | |
| left: auto; | |
| } | |
| .navbar .pull-right > li > .dropdown-menu .dropdown-menu, | |
| .navbar .nav > li > .dropdown-menu.pull-right .dropdown-menu { | |
| right: 100%; | |
| left: auto; | |
| margin-right: -1px; | |
| margin-left: 0; | |
| -webkit-border-radius: 6px 0 6px 6px; | |
| -moz-border-radius: 6px 0 6px 6px; | |
| border-radius: 6px 0 6px 6px; | |
| } | |
| .navbar-inverse .navbar-inner { | |
| background-color: #1b1b1b; | |
| background-image: -moz-linear-gradient(top, #222222, #111111); | |
| background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111)); | |
| background-image: -webkit-linear-gradient(top, #222222, #111111); | |
| background-image: -o-linear-gradient(top, #222222, #111111); | |
| background-image: linear-gradient(to bottom, #222222, #111111); | |
| background-repeat: repeat-x; | |
| border-color: #252525; | |
| filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0); | |
| } | |
| .navbar-inverse .brand, | |
| .navbar-inverse .nav > li > a { | |
| color: #999999; | |
| text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); | |
| } | |
| .navbar-inverse .brand:hover, | |
| .navbar-inverse .nav > li > a:hover { | |
| color: #ffffff; | |
| } | |
| .navbar-inverse .brand { | |
| color: #999999; | |
| } | |
| .navbar-inverse .navbar-text { | |
| color: #999999; | |
| } | |
| .navbar-inverse .nav > li > a:focus, | |
| .navbar-inverse .nav > li > a:hover { | |
| color: #ffffff; | |
| background-color: transparent; | |
| } | |
| .navbar-inverse .nav .active > a, | |
| .navbar-inverse .nav .active > a:hover, | |
| .navbar-inverse .nav .active > a:focus { | |
| color: #ffffff; | |
| background-color: #111111; | |
| } | |
| .navbar-inverse .navbar-link { | |
| color: #999999; | |
| } | |
| .navbar-inverse .navbar-link:hover { | |
| color: #ffffff; | |
| } | |
| .navbar-inverse .divider-vertical { | |
| border-right-color: #222222; | |
| border-left-color: #111111; | |
| } | |
| .navbar-inverse .nav li.dropdown.open > .dropdown-toggle, | |
| .navbar-inverse .nav li.dropdown.active > .dropdown-toggle, | |
| .navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle { | |
| color: #ffffff; | |
| background-color: #111111; | |
| } | |
| .navbar-inverse .nav li.dropdown > a:hover .caret { | |
| border-top-color: #ffffff; | |
| border-bottom-color: #ffffff; | |
| } | |
| .navbar-inverse .nav li.dropdown > .dropdown-toggle .caret { | |
| border-top-color: #999999; | |
| border-bottom-color: #999999; | |
| } | |
| .navbar-inverse .nav li.dropdown.open > .dropdown-toggle .caret, | |
| .navbar-inverse .nav li.dropdown.active > .dropdown-toggle .caret, | |
| .navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle .caret { | |
| border-top-color: #ffffff; | |
| border-bottom-color: #ffffff; | |
| } | |
| .navbar-inverse .navbar-search .search-query { | |
| color: #ffffff; | |
| background-color: #515151; | |
| border-color: #111111; | |
| -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); | |
| -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); | |
| box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); | |
| -webkit-transition: none; | |
| -moz-transition: none; | |
| -o-transition: none; | |
| transition: none; | |
| } | |
| .navbar-inverse .navbar-search .search-query:-moz-placeholder { | |
| color: #cccccc; | |
| } | |
| .navbar-inverse .navbar-search .search-query:-ms-input-placeholder { | |
| color: #cccccc; | |
| } | |
| .navbar-inverse .navbar-search .search-query::-webkit-input-placeholder { | |
| color: #cccccc; | |
| } | |
| .navbar-inverse .navbar-search .search-query:focus, | |
| .navbar-inverse .navbar-search .search-query.focused { | |
| padding: 5px 15px; | |
| color: #333333; | |
| text-shadow: 0 1px 0 #ffffff; | |
| background-color: #ffffff; | |
| border: 0; | |
| outline: 0; | |
| -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); | |
| -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); | |
| box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); | |
| } | |
| .navbar-inverse .btn-navbar { | |
| color: #ffffff; | |
| text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); | |
| background-color: #0e0e0e; | |
| *background-color: #040404; | |
| background-image: -moz-linear-gradient(top, #151515, #040404); | |
| background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404)); | |
| background-image: -webkit-linear-gradient(top, #151515, #040404); | |
| background-image: -o-linear-gradient(top, #151515, #040404); | |
| background-image: linear-gradient(to bottom, #151515, #040404); | |
| background-repeat: repeat-x; | |
| border-color: #040404 #040404 #000000; | |
| border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); | |
| filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515', endColorstr='#ff040404', GradientType=0); | |
| filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); | |
| } | |
| .navbar-inverse .btn-navbar:hover, | |
| .navbar-inverse .btn-navbar:active, | |
| .navbar-inverse .btn-navbar.active, | |
| .navbar-inverse .btn-navbar.disabled, | |
| .navbar-inverse .btn-navbar[disabled] { | |
| color: #ffffff; | |
| background-color: #040404; | |
| *background-color: #000000; | |
| } | |
| .navbar-inverse .btn-navbar:active, | |
| .navbar-inverse .btn-navbar.active { | |
| background-color: #000000 \9; | |
| } | |
| .breadcrumb { | |
| padding: 8px 15px; | |
| margin: 0 0 20px; | |
| list-style: none; | |
| background-color: #f5f5f5; | |
| -webkit-border-radius: 4px; | |
| -moz-border-radius: 4px; | |
| border-radius: 4px; | |
| } | |
| .breadcrumb > li { | |
| display: inline-block; | |
| *display: inline; | |
| text-shadow: 0 1px 0 #ffffff; | |
| *zoom: 1; | |
| } | |
| .breadcrumb > li > .divider { | |
| padding: 0 5px; | |
| color: #ccc; | |
| } | |
| .breadcrumb > .active { | |
| color: #999999; | |
| } | |
| .pagination { | |
| margin: 20px 0; | |
| } | |
| .pagination ul { | |
| display: inline-block; | |
| *display: inline; | |
| margin-bottom: 0; | |
| margin-left: 0; | |
| -webkit-border-radius: 4px; | |
| -moz-border-radius: 4px; | |
| border-radius: 4px; | |
| *zoom: 1; | |
| -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); | |
| -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); | |
| box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); | |
| } | |
| .pagination ul > li { | |
| display: inline; | |
| } | |
| .pagination ul > li > a, | |
| .pagination ul > li > span { | |
| float: left; | |
| padding: 4px 12px; | |
| line-height: 20px; | |
| text-decoration: none; | |
| background-color: #ffffff; | |
| border: 1px solid #dddddd; | |
| border-left-width: 0; | |
| } | |
| .pagination ul > li > a:hover, | |
| .pagination ul > .active > a, | |
| .pagination ul > .active > span { | |
| background-color: #f5f5f5; | |
| } | |
| .pagination ul > .active > a, | |
| .pagination ul > .active > span { | |
| color: #999999; | |
| cursor: default; | |
| } | |
| .pagination ul > .disabled > span, | |
| .pagination ul > .disabled > a, | |
| .pagination ul > .disabled > a:hover { | |
| color: #999999; | |
| cursor: default; | |
| background-color: transparent; | |
| } | |
| .pagination ul > li:first-child > a, | |
| .pagination ul > li:first-child > span { | |
| border-left-width: 1px; | |
| -webkit-border-bottom-left-radius: 4px; | |
| border-bottom-left-radius: 4px; | |
| -webkit-border-top-left-radius: 4px; | |
| border-top-left-radius: 4px; | |
| -moz-border-radius-bottomleft: 4px; | |
| -moz-border-radius-topleft: 4px; | |
| } | |
| .pagination ul > li:last-child > a, | |
| .pagination ul > li:last-child > span { | |
| -webkit-border-top-right-radius: 4px; | |
| border-top-right-radius: 4px; | |
| -webkit-border-bottom-right-radius: 4px; | |
| border-bottom-right-radius: 4px; | |
| -moz-border-radius-topright: 4px; | |
| -moz-border-radius-bottomright: 4px; | |
| } | |
| .pagination-centered { | |
| text-align: center; | |
| } | |
| .pagination-right { | |
| text-align: right; | |
| } | |
| .pagination-large ul > li > a, | |
| .pagination-large ul > li > span { | |
| padding: 11px 19px; | |
| font-size: 17.5px; | |
| } | |
| .pagination-large ul > li:first-child > a, | |
| .pagination-large ul > li:first-child > span { | |
| -webkit-border-bottom-left-radius: 6px; | |
| border-bottom-left-radius: 6px; | |
| -webkit-border-top-left-radius: 6px; | |
| border-top-left-radius: 6px; | |
| -moz-border-radius-bottomleft: 6px; | |
| -moz-border-radius-topleft: 6px; | |
| } | |
| .pagination-large ul > li:last-child > a, | |
| .pagination-large ul > li:last-child > span { | |
| -webkit-border-top-right-radius: 6px; | |
| border-top-right-radius: 6px; | |
| -webkit-border-bottom-right-radius: 6px; | |
| border-bottom-right-radius: 6px; | |
| -moz-border-radius-topright: 6px; | |
| -moz-border-radius-bottomright: 6px; | |
| } | |
| .pagination-mini ul > li:first-child > a, | |
| .pagination-small ul > li:first-child > a, | |
| .pagination-mini ul > li:first-child > span, | |
| .pagination-small ul > li:first-child > span { | |
| -webkit-border-bottom-left-radius: 3px; | |
| border-bottom-left-radius: 3px; | |
| -webkit-border-top-left-radius: 3px; | |
| border-top-left-radius: 3px; | |
| -moz-border-radius-bottomleft: 3px; | |
| -moz-border-radius-topleft: 3px; | |
| } | |
| .pagination-mini ul > li:last-child > a, | |
| .pagination-small ul > li:last-child > a, | |
| .pagination-mini ul > li:last-child > span, | |
| .pagination-small ul > li:last-child > span { | |
| -webkit-border-top-right-radius: 3px; | |
| border-top-right-radius: 3px; | |
| -webkit-border-bottom-right-radius: 3px; | |
| border-bottom-right-radius: 3px; | |
| -moz-border-radius-topright: 3px; | |
| -moz-border-radius-bottomright: 3px; | |
| } | |
| .pagination-small ul > li > a, | |
| .pagination-small ul > li > span { | |
| padding: 2px 10px; | |
| font-size: 11.9px; | |
| } | |
| .pagination-mini ul > li > a, | |
| .pagination-mini ul > li > span { | |
| padding: 0 6px; | |
| font-size: 10.5px; | |
| } | |
| .pager { | |
| margin: 20px 0; | |
| text-align: center; | |
| list-style: none; | |
| *zoom: 1; | |
| } | |
| .pager:before, | |
| .pager:after { | |
| display: table; | |
| line-height: 0; | |
| content: ""; | |
| } | |
| .pager:after { | |
| clear: both; | |
| } | |
| .pager li { | |
| display: inline; | |
| } | |
| .pager li > a, | |
| .pager li > span { | |
| display: inline-block; | |
| padding: 5px 14px; | |
| background-color: #fff; | |
| border: 1px solid #ddd; | |
| -webkit-border-radius: 15px; | |
| -moz-border-radius: 15px; | |
| border-radius: 15px; | |
| } | |
| .pager li > a:hover { | |
| text-decoration: none; | |
| background-color: #f5f5f5; | |
| } | |
| .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 > span { | |
| color: #999999; | |
| cursor: default; | |
| background-color: #fff; | |
| } | |
| .modal-backdrop { | |
| position: fixed; | |
| top: 0; | |
| right: 0; | |
| bottom: 0; | |
| left: 0; | |
| z-index: 1040; | |
| background-color: #000000; | |
| } | |
| .modal-backdrop.fade { | |
| opacity: 0; | |
| } | |
| .modal-backdrop, | |
| .modal-backdrop.fade.in { | |
| opacity: 0.8; | |
| filter: alpha(opacity=80); | |
| } | |
| .modal { | |
| position: fixed; | |
| top: 10%; | |
| left: 50%; | |
| z-index: 1050; | |
| width: 560px; | |
| margin-left: -280px; | |
| background-color: #ffffff; | |
| border: 1px solid #999; | |
| border: 1px solid rgba(0, 0, 0, 0.3); | |
| *border: 1px solid #999; | |
| -webkit-border-radius: 6px; | |
| -moz-border-radius: 6px; | |
| border-radius: 6px; | |
| outline: none; | |
| -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); | |
| -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); | |
| box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); | |
| -webkit-background-clip: padding-box; | |
| -moz-background-clip: padding-box; | |
| background-clip: padding-box; | |
| } | |
| .modal.fade { | |
| top: -25%; | |
| -webkit-transition: opacity 0.3s linear, top 0.3s ease-out; | |
| -moz-transition: opacity 0.3s linear, top 0.3s ease-out; | |
| -o-transition: opacity 0.3s linear, top 0.3s ease-out; | |
| transition: opacity 0.3s linear, top 0.3s ease-out; | |
| } | |
| .modal.fade.in { | |
| top: 10%; | |
| } | |
| .modal-header { | |
| padding: 9px 15px; | |
| border-bottom: 1px solid #eee; | |
| } | |
| .modal-header .close { | |
| margin-top: 2px; | |
| } | |
| .modal-header h3 { | |
| margin: 0; | |
| line-height: 30px; | |
| } | |
| .modal-body { | |
| position: relative; | |
| max-height: 400px; | |
| padding: 15px; | |
| overflow-y: auto; | |
| } | |
| .modal-form { | |
| margin-bottom: 0; | |
| } | |
| .modal-footer { | |
| padding: 14px 15px 15px; | |
| margin-bottom: 0; | |
| text-align: right; | |
| background-color: #f5f5f5; | |
| border-top: 1px solid #ddd; | |
| -webkit-border-radius: 0 0 6px 6px; | |
| -moz-border-radius: 0 0 6px 6px; | |
| border-radius: 0 0 6px 6px; | |
| *zoom: 1; | |
| -webkit-box-shadow: inset 0 1px 0 #ffffff; | |
| -moz-box-shadow: inset 0 1px 0 #ffffff; | |
| box-shadow: inset 0 1px 0 #ffffff; | |
| } | |
| .modal-footer:before, | |
| .modal-footer:after { | |
| display: table; | |
| line-height: 0; | |
| content: ""; | |
| } | |
| .modal-footer:after { | |
| clear: both; | |
| } | |
| .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; | |
| } | |
| .tooltip { | |
| position: absolute; | |
| z-index: 1030; | |
| display: block; | |
| padding: 5px; | |
| font-size: 11px; | |
| opacity: 0; | |
| filter: alpha(opacity=0); | |
| visibility: visible; | |
| } | |
| .tooltip.in { | |
| opacity: 0.8; | |
| filter: alpha(opacity=80); | |
| } | |
| .tooltip.top { | |
| margin-top: -3px; | |
| } | |
| .tooltip.right { | |
| margin-left: 3px; | |
| } | |
| .tooltip.bottom { | |
| margin-top: 3px; | |
| } | |
| .tooltip.left { | |
| margin-left: -3px; | |
| } | |
| .tooltip-inner { | |
| max-width: 200px; | |
| padding: 3px 8px; | |
| color: #ffffff; | |
| text-align: center; | |
| text-decoration: none; | |
| background-color: #000000; | |
| -webkit-border-radius: 4px; | |
| -moz-border-radius: 4px; | |
| 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-top-color: #000000; | |
| border-width: 5px 5px 0; | |
| } | |
| .tooltip.right .tooltip-arrow { | |
| top: 50%; | |
| left: 0; | |
| margin-top: -5px; | |
| border-right-color: #000000; | |
| border-width: 5px 5px 5px 0; | |
| } | |
| .tooltip.left .tooltip-arrow { | |
| top: 50%; | |
| right: 0; | |
| margin-top: -5px; | |
| border-left-color: #000000; | |
| border-width: 5px 0 5px 5px; | |
| } | |
| .tooltip.bottom .tooltip-arrow { | |
| top: 0; | |
| left: 50%; | |
| margin-left: -5px; | |
| border-bottom-color: #000000; | |
| border-width: 0 5px 5px; | |
| } | |
| .popover { | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| z-index: 1010; | |
| display: none; | |
| width: 236px; | |
| padding: 1px; | |
| text-align: left; | |
| white-space: normal; | |
| background-color: #ffffff; | |
| border: 1px solid #ccc; | |
| border: 1px solid rgba(0, 0, 0, 0.2); | |
| -webkit-border-radius: 6px; | |
| -moz-border-radius: 6px; | |
| border-radius: 6px; | |
| -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); | |
| -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); | |
| box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); | |
| -webkit-background-clip: padding-box; | |
| -moz-background-clip: padding; | |
| background-clip: padding-box; | |
| } | |
| .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; | |
| font-weight: normal; | |
| line-height: 18px; | |
| background-color: #f7f7f7; | |
| border-bottom: 1px solid #ebebeb; | |
| -webkit-border-radius: 5px 5px 0 0; | |
| -moz-border-radius: 5px 5px 0 0; | |
| 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 { | |
| border-width: 10px; | |
| content: ""; | |
| } | |
| .popover.top .arrow { | |
| bottom: -11px; | |
| left: 50%; | |
| margin-left: -11px; | |
| border-top-color: #999; | |
| border-top-color: rgba(0, 0, 0, 0.25); | |
| border-bottom-width: 0; | |
| } | |
| .popover.top .arrow:after { | |
| bottom: 1px; | |
| margin-left: -10px; | |
| border-top-color: #ffffff; | |
| 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, 0.25); | |
| border-left-width: 0; | |
| } | |
| .popover.right .arrow:after { | |
| bottom: -10px; | |
| left: 1px; | |
| border-right-color: #ffffff; | |
| border-left-width: 0; | |
| } | |
| .popover.bottom .arrow { | |
| top: -11px; | |
| left: 50%; | |
| margin-left: -11px; | |
| border-bottom-color: #999; | |
| border-bottom-color: rgba(0, 0, 0, 0.25); | |
| border-top-width: 0; | |
| } | |
| .popover.bottom .arrow:after { | |
| top: 1px; | |
| margin-left: -10px; | |
| border-bottom-color: #ffffff; | |
| border-top-width: 0; | |
| } | |
| .popover.left .arrow { | |
| top: 50%; | |
| right: -11px; | |
| margin-top: -11px; | |
| border-left-color: #999; | |
| border-left-color: rgba(0, 0, 0, 0.25); | |
| border-right-width: 0; | |
| } | |
| .popover.left .arrow:after { | |
| right: 1px; | |
| bottom: -10px; | |
| border-left-color: #ffffff; | |
| border-right-width: 0; | |
| } | |
| .thumbnails { | |
| margin-left: -20px; | |
| list-style: none; | |
| *zoom: 1; | |
| } | |
| .thumbnails:before, | |
| .thumbnails:after { | |
| display: table; | |
| line-height: 0; | |
| content: ""; | |
| } | |
| .thumbnails:after { | |
| clear: both; | |
| } | |
| .row-fluid .thumbnails { | |
| margin-left: 0; | |
| } | |
| .thumbnails > li { | |
| float: left; | |
| margin-bottom: 20px; | |
| margin-left: 20px; | |
| } | |
| .thumbnail { | |
| display: block; | |
| padding: 4px; | |
| line-height: 20px; | |
| border: 1px solid #ddd; | |
| -webkit-border-radius: 4px; | |
| -moz-border-radius: 4px; | |
| border-radius: 4px; | |
| -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); | |
| -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); | |
| box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); | |
| -webkit-transition: all 0.2s ease-in-out; | |
| -moz-transition: all 0.2s ease-in-out; | |
| -o-transition: all 0.2s ease-in-out; | |
| transition: all 0.2s ease-in-out; | |
| } | |
| a.thumbnail:hover { | |
| border-color: #0088cc; | |
| -webkit-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); | |
| -moz-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); | |
| box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); | |
| } | |
| .thumbnail > img { | |
| display: block; | |
| max-width: 100%; | |
| margin-right: auto; | |
| margin-left: auto; | |
| } | |
| .thumbnail .caption { | |
| padding: 9px; | |
| color: #555555; | |
| } | |
| .media, | |
| .media-body { | |
| overflow: hidden; | |
| *overflow: visible; | |
| zoom: 1; | |
| } | |
| .media, | |
| .media .media { | |
| margin-top: 15px; | |
| } | |
| .media:first-child { | |
| margin-top: 0; | |
| } | |
| .media-object { | |
| display: block; | |
| } | |
| .media-heading { | |
| margin: 0 0 5px; | |
| } | |
| .media .pull-left { | |
| margin-right: 10px; | |
| } | |
| .media .pull-right { | |
| margin-left: 10px; | |
| } | |
| .media-list { | |
| margin-left: 0; | |
| list-style: none; | |
| } | |
| .label, | |
| .badge { | |
| display: inline-block; | |
| padding: 2px 4px; | |
| font-size: 11.844px; | |
| font-weight: bold; | |
| line-height: 14px; | |
| color: #ffffff; | |
| text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); | |
| white-space: nowrap; | |
| vertical-align: baseline; | |
| background-color: #999999; | |
| } | |
| .label { | |
| -webkit-border-radius: 3px; | |
| -moz-border-radius: 3px; | |
| border-radius: 3px; | |
| } | |
| .badge { | |
| padding-right: 9px; | |
| padding-left: 9px; | |
| -webkit-border-radius: 9px; | |
| -moz-border-radius: 9px; | |
| border-radius: 9px; | |
| } | |
| .label:empty, | |
| .badge:empty { | |
| display: none; | |
| } | |
| a.label:hover, | |
| a.badge:hover { | |
| color: #ffffff; | |
| text-decoration: none; | |
| cursor: pointer; | |
| } | |
| .label-important, | |
| .badge-important { | |
| background-color: #b94a48; | |
| } | |
| .label-important[href], | |
| .badge-important[href] { | |
| background-color: #953b39; | |
| } | |
| .label-warning, | |
| .badge-warning { | |
| background-color: #f89406; | |
| } | |
| .label-warning[href], | |
| .badge-warning[href] { | |
| background-color: #c67605; | |
| } | |
| .label-success, | |
| .badge-success { | |
| background-color: #468847; | |
| } | |
| .label-success[href], | |
| .badge-success[href] { | |
| background-color: #356635; | |
| } | |
| .label-info, | |
| .badge-info { | |
| background-color: #3a87ad; | |
| } | |
| .label-info[href], | |
| .badge-info[href] { | |
| background-color: #2d6987; | |
| } | |
| .label-inverse, | |
| .badge-inverse { | |
| background-color: #333333; | |
| } | |
| .label-inverse[href], | |
| .badge-inverse[href] { | |
| background-color: #1a1a1a; | |
| } | |
| .btn .label, | |
| .btn .badge { | |
| position: relative; | |
| top: -1px; | |
| } | |
| .btn-mini .label, | |
| .btn-mini .badge { | |
| top: 0; | |
| } | |
| @-webkit-keyframes progress-bar-stripes { | |
| from { | |
| background-position: 40px 0; | |
| } | |
| to { | |
| background-position: 0 0; | |
| } | |
| } | |
| @-moz-keyframes progress-bar-stripes { | |
| from { | |
| background-position: 40px 0; | |
| } | |
| to { | |
| background-position: 0 0; | |
| } | |
| } | |
| @-ms-keyframes progress-bar-stripes { | |
| from { | |
| background-position: 40px 0; | |
| } | |
| to { | |
| background-position: 0 0; | |
| } | |
| } | |
| @-o-keyframes progress-bar-stripes { | |
| from { | |
| background-position: 0 0; | |
| } | |
| to { | |
| background-position: 40px 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: #f7f7f7; | |
| background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9); | |
| background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9)); | |
| background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9); | |
| background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9); | |
| background-image: linear-gradient(to bottom, #f5f5f5, #f9f9f9); | |
| background-repeat: repeat-x; | |
| -webkit-border-radius: 4px; | |
| -moz-border-radius: 4px; | |
| border-radius: 4px; | |
| filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0); | |
| -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); | |
| -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); | |
| box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); | |
| } | |
| .progress .bar { | |
| float: left; | |
| width: 0; | |
| height: 100%; | |
| font-size: 12px; | |
| color: #ffffff; | |
| text-align: center; | |
| text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); | |
| background-color: #0e90d2; | |
| background-image: -moz-linear-gradient(top, #149bdf, #0480be); | |
| background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be)); | |
| background-image: -webkit-linear-gradient(top, #149bdf, #0480be); | |
| background-image: -o-linear-gradient(top, #149bdf, #0480be); | |
| background-image: linear-gradient(to bottom, #149bdf, #0480be); | |
| background-repeat: repeat-x; | |
| filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0); | |
| -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); | |
| -moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); | |
| box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); | |
| -webkit-box-sizing: border-box; | |
| -moz-box-sizing: border-box; | |
| box-sizing: border-box; | |
| -webkit-transition: width 0.6s ease; | |
| -moz-transition: width 0.6s ease; | |
| -o-transition: width 0.6s ease; | |
| transition: width 0.6s ease; | |
| } | |
| .progress .bar + .bar { | |
| -webkit-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); | |
| -moz-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); | |
| box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); | |
| } | |
| .progress-striped .bar { | |
| background-color: #149bdf; | |
| background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); | |
| 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); | |
| background-image: -moz-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); | |
| 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); | |
| 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); | |
| -webkit-background-size: 40px 40px; | |
| -moz-background-size: 40px 40px; | |
| -o-background-size: 40px 40px; | |
| background-size: 40px 40px; | |
| } | |
| .progress.active .bar { | |
| -webkit-animation: progress-bar-stripes 2s linear infinite; | |
| -moz-animation: progress-bar-stripes 2s linear infinite; | |
| -ms-animation: progress-bar-stripes 2s linear infinite; | |
| -o-animation: progress-bar-stripes 2s linear infinite; | |
| animation: progress-bar-stripes 2s linear infinite; | |
| } | |
| .progress-danger .bar, | |
| .progress .bar-danger { | |
| background-color: #dd514c; | |
| background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35); | |
| background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35)); | |
| background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35); | |
| background-image: -o-linear-gradient(top, #ee5f5b, #c43c35); | |
| background-image: linear-gradient(to bottom, #ee5f5b, #c43c35); | |
| background-repeat: repeat-x; | |
| filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0); | |
| } | |
| .progress-danger.progress-striped .bar, | |
| .progress-striped .bar-danger { | |
| background-color: #ee5f5b; | |
| background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); | |
| 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); | |
| background-image: -moz-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); | |
| 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); | |
| 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); | |
| } | |
| .progress-success .bar, | |
| .progress .bar-success { | |
| background-color: #5eb95e; | |
| background-image: -moz-linear-gradient(top, #62c462, #57a957); | |
| background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957)); | |
| background-image: -webkit-linear-gradient(top, #62c462, #57a957); | |
| background-image: -o-linear-gradient(top, #62c462, #57a957); | |
| background-image: linear-gradient(to bottom, #62c462, #57a957); | |
| background-repeat: repeat-x; | |
| filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0); | |
| } | |
| .progress-success.progress-striped .bar, | |
| .progress-striped .bar-success { | |
| background-color: #62c462; | |
| background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); | |
| 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); | |
| background-image: -moz-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); | |
| 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); | |
| 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); | |
| } | |
| .progress-info .bar, | |
| .progress .bar-info { | |
| background-color: #4bb1cf; | |
| background-image: -moz-linear-gradient(top, #5bc0de, #339bb9); | |
| background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9)); | |
| background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9); | |
| background-image: -o-linear-gradient(top, #5bc0de, #339bb9); | |
| background-image: linear-gradient(to bottom, #5bc0de, #339bb9); | |
| background-repeat: repeat-x; | |
| filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0); | |
| } | |
| .progress-info.progress-striped .bar, | |
| .progress-striped .bar-info { | |
| background-color: #5bc0de; | |
| background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); | |
| 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); | |
| background-image: -moz-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); | |
| 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); | |
| 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); | |
| } | |
| .progress-warning .bar, | |
| .progress .bar-warning { | |
| background-color: #faa732; | |
| background-image: -moz-linear-gradient(top, #fbb450, #f89406); | |
| background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); | |
| background-image: -webkit-linear-gradient(top, #fbb450, #f89406); | |
| background-image: -o-linear-gradient(top, #fbb450, #f89406); | |
| background-image: linear-gradient(to bottom, #fbb450, #f89406); | |
| background-repeat: repeat-x; | |
| filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); | |
| } | |
| .progress-warning.progress-striped .bar, | |
| .progress-striped .bar-warning { | |
| background-color: #fbb450; | |
| background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); | |
| 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); | |
| background-image: -moz-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); | |
| 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); | |
| 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); | |
| } | |
| .accordion { | |
| margin-bottom: 20px; | |
| } | |
| .accordion-group { | |
| margin-bottom: 2px; | |
| border: 1px solid #e5e5e5; | |
| -webkit-border-radius: 4px; | |
| -moz-border-radius: 4px; | |
| border-radius: 4px; | |
| } | |
| .accordion-heading { | |
| border-bottom: 0; | |
| } | |
| .accordion-heading .accordion-toggle { | |
| display: block; | |
| padding: 8px 15px; | |
| } | |
| .accordion-toggle { | |
| cursor: pointer; | |
| } | |
| .accordion-inner { | |
| padding: 9px 15px; | |
| border-top: 1px solid #e5e5e5; | |
| } | |
| .carousel { | |
| position: relative; | |
| margin-bottom: 20px; | |
| line-height: 1; | |
| } | |
| .carousel-inner { | |
| position: relative; | |
| width: 100%; | |
| overflow: hidden; | |
| } | |
| .carousel-inner > .item { | |
| position: relative; | |
| display: none; | |
| -webkit-transition: 0.6s ease-in-out left; | |
| -moz-transition: 0.6s ease-in-out left; | |
| -o-transition: 0.6s ease-in-out left; | |
| transition: 0.6s ease-in-out left; | |
| } | |
| .carousel-inner > .item > img { | |
| display: block; | |
| line-height: 1; | |
| } | |
| .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: 40%; | |
| left: 15px; | |
| width: 40px; | |
| height: 40px; | |
| margin-top: -20px; | |
| font-size: 60px; | |
| font-weight: 100; | |
| line-height: 30px; | |
| color: #ffffff; | |
| text-align: center; | |
| background: #222222; | |
| border: 3px solid #ffffff; | |
| -webkit-border-radius: 23px; | |
| -moz-border-radius: 23px; | |
| border-radius: 23px; | |
| opacity: 0.5; | |
| filter: alpha(opacity=50); | |
| } | |
| .carousel-control.right { | |
| right: 15px; | |
| left: auto; | |
| } | |
| .carousel-control:hover { | |
| color: #ffffff; | |
| text-decoration: none; | |
| opacity: 0.9; | |
| filter: alpha(opacity=90); | |
| } | |
| .carousel-caption { | |
| position: absolute; | |
| right: 0; | |
| bottom: 0; | |
| left: 0; | |
| padding: 15px; | |
| background: #333333; | |
| background: rgba(0, 0, 0, 0.75); | |
| } | |
| .carousel-caption h4, | |
| .carousel-caption p { | |
| line-height: 20px; | |
| color: #ffffff; | |
| } | |
| .carousel-caption h4 { | |
| margin: 0 0 5px; | |
| } | |
| .carousel-caption p { | |
| margin-bottom: 0; | |
| } | |
| .hero-unit { | |
| padding: 60px; | |
| margin-bottom: 30px; | |
| font-size: 18px; | |
| font-weight: 200; | |
| line-height: 30px; | |
| color: inherit; | |
| background-color: #eeeeee; | |
| -webkit-border-radius: 6px; | |
| -moz-border-radius: 6px; | |
| border-radius: 6px; | |
| } | |
| .hero-unit h1 { | |
| margin-bottom: 0; | |
| font-size: 60px; | |
| line-height: 1; | |
| letter-spacing: -1px; | |
| color: inherit; | |
| } | |
| .hero-unit li { | |
| line-height: 30px; | |
| } | |
| .pull-right { | |
| float: right; | |
| } | |
| .pull-left { | |
| float: left; | |
| } | |
| .hide { | |
| display: none; | |
| } | |
| .show { | |
| display: block; | |
| } | |
| .invisible { | |
| visibility: hidden; | |
| } | |
| .affix { | |
| position: fixed; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* =================================================== | |
| * bootstrap-transition.js v2.2.2 | |
| * http://twitter.github.com/bootstrap/javascript.html#transitions | |
| * =================================================== | |
| * Copyright 2012 Twitter, Inc. | |
| * | |
| * Licensed 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. | |
| * ========================================================== */ | |
| !function ($) { | |
| "use strict"; // jshint ;_; | |
| /* CSS TRANSITION SUPPORT (http://www.modernizr.com/) | |
| * ======================================================= */ | |
| $(function () { | |
| $.support.transition = (function () { | |
| var transitionEnd = (function () { | |
| var el = document.createElement('bootstrap') | |
| , transEndEventNames = { | |
| 'WebkitTransition' : 'webkitTransitionEnd' | |
| , 'MozTransition' : 'transitionend' | |
| , 'OTransition' : 'oTransitionEnd otransitionend' | |
| , 'transition' : 'transitionend' | |
| } | |
| , name | |
| for (name in transEndEventNames){ | |
| if (el.style[name] !== undefined) { | |
| return transEndEventNames[name] | |
| } | |
| } | |
| }()) | |
| return transitionEnd && { | |
| end: transitionEnd | |
| } | |
| })() | |
| }) | |
| }(window.jQuery);/* ========================================================== | |
| * bootstrap-alert.js v2.2.2 | |
| * http://twitter.github.com/bootstrap/javascript.html#alerts | |
| * ========================================================== | |
| * Copyright 2012 Twitter, Inc. | |
| * | |
| * Licensed 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. | |
| * ========================================================== */ | |
| !function ($) { | |
| "use strict"; // jshint ;_; | |
| /* ALERT CLASS DEFINITION | |
| * ====================== */ | |
| var dismiss = '[data-dismiss="alert"]' | |
| , Alert = function (el) { | |
| $(el).on('click', dismiss, this.close) | |
| } | |
| Alert.prototype.close = function (e) { | |
| var $this = $(this) | |
| , selector = $this.attr('data-target') | |
| , $parent | |
| if (!selector) { | |
| selector = $this.attr('href') | |
| selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 | |
| } | |
| $parent = $(selector) | |
| e && e.preventDefault() | |
| $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent()) | |
| $parent.trigger(e = $.Event('close')) | |
| if (e.isDefaultPrevented()) return | |
| $parent.removeClass('in') | |
| function removeElement() { | |
| $parent | |
| .trigger('closed') | |
| .remove() | |
| } | |
| $.support.transition && $parent.hasClass('fade') ? | |
| $parent.on($.support.transition.end, removeElement) : | |
| removeElement() | |
| } | |
| /* ALERT PLUGIN DEFINITION | |
| * ======================= */ | |
| var old = $.fn.alert | |
| $.fn.alert = function (option) { | |
| return this.each(function () { | |
| var $this = $(this) | |
| , data = $this.data('alert') | |
| if (!data) $this.data('alert', (data = new Alert(this))) | |
| if (typeof option == 'string') data[option].call($this) | |
| }) | |
| } | |
| $.fn.alert.Constructor = Alert | |
| /* ALERT NO CONFLICT | |
| * ================= */ | |
| $.fn.alert.noConflict = function () { | |
| $.fn.alert = old | |
| return this | |
| } | |
| /* ALERT DATA-API | |
| * ============== */ | |
| $(document).on('click.alert.data-api', dismiss, Alert.prototype.close) | |
| }(window.jQuery);/* ============================================================ | |
| * bootstrap-button.js v2.2.2 | |
| * http://twitter.github.com/bootstrap/javascript.html#buttons | |
| * ============================================================ | |
| * Copyright 2012 Twitter, Inc. | |
| * | |
| * Licensed 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. | |
| * ============================================================ */ | |
| !function ($) { | |
| "use strict"; // jshint ;_; | |
| /* BUTTON PUBLIC CLASS DEFINITION | |
| * ============================== */ | |
| var Button = function (element, options) { | |
| this.$element = $(element) | |
| this.options = $.extend({}, $.fn.button.defaults, options) | |
| } | |
| Button.prototype.setState = function (state) { | |
| var d = 'disabled' | |
| , $el = this.$element | |
| , data = $el.data() | |
| , val = $el.is('input') ? 'val' : 'html' | |
| state = state + 'Text' | |
| data.resetText || $el.data('resetText', $el[val]()) | |
| $el[val](data[state] || this.options[state]) | |
| // push to event loop to allow forms to submit | |
| setTimeout(function () { | |
| state == 'loadingText' ? | |
| $el.addClass(d).attr(d, d) : | |
| $el.removeClass(d).removeAttr(d) | |
| }, 0) | |
| } | |
| Button.prototype.toggle = function () { | |
| var $parent = this.$element.closest('[data-toggle="buttons-radio"]') | |
| $parent && $parent | |
| .find('.active') | |
| .removeClass('active') | |
| this.$element.toggleClass('active') | |
| } | |
| /* BUTTON PLUGIN DEFINITION | |
| * ======================== */ | |
| var old = $.fn.button | |
| $.fn.button = function (option) { | |
| return this.each(function () { | |
| var $this = $(this) | |
| , data = $this.data('button') | |
| , options = typeof option == 'object' && option | |
| if (!data) $this.data('button', (data = new Button(this, options))) | |
| if (option == 'toggle') data.toggle() | |
| else if (option) data.setState(option) | |
| }) | |
| } | |
| $.fn.button.defaults = { | |
| loadingText: 'loading...' | |
| } | |
| $.fn.button.Constructor = Button | |
| /* BUTTON NO CONFLICT | |
| * ================== */ | |
| $.fn.button.noConflict = function () { | |
| $.fn.button = old | |
| return this | |
| } | |
| /* BUTTON DATA-API | |
| * =============== */ | |
| $(document).on('click.button.data-api', '[data-toggle^=button]', function (e) { | |
| var $btn = $(e.target) | |
| if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') | |
| $btn.button('toggle') | |
| }) | |
| }(window.jQuery);/* ========================================================== | |
| * bootstrap-carousel.js v2.2.2 | |
| * http://twitter.github.com/bootstrap/javascript.html#carousel | |
| * ========================================================== | |
| * Copyright 2012 Twitter, Inc. | |
| * | |
| * Licensed 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. | |
| * ========================================================== */ | |
| !function ($) { | |
| "use strict"; // jshint ;_; | |
| /* CAROUSEL CLASS DEFINITION | |
| * ========================= */ | |
| var Carousel = function (element, options) { | |
| this.$element = $(element) | |
| this.options = options | |
| this.options.pause == 'hover' && this.$element | |
| .on('mouseenter', $.proxy(this.pause, this)) | |
| .on('mouseleave', $.proxy(this.cycle, this)) | |
| } | |
| Carousel.prototype = { | |
| cycle: function (e) { | |
| if (!e) this.paused = false | |
| this.options.interval | |
| && !this.paused | |
| && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) | |
| return this | |
| } | |
| , to: function (pos) { | |
| var $active = this.$element.find('.item.active') | |
| , children = $active.parent().children() | |
| , activePos = children.index($active) | |
| , that = this | |
| if (pos > (children.length - 1) || pos < 0) return | |
| if (this.sliding) { | |
| return this.$element.one('slid', function () { | |
| that.to(pos) | |
| }) | |
| } | |
| if (activePos == pos) { | |
| return this.pause().cycle() | |
| } | |
| return this.slide(pos > activePos ? 'next' : 'prev', $(children[pos])) | |
| } | |
| , pause: function (e) { | |
| if (!e) this.paused = true | |
| if (this.$element.find('.next, .prev').length && $.support.transition.end) { | |
| this.$element.trigger($.support.transition.end) | |
| this.cycle() | |
| } | |
| clearInterval(this.interval) | |
| this.interval = null | |
| return this | |
| } | |
| , next: function () { | |
| if (this.sliding) return | |
| return this.slide('next') | |
| } | |
| , prev: function () { | |
| if (this.sliding) return | |
| return this.slide('prev') | |
| } | |
| , slide: function (type, next) { | |
| var $active = this.$element.find('.item.active') | |
| , $next = next || $active[type]() | |
| , isCycling = this.interval | |
| , direction = type == 'next' ? 'left' : 'right' | |
| , fallback = type == 'next' ? 'first' : 'last' | |
| , that = this | |
| , e | |
| this.sliding = true | |
| isCycling && this.pause() | |
| $next = $next.length ? $next : this.$element.find('.item')[fallback]() | |
| e = $.Event('slide', { | |
| relatedTarget: $next[0] | |
| }) | |
| if ($next.hasClass('active')) return | |
| if ($.support.transition && this.$element.hasClass('slide')) { | |
| this.$element.trigger(e) | |
| if (e.isDefaultPrevented()) return | |
| $next.addClass(type) | |
| $next[0].offsetWidth // force reflow | |
| $active.addClass(direction) | |
| $next.addClass(direction) | |
| this.$element.one($.support.transition.end, function () { | |
| $next.removeClass([type, direction].join(' ')).addClass('active') | |
| $active.removeClass(['active', direction].join(' ')) | |
| that.sliding = false | |
| setTimeout(function () { that.$element.trigger('slid') }, 0) | |
| }) | |
| } else { | |
| this.$element.trigger(e) | |
| if (e.isDefaultPrevented()) return | |
| $active.removeClass('active') | |
| $next.addClass('active') | |
| this.sliding = false | |
| this.$element.trigger('slid') | |
| } | |
| isCycling && this.cycle() | |
| return this | |
| } | |
| } | |
| /* CAROUSEL PLUGIN DEFINITION | |
| * ========================== */ | |
| var old = $.fn.carousel | |
| $.fn.carousel = function (option) { | |
| return this.each(function () { | |
| var $this = $(this) | |
| , data = $this.data('carousel') | |
| , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option) | |
| , action = typeof option == 'string' ? option : options.slide | |
| if (!data) $this.data('carousel', (data = new Carousel(this, options))) | |
| if (typeof option == 'number') data.to(option) | |
| else if (action) data[action]() | |
| else if (options.interval) data.cycle() | |
| }) | |
| } | |
| $.fn.carousel.defaults = { | |
| interval: 5000 | |
| , pause: 'hover' | |
| } | |
| $.fn.carousel.Constructor = Carousel | |
| /* CAROUSEL NO CONFLICT | |
| * ==================== */ | |
| $.fn.carousel.noConflict = function () { | |
| $.fn.carousel = old | |
| return this | |
| } | |
| /* CAROUSEL DATA-API | |
| * ================= */ | |
| $(document).on('click.carousel.data-api', '[data-slide]', function (e) { | |
| var $this = $(this), href | |
| , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7 | |
| , options = $.extend({}, $target.data(), $this.data()) | |
| $target.carousel(options) | |
| e.preventDefault() | |
| }) | |
| }(window.jQuery);/* ============================================================= | |
| * bootstrap-collapse.js v2.2.2 | |
| * http://twitter.github.com/bootstrap/javascript.html#collapse | |
| * ============================================================= | |
| * Copyright 2012 Twitter, Inc. | |
| * | |
| * Licensed 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. | |
| * ============================================================ */ | |
| !function ($) { | |
| "use strict"; // jshint ;_; | |
| /* COLLAPSE PUBLIC CLASS DEFINITION | |
| * ================================ */ | |
| var Collapse = function (element, options) { | |
| this.$element = $(element) | |
| this.options = $.extend({}, $.fn.collapse.defaults, options) | |
| if (this.options.parent) { | |
| this.$parent = $(this.options.parent) | |
| } | |
| this.options.toggle && this.toggle() | |
| } | |
| Collapse.prototype = { | |
| constructor: Collapse | |
| , dimension: function () { | |
| var hasWidth = this.$element.hasClass('width') | |
| return hasWidth ? 'width' : 'height' | |
| } | |
| , show: function () { | |
| var dimension | |
| , scroll | |
| , actives | |
| , hasData | |
| if (this.transitioning) return | |
| dimension = this.dimension() | |
| scroll = $.camelCase(['scroll', dimension].join('-')) | |
| actives = this.$parent && this.$parent.find('> .accordion-group > .in') | |
| if (actives && actives.length) { | |
| hasData = actives.data('collapse') | |
| if (hasData && hasData.transitioning) return | |
| actives.collapse('hide') | |
| hasData || actives.data('collapse', null) | |
| } | |
| this.$element[dimension](0) | |
| this.transition('addClass', $.Event('show'), 'shown') | |
| $.support.transition && this.$element[dimension](this.$element[0][scroll]) | |
| } | |
| , hide: function () { | |
| var dimension | |
| if (this.transitioning) return | |
| dimension = this.dimension() | |
| this.reset(this.$element[dimension]()) | |
| this.transition('removeClass', $.Event('hide'), 'hidden') | |
| this.$element[dimension](0) | |
| } | |
| , reset: function (size) { | |
| var dimension = this.dimension() | |
| this.$element | |
| .removeClass('collapse') | |
| [dimension](size || 'auto') | |
| [0].offsetWidth | |
| this.$element[size !== null ? 'addClass' : 'removeClass']('collapse') | |
| return this | |
| } | |
| , transition: function (method, startEvent, completeEvent) { | |
| var that = this | |
| , complete = function () { | |
| if (startEvent.type == 'show') that.reset() | |
| that.transitioning = 0 | |
| that.$element.trigger(completeEvent) | |
| } | |
| this.$element.trigger(startEvent) | |
| if (startEvent.isDefaultPrevented()) return | |
| this.transitioning = 1 | |
| this.$element[method]('in') | |
| $.support.transition && this.$element.hasClass('collapse') ? | |
| this.$element.one($.support.transition.end, complete) : | |
| complete() | |
| } | |
| , toggle: function () { | |
| this[this.$element.hasClass('in') ? 'hide' : 'show']() | |
| } | |
| } | |
| /* COLLAPSE PLUGIN DEFINITION | |
| * ========================== */ | |
| var old = $.fn.collapse | |
| $.fn.collapse = function (option) { | |
| return this.each(function () { | |
| var $this = $(this) | |
| , data = $this.data('collapse') | |
| , options = typeof option == 'object' && option | |
| if (!data) $this.data('collapse', (data = new Collapse(this, options))) | |
| if (typeof option == 'string') data[option]() | |
| }) | |
| } | |
| $.fn.collapse.defaults = { | |
| toggle: true | |
| } | |
| $.fn.collapse.Constructor = Collapse | |
| /* COLLAPSE NO CONFLICT | |
| * ==================== */ | |
| $.fn.collapse.noConflict = function () { | |
| $.fn.collapse = old | |
| return this | |
| } | |
| /* COLLAPSE DATA-API | |
| * ================= */ | |
| $(document).on('click.collapse.data-api', '[data-toggle=collapse]', function (e) { | |
| var $this = $(this), href | |
| , target = $this.attr('data-target') | |
| || e.preventDefault() | |
| || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 | |
| , option = $(target).data('collapse') ? 'toggle' : $this.data() | |
| $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed') | |
| $(target).collapse(option) | |
| }) | |
| }(window.jQuery);/* ============================================================ | |
| * bootstrap-dropdown.js v2.2.2 | |
| * http://twitter.github.com/bootstrap/javascript.html#dropdowns | |
| * ============================================================ | |
| * Copyright 2012 Twitter, Inc. | |
| * | |
| * Licensed 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. | |
| * ============================================================ */ | |
| !function ($) { | |
| "use strict"; // jshint ;_; | |
| /* DROPDOWN CLASS DEFINITION | |
| * ========================= */ | |
| var toggle = '[data-toggle=dropdown]' | |
| , Dropdown = function (element) { | |
| var $el = $(element).on('click.dropdown.data-api', this.toggle) | |
| $('html').on('click.dropdown.data-api', function () { | |
| $el.parent().removeClass('open') | |
| }) | |
| } | |
| Dropdown.prototype = { | |
| constructor: Dropdown | |
| , toggle: function (e) { | |
| var $this = $(this) | |
| , $parent | |
| , isActive | |
| if ($this.is('.disabled, :disabled')) return | |
| $parent = getParent($this) | |
| isActive = $parent.hasClass('open') | |
| clearMenus() | |
| if (!isActive) { | |
| $parent.toggleClass('open') | |
| } | |
| $this.focus() | |
| return false | |
| } | |
| , keydown: function (e) { | |
| var $this | |
| , $items | |
| , $active | |
| , $parent | |
| , isActive | |
| , index | |
| if (!/(38|40|27)/.test(e.keyCode)) return | |
| $this = $(this) | |
| e.preventDefault() | |
| e.stopPropagation() | |
| if ($this.is('.disabled, :disabled')) return | |
| $parent = getParent($this) | |
| isActive = $parent.hasClass('open') | |
| if (!isActive || (isActive && e.keyCode == 27)) return $this.click() | |
| $items = $('[role=menu] li:not(.divider):visible a', $parent) | |
| if (!$items.length) return | |
| index = $items.index($items.filter(':focus')) | |
| if (e.keyCode == 38 && index > 0) index-- // up | |
| if (e.keyCode == 40 && index < $items.length - 1) index++ // down | |
| if (!~index) index = 0 | |
| $items | |
| .eq(index) | |
| .focus() | |
| } | |
| } | |
| function clearMenus() { | |
| $(toggle).each(function () { | |
| getParent($(this)).removeClass('open') | |
| }) | |
| } | |
| function getParent($this) { | |
| var selector = $this.attr('data-target') | |
| , $parent | |
| if (!selector) { | |
| selector = $this.attr('href') | |
| selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 | |
| } | |
| $parent = $(selector) | |
| $parent.length || ($parent = $this.parent()) | |
| return $parent | |
| } | |
| /* DROPDOWN PLUGIN DEFINITION | |
| * ========================== */ | |
| var old = $.fn.dropdown | |
| $.fn.dropdown = function (option) { | |
| return this.each(function () { | |
| var $this = $(this) | |
| , data = $this.data('dropdown') | |
| if (!data) $this.data('dropdown', (data = new Dropdown(this))) | |
| if (typeof option == 'string') data[option].call($this) | |
| }) | |
| } | |
| $.fn.dropdown.Constructor = Dropdown | |
| /* DROPDOWN NO CONFLICT | |
| * ==================== */ | |
| $.fn.dropdown.noConflict = function () { | |
| $.fn.dropdown = old | |
| return this | |
| } | |
| /* APPLY TO STANDARD DROPDOWN ELEMENTS | |
| * =================================== */ | |
| $(document) | |
| .on('click.dropdown.data-api touchstart.dropdown.data-api', clearMenus) | |
| .on('click.dropdown touchstart.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) | |
| .on('touchstart.dropdown.data-api', '.dropdown-menu', function (e) { e.stopPropagation() }) | |
| .on('click.dropdown.data-api touchstart.dropdown.data-api' , toggle, Dropdown.prototype.toggle) | |
| .on('keydown.dropdown.data-api touchstart.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown) | |
| }(window.jQuery);/* ========================================================= | |
| * bootstrap-modal.js v2.2.2 | |
| * http://twitter.github.com/bootstrap/javascript.html#modals | |
| * ========================================================= | |
| * Copyright 2012 Twitter, Inc. | |
| * | |
| * Licensed 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. | |
| * ========================================================= */ | |
| !function ($) { | |
| "use strict"; // jshint ;_; | |
| /* MODAL CLASS DEFINITION | |
| * ====================== */ | |
| var Modal = function (element, options) { | |
| this.options = options | |
| this.$element = $(element) | |
| .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this)) | |
| this.options.remote && this.$element.find('.modal-body').load(this.options.remote) | |
| } | |
| Modal.prototype = { | |
| constructor: Modal | |
| , toggle: function () { | |
| return this[!this.isShown ? 'show' : 'hide']() | |
| } | |
| , show: function () { | |
| var that = this | |
| , e = $.Event('show') | |
| this.$element.trigger(e) | |
| if (this.isShown || e.isDefaultPrevented()) return | |
| this.isShown = true | |
| this.escape() | |
| this.backdrop(function () { | |
| var transition = $.support.transition && that.$element.hasClass('fade') | |
| if (!that.$element.parent().length) { | |
| that.$element.appendTo(document.body) //don't move modals dom position | |
| } | |
| that.$element | |
| .show() | |
| if (transition) { | |
| that.$element[0].offsetWidth // force reflow | |
| } | |
| that.$element | |
| .addClass('in') | |
| .attr('aria-hidden', false) | |
| that.enforceFocus() | |
| transition ? | |
| that.$element.one($.support.transition.end, function () { that.$element.focus().trigger('shown') }) : | |
| that.$element.focus().trigger('shown') | |
| }) | |
| } | |
| , hide: function (e) { | |
| e && e.preventDefault() | |
| var that = this | |
| e = $.Event('hide') | |
| this.$element.trigger(e) | |
| if (!this.isShown || e.isDefaultPrevented()) return | |
| this.isShown = false | |
| this.escape() | |
| $(document).off('focusin.modal') | |
| this.$element | |
| .removeClass('in') | |
| .attr('aria-hidden', true) | |
| $.support.transition && this.$element.hasClass('fade') ? | |
| this.hideWithTransition() : | |
| this.hideModal() | |
| } | |
| , enforceFocus: function () { | |
| var that = this | |
| $(document).on('focusin.modal', function (e) { | |
| if (that.$element[0] !== e.target && !that.$element.has(e.target).length) { | |
| that.$element.focus() | |
| } | |
| }) | |
| } | |
| , escape: function () { | |
| var that = this | |
| if (this.isShown && this.options.keyboard) { | |
| this.$element.on('keyup.dismiss.modal', function ( e ) { | |
| e.which == 27 && that.hide() | |
| }) | |
| } else if (!this.isShown) { | |
| this.$element.off('keyup.dismiss.modal') | |
| } | |
| } | |
| , hideWithTransition: function () { | |
| var that = this | |
| , timeout = setTimeout(function () { | |
| that.$element.off($.support.transition.end) | |
| that.hideModal() | |
| }, 500) | |
| this.$element.one($.support.transition.end, function () { | |
| clearTimeout(timeout) | |
| that.hideModal() | |
| }) | |
| } | |
| , hideModal: function (that) { | |
| this.$element | |
| .hide() | |
| .trigger('hidden') | |
| this.backdrop() | |
| } | |
| , removeBackdrop: function () { | |
| this.$backdrop.remove() | |
| this.$backdrop = null | |
| } | |
| , backdrop: function (callback) { | |
| var that = this | |
| , animate = this.$element.hasClass('fade') ? 'fade' : '' | |
| if (this.isShown && this.options.backdrop) { | |
| var doAnimate = $.support.transition && animate | |
| this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />') | |
| .appendTo(document.body) | |
| this.$backdrop.click( | |
| this.options.backdrop == 'static' ? | |
| $.proxy(this.$element[0].focus, this.$element[0]) | |
| : $.proxy(this.hide, this) | |
| ) | |
| if (doAnimate) this.$backdrop[0].offsetWidth // force reflow | |
| this.$backdrop.addClass('in') | |
| doAnimate ? | |
| this.$backdrop.one($.support.transition.end, callback) : | |
| callback() | |
| } else if (!this.isShown && this.$backdrop) { | |
| this.$backdrop.removeClass('in') | |
| $.support.transition && this.$element.hasClass('fade')? | |
| this.$backdrop.one($.support.transition.end, $.proxy(this.removeBackdrop, this)) : | |
| this.removeBackdrop() | |
| } else if (callback) { | |
| callback() | |
| } | |
| } | |
| } | |
| /* MODAL PLUGIN DEFINITION | |
| * ======================= */ | |
| var old = $.fn.modal | |
| $.fn.modal = function (option) { | |
| return this.each(function () { | |
| var $this = $(this) | |
| , data = $this.data('modal') | |
| , options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option) | |
| if (!data) $this.data('modal', (data = new Modal(this, options))) | |
| if (typeof option == 'string') data[option]() | |
| else if (options.show) data.show() | |
| }) | |
| } | |
| $.fn.modal.defaults = { | |
| backdrop: true | |
| , keyboard: true | |
| , show: true | |
| } | |
| $.fn.modal.Constructor = Modal | |
| /* MODAL NO CONFLICT | |
| * ================= */ | |
| $.fn.modal.noConflict = function () { | |
| $.fn.modal = old | |
| return this | |
| } | |
| /* MODAL DATA-API | |
| * ============== */ | |
| $(document).on('click.modal.data-api', '[data-toggle="modal"]', function (e) { | |
| var $this = $(this) | |
| , href = $this.attr('href') | |
| , $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7 | |
| , option = $target.data('modal') ? 'toggle' : $.extend({ remote:!/#/.test(href) && href }, $target.data(), $this.data()) | |
| e.preventDefault() | |
| $target | |
| .modal(option) | |
| .one('hide', function () { | |
| $this.focus() | |
| }) | |
| }) | |
| }(window.jQuery); | |
| /* =========================================================== | |
| * bootstrap-tooltip.js v2.2.2 | |
| * http://twitter.github.com/bootstrap/javascript.html#tooltips | |
| * Inspired by the original jQuery.tipsy by Jason Frame | |
| * =========================================================== | |
| * Copyright 2012 Twitter, Inc. | |
| * | |
| * Licensed 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. | |
| * ========================================================== */ | |
| !function ($) { | |
| "use strict"; // jshint ;_; | |
| /* TOOLTIP PUBLIC CLASS DEFINITION | |
| * =============================== */ | |
| var Tooltip = function (element, options) { | |
| this.init('tooltip', element, options) | |
| } | |
| Tooltip.prototype = { | |
| constructor: Tooltip | |
| , init: function (type, element, options) { | |
| var eventIn | |
| , eventOut | |
| this.type = type | |
| this.$element = $(element) | |
| this.options = this.getOptions(options) | |
| this.enabled = true | |
| if (this.options.trigger == 'click') { | |
| this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) | |
| } else if (this.options.trigger != 'manual') { | |
| eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus' | |
| eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur' | |
| 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() | |
| } | |
| , getOptions: function (options) { | |
| options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data()) | |
| if (options.delay && typeof options.delay == 'number') { | |
| options.delay = { | |
| show: options.delay | |
| , hide: options.delay | |
| } | |
| } | |
| return options | |
| } | |
| , enter: function (e) { | |
| var self = $(e.currentTarget)[this.type](this._options).data(this.type) | |
| if (!self.options.delay || !self.options.delay.show) return self.show() | |
| clearTimeout(this.timeout) | |
| self.hoverState = 'in' | |
| this.timeout = setTimeout(function() { | |
| if (self.hoverState == 'in') self.show() | |
| }, self.options.delay.show) | |
| } | |
| , leave: function (e) { | |
| var self = $(e.currentTarget)[this.type](this._options).data(this.type) | |
| if (this.timeout) clearTimeout(this.timeout) | |
| if (!self.options.delay || !self.options.delay.hide) return self.hide() | |
| self.hoverState = 'out' | |
| this.timeout = setTimeout(function() { | |
| if (self.hoverState == 'out') self.hide() | |
| }, self.options.delay.hide) | |
| } | |
| , show: function () { | |
| var $tip | |
| , inside | |
| , pos | |
| , actualWidth | |
| , actualHeight | |
| , placement | |
| , tp | |
| if (this.hasContent() && this.enabled) { | |
| $tip = this.tip() | |
| this.setContent() | |
| if (this.options.animation) { | |
| $tip.addClass('fade') | |
| } | |
| placement = typeof this.options.placement == 'function' ? | |
| this.options.placement.call(this, $tip[0], this.$element[0]) : | |
| this.options.placement | |
| inside = /in/.test(placement) | |
| $tip | |
| .detach() | |
| .css({ top: 0, left: 0, display: 'block' }) | |
| .insertAfter(this.$element) | |
| pos = this.getPosition(inside) | |
| actualWidth = $tip[0].offsetWidth | |
| actualHeight = $tip[0].offsetHeight | |
| switch (inside ? placement.split(' ')[1] : placement) { | |
| case 'bottom': | |
| tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2} | |
| break | |
| case 'top': | |
| tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2} | |
| break | |
| case 'left': | |
| tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth} | |
| break | |
| case 'right': | |
| tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width} | |
| break | |
| } | |
| $tip | |
| .offset(tp) | |
| .addClass(placement) | |
| .addClass('in') | |
| } | |
| } | |
| , setContent: function () { | |
| var $tip = this.tip() | |
| , title = this.getTitle() | |
| $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) | |
| $tip.removeClass('fade in top bottom left right') | |
| } | |
| , hide: function () { | |
| var that = this | |
| , $tip = this.tip() | |
| $tip.removeClass('in') | |
| function removeWithAnimation() { | |
| var timeout = setTimeout(function () { | |
| $tip.off($.support.transition.end).detach() | |
| }, 500) | |
| $tip.one($.support.transition.end, function () { | |
| clearTimeout(timeout) | |
| $tip.detach() | |
| }) | |
| } | |
| $.support.transition && this.$tip.hasClass('fade') ? | |
| removeWithAnimation() : | |
| $tip.detach() | |
| return this | |
| } | |
| , 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') || '').removeAttr('title') | |
| } | |
| } | |
| , hasContent: function () { | |
| return this.getTitle() | |
| } | |
| , getPosition: function (inside) { | |
| return $.extend({}, (inside ? {top: 0, left: 0} : this.$element.offset()), { | |
| width: this.$element[0].offsetWidth | |
| , height: this.$element[0].offsetHeight | |
| }) | |
| } | |
| , getTitle: function () { | |
| var title | |
| , $e = this.$element | |
| , o = this.options | |
| title = $e.attr('data-original-title') | |
| || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) | |
| return title | |
| } | |
| , tip: function () { | |
| return this.$tip = this.$tip || $(this.options.template) | |
| } | |
| , validate: function () { | |
| if (!this.$element[0].parentNode) { | |
| this.hide() | |
| this.$element = null | |
| this.options = null | |
| } | |
| } | |
| , enable: function () { | |
| this.enabled = true | |
| } | |
| , disable: function () { | |
| this.enabled = false | |
| } | |
| , toggleEnabled: function () { | |
| this.enabled = !this.enabled | |
| } | |
| , toggle: function (e) { | |
| var self = $(e.currentTarget)[this.type](this._options).data(this.type) | |
| self[self.tip().hasClass('in') ? 'hide' : 'show']() | |
| } | |
| , destroy: function () { | |
| this.hide().$element.off('.' + this.type).removeData(this.type) | |
| } | |
| } | |
| /* TOOLTIP PLUGIN DEFINITION | |
| * ========================= */ | |
| var old = $.fn.tooltip | |
| $.fn.tooltip = function ( option ) { | |
| return this.each(function () { | |
| var $this = $(this) | |
| , data = $this.data('tooltip') | |
| , options = typeof option == 'object' && option | |
| if (!data) $this.data('tooltip', (data = new Tooltip(this, options))) | |
| if (typeof option == 'string') data[option]() | |
| }) | |
| } | |
| $.fn.tooltip.Constructor = Tooltip | |
| $.fn.tooltip.defaults = { | |
| animation: true | |
| , placement: 'top' | |
| , selector: false | |
| , template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>' | |
| , trigger: 'hover' | |
| , title: '' | |
| , delay: 0 | |
| , html: false | |
| } | |
| /* TOOLTIP NO CONFLICT | |
| * =================== */ | |
| $.fn.tooltip.noConflict = function () { | |
| $.fn.tooltip = old | |
| return this | |
| } | |
| }(window.jQuery);/* =========================================================== | |
| * bootstrap-popover.js v2.2.2 | |
| * http://twitter.github.com/bootstrap/javascript.html#popovers | |
| * =========================================================== | |
| * Copyright 2012 Twitter, Inc. | |
| * | |
| * Licensed 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. | |
| * =========================================================== */ | |
| !function ($) { | |
| "use strict"; // jshint ;_; | |
| /* POPOVER PUBLIC CLASS DEFINITION | |
| * =============================== */ | |
| var Popover = function (element, options) { | |
| this.init('popover', element, options) | |
| } | |
| /* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js | |
| ========================================== */ | |
| Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, { | |
| constructor: Popover | |
| , setContent: function () { | |
| var $tip = this.tip() | |
| , title = this.getTitle() | |
| , content = this.getContent() | |
| $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title) | |
| $tip.find('.popover-content')[this.options.html ? 'html' : 'text'](content) | |
| $tip.removeClass('fade top bottom left right in') | |
| } | |
| , hasContent: function () { | |
| return this.getTitle() || this.getContent() | |
| } | |
| , getContent: function () { | |
| var content | |
| , $e = this.$element | |
| , o = this.options | |
| content = $e.attr('data-content') | |
| || (typeof o.content == 'function' ? o.content.call($e[0]) : o.content) | |
| return content | |
| } | |
| , tip: function () { | |
| if (!this.$tip) { | |
| this.$tip = $(this.options.template) | |
| } | |
| return this.$tip | |
| } | |
| , destroy: function () { | |
| this.hide().$element.off('.' + this.type).removeData(this.type) | |
| } | |
| }) | |
| /* POPOVER PLUGIN DEFINITION | |
| * ======================= */ | |
| var old = $.fn.popover | |
| $.fn.popover = function (option) { | |
| return this.each(function () { | |
| var $this = $(this) | |
| , data = $this.data('popover') | |
| , options = typeof option == 'object' && option | |
| if (!data) $this.data('popover', (data = new Popover(this, options))) | |
| if (typeof option == 'string') data[option]() | |
| }) | |
| } | |
| $.fn.popover.Constructor = Popover | |
| $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, { | |
| placement: 'right' | |
| , trigger: 'click' | |
| , content: '' | |
| , template: '<div class="popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"></div></div></div>' | |
| }) | |
| /* POPOVER NO CONFLICT | |
| * =================== */ | |
| $.fn.popover.noConflict = function () { | |
| $.fn.popover = old | |
| return this | |
| } | |
| }(window.jQuery);/* ============================================================= | |
| * bootstrap-scrollspy.js v2.2.2 | |
| * http://twitter.github.com/bootstrap/javascript.html#scrollspy | |
| * ============================================================= | |
| * Copyright 2012 Twitter, Inc. | |
| * | |
| * Licensed 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. | |
| * ============================================================== */ | |
| !function ($) { | |
| "use strict"; // jshint ;_; | |
| /* SCROLLSPY CLASS DEFINITION | |
| * ========================== */ | |
| function ScrollSpy(element, options) { | |
| var process = $.proxy(this.process, this) | |
| , $element = $(element).is('body') ? $(window) : $(element) | |
| , href | |
| this.options = $.extend({}, $.fn.scrollspy.defaults, options) | |
| this.$scrollElement = $element.on('scroll.scroll-spy.data-api', process) | |
| this.selector = (this.options.target | |
| || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7 | |
| || '') + ' .nav li > a' | |
| this.$body = $('body') | |
| this.refresh() | |
| this.process() | |
| } | |
| ScrollSpy.prototype = { | |
| constructor: ScrollSpy | |
| , refresh: function () { | |
| var self = this | |
| , $targets | |
| this.offsets = $([]) | |
| this.targets = $([]) | |
| $targets = this.$body | |
| .find(this.selector) | |
| .map(function () { | |
| var $el = $(this) | |
| , href = $el.data('target') || $el.attr('href') | |
| , $href = /^#\w/.test(href) && $(href) | |
| return ( $href | |
| && $href.length | |
| && [[ $href.position().top + self.$scrollElement.scrollTop(), href ]] ) || null | |
| }) | |
| .sort(function (a, b) { return a[0] - b[0] }) | |
| .each(function () { | |
| self.offsets.push(this[0]) | |
| self.targets.push(this[1]) | |
| }) | |
| } | |
| , process: function () { | |
| var scrollTop = this.$scrollElement.scrollTop() + this.options.offset | |
| , scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight | |
| , maxScroll = scrollHeight - this.$scrollElement.height() | |
| , offsets = this.offsets | |
| , targets = this.targets | |
| , activeTarget = this.activeTarget | |
| , i | |
| if (scrollTop >= maxScroll) { | |
| return activeTarget != (i = targets.last()[0]) | |
| && this.activate ( i ) | |
| } | |
| for (i = offsets.length; i--;) { | |
| activeTarget != targets[i] | |
| && scrollTop >= offsets[i] | |
| && (!offsets[i + 1] || scrollTop <= offsets[i + 1]) | |
| && this.activate( targets[i] ) | |
| } | |
| } | |
| , activate: function (target) { | |
| var active | |
| , selector | |
| this.activeTarget = target | |
| $(this.selector) | |
| .parent('.active') | |
| .removeClass('active') | |
| selector = this.selector | |
| + '[data-target="' + target + '"],' | |
| + this.selector + '[href="' + target + '"]' | |
| active = $(selector) | |
| .parent('li') | |
| .addClass('active') | |
| if (active.parent('.dropdown-menu').length) { | |
| active = active.closest('li.dropdown').addClass('active') | |
| } | |
| active.trigger('activate') | |
| } | |
| } | |
| /* SCROLLSPY PLUGIN DEFINITION | |
| * =========================== */ | |
| var old = $.fn.scrollspy | |
| $.fn.scrollspy = function (option) { | |
| return this.each(function () { | |
| var $this = $(this) | |
| , data = $this.data('scrollspy') | |
| , options = typeof option == 'object' && option | |
| if (!data) $this.data('scrollspy', (data = new ScrollSpy(this, options))) | |
| if (typeof option == 'string') data[option]() | |
| }) | |
| } | |
| $.fn.scrollspy.Constructor = ScrollSpy | |
| $.fn.scrollspy.defaults = { | |
| offset: 10 | |
| } | |
| /* SCROLLSPY NO CONFLICT | |
| * ===================== */ | |
| $.fn.scrollspy.noConflict = function () { | |
| $.fn.scrollspy = old | |
| return this | |
| } | |
| /* SCROLLSPY DATA-API | |
| * ================== */ | |
| $(window).on('load', function () { | |
| $('[data-spy="scroll"]').each(function () { | |
| var $spy = $(this) | |
| $spy.scrollspy($spy.data()) | |
| }) | |
| }) | |
| }(window.jQuery);/* ======================================================== | |
| * bootstrap-tab.js v2.2.2 | |
| * http://twitter.github.com/bootstrap/javascript.html#tabs | |
| * ======================================================== | |
| * Copyright 2012 Twitter, Inc. | |
| * | |
| * Licensed 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. | |
| * ======================================================== */ | |
| !function ($) { | |
| "use strict"; // jshint ;_; | |
| /* TAB CLASS DEFINITION | |
| * ==================== */ | |
| var Tab = function (element) { | |
| this.element = $(element) | |
| } | |
| Tab.prototype = { | |
| constructor: Tab | |
| , show: function () { | |
| var $this = this.element | |
| , $ul = $this.closest('ul:not(.dropdown-menu)') | |
| , selector = $this.attr('data-target') | |
| , previous | |
| , $target | |
| , e | |
| if (!selector) { | |
| selector = $this.attr('href') | |
| selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 | |
| } | |
| if ( $this.parent('li').hasClass('active') ) return | |
| previous = $ul.find('.active:last a')[0] | |
| e = $.Event('show', { | |
| relatedTarget: previous | |
| }) | |
| $this.trigger(e) | |
| if (e.isDefaultPrevented()) return | |
| $target = $(selector) | |
| this.activate($this.parent('li'), $ul) | |
| this.activate($target, $target.parent(), function () { | |
| $this.trigger({ | |
| type: 'shown' | |
| , relatedTarget: previous | |
| }) | |
| }) | |
| } | |
| , activate: function ( element, container, callback) { | |
| var $active = container.find('> .active') | |
| , transition = callback | |
| && $.support.transition | |
| && $active.hasClass('fade') | |
| function next() { | |
| $active | |
| .removeClass('active') | |
| .find('> .dropdown-menu > .active') | |
| .removeClass('active') | |
| element.addClass('active') | |
| if (transition) { | |
| element[0].offsetWidth // reflow for transition | |
| element.addClass('in') | |
| } else { | |
| element.removeClass('fade') | |
| } | |
| if ( element.parent('.dropdown-menu') ) { | |
| element.closest('li.dropdown').addClass('active') | |
| } | |
| callback && callback() | |
| } | |
| transition ? | |
| $active.one($.support.transition.end, next) : | |
| next() | |
| $active.removeClass('in') | |
| } | |
| } | |
| /* TAB PLUGIN DEFINITION | |
| * ===================== */ | |
| var old = $.fn.tab | |
| $.fn.tab = function ( option ) { | |
| return this.each(function () { | |
| var $this = $(this) | |
| , data = $this.data('tab') | |
| if (!data) $this.data('tab', (data = new Tab(this))) | |
| if (typeof option == 'string') data[option]() | |
| }) | |
| } | |
| $.fn.tab.Constructor = Tab | |
| /* TAB NO CONFLICT | |
| * =============== */ | |
| $.fn.tab.noConflict = function () { | |
| $.fn.tab = old | |
| return this | |
| } | |
| /* TAB DATA-API | |
| * ============ */ | |
| $(document).on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) { | |
| e.preventDefault() | |
| $(this).tab('show') | |
| }) | |
| }(window.jQuery);/* ============================================================= | |
| * bootstrap-typeahead.js v2.2.2 | |
| * http://twitter.github.com/bootstrap/javascript.html#typeahead | |
| * ============================================================= | |
| * Copyright 2012 Twitter, Inc. | |
| * | |
| * Licensed 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. | |
| * ============================================================ */ | |
| !function($){ | |
| "use strict"; // jshint ;_; | |
| /* TYPEAHEAD PUBLIC CLASS DEFINITION | |
| * ================================= */ | |
| var Typeahead = function (element, options) { | |
| this.$element = $(element) | |
| this.options = $.extend({}, $.fn.typeahead.defaults, options) | |
| this.matcher = this.options.matcher || this.matcher | |
| this.sorter = this.options.sorter || this.sorter | |
| this.highlighter = this.options.highlighter || this.highlighter | |
| this.updater = this.options.updater || this.updater | |
| this.source = this.options.source | |
| this.$menu = $(this.options.menu) | |
| this.shown = false | |
| this.listen() | |
| } | |
| Typeahead.prototype = { | |
| constructor: Typeahead | |
| , select: function () { | |
| var val = this.$menu.find('.active').attr('data-value') | |
| this.$element | |
| .val(this.updater(val)) | |
| .change() | |
| return this.hide() | |
| } | |
| , updater: function (item) { | |
| return item | |
| } | |
| , show: function () { | |
| var pos = $.extend({}, this.$element.position(), { | |
| height: this.$element[0].offsetHeight | |
| }) | |
| this.$menu | |
| .insertAfter(this.$element) | |
| .css({ | |
| top: pos.top + pos.height | |
| , left: pos.left | |
| }) | |
| .show() | |
| this.shown = true | |
| return this | |
| } | |
| , hide: function () { | |
| this.$menu.hide() | |
| this.shown = false | |
| return this | |
| } | |
| , lookup: function (event) { | |
| var items | |
| this.query = this.$element.val() | |
| if (!this.query || this.query.length < this.options.minLength) { | |
| return this.shown ? this.hide() : this | |
| } | |
| items = $.isFunction(this.source) ? this.source(this.query, $.proxy(this.process, this)) : this.source | |
| return items ? this.process(items) : this | |
| } | |
| , process: function (items) { | |
| var that = this | |
| items = $.grep(items, function (item) { | |
| return that.matcher(item) | |
| }) | |
| items = this.sorter(items) | |
| if (!items.length) { | |
| return this.shown ? this.hide() : this | |
| } | |
| return this.render(items.slice(0, this.options.items)).show() | |
| } | |
| , matcher: function (item) { | |
| return ~item.toLowerCase().indexOf(this.query.toLowerCase()) | |
| } | |
| , sorter: function (items) { | |
| var beginswith = [] | |
| , caseSensitive = [] | |
| , caseInsensitive = [] | |
| , item | |
| while (item = items.shift()) { | |
| if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item) | |
| else if (~item.indexOf(this.query)) caseSensitive.push(item) | |
| else caseInsensitive.push(item) | |
| } | |
| return beginswith.concat(caseSensitive, caseInsensitive) | |
| } | |
| , highlighter: function (item) { | |
| var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&') | |
| return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) { | |
| return '<strong>' + match + '</strong>' | |
| }) | |
| } | |
| , render: function (items) { | |
| var that = this | |
| items = $(items).map(function (i, item) { | |
| i = $(that.options.item).attr('data-value', item) | |
| i.find('a').html(that.highlighter(item)) | |
| return i[0] | |
| }) | |
| items.first().addClass('active') | |
| this.$menu.html(items) | |
| return this | |
| } | |
| , next: function (event) { | |
| var active = this.$menu.find('.active').removeClass('active') | |
| , next = active.next() | |
| if (!next.length) { | |
| next = $(this.$menu.find('li')[0]) | |
| } | |
| next.addClass('active') | |
| } | |
| , prev: function (event) { | |
| var active = this.$menu.find('.active').removeClass('active') | |
| , prev = active.prev() | |
| if (!prev.length) { | |
| prev = this.$menu.find('li').last() | |
| } | |
| prev.addClass('active') | |
| } | |
| , listen: function () { | |
| this.$element | |
| .on('blur', $.proxy(this.blur, this)) | |
| .on('keypress', $.proxy(this.keypress, this)) | |
| .on('keyup', $.proxy(this.keyup, this)) | |
| if (this.eventSupported('keydown')) { | |
| this.$element.on('keydown', $.proxy(this.keydown, this)) | |
| } | |
| this.$menu | |
| .on('click', $.proxy(this.click, this)) | |
| .on('mouseenter', 'li', $.proxy(this.mouseenter, this)) | |
| } | |
| , eventSupported: function(eventName) { | |
| var isSupported = eventName in this.$element | |
| if (!isSupported) { | |
| this.$element.setAttribute(eventName, 'return;') | |
| isSupported = typeof this.$element[eventName] === 'function' | |
| } | |
| return isSupported | |
| } | |
| , move: function (e) { | |
| if (!this.shown) return | |
| switch(e.keyCode) { | |
| case 9: // tab | |
| case 13: // enter | |
| case 27: // escape | |
| e.preventDefault() | |
| break | |
| case 38: // up arrow | |
| e.preventDefault() | |
| this.prev() | |
| break | |
| case 40: // down arrow | |
| e.preventDefault() | |
| this.next() | |
| break | |
| } | |
| e.stopPropagation() | |
| } | |
| , keydown: function (e) { | |
| this.suppressKeyPressRepeat = ~$.inArray(e.keyCode, [40,38,9,13,27]) | |
| this.move(e) | |
| } | |
| , keypress: function (e) { | |
| if (this.suppressKeyPressRepeat) return | |
| this.move(e) | |
| } | |
| , keyup: function (e) { | |
| switch(e.keyCode) { | |
| case 40: // down arrow | |
| case 38: // up arrow | |
| case 16: // shift | |
| case 17: // ctrl | |
| case 18: // alt | |
| break | |
| case 9: // tab | |
| case 13: // enter | |
| if (!this.shown) return | |
| this.select() | |
| break | |
| case 27: // escape | |
| if (!this.shown) return | |
| this.hide() | |
| break | |
| default: | |
| this.lookup() | |
| } | |
| e.stopPropagation() | |
| e.preventDefault() | |
| } | |
| , blur: function (e) { | |
| var that = this | |
| setTimeout(function () { that.hide() }, 150) | |
| } | |
| , click: function (e) { | |
| e.stopPropagation() | |
| e.preventDefault() | |
| this.select() | |
| } | |
| , mouseenter: function (e) { | |
| this.$menu.find('.active').removeClass('active') | |
| $(e.currentTarget).addClass('active') | |
| } | |
| } | |
| /* TYPEAHEAD PLUGIN DEFINITION | |
| * =========================== */ | |
| var old = $.fn.typeahead | |
| $.fn.typeahead = function (option) { | |
| return this.each(function () { | |
| var $this = $(this) | |
| , data = $this.data('typeahead') | |
| , options = typeof option == 'object' && option | |
| if (!data) $this.data('typeahead', (data = new Typeahead(this, options))) | |
| if (typeof option == 'string') data[option]() | |
| }) | |
| } | |
| $.fn.typeahead.defaults = { | |
| source: [] | |
| , items: 8 | |
| , menu: '<ul class="typeahead dropdown-menu"></ul>' | |
| , item: '<li><a href="#"></a></li>' | |
| , minLength: 1 | |
| } | |
| $.fn.typeahead.Constructor = Typeahead | |
| /* TYPEAHEAD NO CONFLICT | |
| * =================== */ | |
| $.fn.typeahead.noConflict = function () { | |
| $.fn.typeahead = old | |
| return this | |
| } | |
| /* TYPEAHEAD DATA-API | |
| * ================== */ | |
| $(document).on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) { | |
| var $this = $(this) | |
| if ($this.data('typeahead')) return | |
| e.preventDefault() | |
| $this.typeahead($this.data()) | |
| }) | |
| }(window.jQuery); | |
| /* ========================================================== | |
| * bootstrap-affix.js v2.2.2 | |
| * http://twitter.github.com/bootstrap/javascript.html#affix | |
| * ========================================================== | |
| * Copyright 2012 Twitter, Inc. | |
| * | |
| * Licensed 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. | |
| * ========================================================== */ | |
| !function ($) { | |
| "use strict"; // jshint ;_; | |
| /* AFFIX CLASS DEFINITION | |
| * ====================== */ | |
| var Affix = function (element, options) { | |
| this.options = $.extend({}, $.fn.affix.defaults, options) | |
| this.$window = $(window) | |
| .on('scroll.affix.data-api', $.proxy(this.checkPosition, this)) | |
| .on('click.affix.data-api', $.proxy(function () { setTimeout($.proxy(this.checkPosition, this), 1) }, this)) | |
| this.$element = $(element) | |
| this.checkPosition() | |
| } | |
| Affix.prototype.checkPosition = function () { | |
| if (!this.$element.is(':visible')) return | |
| var scrollHeight = $(document).height() | |
| , scrollTop = this.$window.scrollTop() | |
| , position = this.$element.offset() | |
| , offset = this.options.offset | |
| , offsetBottom = offset.bottom | |
| , offsetTop = offset.top | |
| , reset = 'affix affix-top affix-bottom' | |
| , affix | |
| if (typeof offset != 'object') offsetBottom = offsetTop = offset | |
| if (typeof offsetTop == 'function') offsetTop = offset.top() | |
| if (typeof offsetBottom == 'function') offsetBottom = offset.bottom() | |
| affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ? | |
| false : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? | |
| 'bottom' : offsetTop != null && scrollTop <= offsetTop ? | |
| 'top' : false | |
| if (this.affixed === affix) return | |
| this.affixed = affix | |
| this.unpin = affix == 'bottom' ? position.top - scrollTop : null | |
| this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : '')) | |
| } | |
| /* AFFIX PLUGIN DEFINITION | |
| * ======================= */ | |
| var old = $.fn.affix | |
| $.fn.affix = function (option) { | |
| return this.each(function () { | |
| var $this = $(this) | |
| , data = $this.data('affix') | |
| , options = typeof option == 'object' && option | |
| if (!data) $this.data('affix', (data = new Affix(this, options))) | |
| if (typeof option == 'string') data[option]() | |
| }) | |
| } | |
| $.fn.affix.Constructor = Affix | |
| $.fn.affix.defaults = { | |
| offset: 0 | |
| } | |
| /* 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) | |
| , data = $spy.data() | |
| data.offset = data.offset || {} | |
| data.offsetBottom && (data.offset.bottom = data.offsetBottom) | |
| data.offsetTop && (data.offset.top = data.offsetTop) | |
| $spy.affix(data) | |
| }) | |
| }) | |
| }(window.jQuery); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /*! | |
| * Bootstrap v2.2.2 | |
| * | |
| * Copyright 2012 Twitter, Inc | |
| * Licensed under the Apache License v2.0 | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Designed and built with all the love in the world @twitter by @mdo and @fat. | |
| */article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{width:auto\9;height:auto;max-width:100%;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img,.google-maps img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer}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-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]: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}@page{margin:.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:20px;color:#333;background-color:#fff}a{color:#08c;text-decoration:none}a:hover{color:#005580;text-decoration:underline}.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1)}.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px}.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.span12{width:940px}.span11{width:860px}.span10{width:780px}.span9{width:700px}.span8{width:620px}.span7{width:540px}.span6{width:460px}.span5{width:380px}.span4{width:300px}.span3{width:220px}.span2{width:140px}.span1{width:60px}.offset12{margin-left:980px}.offset11{margin-left:900px}.offset10{margin-left:820px}.offset9{margin-left:740px}.offset8{margin-left:660px}.offset7{margin-left:580px}.offset6{margin-left:500px}.offset5{margin-left:420px}.offset4{margin-left:340px}.offset3{margin-left:260px}.offset2{margin-left:180px}.offset1{margin-left:100px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.127659574468085%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%}.row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%}.row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%}.row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%}.row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%}.row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%}.row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%}.row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%}.row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%}.row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%}.row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%}.row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%}.row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%}.row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%}.row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%}.row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%}.row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%}.row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%}.row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%}.row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%}.row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%}.row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%}.row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%}.row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%}.row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%}.row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%}.row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%}.row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%}.row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%}.row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%}.row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%}.row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%}.row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%}.row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%}.row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%}[class*="span"].hide,.row-fluid [class*="span"].hide{display:none}[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right}.container{margin-right:auto;margin-left:auto;*zoom:1}.container:before,.container:after{display:table;line-height:0;content:""}.container:after{clear:both}.container-fluid{padding-right:20px;padding-left:20px;*zoom:1}.container-fluid:before,.container-fluid:after{display:table;line-height:0;content:""}.container-fluid:after{clear:both}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:21px;font-weight:200;line-height:30px}small{font-size:85%}strong{font-weight:bold}em{font-style:italic}cite{font-style:normal}.muted{color:#999}a.muted:hover{color:#808080}.text-warning{color:#c09853}a.text-warning:hover{color:#a47e3c}.text-error{color:#b94a48}a.text-error:hover{color:#953b39}.text-info{color:#3a87ad}a.text-info:hover{color:#2d6987}.text-success{color:#468847}a.text-success:hover{color:#356635}h1,h2,h3,h4,h5,h6{margin:10px 0;font-family:inherit;font-weight:bold;line-height:20px;color:inherit;text-rendering:optimizelegibility}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#999}h1,h2,h3{line-height:40px}h1{font-size:38.5px}h2{font-size:31.5px}h3{font-size:24.5px}h4{font-size:17.5px}h5{font-size:14px}h6{font-size:11.9px}h1 small{font-size:24.5px}h2 small{font-size:17.5px}h3 small{font-size:14px}h4 small{font-size:14px}.page-header{padding-bottom:9px;margin:20px 0 30px;border-bottom:1px solid #eee}ul,ol{padding:0;margin:0 0 10px 25px}ul ul,ul ol,ol ol,ol ul{margin-bottom:0}li{line-height:20px}ul.unstyled,ol.unstyled{margin-left:0;list-style:none}ul.inline,ol.inline{margin-left:0;list-style:none}ul.inline>li,ol.inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-bottom:20px}dt,dd{line-height:20px}dt{font-weight:bold}dd{margin-left:10px}.dl-horizontal{*zoom:1}.dl-horizontal:before,.dl-horizontal:after{display:table;line-height:0;content:""}.dl-horizontal:after{clear:both}.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}hr{margin:20px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:0 0 0 15px;margin:0 0 20px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:16px;font-weight:300;line-height:25px}blockquote small{display:block;line-height:20px;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:20px;font-style:normal;line-height:20px}code,pre{padding:0 3px 2px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:12px;color:#333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}code{padding:2px 4px;color:#d14;white-space:nowrap;background-color:#f7f7f9;border:1px solid #e1e1e8}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:20px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}pre.prettyprint{margin-bottom:20px}pre code{padding:0;color:inherit;white-space:pre;white-space:pre-wrap;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}form{margin:0 0 20px}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:40px;color:#333;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:15px;color:#999}label,input,button,select,textarea{font-size:14px;font-weight:normal;line-height:20px}input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}label{display:block;margin-bottom:5px}select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:20px;padding:4px 6px;margin-bottom:10px;font-size:14px;line-height:20px;color:#555;vertical-align:middle;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}input,textarea,.uneditable-input{width:206px}textarea{height:auto}textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#fff;border:1px solid #ccc;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border linear .2s,box-shadow linear .2s;-moz-transition:border linear .2s,box-shadow linear .2s;-o-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;*margin-top:0;line-height:normal}input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto}select,input[type="file"]{height:30px;*margin-top:4px;line-height:30px}select{width:220px;background-color:#fff;border:1px solid #ccc}select[multiple],select[size]{height:auto}select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.uneditable-input,.uneditable-textarea{color:#999;cursor:not-allowed;background-color:#fcfcfc;border-color:#ccc;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);box-shadow:inset 0 1px 2px rgba(0,0,0,0.025)}.uneditable-input{overflow:hidden;white-space:nowrap}.uneditable-textarea{width:auto;height:auto}input:-moz-placeholder,textarea:-moz-placeholder{color:#999}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.radio,.checkbox{min-height:20px;padding-left:20px}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px}.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}.input-mini{width:60px}.input-small{width:90px}.input-medium{width:150px}.input-large{width:210px}.input-xlarge{width:270px}.input-xxlarge{width:530px}input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0}.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:926px}input.span11,textarea.span11,.uneditable-input.span11{width:846px}input.span10,textarea.span10,.uneditable-input.span10{width:766px}input.span9,textarea.span9,.uneditable-input.span9{width:686px}input.span8,textarea.span8,.uneditable-input.span8{width:606px}input.span7,textarea.span7,.uneditable-input.span7{width:526px}input.span6,textarea.span6,.uneditable-input.span6{width:446px}input.span5,textarea.span5,.uneditable-input.span5{width:366px}input.span4,textarea.span4,.uneditable-input.span4{width:286px}input.span3,textarea.span3,.uneditable-input.span3{width:206px}input.span2,textarea.span2,.uneditable-input.span2{width:126px}input.span1,textarea.span1,.uneditable-input.span1{width:46px}.controls-row{*zoom:1}.controls-row:before,.controls-row:after{display:table;line-height:0;content:""}.controls-row:after{clear:both}.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left}.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent}.control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853}.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853}.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48}.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48}.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847}.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847}.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847}.control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad}.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad}.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3}.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7}.form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1}.form-actions:before,.form-actions:after{display:table;line-height:0;content:""}.form-actions:after{clear:both}.help-block,.help-inline{color:#595959}.help-block{display:block;margin-bottom:10px}.help-inline{display:inline-block;*display:inline;padding-left:5px;vertical-align:middle;*zoom:1}.input-append,.input-prepend{margin-bottom:5px;font-size:0;white-space:nowrap}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu{font-size:14px}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2}.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #fff;background-color:#eee;border:1px solid #ccc}.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn,.input-append .btn-group>.dropdown-toggle,.input-prepend .btn-group>.dropdown-toggle{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546}.input-prepend .add-on,.input-prepend .btn{margin-right:-1px}.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input+.btn-group .btn:last-child,.input-append select+.btn-group .btn:last-child,.input-append .uneditable-input+.btn-group .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px}.input-append .add-on:last-child,.input-append .btn:last-child,.input-append .btn-group:last-child>.dropdown-toggle{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .btn-group:first-child{margin-left:0}input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;margin-bottom:0;vertical-align:middle;*zoom:1}.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block}.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0}.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle}.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}.control-group{margin-bottom:10px}legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate}.form-horizontal .control-group{margin-bottom:20px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;line-height:0;content:""}.form-horizontal .control-group:after{clear:both}.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right}.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:180px}.form-horizontal .help-block{margin-bottom:0}.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block,.form-horizontal .uneditable-input+.help-block,.form-horizontal .input-prepend+.help-block,.form-horizontal .input-append+.help-block{margin-top:10px}.form-horizontal .form-actions{padding-left:180px}table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}.table{width:100%;margin-bottom:20px}.table th,.table td{padding:8px;line-height:20px;text-align:left;vertical-align:top;border-top:1px solid #ddd}.table th{font-weight:bold}.table thead th{vertical-align:bottom}.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.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 th,.table-condensed td{padding:4px 5px}.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.table-bordered th,.table-bordered td{border-left:1px solid #ddd}.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0}.table-bordered thead:first-child tr:first-child>th:first-child,.table-bordered tbody:first-child tr:first-child>td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered thead:first-child tr:first-child>th:last-child,.table-bordered tbody:first-child tr:first-child>td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-bordered thead:last-child tr:last-child>th:first-child,.table-bordered tbody:last-child tr:last-child>td:first-child,.table-bordered tfoot:last-child tr:last-child>td:first-child{-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px}.table-bordered thead:last-child tr:last-child>th:last-child,.table-bordered tbody:last-child tr:last-child>td:last-child,.table-bordered tfoot:last-child tr:last-child>td:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px}.table-bordered tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-moz-border-radius-bottomleft:0}.table-bordered tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-bottomright:0}.table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover tbody tr:hover td,.table-hover tbody tr:hover th{background-color:#f5f5f5}table td[class*="span"],table th[class*="span"],.row-fluid table td[class*="span"],.row-fluid table th[class*="span"]{display:table-cell;float:none;margin-left:0}.table td.span1,.table th.span1{float:none;width:44px;margin-left:0}.table td.span2,.table th.span2{float:none;width:124px;margin-left:0}.table td.span3,.table th.span3{float:none;width:204px;margin-left:0}.table td.span4,.table th.span4{float:none;width:284px;margin-left:0}.table td.span5,.table th.span5{float:none;width:364px;margin-left:0}.table td.span6,.table th.span6{float:none;width:444px;margin-left:0}.table td.span7,.table th.span7{float:none;width:524px;margin-left:0}.table td.span8,.table th.span8{float:none;width:604px;margin-left:0}.table td.span9,.table th.span9{float:none;width:684px;margin-left:0}.table td.span10,.table th.span10{float:none;width:764px;margin-left:0}.table td.span11,.table th.span11{float:none;width:844px;margin-left:0}.table td.span12,.table th.span12{float:none;width:924px;margin-left:0}.table tbody tr.success td{background-color:#dff0d8}.table tbody tr.error td{background-color:#f2dede}.table tbody tr.warning td{background-color:#fcf8e3}.table tbody tr.info td{background-color:#d9edf7}.table-hover tbody tr.success:hover td{background-color:#d0e9c6}.table-hover tbody tr.error:hover td{background-color:#ebcccc}.table-hover tbody tr.warning:hover td{background-color:#faf2cc}.table-hover tbody tr.info:hover td{background-color:#c4e3f3}[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;margin-top:1px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat}.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"]{background-image:url("../img/glyphicons-halflings-white.png")}.icon-glass{background-position:0 0}.icon-music{background-position:-24px 0}.icon-search{background-position:-48px 0}.icon-envelope{background-position:-72px 0}.icon-heart{background-position:-96px 0}.icon-star{background-position:-120px 0}.icon-star-empty{background-position:-144px 0}.icon-user{background-position:-168px 0}.icon-film{background-position:-192px 0}.icon-th-large{background-position:-216px 0}.icon-th{background-position:-240px 0}.icon-th-list{background-position:-264px 0}.icon-ok{background-position:-288px 0}.icon-remove{background-position:-312px 0}.icon-zoom-in{background-position:-336px 0}.icon-zoom-out{background-position:-360px 0}.icon-off{background-position:-384px 0}.icon-signal{background-position:-408px 0}.icon-cog{background-position:-432px 0}.icon-trash{background-position:-456px 0}.icon-home{background-position:0 -24px}.icon-file{background-position:-24px -24px}.icon-time{background-position:-48px -24px}.icon-road{background-position:-72px -24px}.icon-download-alt{background-position:-96px -24px}.icon-download{background-position:-120px -24px}.icon-upload{background-position:-144px -24px}.icon-inbox{background-position:-168px -24px}.icon-play-circle{background-position:-192px -24px}.icon-repeat{background-position:-216px -24px}.icon-refresh{background-position:-240px -24px}.icon-list-alt{background-position:-264px -24px}.icon-lock{background-position:-287px -24px}.icon-flag{background-position:-312px -24px}.icon-headphones{background-position:-336px -24px}.icon-volume-off{background-position:-360px -24px}.icon-volume-down{background-position:-384px -24px}.icon-volume-up{background-position:-408px -24px}.icon-qrcode{background-position:-432px -24px}.icon-barcode{background-position:-456px -24px}.icon-tag{background-position:0 -48px}.icon-tags{background-position:-25px -48px}.icon-book{background-position:-48px -48px}.icon-bookmark{background-position:-72px -48px}.icon-print{background-position:-96px -48px}.icon-camera{background-position:-120px -48px}.icon-font{background-position:-144px -48px}.icon-bold{background-position:-167px -48px}.icon-italic{background-position:-192px -48px}.icon-text-height{background-position:-216px -48px}.icon-text-width{background-position:-240px -48px}.icon-align-left{background-position:-264px -48px}.icon-align-center{background-position:-288px -48px}.icon-align-right{background-position:-312px -48px}.icon-align-justify{background-position:-336px -48px}.icon-list{background-position:-360px -48px}.icon-indent-left{background-position:-384px -48px}.icon-indent-right{background-position:-408px -48px}.icon-facetime-video{background-position:-432px -48px}.icon-picture{background-position:-456px -48px}.icon-pencil{background-position:0 -72px}.icon-map-marker{background-position:-24px -72px}.icon-adjust{background-position:-48px -72px}.icon-tint{background-position:-72px -72px}.icon-edit{background-position:-96px -72px}.icon-share{background-position:-120px -72px}.icon-check{background-position:-144px -72px}.icon-move{background-position:-168px -72px}.icon-step-backward{background-position:-192px -72px}.icon-fast-backward{background-position:-216px -72px}.icon-backward{background-position:-240px -72px}.icon-play{background-position:-264px -72px}.icon-pause{background-position:-288px -72px}.icon-stop{background-position:-312px -72px}.icon-forward{background-position:-336px -72px}.icon-fast-forward{background-position:-360px -72px}.icon-step-forward{background-position:-384px -72px}.icon-eject{background-position:-408px -72px}.icon-chevron-left{background-position:-432px -72px}.icon-chevron-right{background-position:-456px -72px}.icon-plus-sign{background-position:0 -96px}.icon-minus-sign{background-position:-24px -96px}.icon-remove-sign{background-position:-48px -96px}.icon-ok-sign{background-position:-72px -96px}.icon-question-sign{background-position:-96px -96px}.icon-info-sign{background-position:-120px -96px}.icon-screenshot{background-position:-144px -96px}.icon-remove-circle{background-position:-168px -96px}.icon-ok-circle{background-position:-192px -96px}.icon-ban-circle{background-position:-216px -96px}.icon-arrow-left{background-position:-240px -96px}.icon-arrow-right{background-position:-264px -96px}.icon-arrow-up{background-position:-289px -96px}.icon-arrow-down{background-position:-312px -96px}.icon-share-alt{background-position:-336px -96px}.icon-resize-full{background-position:-360px -96px}.icon-resize-small{background-position:-384px -96px}.icon-plus{background-position:-408px -96px}.icon-minus{background-position:-433px -96px}.icon-asterisk{background-position:-456px -96px}.icon-exclamation-sign{background-position:0 -120px}.icon-gift{background-position:-24px -120px}.icon-leaf{background-position:-48px -120px}.icon-fire{background-position:-72px -120px}.icon-eye-open{background-position:-96px -120px}.icon-eye-close{background-position:-120px -120px}.icon-warning-sign{background-position:-144px -120px}.icon-plane{background-position:-168px -120px}.icon-calendar{background-position:-192px -120px}.icon-random{width:16px;background-position:-216px -120px}.icon-comment{background-position:-240px -120px}.icon-magnet{background-position:-264px -120px}.icon-chevron-up{background-position:-288px -120px}.icon-chevron-down{background-position:-313px -119px}.icon-retweet{background-position:-336px -120px}.icon-shopping-cart{background-position:-360px -120px}.icon-folder-close{background-position:-384px -120px}.icon-folder-open{width:16px;background-position:-408px -120px}.icon-resize-vertical{background-position:-432px -119px}.icon-resize-horizontal{background-position:-456px -118px}.icon-hdd{background-position:0 -144px}.icon-bullhorn{background-position:-24px -144px}.icon-bell{background-position:-48px -144px}.icon-certificate{background-position:-72px -144px}.icon-thumbs-up{background-position:-96px -144px}.icon-thumbs-down{background-position:-120px -144px}.icon-hand-right{background-position:-144px -144px}.icon-hand-left{background-position:-168px -144px}.icon-hand-up{background-position:-192px -144px}.icon-hand-down{background-position:-216px -144px}.icon-circle-arrow-right{background-position:-240px -144px}.icon-circle-arrow-left{background-position:-264px -144px}.icon-circle-arrow-up{background-position:-288px -144px}.icon-circle-arrow-down{background-position:-312px -144px}.icon-globe{background-position:-336px -144px}.icon-wrench{background-position:-360px -144px}.icon-tasks{background-position:-384px -144px}.icon-filter{background-position:-408px -144px}.icon-briefcase{background-position:-432px -144px}.icon-fullscreen{background-position:-456px -144px}.dropup,.dropdown{position:relative}.dropdown-toggle{*margin-bottom:-3px}.dropdown-toggle:active,.open .dropdown-toggle{outline:0}.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.dropdown .caret{margin-top:8px;margin-left:2px}.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;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.dropdown-menu li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap}.dropdown-menu li>a:hover,.dropdown-menu li>a:focus,.dropdown-submenu:hover>a{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu .active>a,.dropdown-menu .active>a:hover{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;outline:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu .disabled>a,.dropdown-menu .disabled>a:hover{color:#999}.dropdown-menu .disabled>a:hover{text-decoration:none;cursor:default;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open{*z-index:1000}.open>.dropdown-menu{display:block}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}.dropdown-submenu:hover>.dropdown-menu{display:block}.dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0}.dropdown-submenu>a:after{display:block;float:right;width:0;height:0;margin-top:5px;margin-right:-10px;border-color:transparent;border-left-color:#ccc;border-style:solid;border-width:5px 0 5px 5px;content:" "}.dropdown-submenu:hover>a:after{border-left-color:#fff}.dropdown-submenu.pull-left{float:none}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.dropdown .dropdown-menu .nav-header{padding-right:20px;padding-left:20px}.typeahead{z-index:1051;margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.fade{opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-moz-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.collapse.in{height:auto}.close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.btn{display:inline-block;*display:inline;padding:4px 12px;margin-bottom:0;*margin-left:.3em;font-size:14px;line-height:20px;color:#333;text-align:center;text-shadow:0 1px 1px rgba(255,255,255,0.75);vertical-align:middle;cursor:pointer;background-color:#f5f5f5;*background-color:#e6e6e6;background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-repeat:repeat-x;border:1px solid #bbb;*border:0;border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);border-bottom-color:#a2a2a2;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);*zoom:1;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn:hover,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9}.btn:active,.btn.active{background-color:#ccc \9}.btn:first-child{*margin-left:0}.btn:hover{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px}.btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0}.btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px}.btn-mini{padding:0 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-block{display:block;width:100%;padding-right:0;padding-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,0.75)}.btn{border-color:#c5c5c5;border-color:rgba(0,0,0,0.15) rgba(0,0,0,0.15) rgba(0,0,0,0.25)}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006dcc;*background-color:#04c;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.btn-primary:active,.btn-primary.active{background-color:#039 \9}.btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#faa732;*background-color:#f89406;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-warning:hover,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#f89406;*background-color:#df8505}.btn-warning:active,.btn-warning.active{background-color:#c67605 \9}.btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#da4f49;*background-color:#bd362f;background-image:-moz-linear-gradient(top,#ee5f5b,#bd362f);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#bd362f));background-image:-webkit-linear-gradient(top,#ee5f5b,#bd362f);background-image:-o-linear-gradient(top,#ee5f5b,#bd362f);background-image:linear-gradient(to bottom,#ee5f5b,#bd362f);background-repeat:repeat-x;border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffbd362f',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-danger:hover,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#bd362f;*background-color:#a9302a}.btn-danger:active,.btn-danger.active{background-color:#942a25 \9}.btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#5bb75b;*background-color:#51a351;background-image:-moz-linear-gradient(top,#62c462,#51a351);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#51a351));background-image:-webkit-linear-gradient(top,#62c462,#51a351);background-image:-o-linear-gradient(top,#62c462,#51a351);background-image:linear-gradient(to bottom,#62c462,#51a351);background-repeat:repeat-x;border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff51a351',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-success:hover,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#51a351;*background-color:#499249}.btn-success:active,.btn-success.active{background-color:#408140 \9}.btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#49afcd;*background-color:#2f96b4;background-image:-moz-linear-gradient(top,#5bc0de,#2f96b4);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#2f96b4));background-image:-webkit-linear-gradient(top,#5bc0de,#2f96b4);background-image:-o-linear-gradient(top,#5bc0de,#2f96b4);background-image:linear-gradient(to bottom,#5bc0de,#2f96b4);background-repeat:repeat-x;border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff2f96b4',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-info:hover,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#2f96b4;*background-color:#2a85a0}.btn-info:active,.btn-info.active{background-color:#24748c \9}.btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#363636;*background-color:#222;background-image:-moz-linear-gradient(top,#444,#222);background-image:-webkit-gradient(linear,0 0,0 100%,from(#444),to(#222));background-image:-webkit-linear-gradient(top,#444,#222);background-image:-o-linear-gradient(top,#444,#222);background-image:linear-gradient(to bottom,#444,#222);background-repeat:repeat-x;border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444',endColorstr='#ff222222',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-inverse:hover,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#222;*background-color:#151515}.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9}button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-link{color:#08c;cursor:pointer;border-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-link:hover{color:#005580;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover{color:#333;text-decoration:none}.btn-group{position:relative;display:inline-block;*display:inline;*margin-left:.3em;font-size:0;white-space:nowrap;vertical-align:middle;*zoom:1}.btn-group:first-child{*margin-left:0}.btn-group+.btn-group{margin-left:5px}.btn-toolbar{margin-top:10px;margin-bottom:10px;font-size:0}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group{margin-left:5px}.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group>.btn+.btn{margin-left:-1px}.btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover{font-size:14px}.btn-group>.btn-mini{font-size:10.5px}.btn-group>.btn-small{font-size:11.9px}.btn-group>.btn-large{font-size:17.5px}.btn-group>.btn:first-child{margin-left:0;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{*padding-top:5px;padding-right:8px;*padding-bottom:5px;padding-left:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn-group>.btn-mini+.dropdown-toggle{*padding-top:2px;padding-right:5px;*padding-bottom:2px;padding-left:5px}.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px}.btn-group>.btn-large+.dropdown-toggle{*padding-top:7px;padding-right:12px;*padding-bottom:7px;padding-left:12px}.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6}.btn-group.open .btn-primary.dropdown-toggle{background-color:#04c}.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406}.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f}.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351}.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4}.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222}.btn .caret{margin-top:8px;margin-left:0}.btn-mini .caret,.btn-small .caret,.btn-large .caret{margin-top:6px}.btn-large .caret{border-top-width:5px;border-right-width:5px;border-left-width:5px}.dropup .btn-large .caret{border-bottom-width:5px}.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff}.btn-group-vertical{display:inline-block;*display:inline;*zoom:1}.btn-group-vertical>.btn{display:block;float:none;max-width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical>.btn+.btn{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.btn-group-vertical>.btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.btn-group-vertical>.btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0}.btn-group-vertical>.btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.alert,.alert h4{color:#c09853}.alert h4{margin:0}.alert .close{position:relative;top:-2px;right:-21px;line-height:20px}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-success h4{color:#468847}.alert-danger,.alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-danger h4,.alert-error h4{color:#b94a48}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.alert-info h4{color:#3a87ad}.alert-block{padding-top:14px;padding-bottom:14px}.alert-block>p,.alert-block>ul{margin-bottom:0}.alert-block p+p{margin-top:5px}.nav{margin-bottom:20px;margin-left:0;list-style:none}.nav>li>a{display:block}.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li>a>img{max-width:none}.nav>.pull-right{float:right}.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase}.nav li+.nav-header{margin-top:9px}.nav-list{padding-right:15px;padding-left:15px;margin-bottom:0}.nav-list>li>a,.nav-list .nav-header{margin-right:-15px;margin-left:-15px;text-shadow:0 1px 0 rgba(255,255,255,0.5)}.nav-list>li>a{padding:3px 15px}.nav-list>.active>a,.nav-list>.active>a:hover{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#08c}.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px}.nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;line-height:0;content:""}.nav-tabs:after,.nav-pills:after{clear:both}.nav-tabs>li,.nav-pills>li{float:left}.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{margin-bottom:-1px}.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:20px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>.active>a,.nav-tabs>.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nav-pills>.active>a,.nav-pills>.active>a:hover{color:#fff;background-color:#08c}.nav-stacked>li{float:none}.nav-stacked>li>a{margin-right:0}.nav-tabs.nav-stacked{border-bottom:0}.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-moz-border-radius-bottomleft:4px}.nav-tabs.nav-stacked>li>a:hover{z-index:2;border-color:#ddd}.nav-pills.nav-stacked>li>a{margin-bottom:3px}.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px}.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.nav .dropdown-toggle .caret{margin-top:6px;border-top-color:#08c;border-bottom-color:#08c}.nav .dropdown-toggle:hover .caret{border-top-color:#005580;border-bottom-color:#005580}.nav-tabs .dropdown-toggle .caret{margin-top:8px}.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.nav>.dropdown.active>a:hover{cursor:pointer}.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover{color:#fff;background-color:#999;border-color:#999}.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:1;filter:alpha(opacity=100)}.tabs-stacked .open>a:hover{border-color:#999}.tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;line-height:0;content:""}.tabbable:after{clear:both}.tab-content{overflow:auto}.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd #ddd}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px}.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd}.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff}.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd}.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd}.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}.nav>.disabled>a{color:#999}.nav>.disabled>a:hover{text-decoration:none;cursor:default;background-color:transparent}.navbar{*position:relative;*z-index:2;margin-bottom:20px;overflow:visible}.navbar-inner{min-height:40px;padding-right:20px;padding-left:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top,#fff,#f2f2f2);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#f2f2f2));background-image:-webkit-linear-gradient(top,#fff,#f2f2f2);background-image:-o-linear-gradient(top,#fff,#f2f2f2);background-image:linear-gradient(to bottom,#fff,#f2f2f2);background-repeat:repeat-x;border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff2f2f2',GradientType=0);*zoom:1;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.065);-moz-box-shadow:0 1px 4px rgba(0,0,0,0.065);box-shadow:0 1px 4px rgba(0,0,0,0.065)}.navbar-inner:before,.navbar-inner:after{display:table;line-height:0;content:""}.navbar-inner:after{clear:both}.navbar .container{width:auto}.nav-collapse.collapse{height:auto;overflow:visible}.navbar .brand{display:block;float:left;padding:10px 20px 10px;margin-left:-20px;font-size:20px;font-weight:200;color:#777;text-shadow:0 1px 0 #fff}.navbar .brand:hover{text-decoration:none}.navbar-text{margin-bottom:0;line-height:40px;color:#777}.navbar-link{color:#777}.navbar-link:hover{color:#333}.navbar .divider-vertical{height:40px;margin:0 9px;border-right:1px solid #fff;border-left:1px solid #f2f2f2}.navbar .btn,.navbar .btn-group{margin-top:5px}.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn{margin-top:0}.navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;line-height:0;content:""}.navbar-form:after{clear:both}.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px}.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0}.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px}.navbar-form .input-append,.navbar-form .input-prepend{margin-top:5px;white-space:nowrap}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0}.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0}.navbar-search .search-query{padding:4px 14px;margin-bottom:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.navbar-static-top{position:static;margin-bottom:0}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px}.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-right:0;padding-left:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.navbar-fixed-top{top:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,0.1);box-shadow:0 1px 10px rgba(0,0,0,0.1)}.navbar-fixed-bottom{bottom:0}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,0.1);box-shadow:0 -1px 10px rgba(0,0,0,0.1)}.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0}.navbar .nav.pull-right{float:right;margin-right:0}.navbar .nav>li{float:left}.navbar .nav>li>a{float:none;padding:10px 15px 10px;color:#777;text-decoration:none;text-shadow:0 1px 0 #fff}.navbar .nav .dropdown-toggle .caret{margin-top:8px}.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{color:#333;text-decoration:none;background-color:transparent}.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);box-shadow:inset 0 3px 8px rgba(0,0,0,0.125)}.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-right:5px;margin-left:5px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#ededed;*background-color:#e5e5e5;background-image:-moz-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#e5e5e5));background-image:-webkit-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-o-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:linear-gradient(to bottom,#f2f2f2,#e5e5e5);background-repeat:repeat-x;border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffe5e5e5',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075)}.navbar .btn-navbar:hover,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#fff;background-color:#e5e5e5;*background-color:#d9d9d9}.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#ccc \9}.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.25);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.25);box-shadow:0 1px 0 rgba(0,0,0,0.25)}.btn-navbar .icon-bar+.icon-bar{margin-top:3px}.navbar .nav>li>.dropdown-menu:before{position:absolute;top:-7px;left:9px;display:inline-block;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,0.2);content:''}.navbar .nav>li>.dropdown-menu:after{position:absolute;top:-6px;left:10px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''}.navbar-fixed-bottom .nav>li>.dropdown-menu:before{top:auto;bottom:-7px;border-top:7px solid #ccc;border-bottom:0;border-top-color:rgba(0,0,0,0.2)}.navbar-fixed-bottom .nav>li>.dropdown-menu:after{top:auto;bottom:-6px;border-top:6px solid #fff;border-bottom:0}.navbar .nav li.dropdown>a:hover .caret{border-top-color:#555;border-bottom-color:#555}.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{color:#555;background-color:#e5e5e5}.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777;border-bottom-color:#777}.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{right:0;left:auto}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{right:12px;left:auto}.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{right:13px;left:auto}.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{right:100%;left:auto;margin-right:-1px;margin-left:0;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top,#222,#111);background-image:-webkit-gradient(linear,0 0,0 100%,from(#222),to(#111));background-image:-webkit-linear-gradient(top,#222,#111);background-image:-o-linear-gradient(top,#222,#111);background-image:linear-gradient(to bottom,#222,#111);background-repeat:repeat-x;border-color:#252525;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222',endColorstr='#ff111111',GradientType=0)}.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover{color:#fff}.navbar-inverse .brand{color:#999}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#fff;background-color:#111}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .divider-vertical{border-right-color:#222;border-left-color:#111}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{color:#fff;background-color:#111}.navbar-inverse .nav li.dropdown>a:hover .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999;border-bottom-color:#999}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-search .search-query{color:#fff;background-color:#515151;border-color:#111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;outline:0;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.15);-moz-box-shadow:0 0 3px rgba(0,0,0,0.15);box-shadow:0 0 3px rgba(0,0,0,0.15)}.navbar-inverse .btn-navbar{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e0e0e;*background-color:#040404;background-image:-moz-linear-gradient(top,#151515,#040404);background-image:-webkit-gradient(linear,0 0,0 100%,from(#151515),to(#040404));background-image:-webkit-linear-gradient(top,#151515,#040404);background-image:-o-linear-gradient(top,#151515,#040404);background-image:linear-gradient(to bottom,#151515,#040404);background-repeat:repeat-x;border-color:#040404 #040404 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515',endColorstr='#ff040404',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#fff;background-color:#040404;*background-color:#000}.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000 \9}.breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.breadcrumb>li{display:inline-block;*display:inline;text-shadow:0 1px 0 #fff;*zoom:1}.breadcrumb>li>.divider{padding:0 5px;color:#ccc}.breadcrumb>.active{color:#999}.pagination{margin:20px 0}.pagination ul{display:inline-block;*display:inline;margin-bottom:0;margin-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*zoom:1;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.pagination ul>li{display:inline}.pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#fff;border:1px solid #ddd;border-left-width:0}.pagination ul>li>a:hover,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5}.pagination ul>.active>a,.pagination ul>.active>span{color:#999;cursor:default}.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover{color:#999;cursor:default;background-color:transparent}.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.pagination-centered{text-align:center}.pagination-right{text-align:right}.pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:17.5px}.pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span{-webkit-border-bottom-left-radius:3px;border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;-moz-border-radius-bottomleft:3px;-moz-border-radius-topleft:3px}.pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:3px;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-bottom-right-radius:3px;-moz-border-radius-topright:3px;-moz-border-radius-bottomright:3px}.pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.9px}.pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:0 6px;font-size:10.5px}.pager{margin:20px 0;text-align:center;list-style:none;*zoom:1}.pager:before,.pager:after{display:table;line-height:0;content:""}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.pager li>a:hover{text-decoration:none;background-color:#f5f5f5}.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>span{color:#999;cursor:default;background-color:#fff}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop,.modal-backdrop.fade.in{opacity:.8;filter:alpha(opacity=80)}.modal{position:fixed;top:10%;left:50%;z-index:1050;width:560px;margin-left:-280px;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;outline:0;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box}.modal.fade{top:-25%;-webkit-transition:opacity .3s linear,top .3s ease-out;-moz-transition:opacity .3s linear,top .3s ease-out;-o-transition:opacity .3s linear,top .3s ease-out;transition:opacity .3s linear,top .3s ease-out}.modal.fade.in{top:10%}.modal-header{padding:9px 15px;border-bottom:1px solid #eee}.modal-header .close{margin-top:2px}.modal-header h3{margin:0;line-height:30px}.modal-body{position:relative;max-height:400px;padding:15px;overflow-y:auto}.modal-form{margin-bottom:0}.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;*zoom:1;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.modal-footer:before,.modal-footer:after{display:table;line-height:0;content:""}.modal-footer:after{clear:both}.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}.tooltip{position:absolute;z-index:1030;display:block;padding:5px;font-size:11px;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.8;filter:alpha(opacity=80)}.tooltip.top{margin-top:-3px}.tooltip.right{margin-left:3px}.tooltip.bottom{margin-top:3px}.tooltip.left{margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;-webkit-border-radius:4px;-moz-border-radius:4px;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-top-color:#000;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#000;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#000;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#000;border-width:0 5px 5px}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;width:236px;padding:1px;text-align:left;white-space:normal;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.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;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;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{border-width:10px;content:""}.popover.top .arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);border-bottom-width:0}.popover.top .arrow:after{bottom:1px;margin-left:-10px;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,0.25);border-left-width:0}.popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#fff;border-left-width:0}.popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);border-top-width:0}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#fff;border-top-width:0}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,0.25);border-right-width:0}.popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#fff;border-right-width:0}.thumbnails{margin-left:-20px;list-style:none;*zoom:1}.thumbnails:before,.thumbnails:after{display:table;line-height:0;content:""}.thumbnails:after{clear:both}.row-fluid .thumbnails{margin-left:0}.thumbnails>li{float:left;margin-bottom:20px;margin-left:20px}.thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.055);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.055);box-shadow:0 1px 3px rgba(0,0,0,0.055);-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}a.thumbnail:hover{border-color:#08c;-webkit-box-shadow:0 1px 4px rgba(0,105,214,0.25);-moz-box-shadow:0 1px 4px rgba(0,105,214,0.25);box-shadow:0 1px 4px rgba(0,105,214,0.25)}.thumbnail>img{display:block;max-width:100%;margin-right:auto;margin-left:auto}.thumbnail .caption{padding:9px;color:#555}.media,.media-body{overflow:hidden;*overflow:visible;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media .pull-left{margin-right:10px}.media .pull-right{margin-left:10px}.media-list{margin-left:0;list-style:none}.label,.badge{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999}.label{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.badge{padding-right:9px;padding-left:9px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px}.label:empty,.badge:empty{display:none}a.label:hover,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.label-important,.badge-important{background-color:#b94a48}.label-important[href],.badge-important[href]{background-color:#953b39}.label-warning,.badge-warning{background-color:#f89406}.label-warning[href],.badge-warning[href]{background-color:#c67605}.label-success,.badge-success{background-color:#468847}.label-success[href],.badge-success[href]{background-color:#356635}.label-info,.badge-info{background-color:#3a87ad}.label-info[href],.badge-info[href]{background-color:#2d6987}.label-inverse,.badge-inverse{background-color:#333}.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a}.btn .label,.btn .badge{position:relative;top:-1px}.btn-mini .label,.btn-mini .badge{top:0}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 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:#f7f7f7;background-image:-moz-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9));background-image:-webkit-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-o-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);background-repeat:repeat-x;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress .bar{float:left;width:0;height:100%;font-size:12px;color:#fff;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top,#149bdf,#0480be);background-image:-webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be));background-image:-webkit-linear-gradient(top,#149bdf,#0480be);background-image:-o-linear-gradient(top,#149bdf,#0480be);background-image:linear-gradient(to bottom,#149bdf,#0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf',endColorstr='#ff0480be',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15)}.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));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);background-image:-moz-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);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);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);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px}.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-danger .bar,.progress .bar-danger{background-color:#dd514c;background-image:-moz-linear-gradient(top,#ee5f5b,#c43c35);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#c43c35));background-image:-webkit-linear-gradient(top,#ee5f5b,#c43c35);background-image:-o-linear-gradient(top,#ee5f5b,#c43c35);background-image:linear-gradient(to bottom,#ee5f5b,#c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffc43c35',GradientType=0)}.progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));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);background-image:-moz-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);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);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)}.progress-success .bar,.progress .bar-success{background-color:#5eb95e;background-image:-moz-linear-gradient(top,#62c462,#57a957);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#57a957));background-image:-webkit-linear-gradient(top,#62c462,#57a957);background-image:-o-linear-gradient(top,#62c462,#57a957);background-image:linear-gradient(to bottom,#62c462,#57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff57a957',GradientType=0)}.progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));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);background-image:-moz-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);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);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)}.progress-info .bar,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-linear-gradient(top,#5bc0de,#339bb9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#339bb9));background-image:-webkit-linear-gradient(top,#5bc0de,#339bb9);background-image:-o-linear-gradient(top,#5bc0de,#339bb9);background-image:linear-gradient(to bottom,#5bc0de,#339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff339bb9',GradientType=0)}.progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));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);background-image:-moz-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);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);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)}.progress-warning .bar,.progress .bar-warning{background-color:#faa732;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0)}.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));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);background-image:-moz-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);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);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)}.accordion{margin-bottom:20px}.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.accordion-heading{border-bottom:0}.accordion-heading .accordion-toggle{display:block;padding:8px 15px}.accordion-toggle{cursor:pointer}.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5}.carousel{position:relative;margin-bottom:20px;line-height:1}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-moz-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img{display:block;line-height:1}.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:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#fff;text-align:center;background:#222;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:.5;filter:alpha(opacity=50)}.carousel-control.right{right:15px;left:auto}.carousel-control:hover{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-caption{position:absolute;right:0;bottom:0;left:0;padding:15px;background:#333;background:rgba(0,0,0,0.75)}.carousel-caption h4,.carousel-caption p{line-height:20px;color:#fff}.carousel-caption h4{margin:0 0 5px}.carousel-caption p{margin-bottom:0}.hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:30px;color:inherit;background-color:#eee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;letter-spacing:-1px;color:inherit}.hero-unit li{line-height:30px}.pull-right{float:right}.pull-left{float:left}.hide{display:none}.show{display:block}.invisible{visibility:hidden}.affix{position:fixed} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /*! | |
| * Bootstrap.js by @fat & @mdo | |
| * Copyright 2012 Twitter, Inc. | |
| * http://www.apache.org/licenses/LICENSE-2.0.txt | |
| */ | |
| !function($){"use strict";$(function(){$.support.transition=function(){var transitionEnd=function(){var name,el=document.createElement("bootstrap"),transEndEventNames={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(name in transEndEventNames)if(void 0!==el.style[name])return transEndEventNames[name]}();return transitionEnd&&{end:transitionEnd}}()})}(window.jQuery),!function($){"use strict";var dismiss='[data-dismiss="alert"]',Alert=function(el){$(el).on("click",dismiss,this.close)};Alert.prototype.close=function(e){function removeElement(){$parent.trigger("closed").remove()}var $parent,$this=$(this),selector=$this.attr("data-target");selector||(selector=$this.attr("href"),selector=selector&&selector.replace(/.*(?=#[^\s]*$)/,"")),$parent=$(selector),e&&e.preventDefault(),$parent.length||($parent=$this.hasClass("alert")?$this:$this.parent()),$parent.trigger(e=$.Event("close")),e.isDefaultPrevented()||($parent.removeClass("in"),$.support.transition&&$parent.hasClass("fade")?$parent.on($.support.transition.end,removeElement):removeElement())};var old=$.fn.alert;$.fn.alert=function(option){return this.each(function(){var $this=$(this),data=$this.data("alert");data||$this.data("alert",data=new Alert(this)),"string"==typeof option&&data[option].call($this)})},$.fn.alert.Constructor=Alert,$.fn.alert.noConflict=function(){return $.fn.alert=old,this},$(document).on("click.alert.data-api",dismiss,Alert.prototype.close)}(window.jQuery),!function($){"use strict";var Button=function(element,options){this.$element=$(element),this.options=$.extend({},$.fn.button.defaults,options)};Button.prototype.setState=function(state){var d="disabled",$el=this.$element,data=$el.data(),val=$el.is("input")?"val":"html";state+="Text",data.resetText||$el.data("resetText",$el[val]()),$el[val](data[state]||this.options[state]),setTimeout(function(){"loadingText"==state?$el.addClass(d).attr(d,d):$el.removeClass(d).removeAttr(d)},0)},Button.prototype.toggle=function(){var $parent=this.$element.closest('[data-toggle="buttons-radio"]');$parent&&$parent.find(".active").removeClass("active"),this.$element.toggleClass("active")};var old=$.fn.button;$.fn.button=function(option){return this.each(function(){var $this=$(this),data=$this.data("button"),options="object"==typeof option&&option;data||$this.data("button",data=new Button(this,options)),"toggle"==option?data.toggle():option&&data.setState(option)})},$.fn.button.defaults={loadingText:"loading..."},$.fn.button.Constructor=Button,$.fn.button.noConflict=function(){return $.fn.button=old,this},$(document).on("click.button.data-api","[data-toggle^=button]",function(e){var $btn=$(e.target);$btn.hasClass("btn")||($btn=$btn.closest(".btn")),$btn.button("toggle")})}(window.jQuery),!function($){"use strict";var Carousel=function(element,options){this.$element=$(element),this.options=options,"hover"==this.options.pause&&this.$element.on("mouseenter",$.proxy(this.pause,this)).on("mouseleave",$.proxy(this.cycle,this))};Carousel.prototype={cycle:function(e){return e||(this.paused=!1),this.options.interval&&!this.paused&&(this.interval=setInterval($.proxy(this.next,this),this.options.interval)),this},to:function(pos){var $active=this.$element.find(".item.active"),children=$active.parent().children(),activePos=children.index($active),that=this;if(!(pos>children.length-1||0>pos))return this.sliding?this.$element.one("slid",function(){that.to(pos)}):activePos==pos?this.pause().cycle():this.slide(pos>activePos?"next":"prev",$(children[pos]))},pause:function(e){return e||(this.paused=!0),this.$element.find(".next, .prev").length&&$.support.transition.end&&(this.$element.trigger($.support.transition.end),this.cycle()),clearInterval(this.interval),this.interval=null,this},next:function(){return this.sliding?void 0:this.slide("next")},prev:function(){return this.sliding?void 0:this.slide("prev")},slide:function(type,next){var e,$active=this.$element.find(".item.active"),$next=next||$active[type](),isCycling=this.interval,direction="next"==type?"left":"right",fallback="next"==type?"first":"last",that=this;if(this.sliding=!0,isCycling&&this.pause(),$next=$next.length?$next:this.$element.find(".item")[fallback](),e=$.Event("slide",{relatedTarget:$next[0]}),!$next.hasClass("active")){if($.support.transition&&this.$element.hasClass("slide")){if(this.$element.trigger(e),e.isDefaultPrevented())return;$next.addClass(type),$next[0].offsetWidth,$active.addClass(direction),$next.addClass(direction),this.$element.one($.support.transition.end,function(){$next.removeClass([type,direction].join(" ")).addClass("active"),$active.removeClass(["active",direction].join(" ")),that.sliding=!1,setTimeout(function(){that.$element.trigger("slid")},0)})}else{if(this.$element.trigger(e),e.isDefaultPrevented())return;$active.removeClass("active"),$next.addClass("active"),this.sliding=!1,this.$element.trigger("slid")}return isCycling&&this.cycle(),this}}};var old=$.fn.carousel;$.fn.carousel=function(option){return this.each(function(){var $this=$(this),data=$this.data("carousel"),options=$.extend({},$.fn.carousel.defaults,"object"==typeof option&&option),action="string"==typeof option?option:options.slide;data||$this.data("carousel",data=new Carousel(this,options)),"number"==typeof option?data.to(option):action?data[action]():options.interval&&data.cycle()})},$.fn.carousel.defaults={interval:5e3,pause:"hover"},$.fn.carousel.Constructor=Carousel,$.fn.carousel.noConflict=function(){return $.fn.carousel=old,this},$(document).on("click.carousel.data-api","[data-slide]",function(e){var href,$this=$(this),$target=$($this.attr("data-target")||(href=$this.attr("href"))&&href.replace(/.*(?=#[^\s]+$)/,"")),options=$.extend({},$target.data(),$this.data());$target.carousel(options),e.preventDefault()})}(window.jQuery),!function($){"use strict";var Collapse=function(element,options){this.$element=$(element),this.options=$.extend({},$.fn.collapse.defaults,options),this.options.parent&&(this.$parent=$(this.options.parent)),this.options.toggle&&this.toggle()};Collapse.prototype={constructor:Collapse,dimension:function(){var hasWidth=this.$element.hasClass("width");return hasWidth?"width":"height"},show:function(){var dimension,scroll,actives,hasData;if(!this.transitioning){if(dimension=this.dimension(),scroll=$.camelCase(["scroll",dimension].join("-")),actives=this.$parent&&this.$parent.find("> .accordion-group > .in"),actives&&actives.length){if(hasData=actives.data("collapse"),hasData&&hasData.transitioning)return;actives.collapse("hide"),hasData||actives.data("collapse",null)}this.$element[dimension](0),this.transition("addClass",$.Event("show"),"shown"),$.support.transition&&this.$element[dimension](this.$element[0][scroll])}},hide:function(){var dimension;this.transitioning||(dimension=this.dimension(),this.reset(this.$element[dimension]()),this.transition("removeClass",$.Event("hide"),"hidden"),this.$element[dimension](0))},reset:function(size){var dimension=this.dimension();return this.$element.removeClass("collapse")[dimension](size||"auto")[0].offsetWidth,this.$element[null!==size?"addClass":"removeClass"]("collapse"),this},transition:function(method,startEvent,completeEvent){var that=this,complete=function(){"show"==startEvent.type&&that.reset(),that.transitioning=0,that.$element.trigger(completeEvent)};this.$element.trigger(startEvent),startEvent.isDefaultPrevented()||(this.transitioning=1,this.$element[method]("in"),$.support.transition&&this.$element.hasClass("collapse")?this.$element.one($.support.transition.end,complete):complete())},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}};var old=$.fn.collapse;$.fn.collapse=function(option){return this.each(function(){var $this=$(this),data=$this.data("collapse"),options="object"==typeof option&&option;data||$this.data("collapse",data=new Collapse(this,options)),"string"==typeof option&&data[option]()})},$.fn.collapse.defaults={toggle:!0},$.fn.collapse.Constructor=Collapse,$.fn.collapse.noConflict=function(){return $.fn.collapse=old,this},$(document).on("click.collapse.data-api","[data-toggle=collapse]",function(e){var href,$this=$(this),target=$this.attr("data-target")||e.preventDefault()||(href=$this.attr("href"))&&href.replace(/.*(?=#[^\s]+$)/,""),option=$(target).data("collapse")?"toggle":$this.data();$this[$(target).hasClass("in")?"addClass":"removeClass"]("collapsed"),$(target).collapse(option)})}(window.jQuery),!function($){"use strict";function clearMenus(){$(toggle).each(function(){getParent($(this)).removeClass("open")})}function getParent($this){var $parent,selector=$this.attr("data-target");return selector||(selector=$this.attr("href"),selector=selector&&/#/.test(selector)&&selector.replace(/.*(?=#[^\s]*$)/,"")),$parent=$(selector),$parent.length||($parent=$this.parent()),$parent}var toggle="[data-toggle=dropdown]",Dropdown=function(element){var $el=$(element).on("click.dropdown.data-api",this.toggle);$("html").on("click.dropdown.data-api",function(){$el.parent().removeClass("open")})};Dropdown.prototype={constructor:Dropdown,toggle:function(){var $parent,isActive,$this=$(this);if(!$this.is(".disabled, :disabled"))return $parent=getParent($this),isActive=$parent.hasClass("open"),clearMenus(),isActive||$parent.toggleClass("open"),$this.focus(),!1},keydown:function(e){var $this,$items,$parent,isActive,index;if(/(38|40|27)/.test(e.keyCode)&&($this=$(this),e.preventDefault(),e.stopPropagation(),!$this.is(".disabled, :disabled"))){if($parent=getParent($this),isActive=$parent.hasClass("open"),!isActive||isActive&&27==e.keyCode)return $this.click();$items=$("[role=menu] li:not(.divider):visible a",$parent),$items.length&&(index=$items.index($items.filter(":focus")),38==e.keyCode&&index>0&&index--,40==e.keyCode&&$items.length-1>index&&index++,~index||(index=0),$items.eq(index).focus())}}};var old=$.fn.dropdown;$.fn.dropdown=function(option){return this.each(function(){var $this=$(this),data=$this.data("dropdown");data||$this.data("dropdown",data=new Dropdown(this)),"string"==typeof option&&data[option].call($this)})},$.fn.dropdown.Constructor=Dropdown,$.fn.dropdown.noConflict=function(){return $.fn.dropdown=old,this},$(document).on("click.dropdown.data-api touchstart.dropdown.data-api",clearMenus).on("click.dropdown touchstart.dropdown.data-api",".dropdown form",function(e){e.stopPropagation()}).on("touchstart.dropdown.data-api",".dropdown-menu",function(e){e.stopPropagation()}).on("click.dropdown.data-api touchstart.dropdown.data-api",toggle,Dropdown.prototype.toggle).on("keydown.dropdown.data-api touchstart.dropdown.data-api",toggle+", [role=menu]",Dropdown.prototype.keydown)}(window.jQuery),!function($){"use strict";var Modal=function(element,options){this.options=options,this.$element=$(element).delegate('[data-dismiss="modal"]',"click.dismiss.modal",$.proxy(this.hide,this)),this.options.remote&&this.$element.find(".modal-body").load(this.options.remote)};Modal.prototype={constructor:Modal,toggle:function(){return this[this.isShown?"hide":"show"]()},show:function(){var that=this,e=$.Event("show");this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.escape(),this.backdrop(function(){var transition=$.support.transition&&that.$element.hasClass("fade");that.$element.parent().length||that.$element.appendTo(document.body),that.$element.show(),transition&&that.$element[0].offsetWidth,that.$element.addClass("in").attr("aria-hidden",!1),that.enforceFocus(),transition?that.$element.one($.support.transition.end,function(){that.$element.focus().trigger("shown")}):that.$element.focus().trigger("shown")}))},hide:function(e){e&&e.preventDefault(),e=$.Event("hide"),this.$element.trigger(e),this.isShown&&!e.isDefaultPrevented()&&(this.isShown=!1,this.escape(),$(document).off("focusin.modal"),this.$element.removeClass("in").attr("aria-hidden",!0),$.support.transition&&this.$element.hasClass("fade")?this.hideWithTransition():this.hideModal())},enforceFocus:function(){var that=this;$(document).on("focusin.modal",function(e){that.$element[0]===e.target||that.$element.has(e.target).length||that.$element.focus()})},escape:function(){var that=this;this.isShown&&this.options.keyboard?this.$element.on("keyup.dismiss.modal",function(e){27==e.which&&that.hide()}):this.isShown||this.$element.off("keyup.dismiss.modal")},hideWithTransition:function(){var that=this,timeout=setTimeout(function(){that.$element.off($.support.transition.end),that.hideModal()},500);this.$element.one($.support.transition.end,function(){clearTimeout(timeout),that.hideModal()})},hideModal:function(){this.$element.hide().trigger("hidden"),this.backdrop()},removeBackdrop:function(){this.$backdrop.remove(),this.$backdrop=null},backdrop:function(callback){var animate=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var doAnimate=$.support.transition&&animate;this.$backdrop=$('<div class="modal-backdrop '+animate+'" />').appendTo(document.body),this.$backdrop.click("static"==this.options.backdrop?$.proxy(this.$element[0].focus,this.$element[0]):$.proxy(this.hide,this)),doAnimate&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),doAnimate?this.$backdrop.one($.support.transition.end,callback):callback()}else!this.isShown&&this.$backdrop?(this.$backdrop.removeClass("in"),$.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one($.support.transition.end,$.proxy(this.removeBackdrop,this)):this.removeBackdrop()):callback&&callback()}};var old=$.fn.modal;$.fn.modal=function(option){return this.each(function(){var $this=$(this),data=$this.data("modal"),options=$.extend({},$.fn.modal.defaults,$this.data(),"object"==typeof option&&option);data||$this.data("modal",data=new Modal(this,options)),"string"==typeof option?data[option]():options.show&&data.show()})},$.fn.modal.defaults={backdrop:!0,keyboard:!0,show:!0},$.fn.modal.Constructor=Modal,$.fn.modal.noConflict=function(){return $.fn.modal=old,this},$(document).on("click.modal.data-api",'[data-toggle="modal"]',function(e){var $this=$(this),href=$this.attr("href"),$target=$($this.attr("data-target")||href&&href.replace(/.*(?=#[^\s]+$)/,"")),option=$target.data("modal")?"toggle":$.extend({remote:!/#/.test(href)&&href},$target.data(),$this.data());e.preventDefault(),$target.modal(option).one("hide",function(){$this.focus()})})}(window.jQuery),!function($){"use strict";var Tooltip=function(element,options){this.init("tooltip",element,options)};Tooltip.prototype={constructor:Tooltip,init:function(type,element,options){var eventIn,eventOut;this.type=type,this.$element=$(element),this.options=this.getOptions(options),this.enabled=!0,"click"==this.options.trigger?this.$element.on("click."+this.type,this.options.selector,$.proxy(this.toggle,this)):"manual"!=this.options.trigger&&(eventIn="hover"==this.options.trigger?"mouseenter":"focus",eventOut="hover"==this.options.trigger?"mouseleave":"blur",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()},getOptions:function(options){return options=$.extend({},$.fn[this.type].defaults,options,this.$element.data()),options.delay&&"number"==typeof options.delay&&(options.delay={show:options.delay,hide:options.delay}),options},enter:function(e){var self=$(e.currentTarget)[this.type](this._options).data(this.type);return self.options.delay&&self.options.delay.show?(clearTimeout(this.timeout),self.hoverState="in",this.timeout=setTimeout(function(){"in"==self.hoverState&&self.show()},self.options.delay.show),void 0):self.show()},leave:function(e){var self=$(e.currentTarget)[this.type](this._options).data(this.type);return this.timeout&&clearTimeout(this.timeout),self.options.delay&&self.options.delay.hide?(self.hoverState="out",this.timeout=setTimeout(function(){"out"==self.hoverState&&self.hide()},self.options.delay.hide),void 0):self.hide()},show:function(){var $tip,inside,pos,actualWidth,actualHeight,placement,tp;if(this.hasContent()&&this.enabled){switch($tip=this.tip(),this.setContent(),this.options.animation&&$tip.addClass("fade"),placement="function"==typeof this.options.placement?this.options.placement.call(this,$tip[0],this.$element[0]):this.options.placement,inside=/in/.test(placement),$tip.detach().css({top:0,left:0,display:"block"}).insertAfter(this.$element),pos=this.getPosition(inside),actualWidth=$tip[0].offsetWidth,actualHeight=$tip[0].offsetHeight,inside?placement.split(" ")[1]:placement){case"bottom":tp={top:pos.top+pos.height,left:pos.left+pos.width/2-actualWidth/2};break;case"top":tp={top:pos.top-actualHeight,left:pos.left+pos.width/2-actualWidth/2};break;case"left":tp={top:pos.top+pos.height/2-actualHeight/2,left:pos.left-actualWidth};break;case"right":tp={top:pos.top+pos.height/2-actualHeight/2,left:pos.left+pos.width}}$tip.offset(tp).addClass(placement).addClass("in")}},setContent:function(){var $tip=this.tip(),title=this.getTitle();$tip.find(".tooltip-inner")[this.options.html?"html":"text"](title),$tip.removeClass("fade in top bottom left right")},hide:function(){function removeWithAnimation(){var timeout=setTimeout(function(){$tip.off($.support.transition.end).detach()},500);$tip.one($.support.transition.end,function(){clearTimeout(timeout),$tip.detach()})}var $tip=this.tip();return $tip.removeClass("in"),$.support.transition&&this.$tip.hasClass("fade")?removeWithAnimation():$tip.detach(),this},fixTitle:function(){var $e=this.$element;($e.attr("title")||"string"!=typeof $e.attr("data-original-title"))&&$e.attr("data-original-title",$e.attr("title")||"").removeAttr("title")},hasContent:function(){return this.getTitle()},getPosition:function(inside){return $.extend({},inside?{top:0,left:0}:this.$element.offset(),{width:this.$element[0].offsetWidth,height:this.$element[0].offsetHeight})},getTitle:function(){var title,$e=this.$element,o=this.options;return title=$e.attr("data-original-title")||("function"==typeof o.title?o.title.call($e[0]):o.title)},tip:function(){return this.$tip=this.$tip||$(this.options.template)},validate:function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},enable:function(){this.enabled=!0},disable:function(){this.enabled=!1},toggleEnabled:function(){this.enabled=!this.enabled},toggle:function(e){var self=$(e.currentTarget)[this.type](this._options).data(this.type);self[self.tip().hasClass("in")?"hide":"show"]()},destroy:function(){this.hide().$element.off("."+this.type).removeData(this.type)}};var old=$.fn.tooltip;$.fn.tooltip=function(option){return this.each(function(){var $this=$(this),data=$this.data("tooltip"),options="object"==typeof option&&option;data||$this.data("tooltip",data=new Tooltip(this,options)),"string"==typeof option&&data[option]()})},$.fn.tooltip.Constructor=Tooltip,$.fn.tooltip.defaults={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover",title:"",delay:0,html:!1},$.fn.tooltip.noConflict=function(){return $.fn.tooltip=old,this}}(window.jQuery),!function($){"use strict";var Popover=function(element,options){this.init("popover",element,options)};Popover.prototype=$.extend({},$.fn.tooltip.Constructor.prototype,{constructor:Popover,setContent:function(){var $tip=this.tip(),title=this.getTitle(),content=this.getContent();$tip.find(".popover-title")[this.options.html?"html":"text"](title),$tip.find(".popover-content")[this.options.html?"html":"text"](content),$tip.removeClass("fade top bottom left right in")},hasContent:function(){return this.getTitle()||this.getContent()},getContent:function(){var content,$e=this.$element,o=this.options;return content=$e.attr("data-content")||("function"==typeof o.content?o.content.call($e[0]):o.content)},tip:function(){return this.$tip||(this.$tip=$(this.options.template)),this.$tip},destroy:function(){this.hide().$element.off("."+this.type).removeData(this.type)}});var old=$.fn.popover;$.fn.popover=function(option){return this.each(function(){var $this=$(this),data=$this.data("popover"),options="object"==typeof option&&option;data||$this.data("popover",data=new Popover(this,options)),"string"==typeof option&&data[option]()})},$.fn.popover.Constructor=Popover,$.fn.popover.defaults=$.extend({},$.fn.tooltip.defaults,{placement:"right",trigger:"click",content:"",template:'<div class="popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"></div></div></div>'}),$.fn.popover.noConflict=function(){return $.fn.popover=old,this}}(window.jQuery),!function($){"use strict";function ScrollSpy(element,options){var href,process=$.proxy(this.process,this),$element=$(element).is("body")?$(window):$(element);this.options=$.extend({},$.fn.scrollspy.defaults,options),this.$scrollElement=$element.on("scroll.scroll-spy.data-api",process),this.selector=(this.options.target||(href=$(element).attr("href"))&&href.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a",this.$body=$("body"),this.refresh(),this.process()}ScrollSpy.prototype={constructor:ScrollSpy,refresh:function(){var $targets,self=this;this.offsets=$([]),this.targets=$([]),$targets=this.$body.find(this.selector).map(function(){var $el=$(this),href=$el.data("target")||$el.attr("href"),$href=/^#\w/.test(href)&&$(href);return $href&&$href.length&&[[$href.position().top+self.$scrollElement.scrollTop(),href]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){self.offsets.push(this[0]),self.targets.push(this[1])})},process:function(){var i,scrollTop=this.$scrollElement.scrollTop()+this.options.offset,scrollHeight=this.$scrollElement[0].scrollHeight||this.$body[0].scrollHeight,maxScroll=scrollHeight-this.$scrollElement.height(),offsets=this.offsets,targets=this.targets,activeTarget=this.activeTarget;if(scrollTop>=maxScroll)return activeTarget!=(i=targets.last()[0])&&this.activate(i);for(i=offsets.length;i--;)activeTarget!=targets[i]&&scrollTop>=offsets[i]&&(!offsets[i+1]||offsets[i+1]>=scrollTop)&&this.activate(targets[i])},activate:function(target){var active,selector;this.activeTarget=target,$(this.selector).parent(".active").removeClass("active"),selector=this.selector+'[data-target="'+target+'"],'+this.selector+'[href="'+target+'"]',active=$(selector).parent("li").addClass("active"),active.parent(".dropdown-menu").length&&(active=active.closest("li.dropdown").addClass("active")),active.trigger("activate")}};var old=$.fn.scrollspy;$.fn.scrollspy=function(option){return this.each(function(){var $this=$(this),data=$this.data("scrollspy"),options="object"==typeof option&&option;data||$this.data("scrollspy",data=new ScrollSpy(this,options)),"string"==typeof option&&data[option]()})},$.fn.scrollspy.Constructor=ScrollSpy,$.fn.scrollspy.defaults={offset:10},$.fn.scrollspy.noConflict=function(){return $.fn.scrollspy=old,this},$(window).on("load",function(){$('[data-spy="scroll"]').each(function(){var $spy=$(this);$spy.scrollspy($spy.data())})})}(window.jQuery),!function($){"use strict";var Tab=function(element){this.element=$(element)};Tab.prototype={constructor:Tab,show:function(){var previous,$target,e,$this=this.element,$ul=$this.closest("ul:not(.dropdown-menu)"),selector=$this.attr("data-target");selector||(selector=$this.attr("href"),selector=selector&&selector.replace(/.*(?=#[^\s]*$)/,"")),$this.parent("li").hasClass("active")||(previous=$ul.find(".active:last a")[0],e=$.Event("show",{relatedTarget:previous}),$this.trigger(e),e.isDefaultPrevented()||($target=$(selector),this.activate($this.parent("li"),$ul),this.activate($target,$target.parent(),function(){$this.trigger({type:"shown",relatedTarget:previous})})))},activate:function(element,container,callback){function next(){$active.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),element.addClass("active"),transition?(element[0].offsetWidth,element.addClass("in")):element.removeClass("fade"),element.parent(".dropdown-menu")&&element.closest("li.dropdown").addClass("active"),callback&&callback()}var $active=container.find("> .active"),transition=callback&&$.support.transition&&$active.hasClass("fade");transition?$active.one($.support.transition.end,next):next(),$active.removeClass("in")}};var old=$.fn.tab;$.fn.tab=function(option){return this.each(function(){var $this=$(this),data=$this.data("tab");data||$this.data("tab",data=new Tab(this)),"string"==typeof option&&data[option]()})},$.fn.tab.Constructor=Tab,$.fn.tab.noConflict=function(){return $.fn.tab=old,this},$(document).on("click.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(e){e.preventDefault(),$(this).tab("show")})}(window.jQuery),!function($){"use strict";var Typeahead=function(element,options){this.$element=$(element),this.options=$.extend({},$.fn.typeahead.defaults,options),this.matcher=this.options.matcher||this.matcher,this.sorter=this.options.sorter||this.sorter,this.highlighter=this.options.highlighter||this.highlighter,this.updater=this.options.updater||this.updater,this.source=this.options.source,this.$menu=$(this.options.menu),this.shown=!1,this.listen()};Typeahead.prototype={constructor:Typeahead,select:function(){var val=this.$menu.find(".active").attr("data-value");return this.$element.val(this.updater(val)).change(),this.hide()},updater:function(item){return item},show:function(){var pos=$.extend({},this.$element.position(),{height:this.$element[0].offsetHeight});return this.$menu.insertAfter(this.$element).css({top:pos.top+pos.height,left:pos.left}).show(),this.shown=!0,this},hide:function(){return this.$menu.hide(),this.shown=!1,this},lookup:function(){var items;return this.query=this.$element.val(),!this.query||this.query.length<this.options.minLength?this.shown?this.hide():this:(items=$.isFunction(this.source)?this.source(this.query,$.proxy(this.process,this)):this.source,items?this.process(items):this)},process:function(items){var that=this;return items=$.grep(items,function(item){return that.matcher(item)}),items=this.sorter(items),items.length?this.render(items.slice(0,this.options.items)).show():this.shown?this.hide():this},matcher:function(item){return~item.toLowerCase().indexOf(this.query.toLowerCase())},sorter:function(items){for(var item,beginswith=[],caseSensitive=[],caseInsensitive=[];item=items.shift();)item.toLowerCase().indexOf(this.query.toLowerCase())?~item.indexOf(this.query)?caseSensitive.push(item):caseInsensitive.push(item):beginswith.push(item);return beginswith.concat(caseSensitive,caseInsensitive)},highlighter:function(item){var query=this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&");return item.replace(RegExp("("+query+")","ig"),function($1,match){return"<strong>"+match+"</strong>"})},render:function(items){var that=this;return items=$(items).map(function(i,item){return i=$(that.options.item).attr("data-value",item),i.find("a").html(that.highlighter(item)),i[0]}),items.first().addClass("active"),this.$menu.html(items),this},next:function(){var active=this.$menu.find(".active").removeClass("active"),next=active.next();next.length||(next=$(this.$menu.find("li")[0])),next.addClass("active")},prev:function(){var active=this.$menu.find(".active").removeClass("active"),prev=active.prev();prev.length||(prev=this.$menu.find("li").last()),prev.addClass("active")},listen:function(){this.$element.on("blur",$.proxy(this.blur,this)).on("keypress",$.proxy(this.keypress,this)).on("keyup",$.proxy(this.keyup,this)),this.eventSupported("keydown")&&this.$element.on("keydown",$.proxy(this.keydown,this)),this.$menu.on("click",$.proxy(this.click,this)).on("mouseenter","li",$.proxy(this.mouseenter,this))},eventSupported:function(eventName){var isSupported=eventName in this.$element;return isSupported||(this.$element.setAttribute(eventName,"return;"),isSupported="function"==typeof this.$element[eventName]),isSupported},move:function(e){if(this.shown){switch(e.keyCode){case 9:case 13:case 27:e.preventDefault();break;case 38:e.preventDefault(),this.prev();break;case 40:e.preventDefault(),this.next()}e.stopPropagation()}},keydown:function(e){this.suppressKeyPressRepeat=~$.inArray(e.keyCode,[40,38,9,13,27]),this.move(e)},keypress:function(e){this.suppressKeyPressRepeat||this.move(e)},keyup:function(e){switch(e.keyCode){case 40:case 38:case 16:case 17:case 18:break;case 9:case 13:if(!this.shown)return;this.select();break;case 27:if(!this.shown)return;this.hide();break;default:this.lookup()}e.stopPropagation(),e.preventDefault()},blur:function(){var that=this;setTimeout(function(){that.hide()},150)},click:function(e){e.stopPropagation(),e.preventDefault(),this.select()},mouseenter:function(e){this.$menu.find(".active").removeClass("active"),$(e.currentTarget).addClass("active")}};var old=$.fn.typeahead;$.fn.typeahead=function(option){return this.each(function(){var $this=$(this),data=$this.data("typeahead"),options="object"==typeof option&&option;data||$this.data("typeahead",data=new Typeahead(this,options)),"string"==typeof option&&data[option]()})},$.fn.typeahead.defaults={source:[],items:8,menu:'<ul class="typeahead dropdown-menu"></ul>',item:'<li><a href="#"></a></li>',minLength:1},$.fn.typeahead.Constructor=Typeahead,$.fn.typeahead.noConflict=function(){return $.fn.typeahead=old,this},$(document).on("focus.typeahead.data-api",'[data-provide="typeahead"]',function(e){var $this=$(this);$this.data("typeahead")||(e.preventDefault(),$this.typeahead($this.data()))})}(window.jQuery),!function($){"use strict";var Affix=function(element,options){this.options=$.extend({},$.fn.affix.defaults,options),this.$window=$(window).on("scroll.affix.data-api",$.proxy(this.checkPosition,this)).on("click.affix.data-api",$.proxy(function(){setTimeout($.proxy(this.checkPosition,this),1)},this)),this.$element=$(element),this.checkPosition()};Affix.prototype.checkPosition=function(){if(this.$element.is(":visible")){var affix,scrollHeight=$(document).height(),scrollTop=this.$window.scrollTop(),position=this.$element.offset(),offset=this.options.offset,offsetBottom=offset.bottom,offsetTop=offset.top,reset="affix affix-top affix-bottom";"object"!=typeof offset&&(offsetBottom=offsetTop=offset),"function"==typeof offsetTop&&(offsetTop=offset.top()),"function"==typeof offsetBottom&&(offsetBottom=offset.bottom()),affix=null!=this.unpin&&scrollTop+this.unpin<=position.top?!1:null!=offsetBottom&&position.top+this.$element.height()>=scrollHeight-offsetBottom?"bottom":null!=offsetTop&&offsetTop>=scrollTop?"top":!1,this.affixed!==affix&&(this.affixed=affix,this.unpin="bottom"==affix?position.top-scrollTop:null,this.$element.removeClass(reset).addClass("affix"+(affix?"-"+affix:"")))}};var old=$.fn.affix;$.fn.affix=function(option){return this.each(function(){var $this=$(this),data=$this.data("affix"),options="object"==typeof option&&option;data||$this.data("affix",data=new Affix(this,options)),"string"==typeof option&&data[option]()})},$.fn.affix.Constructor=Affix,$.fn.affix.defaults={offset:0},$.fn.affix.noConflict=function(){return $.fn.affix=old,this},$(window).on("load",function(){$('[data-spy="affix"]').each(function(){var $spy=$(this),data=$spy.data();data.offset=data.offset||{},data.offsetBottom&&(data.offset.bottom=data.offsetBottom),data.offsetTop&&(data.offset.top=data.offsetTop),$spy.affix(data)})})}(window.jQuery); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2011 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Loads templates from other loaders. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterface | |
| { | |
| private $hasSourceCache = array(); | |
| protected $loaders; | |
| /** | |
| * Constructor. | |
| * | |
| * @param Twig_LoaderInterface[] $loaders An array of loader instances | |
| */ | |
| public function __construct(array $loaders = array()) | |
| { | |
| $this->loaders = array(); | |
| foreach ($loaders as $loader) { | |
| $this->addLoader($loader); | |
| } | |
| } | |
| /** | |
| * Adds a loader instance. | |
| * | |
| * @param Twig_LoaderInterface $loader A Loader instance | |
| */ | |
| public function addLoader(Twig_LoaderInterface $loader) | |
| { | |
| $this->loaders[] = $loader; | |
| $this->hasSourceCache = array(); | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function getSource($name) | |
| { | |
| $exceptions = array(); | |
| foreach ($this->loaders as $loader) { | |
| if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) { | |
| continue; | |
| } | |
| try { | |
| return $loader->getSource($name); | |
| } catch (Twig_Error_Loader $e) { | |
| $exceptions[] = $e->getMessage(); | |
| } | |
| } | |
| throw new Twig_Error_Loader(sprintf('Template "%s" is not defined (%s).', $name, implode(', ', $exceptions))); | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function exists($name) | |
| { | |
| $name = (string) $name; | |
| if (isset($this->hasSourceCache[$name])) { | |
| return $this->hasSourceCache[$name]; | |
| } | |
| foreach ($this->loaders as $loader) { | |
| if ($loader instanceof Twig_ExistsLoaderInterface && $loader->exists($name)) { | |
| return $this->hasSourceCache[$name] = true; | |
| } | |
| try { | |
| $loader->getSource($name); | |
| return $this->hasSourceCache[$name] = true; | |
| } catch (Twig_Error_Loader $e) { | |
| } | |
| } | |
| return $this->hasSourceCache[$name] = false; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function getCacheKey($name) | |
| { | |
| $exceptions = array(); | |
| foreach ($this->loaders as $loader) { | |
| if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) { | |
| continue; | |
| } | |
| try { | |
| return $loader->getCacheKey($name); | |
| } catch (Twig_Error_Loader $e) { | |
| $exceptions[] = get_class($loader).': '.$e->getMessage(); | |
| } | |
| } | |
| throw new Twig_Error_Loader(sprintf('Template "%s" is not defined (%s).', $name, implode(' ', $exceptions))); | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function isFresh($name, $time) | |
| { | |
| $exceptions = array(); | |
| foreach ($this->loaders as $loader) { | |
| if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) { | |
| continue; | |
| } | |
| try { | |
| return $loader->isFresh($name, $time); | |
| } catch (Twig_Error_Loader $e) { | |
| $exceptions[] = get_class($loader).': '.$e->getMessage(); | |
| } | |
| } | |
| throw new Twig_Error_Loader(sprintf('Template "%s" is not defined (%s).', $name, implode(' ', $exceptions))); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Compiles a node to PHP code. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Compiler implements Twig_CompilerInterface | |
| { | |
| protected $lastLine; | |
| protected $source; | |
| protected $indentation; | |
| protected $env; | |
| protected $debugInfo; | |
| protected $sourceOffset; | |
| protected $sourceLine; | |
| protected $filename; | |
| /** | |
| * Constructor. | |
| * | |
| * @param Twig_Environment $env The twig environment instance | |
| */ | |
| public function __construct(Twig_Environment $env) | |
| { | |
| $this->env = $env; | |
| $this->debugInfo = array(); | |
| } | |
| public function getFilename() | |
| { | |
| return $this->filename; | |
| } | |
| /** | |
| * Returns the environment instance related to this compiler. | |
| * | |
| * @return Twig_Environment The environment instance | |
| */ | |
| public function getEnvironment() | |
| { | |
| return $this->env; | |
| } | |
| /** | |
| * Gets the current PHP code after compilation. | |
| * | |
| * @return string The PHP code | |
| */ | |
| public function getSource() | |
| { | |
| return $this->source; | |
| } | |
| /** | |
| * Compiles a node. | |
| * | |
| * @param Twig_NodeInterface $node The node to compile | |
| * @param integer $indentation The current indentation | |
| * | |
| * @return Twig_Compiler The current compiler instance | |
| */ | |
| public function compile(Twig_NodeInterface $node, $indentation = 0) | |
| { | |
| $this->lastLine = null; | |
| $this->source = ''; | |
| $this->sourceOffset = 0; | |
| // source code starts at 1 (as we then increment it when we encounter new lines) | |
| $this->sourceLine = 1; | |
| $this->indentation = $indentation; | |
| if ($node instanceof Twig_Node_Module) { | |
| $this->filename = $node->getAttribute('filename'); | |
| } | |
| $node->compile($this); | |
| return $this; | |
| } | |
| public function subcompile(Twig_NodeInterface $node, $raw = true) | |
| { | |
| if (false === $raw) { | |
| $this->addIndentation(); | |
| } | |
| $node->compile($this); | |
| return $this; | |
| } | |
| /** | |
| * Adds a raw string to the compiled code. | |
| * | |
| * @param string $string The string | |
| * | |
| * @return Twig_Compiler The current compiler instance | |
| */ | |
| public function raw($string) | |
| { | |
| $this->source .= $string; | |
| return $this; | |
| } | |
| /** | |
| * Writes a string to the compiled code by adding indentation. | |
| * | |
| * @return Twig_Compiler The current compiler instance | |
| */ | |
| public function write() | |
| { | |
| $strings = func_get_args(); | |
| foreach ($strings as $string) { | |
| $this->addIndentation(); | |
| $this->source .= $string; | |
| } | |
| return $this; | |
| } | |
| /** | |
| * Appends an indentation to the current PHP code after compilation. | |
| * | |
| * @return Twig_Compiler The current compiler instance | |
| */ | |
| public function addIndentation() | |
| { | |
| $this->source .= str_repeat(' ', $this->indentation * 4); | |
| return $this; | |
| } | |
| /** | |
| * Adds a quoted string to the compiled code. | |
| * | |
| * @param string $value The string | |
| * | |
| * @return Twig_Compiler The current compiler instance | |
| */ | |
| public function string($value) | |
| { | |
| $this->source .= sprintf('"%s"', addcslashes($value, "\0\t\"\$\\")); | |
| return $this; | |
| } | |
| /** | |
| * Returns a PHP representation of a given value. | |
| * | |
| * @param mixed $value The value to convert | |
| * | |
| * @return Twig_Compiler The current compiler instance | |
| */ | |
| public function repr($value) | |
| { | |
| if (is_int($value) || is_float($value)) { | |
| if (false !== $locale = setlocale(LC_NUMERIC, 0)) { | |
| setlocale(LC_NUMERIC, 'C'); | |
| } | |
| $this->raw($value); | |
| if (false !== $locale) { | |
| setlocale(LC_NUMERIC, $locale); | |
| } | |
| } elseif (null === $value) { | |
| $this->raw('null'); | |
| } elseif (is_bool($value)) { | |
| $this->raw($value ? 'true' : 'false'); | |
| } elseif (is_array($value)) { | |
| $this->raw('array('); | |
| $i = 0; | |
| foreach ($value as $key => $value) { | |
| if ($i++) { | |
| $this->raw(', '); | |
| } | |
| $this->repr($key); | |
| $this->raw(' => '); | |
| $this->repr($value); | |
| } | |
| $this->raw(')'); | |
| } else { | |
| $this->string($value); | |
| } | |
| return $this; | |
| } | |
| /** | |
| * Adds debugging information. | |
| * | |
| * @param Twig_NodeInterface $node The related twig node | |
| * | |
| * @return Twig_Compiler The current compiler instance | |
| */ | |
| public function addDebugInfo(Twig_NodeInterface $node) | |
| { | |
| if ($node->getLine() != $this->lastLine) { | |
| $this->write("// line {$node->getLine()}\n"); | |
| // when mbstring.func_overload is set to 2 | |
| // mb_substr_count() replaces substr_count() | |
| // but they have different signatures! | |
| if (((int) ini_get('mbstring.func_overload')) & 2) { | |
| // this is much slower than the "right" version | |
| $this->sourceLine += mb_substr_count(mb_substr($this->source, $this->sourceOffset), "\n"); | |
| } else { | |
| $this->sourceLine += substr_count($this->source, "\n", $this->sourceOffset); | |
| } | |
| $this->sourceOffset = strlen($this->source); | |
| $this->debugInfo[$this->sourceLine] = $node->getLine(); | |
| $this->lastLine = $node->getLine(); | |
| } | |
| return $this; | |
| } | |
| public function getDebugInfo() | |
| { | |
| return $this->debugInfo; | |
| } | |
| /** | |
| * Indents the generated code. | |
| * | |
| * @param integer $step The number of indentation to add | |
| * | |
| * @return Twig_Compiler The current compiler instance | |
| */ | |
| public function indent($step = 1) | |
| { | |
| $this->indentation += $step; | |
| return $this; | |
| } | |
| /** | |
| * Outdents the generated code. | |
| * | |
| * @param integer $step The number of indentation to remove | |
| * | |
| * @return Twig_Compiler The current compiler instance | |
| */ | |
| public function outdent($step = 1) | |
| { | |
| // can't outdent by more steps that the current indentation level | |
| if ($this->indentation < $step) { | |
| throw new LogicException('Unable to call outdent() as the indentation would become negative'); | |
| } | |
| $this->indentation -= $step; | |
| return $this; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Interface implemented by compiler classes. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| interface Twig_CompilerInterface | |
| { | |
| /** | |
| * Compiles a node. | |
| * | |
| * @param Twig_NodeInterface $node The node to compile | |
| * | |
| * @return Twig_CompilerInterface The current compiler instance | |
| */ | |
| public function compile(Twig_NodeInterface $node); | |
| /** | |
| * Gets the current PHP code after compilation. | |
| * | |
| * @return string The PHP code | |
| */ | |
| public function getSource(); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Binary_Concat extends Twig_Node_Expression_Binary | |
| { | |
| public function operator(Twig_Compiler $compiler) | |
| { | |
| return $compiler->raw('.'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Conditional extends Twig_Node_Expression | |
| { | |
| public function __construct(Twig_Node_Expression $expr1, Twig_Node_Expression $expr2, Twig_Node_Expression $expr3, $lineno) | |
| { | |
| parent::__construct(array('expr1' => $expr1, 'expr2' => $expr2, 'expr3' => $expr3), array(), $lineno); | |
| } | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->raw('((') | |
| ->subcompile($this->getNode('expr1')) | |
| ->raw(') ? (') | |
| ->subcompile($this->getNode('expr2')) | |
| ->raw(') : (') | |
| ->subcompile($this->getNode('expr3')) | |
| ->raw('))') | |
| ; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Constant extends Twig_Node_Expression | |
| { | |
| public function __construct($value, $lineno) | |
| { | |
| parent::__construct(array(), array('value' => $value), $lineno); | |
| } | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler->repr($this->getAttribute('value')); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2011 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Checks if a variable is the exact same value as a constant. | |
| * | |
| * <pre> | |
| * {% if post.status is constant('Post::PUBLISHED') %} | |
| * the status attribute is exactly the same as Post::PUBLISHED | |
| * {% endif %} | |
| * </pre> | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_Expression_Test_Constant extends Twig_Node_Expression_Test | |
| { | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->raw('(') | |
| ->subcompile($this->getNode('node')) | |
| ->raw(' === constant(') | |
| ->subcompile($this->getNode('arguments')->getNode(0)) | |
| ->raw('))') | |
| ; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| if (!defined('ENT_SUBSTITUTE')) { | |
| define('ENT_SUBSTITUTE', 8); | |
| } | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Extension_Core extends Twig_Extension | |
| { | |
| protected $dateFormats = array('F j, Y H:i', '%d days'); | |
| protected $numberFormat = array(0, '.', ','); | |
| protected $timezone = null; | |
| /** | |
| * Sets the default format to be used by the date filter. | |
| * | |
| * @param string $format The default date format string | |
| * @param string $dateIntervalFormat The default date interval format string | |
| */ | |
| public function setDateFormat($format = null, $dateIntervalFormat = null) | |
| { | |
| if (null !== $format) { | |
| $this->dateFormats[0] = $format; | |
| } | |
| if (null !== $dateIntervalFormat) { | |
| $this->dateFormats[1] = $dateIntervalFormat; | |
| } | |
| } | |
| /** | |
| * Gets the default format to be used by the date filter. | |
| * | |
| * @return array The default date format string and the default date interval format string | |
| */ | |
| public function getDateFormat() | |
| { | |
| return $this->dateFormats; | |
| } | |
| /** | |
| * Sets the default timezone to be used by the date filter. | |
| * | |
| * @param DateTimeZone|string $timezone The default timezone string or a DateTimeZone object | |
| */ | |
| public function setTimezone($timezone) | |
| { | |
| $this->timezone = $timezone instanceof DateTimeZone ? $timezone : new DateTimeZone($timezone); | |
| } | |
| /** | |
| * Gets the default timezone to be used by the date filter. | |
| * | |
| * @return DateTimeZone The default timezone currently in use | |
| */ | |
| public function getTimezone() | |
| { | |
| if (null === $this->timezone) { | |
| $this->timezone = new DateTimeZone(date_default_timezone_get()); | |
| } | |
| return $this->timezone; | |
| } | |
| /** | |
| * Sets the default format to be used by the number_format filter. | |
| * | |
| * @param integer $decimal The number of decimal places to use. | |
| * @param string $decimalPoint The character(s) to use for the decimal point. | |
| * @param string $thousandSep The character(s) to use for the thousands separator. | |
| */ | |
| public function setNumberFormat($decimal, $decimalPoint, $thousandSep) | |
| { | |
| $this->numberFormat = array($decimal, $decimalPoint, $thousandSep); | |
| } | |
| /** | |
| * Get the default format used by the number_format filter. | |
| * | |
| * @return array The arguments for number_format() | |
| */ | |
| public function getNumberFormat() | |
| { | |
| return $this->numberFormat; | |
| } | |
| /** | |
| * Returns the token parser instance to add to the existing list. | |
| * | |
| * @return array An array of Twig_TokenParser instances | |
| */ | |
| public function getTokenParsers() | |
| { | |
| return array( | |
| new Twig_TokenParser_For(), | |
| new Twig_TokenParser_If(), | |
| new Twig_TokenParser_Extends(), | |
| new Twig_TokenParser_Include(), | |
| new Twig_TokenParser_Block(), | |
| new Twig_TokenParser_Use(), | |
| new Twig_TokenParser_Filter(), | |
| new Twig_TokenParser_Macro(), | |
| new Twig_TokenParser_Import(), | |
| new Twig_TokenParser_From(), | |
| new Twig_TokenParser_Set(), | |
| new Twig_TokenParser_Spaceless(), | |
| new Twig_TokenParser_Flush(), | |
| new Twig_TokenParser_Do(), | |
| new Twig_TokenParser_Embed(), | |
| ); | |
| } | |
| /** | |
| * Returns a list of filters to add to the existing list. | |
| * | |
| * @return array An array of filters | |
| */ | |
| public function getFilters() | |
| { | |
| $filters = array( | |
| // formatting filters | |
| 'date' => new Twig_Filter_Function('twig_date_format_filter', array('needs_environment' => true)), | |
| 'date_modify' => new Twig_Filter_Function('twig_date_modify_filter', array('needs_environment' => true)), | |
| 'format' => new Twig_Filter_Function('sprintf'), | |
| 'replace' => new Twig_Filter_Function('strtr'), | |
| 'number_format' => new Twig_Filter_Function('twig_number_format_filter', array('needs_environment' => true)), | |
| 'abs' => new Twig_Filter_Function('abs'), | |
| // encoding | |
| 'url_encode' => new Twig_Filter_Function('twig_urlencode_filter'), | |
| 'json_encode' => new Twig_Filter_Function('twig_jsonencode_filter'), | |
| 'convert_encoding' => new Twig_Filter_Function('twig_convert_encoding'), | |
| // string filters | |
| 'title' => new Twig_Filter_Function('twig_title_string_filter', array('needs_environment' => true)), | |
| 'capitalize' => new Twig_Filter_Function('twig_capitalize_string_filter', array('needs_environment' => true)), | |
| 'upper' => new Twig_Filter_Function('strtoupper'), | |
| 'lower' => new Twig_Filter_Function('strtolower'), | |
| 'striptags' => new Twig_Filter_Function('strip_tags'), | |
| 'trim' => new Twig_Filter_Function('trim'), | |
| 'nl2br' => new Twig_Filter_Function('nl2br', array('pre_escape' => 'html', 'is_safe' => array('html'))), | |
| // array helpers | |
| 'join' => new Twig_Filter_Function('twig_join_filter'), | |
| 'split' => new Twig_Filter_Function('twig_split_filter'), | |
| 'sort' => new Twig_Filter_Function('twig_sort_filter'), | |
| 'merge' => new Twig_Filter_Function('twig_array_merge'), | |
| // string/array filters | |
| 'reverse' => new Twig_Filter_Function('twig_reverse_filter', array('needs_environment' => true)), | |
| 'length' => new Twig_Filter_Function('twig_length_filter', array('needs_environment' => true)), | |
| 'slice' => new Twig_Filter_Function('twig_slice', array('needs_environment' => true)), | |
| // iteration and runtime | |
| 'default' => new Twig_Filter_Node('Twig_Node_Expression_Filter_Default'), | |
| '_default' => new Twig_Filter_Function('_twig_default_filter'), | |
| 'keys' => new Twig_Filter_Function('twig_get_array_keys_filter'), | |
| // escaping | |
| 'escape' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe')), | |
| 'e' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe')), | |
| ); | |
| if (function_exists('mb_get_info')) { | |
| $filters['upper'] = new Twig_Filter_Function('twig_upper_filter', array('needs_environment' => true)); | |
| $filters['lower'] = new Twig_Filter_Function('twig_lower_filter', array('needs_environment' => true)); | |
| } | |
| return $filters; | |
| } | |
| /** | |
| * Returns a list of global functions to add to the existing list. | |
| * | |
| * @return array An array of global functions | |
| */ | |
| public function getFunctions() | |
| { | |
| return array( | |
| 'range' => new Twig_Function_Function('range'), | |
| 'constant' => new Twig_Function_Function('constant'), | |
| 'cycle' => new Twig_Function_Function('twig_cycle'), | |
| 'random' => new Twig_Function_Function('twig_random', array('needs_environment' => true)), | |
| 'date' => new Twig_Function_Function('twig_date_converter', array('needs_environment' => true)), | |
| ); | |
| } | |
| /** | |
| * Returns a list of tests to add to the existing list. | |
| * | |
| * @return array An array of tests | |
| */ | |
| public function getTests() | |
| { | |
| return array( | |
| 'even' => new Twig_Test_Node('Twig_Node_Expression_Test_Even'), | |
| 'odd' => new Twig_Test_Node('Twig_Node_Expression_Test_Odd'), | |
| 'defined' => new Twig_Test_Node('Twig_Node_Expression_Test_Defined'), | |
| 'sameas' => new Twig_Test_Node('Twig_Node_Expression_Test_Sameas'), | |
| 'none' => new Twig_Test_Node('Twig_Node_Expression_Test_Null'), | |
| 'null' => new Twig_Test_Node('Twig_Node_Expression_Test_Null'), | |
| 'divisibleby' => new Twig_Test_Node('Twig_Node_Expression_Test_Divisibleby'), | |
| 'constant' => new Twig_Test_Node('Twig_Node_Expression_Test_Constant'), | |
| 'empty' => new Twig_Test_Function('twig_test_empty'), | |
| 'iterable' => new Twig_Test_Function('twig_test_iterable'), | |
| ); | |
| } | |
| /** | |
| * Returns a list of operators to add to the existing list. | |
| * | |
| * @return array An array of operators | |
| */ | |
| public function getOperators() | |
| { | |
| return array( | |
| array( | |
| 'not' => array('precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Not'), | |
| '-' => array('precedence' => 500, 'class' => 'Twig_Node_Expression_Unary_Neg'), | |
| '+' => array('precedence' => 500, 'class' => 'Twig_Node_Expression_Unary_Pos'), | |
| ), | |
| array( | |
| 'or' => array('precedence' => 10, 'class' => 'Twig_Node_Expression_Binary_Or', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), | |
| 'and' => array('precedence' => 15, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), | |
| 'b-or' => array('precedence' => 16, 'class' => 'Twig_Node_Expression_Binary_BitwiseOr', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), | |
| 'b-xor' => array('precedence' => 17, 'class' => 'Twig_Node_Expression_Binary_BitwiseXor', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), | |
| 'b-and' => array('precedence' => 18, 'class' => 'Twig_Node_Expression_Binary_BitwiseAnd', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), | |
| '==' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Equal', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), | |
| '!=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), | |
| '<' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Less', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), | |
| '>' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Greater', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), | |
| '>=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_GreaterEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), | |
| '<=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_LessEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), | |
| 'not in' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotIn', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), | |
| 'in' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_In', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), | |
| '..' => array('precedence' => 25, 'class' => 'Twig_Node_Expression_Binary_Range', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), | |
| '+' => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Add', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), | |
| '-' => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Sub', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), | |
| '~' => array('precedence' => 40, 'class' => 'Twig_Node_Expression_Binary_Concat', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), | |
| '*' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mul', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), | |
| '/' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Div', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), | |
| '//' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_FloorDiv', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), | |
| '%' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mod', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), | |
| 'is' => array('precedence' => 100, 'callable' => array($this, 'parseTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), | |
| 'is not' => array('precedence' => 100, 'callable' => array($this, 'parseNotTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), | |
| '**' => array('precedence' => 200, 'class' => 'Twig_Node_Expression_Binary_Power', 'associativity' => Twig_ExpressionParser::OPERATOR_RIGHT), | |
| ), | |
| ); | |
| } | |
| public function parseNotTestExpression(Twig_Parser $parser, $node) | |
| { | |
| return new Twig_Node_Expression_Unary_Not($this->parseTestExpression($parser, $node), $parser->getCurrentToken()->getLine()); | |
| } | |
| public function parseTestExpression(Twig_Parser $parser, $node) | |
| { | |
| $stream = $parser->getStream(); | |
| $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); | |
| $arguments = null; | |
| if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) { | |
| $arguments = $parser->getExpressionParser()->parseArguments(); | |
| } | |
| $class = $this->getTestNodeClass($parser->getEnvironment(), $name); | |
| return new $class($node, $name, $arguments, $parser->getCurrentToken()->getLine()); | |
| } | |
| protected function getTestNodeClass(Twig_Environment $env, $name) | |
| { | |
| $testMap = $env->getTests(); | |
| if (isset($testMap[$name]) && $testMap[$name] instanceof Twig_Test_Node) { | |
| return $testMap[$name]->getClass(); | |
| } | |
| return 'Twig_Node_Expression_Test'; | |
| } | |
| /** | |
| * Returns the name of the extension. | |
| * | |
| * @return string The extension name | |
| */ | |
| public function getName() | |
| { | |
| return 'core'; | |
| } | |
| } | |
| /** | |
| * Cycles over a value. | |
| * | |
| * @param ArrayAccess|array $values An array or an ArrayAccess instance | |
| * @param integer $i The cycle value | |
| * | |
| * @return string The next value in the cycle | |
| */ | |
| function twig_cycle($values, $i) | |
| { | |
| if (!is_array($values) && !$values instanceof ArrayAccess) { | |
| return $values; | |
| } | |
| return $values[$i % count($values)]; | |
| } | |
| /** | |
| * Returns a random value depending on the supplied parameter type: | |
| * - a random item from a Traversable or array | |
| * - a random character from a string | |
| * - a random integer between 0 and the integer parameter | |
| * | |
| * @param Twig_Environment $env A Twig_Environment instance | |
| * @param Traversable|array|integer|string $values The values to pick a random item from | |
| * | |
| * @throws Twig_Error_Runtime When $values is an empty array (does not apply to an empty string which is returned as is). | |
| * | |
| * @return mixed A random value from the given sequence | |
| */ | |
| function twig_random(Twig_Environment $env, $values = null) | |
| { | |
| if (null === $values) { | |
| return mt_rand(); | |
| } | |
| if (is_int($values) || is_float($values)) { | |
| return $values < 0 ? mt_rand($values, 0) : mt_rand(0, $values); | |
| } | |
| if ($values instanceof Traversable) { | |
| $values = iterator_to_array($values); | |
| } elseif (is_string($values)) { | |
| if ('' === $values) { | |
| return ''; | |
| } | |
| if (null !== $charset = $env->getCharset()) { | |
| if ('UTF-8' != $charset) { | |
| $values = twig_convert_encoding($values, 'UTF-8', $charset); | |
| } | |
| // unicode version of str_split() | |
| // split at all positions, but not after the start and not before the end | |
| $values = preg_split('/(?<!^)(?!$)/u', $values); | |
| if ('UTF-8' != $charset) { | |
| foreach ($values as $i => $value) { | |
| $values[$i] = twig_convert_encoding($value, $charset, 'UTF-8'); | |
| } | |
| } | |
| } else { | |
| return $values[mt_rand(0, strlen($values) - 1)]; | |
| } | |
| } | |
| if (!is_array($values)) { | |
| return $values; | |
| } | |
| if (0 === count($values)) { | |
| throw new Twig_Error_Runtime('The random function cannot pick from an empty array.'); | |
| } | |
| return $values[array_rand($values, 1)]; | |
| } | |
| /** | |
| * Converts a date to the given format. | |
| * | |
| * <pre> | |
| * {{ post.published_at|date("m/d/Y") }} | |
| * </pre> | |
| * | |
| * @param Twig_Environment $env A Twig_Environment instance | |
| * @param DateTime|DateInterval|string $date A date | |
| * @param string $format A format | |
| * @param DateTimeZone|string $timezone A timezone | |
| * | |
| * @return string The formatted date | |
| */ | |
| function twig_date_format_filter(Twig_Environment $env, $date, $format = null, $timezone = null) | |
| { | |
| if (null === $format) { | |
| $formats = $env->getExtension('core')->getDateFormat(); | |
| $format = $date instanceof DateInterval ? $formats[1] : $formats[0]; | |
| } | |
| if ($date instanceof DateInterval) { | |
| return $date->format($format); | |
| } | |
| return twig_date_converter($env, $date, $timezone)->format($format); | |
| } | |
| /** | |
| * Returns a new date object modified | |
| * | |
| * <pre> | |
| * {{ post.published_at|modify("-1day")|date("m/d/Y") }} | |
| * </pre> | |
| * | |
| * @param Twig_Environment $env A Twig_Environment instance | |
| * @param DateTime|string $date A date | |
| * @param string $modifier A modifier string | |
| * | |
| * @return DateTime A new date object | |
| */ | |
| function twig_date_modify_filter(Twig_Environment $env, $date, $modifier) | |
| { | |
| $date = twig_date_converter($env, $date, false); | |
| $date->modify($modifier); | |
| return $date; | |
| } | |
| /** | |
| * Converts an input to a DateTime instance. | |
| * | |
| * <pre> | |
| * {% if date(user.created_at) < date('+2days') %} | |
| * {# do something #} | |
| * {% endif %} | |
| * </pre> | |
| * | |
| * @param Twig_Environment $env A Twig_Environment instance | |
| * @param DateTime|string $date A date | |
| * @param DateTimeZone|string $timezone A timezone | |
| * | |
| * @return DateTime A DateTime instance | |
| */ | |
| function twig_date_converter(Twig_Environment $env, $date = null, $timezone = null) | |
| { | |
| // determine the timezone | |
| if (!$timezone) { | |
| $defaultTimezone = $env->getExtension('core')->getTimezone(); | |
| } elseif (!$timezone instanceof DateTimeZone) { | |
| $defaultTimezone = new DateTimeZone($timezone); | |
| } else { | |
| $defaultTimezone = $timezone; | |
| } | |
| if ($date instanceof DateTime) { | |
| $date = clone $date; | |
| if (false !== $timezone) { | |
| $date->setTimezone($defaultTimezone); | |
| } | |
| return $date; | |
| } | |
| $asString = (string) $date; | |
| if (ctype_digit($asString) || (!empty($asString) && '-' === $asString[0] && ctype_digit(substr($asString, 1)))) { | |
| $date = new DateTime('@'.$date); | |
| $date->setTimezone($defaultTimezone); | |
| return $date; | |
| } | |
| return new DateTime($date, $defaultTimezone); | |
| } | |
| /** | |
| * Number format filter. | |
| * | |
| * All of the formatting options can be left null, in that case the defaults will | |
| * be used. Supplying any of the parameters will override the defaults set in the | |
| * environment object. | |
| * | |
| * @param Twig_Environment $env A Twig_Environment instance | |
| * @param mixed $number A float/int/string of the number to format | |
| * @param integer $decimal The number of decimal points to display. | |
| * @param string $decimalPoint The character(s) to use for the decimal point. | |
| * @param string $thousandSep The character(s) to use for the thousands separator. | |
| * | |
| * @return string The formatted number | |
| */ | |
| function twig_number_format_filter(Twig_Environment $env, $number, $decimal = null, $decimalPoint = null, $thousandSep = null) | |
| { | |
| $defaults = $env->getExtension('core')->getNumberFormat(); | |
| if (null === $decimal) { | |
| $decimal = $defaults[0]; | |
| } | |
| if (null === $decimalPoint) { | |
| $decimalPoint = $defaults[1]; | |
| } | |
| if (null === $thousandSep) { | |
| $thousandSep = $defaults[2]; | |
| } | |
| return number_format((float) $number, $decimal, $decimalPoint, $thousandSep); | |
| } | |
| /** | |
| * URL encodes a string. | |
| * | |
| * @param string $url A URL | |
| * @param bool $raw true to use rawurlencode() instead of urlencode | |
| * | |
| * @return string The URL encoded value | |
| */ | |
| function twig_urlencode_filter($url, $raw = false) | |
| { | |
| if ($raw) { | |
| return rawurlencode($url); | |
| } | |
| return urlencode($url); | |
| } | |
| if (version_compare(PHP_VERSION, '5.3.0', '<')) { | |
| /** | |
| * JSON encodes a variable. | |
| * | |
| * @param mixed $value The value to encode. | |
| * @param integer $options Not used on PHP 5.2.x | |
| * | |
| * @return mixed The JSON encoded value | |
| */ | |
| function twig_jsonencode_filter($value, $options = 0) | |
| { | |
| if ($value instanceof Twig_Markup) { | |
| $value = (string) $value; | |
| } elseif (is_array($value)) { | |
| array_walk_recursive($value, '_twig_markup2string'); | |
| } | |
| return json_encode($value); | |
| } | |
| } else { | |
| /** | |
| * JSON encodes a variable. | |
| * | |
| * @param mixed $value The value to encode. | |
| * @param integer $options Bitmask consisting of JSON_HEX_QUOT, JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_NUMERIC_CHECK, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_FORCE_OBJECT | |
| * | |
| * @return mixed The JSON encoded value | |
| */ | |
| function twig_jsonencode_filter($value, $options = 0) | |
| { | |
| if ($value instanceof Twig_Markup) { | |
| $value = (string) $value; | |
| } elseif (is_array($value)) { | |
| array_walk_recursive($value, '_twig_markup2string'); | |
| } | |
| return json_encode($value, $options); | |
| } | |
| } | |
| function _twig_markup2string(&$value) | |
| { | |
| if ($value instanceof Twig_Markup) { | |
| $value = (string) $value; | |
| } | |
| } | |
| /** | |
| * Merges an array with another one. | |
| * | |
| * <pre> | |
| * {% set items = { 'apple': 'fruit', 'orange': 'fruit' } %} | |
| * | |
| * {% set items = items|merge({ 'peugeot': 'car' }) %} | |
| * | |
| * {# items now contains { 'apple': 'fruit', 'orange': 'fruit', 'peugeot': 'car' } #} | |
| * </pre> | |
| * | |
| * @param array $arr1 An array | |
| * @param array $arr2 An array | |
| * | |
| * @return array The merged array | |
| */ | |
| function twig_array_merge($arr1, $arr2) | |
| { | |
| if (!is_array($arr1) || !is_array($arr2)) { | |
| throw new Twig_Error_Runtime('The merge filter only works with arrays or hashes.'); | |
| } | |
| return array_merge($arr1, $arr2); | |
| } | |
| /** | |
| * Slices a variable. | |
| * | |
| * @param Twig_Environment $env A Twig_Environment instance | |
| * @param mixed $item A variable | |
| * @param integer $start Start of the slice | |
| * @param integer $length Size of the slice | |
| * @param Boolean $preserveKeys Whether to preserve key or not (when the input is an array) | |
| * | |
| * @return mixed The sliced variable | |
| */ | |
| function twig_slice(Twig_Environment $env, $item, $start, $length = null, $preserveKeys = false) | |
| { | |
| if ($item instanceof Traversable) { | |
| $item = iterator_to_array($item, false); | |
| } | |
| if (is_array($item)) { | |
| return array_slice($item, $start, $length, $preserveKeys); | |
| } | |
| $item = (string) $item; | |
| if (function_exists('mb_get_info') && null !== $charset = $env->getCharset()) { | |
| return mb_substr($item, $start, null === $length ? mb_strlen($item, $charset) - $start : $length, $charset); | |
| } | |
| return null === $length ? substr($item, $start) : substr($item, $start, $length); | |
| } | |
| /** | |
| * Joins the values to a string. | |
| * | |
| * The separator between elements is an empty string per default, you can define it with the optional parameter. | |
| * | |
| * <pre> | |
| * {{ [1, 2, 3]|join('|') }} | |
| * {# returns 1|2|3 #} | |
| * | |
| * {{ [1, 2, 3]|join }} | |
| * {# returns 123 #} | |
| * </pre> | |
| * | |
| * @param array $value An array | |
| * @param string $glue The separator | |
| * | |
| * @return string The concatenated string | |
| */ | |
| function twig_join_filter($value, $glue = '') | |
| { | |
| if ($value instanceof Traversable) { | |
| $value = iterator_to_array($value, false); | |
| } | |
| return implode($glue, (array) $value); | |
| } | |
| /** | |
| * Splits the string into an array. | |
| * | |
| * <pre> | |
| * {{ "one,two,three"|split(',') }} | |
| * {# returns [one, two, three] #} | |
| * | |
| * {{ "one,two,three,four,five"|split(',', 3) }} | |
| * {# returns [one, two, "three,four,five"] #} | |
| * | |
| * {{ "123"|split('') }} | |
| * {# returns [1, 2, 3] #} | |
| * | |
| * {{ "aabbcc"|split('', 2) }} | |
| * {# returns [aa, bb, cc] #} | |
| * </pre> | |
| * | |
| * @param string $value A string | |
| * @param string $delimiter The delimiter | |
| * @param integer $limit The limit | |
| * | |
| * @return array The split string as an array | |
| */ | |
| function twig_split_filter($value, $delimiter, $limit = null) | |
| { | |
| if (empty($delimiter)) { | |
| return str_split($value, null === $limit ? 1 : $limit); | |
| } | |
| return null === $limit ? explode($delimiter, $value) : explode($delimiter, $value, $limit); | |
| } | |
| // The '_default' filter is used internally to avoid using the ternary operator | |
| // which costs a lot for big contexts (before PHP 5.4). So, on average, | |
| // a function call is cheaper. | |
| function _twig_default_filter($value, $default = '') | |
| { | |
| if (twig_test_empty($value)) { | |
| return $default; | |
| } | |
| return $value; | |
| } | |
| /** | |
| * Returns the keys for the given array. | |
| * | |
| * It is useful when you want to iterate over the keys of an array: | |
| * | |
| * <pre> | |
| * {% for key in array|keys %} | |
| * {# ... #} | |
| * {% endfor %} | |
| * </pre> | |
| * | |
| * @param array $array An array | |
| * | |
| * @return array The keys | |
| */ | |
| function twig_get_array_keys_filter($array) | |
| { | |
| if (is_object($array) && $array instanceof Traversable) { | |
| return array_keys(iterator_to_array($array)); | |
| } | |
| if (!is_array($array)) { | |
| return array(); | |
| } | |
| return array_keys($array); | |
| } | |
| /** | |
| * Reverses a variable. | |
| * | |
| * @param Twig_Environment $env A Twig_Environment instance | |
| * @param array|Traversable|string $item An array, a Traversable instance, or a string | |
| * @param Boolean $preserveKeys Whether to preserve key or not | |
| * | |
| * @return mixed The reversed input | |
| */ | |
| function twig_reverse_filter(Twig_Environment $env, $item, $preserveKeys = false) | |
| { | |
| if (is_object($item) && $item instanceof Traversable) { | |
| return array_reverse(iterator_to_array($item), $preserveKeys); | |
| } | |
| if (is_array($item)) { | |
| return array_reverse($item, $preserveKeys); | |
| } | |
| if (null !== $charset = $env->getCharset()) { | |
| $string = (string) $item; | |
| if ('UTF-8' != $charset) { | |
| $item = twig_convert_encoding($string, 'UTF-8', $charset); | |
| } | |
| preg_match_all('/./us', $item, $matches); | |
| $string = implode('', array_reverse($matches[0])); | |
| if ('UTF-8' != $charset) { | |
| $string = twig_convert_encoding($string, $charset, 'UTF-8'); | |
| } | |
| return $string; | |
| } | |
| return strrev((string) $item); | |
| } | |
| /** | |
| * Sorts an array. | |
| * | |
| * @param array $array An array | |
| */ | |
| function twig_sort_filter($array) | |
| { | |
| asort($array); | |
| return $array; | |
| } | |
| /* used internally */ | |
| function twig_in_filter($value, $compare) | |
| { | |
| $strict = is_object($value); | |
| if (is_array($compare)) { | |
| return in_array($value, $compare, $strict); | |
| } elseif (is_string($compare)) { | |
| if (!strlen((string) $value)) { | |
| return empty($compare); | |
| } | |
| return false !== strpos($compare, (string) $value); | |
| } elseif (is_object($compare) && $compare instanceof Traversable) { | |
| return in_array($value, iterator_to_array($compare, false), $strict); | |
| } | |
| return false; | |
| } | |
| /** | |
| * Escapes a string. | |
| * | |
| * @param Twig_Environment $env A Twig_Environment instance | |
| * @param string $string The value to be escaped | |
| * @param string $strategy The escaping strategy | |
| * @param string $charset The charset | |
| * @param Boolean $autoescape Whether the function is called by the auto-escaping feature (true) or by the developer (false) | |
| */ | |
| function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html', $charset = null, $autoescape = false) | |
| { | |
| if ($autoescape && is_object($string) && $string instanceof Twig_Markup) { | |
| return $string; | |
| } | |
| if (!is_string($string) && !(is_object($string) && method_exists($string, '__toString'))) { | |
| return $string; | |
| } | |
| if (null === $charset) { | |
| $charset = $env->getCharset(); | |
| } | |
| $string = (string) $string; | |
| switch ($strategy) { | |
| case 'js': | |
| // escape all non-alphanumeric characters | |
| // into their \xHH or \uHHHH representations | |
| if ('UTF-8' != $charset) { | |
| $string = twig_convert_encoding($string, 'UTF-8', $charset); | |
| } | |
| if (0 == strlen($string) ? false : (1 == preg_match('/^./su', $string) ? false : true)) { | |
| throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.'); | |
| } | |
| $string = preg_replace_callback('#[^a-zA-Z0-9,\._]#Su', '_twig_escape_js_callback', $string); | |
| if ('UTF-8' != $charset) { | |
| $string = twig_convert_encoding($string, $charset, 'UTF-8'); | |
| } | |
| return $string; | |
| case 'css': | |
| if ('UTF-8' != $charset) { | |
| $string = twig_convert_encoding($string, 'UTF-8', $charset); | |
| } | |
| if (0 == strlen($string) ? false : (1 == preg_match('/^./su', $string) ? false : true)) { | |
| throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.'); | |
| } | |
| $string = preg_replace_callback('#[^a-zA-Z0-9]#Su', '_twig_escape_css_callback', $string); | |
| if ('UTF-8' != $charset) { | |
| $string = twig_convert_encoding($string, $charset, 'UTF-8'); | |
| } | |
| return $string; | |
| case 'html_attr': | |
| if ('UTF-8' != $charset) { | |
| $string = twig_convert_encoding($string, 'UTF-8', $charset); | |
| } | |
| if (0 == strlen($string) ? false : (1 == preg_match('/^./su', $string) ? false : true)) { | |
| throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.'); | |
| } | |
| $string = preg_replace_callback('#[^a-zA-Z0-9,\.\-_]#Su', '_twig_escape_html_attr_callback', $string); | |
| if ('UTF-8' != $charset) { | |
| $string = twig_convert_encoding($string, $charset, 'UTF-8'); | |
| } | |
| return $string; | |
| case 'html': | |
| // see http://php.net/htmlspecialchars | |
| // Using a static variable to avoid initializing the array | |
| // each time the function is called. Moving the declaration on the | |
| // top of the function slow downs other escaping strategies. | |
| static $htmlspecialcharsCharsets = array( | |
| 'iso-8859-1' => true, 'iso8859-1' => true, | |
| 'iso-8859-15' => true, 'iso8859-15' => true, | |
| 'utf-8' => true, | |
| 'cp866' => true, 'ibm866' => true, '866' => true, | |
| 'cp1251' => true, 'windows-1251' => true, 'win-1251' => true, | |
| '1251' => true, | |
| 'cp1252' => true, 'windows-1252' => true, '1252' => true, | |
| 'koi8-r' => true, 'koi8-ru' => true, 'koi8r' => true, | |
| 'big5' => true, '950' => true, | |
| 'gb2312' => true, '936' => true, | |
| 'big5-hkscs' => true, | |
| 'shift_jis' => true, 'sjis' => true, '932' => true, | |
| 'euc-jp' => true, 'eucjp' => true, | |
| 'iso8859-5' => true, 'iso-8859-5' => true, 'macroman' => true, | |
| ); | |
| if (isset($htmlspecialcharsCharsets[strtolower($charset)])) { | |
| return htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, $charset); | |
| } | |
| $string = twig_convert_encoding($string, 'UTF-8', $charset); | |
| $string = htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); | |
| return twig_convert_encoding($string, $charset, 'UTF-8'); | |
| case 'url': | |
| if (version_compare(PHP_VERSION, '5.3.0', '<')) { | |
| return str_replace('%7E', '~', rawurlencode($string)); | |
| } | |
| return rawurlencode($string); | |
| default: | |
| throw new Twig_Error_Runtime(sprintf('Invalid escaping strategy "%s" (valid ones: html, js, url, css, and html_attr).', $strategy)); | |
| } | |
| } | |
| /* used internally */ | |
| function twig_escape_filter_is_safe(Twig_Node $filterArgs) | |
| { | |
| foreach ($filterArgs as $arg) { | |
| if ($arg instanceof Twig_Node_Expression_Constant) { | |
| return array($arg->getAttribute('value')); | |
| } | |
| return array(); | |
| } | |
| return array('html'); | |
| } | |
| if (function_exists('mb_convert_encoding')) { | |
| function twig_convert_encoding($string, $to, $from) | |
| { | |
| return mb_convert_encoding($string, $to, $from); | |
| } | |
| } elseif (function_exists('iconv')) { | |
| function twig_convert_encoding($string, $to, $from) | |
| { | |
| return iconv($from, $to, $string); | |
| } | |
| } else { | |
| function twig_convert_encoding($string, $to, $from) | |
| { | |
| throw new Twig_Error_Runtime('No suitable convert encoding function (use UTF-8 as your encoding or install the iconv or mbstring extension).'); | |
| } | |
| } | |
| function _twig_escape_js_callback($matches) | |
| { | |
| $char = $matches[0]; | |
| // \xHH | |
| if (!isset($char[1])) { | |
| return '\\x'.strtoupper(substr('00'.bin2hex($char), -2)); | |
| } | |
| // \uHHHH | |
| $char = twig_convert_encoding($char, 'UTF-16BE', 'UTF-8'); | |
| return '\\u'.strtoupper(substr('0000'.bin2hex($char), -4)); | |
| } | |
| function _twig_escape_css_callback($matches) | |
| { | |
| $char = $matches[0]; | |
| // \xHH | |
| if (!isset($char[1])) { | |
| $hex = ltrim(strtoupper(bin2hex($char)), '0'); | |
| if (0 === strlen($hex)) { | |
| $hex = '0'; | |
| } | |
| return '\\'.$hex.' '; | |
| } | |
| // \uHHHH | |
| $char = twig_convert_encoding($char, 'UTF-16BE', 'UTF-8'); | |
| return '\\'.ltrim(strtoupper(bin2hex($char)), '0').' '; | |
| } | |
| /** | |
| * This function is adapted from code coming from Zend Framework. | |
| * | |
| * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) | |
| * @license http://framework.zend.com/license/new-bsd New BSD License | |
| */ | |
| function _twig_escape_html_attr_callback($matches) | |
| { | |
| /* | |
| * While HTML supports far more named entities, the lowest common denominator | |
| * has become HTML5's XML Serialisation which is restricted to the those named | |
| * entities that XML supports. Using HTML entities would result in this error: | |
| * XML Parsing Error: undefined entity | |
| */ | |
| static $entityMap = array( | |
| 34 => 'quot', /* quotation mark */ | |
| 38 => 'amp', /* ampersand */ | |
| 60 => 'lt', /* less-than sign */ | |
| 62 => 'gt', /* greater-than sign */ | |
| ); | |
| $chr = $matches[0]; | |
| $ord = ord($chr); | |
| /** | |
| * The following replaces characters undefined in HTML with the | |
| * hex entity for the Unicode replacement character. | |
| */ | |
| if (($ord <= 0x1f && $chr != "\t" && $chr != "\n" && $chr != "\r") || ($ord >= 0x7f && $ord <= 0x9f)) { | |
| return '�'; | |
| } | |
| /** | |
| * Check if the current character to escape has a name entity we should | |
| * replace it with while grabbing the hex value of the character. | |
| */ | |
| if (strlen($chr) == 1) { | |
| $hex = strtoupper(substr('00'.bin2hex($chr), -2)); | |
| } else { | |
| $chr = twig_convert_encoding($chr, 'UTF-16BE', 'UTF-8'); | |
| $hex = strtoupper(substr('0000'.bin2hex($chr), -4)); | |
| } | |
| $int = hexdec($hex); | |
| if (array_key_exists($int, $entityMap)) { | |
| return sprintf('&%s;', $entityMap[$int]); | |
| } | |
| /** | |
| * Per OWASP recommendations, we'll use hex entities for any other | |
| * characters where a named entity does not exist. | |
| */ | |
| return sprintf('&#x%s;', $hex); | |
| } | |
| // add multibyte extensions if possible | |
| if (function_exists('mb_get_info')) { | |
| /** | |
| * Returns the length of a variable. | |
| * | |
| * @param Twig_Environment $env A Twig_Environment instance | |
| * @param mixed $thing A variable | |
| * | |
| * @return integer The length of the value | |
| */ | |
| function twig_length_filter(Twig_Environment $env, $thing) | |
| { | |
| return is_scalar($thing) ? mb_strlen($thing, $env->getCharset()) : count($thing); | |
| } | |
| /** | |
| * Converts a string to uppercase. | |
| * | |
| * @param Twig_Environment $env A Twig_Environment instance | |
| * @param string $string A string | |
| * | |
| * @return string The uppercased string | |
| */ | |
| function twig_upper_filter(Twig_Environment $env, $string) | |
| { | |
| if (null !== ($charset = $env->getCharset())) { | |
| return mb_strtoupper($string, $charset); | |
| } | |
| return strtoupper($string); | |
| } | |
| /** | |
| * Converts a string to lowercase. | |
| * | |
| * @param Twig_Environment $env A Twig_Environment instance | |
| * @param string $string A string | |
| * | |
| * @return string The lowercased string | |
| */ | |
| function twig_lower_filter(Twig_Environment $env, $string) | |
| { | |
| if (null !== ($charset = $env->getCharset())) { | |
| return mb_strtolower($string, $charset); | |
| } | |
| return strtolower($string); | |
| } | |
| /** | |
| * Returns a titlecased string. | |
| * | |
| * @param Twig_Environment $env A Twig_Environment instance | |
| * @param string $string A string | |
| * | |
| * @return string The titlecased string | |
| */ | |
| function twig_title_string_filter(Twig_Environment $env, $string) | |
| { | |
| if (null !== ($charset = $env->getCharset())) { | |
| return mb_convert_case($string, MB_CASE_TITLE, $charset); | |
| } | |
| return ucwords(strtolower($string)); | |
| } | |
| /** | |
| * Returns a capitalized string. | |
| * | |
| * @param Twig_Environment $env A Twig_Environment instance | |
| * @param string $string A string | |
| * | |
| * @return string The capitalized string | |
| */ | |
| function twig_capitalize_string_filter(Twig_Environment $env, $string) | |
| { | |
| if (null !== ($charset = $env->getCharset())) { | |
| return mb_strtoupper(mb_substr($string, 0, 1, $charset), $charset). | |
| mb_strtolower(mb_substr($string, 1, mb_strlen($string, $charset), $charset), $charset); | |
| } | |
| return ucfirst(strtolower($string)); | |
| } | |
| } | |
| // and byte fallback | |
| else { | |
| /** | |
| * Returns the length of a variable. | |
| * | |
| * @param Twig_Environment $env A Twig_Environment instance | |
| * @param mixed $thing A variable | |
| * | |
| * @return integer The length of the value | |
| */ | |
| function twig_length_filter(Twig_Environment $env, $thing) | |
| { | |
| return is_scalar($thing) ? strlen($thing) : count($thing); | |
| } | |
| /** | |
| * Returns a titlecased string. | |
| * | |
| * @param Twig_Environment $env A Twig_Environment instance | |
| * @param string $string A string | |
| * | |
| * @return string The titlecased string | |
| */ | |
| function twig_title_string_filter(Twig_Environment $env, $string) | |
| { | |
| return ucwords(strtolower($string)); | |
| } | |
| /** | |
| * Returns a capitalized string. | |
| * | |
| * @param Twig_Environment $env A Twig_Environment instance | |
| * @param string $string A string | |
| * | |
| * @return string The capitalized string | |
| */ | |
| function twig_capitalize_string_filter(Twig_Environment $env, $string) | |
| { | |
| return ucfirst(strtolower($string)); | |
| } | |
| } | |
| /* used internally */ | |
| function twig_ensure_traversable($seq) | |
| { | |
| if ($seq instanceof Traversable || is_array($seq)) { | |
| return $seq; | |
| } | |
| return array(); | |
| } | |
| /** | |
| * Checks if a variable is empty. | |
| * | |
| * <pre> | |
| * {# evaluates to true if the foo variable is null, false, or the empty string #} | |
| * {% if foo is empty %} | |
| * {# ... #} | |
| * {% endif %} | |
| * </pre> | |
| * | |
| * @param mixed $value A variable | |
| * | |
| * @return Boolean true if the value is empty, false otherwise | |
| */ | |
| function twig_test_empty($value) | |
| { | |
| if ($value instanceof Countable) { | |
| return 0 == count($value); | |
| } | |
| return false === $value || (empty($value) && '0' != $value); | |
| } | |
| /** | |
| * Checks if a variable is traversable. | |
| * | |
| * <pre> | |
| * {# evaluates to true if the foo variable is an array or a traversable object #} | |
| * {% if foo is traversable %} | |
| * {# ... #} | |
| * {% endif %} | |
| * </pre> | |
| * | |
| * @param mixed $value A variable | |
| * | |
| * @return Boolean true if the value is traversable | |
| */ | |
| function twig_test_iterable($value) | |
| { | |
| return $value instanceof Traversable || is_array($value); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2011 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Extension_Debug extends Twig_Extension | |
| { | |
| /** | |
| * Returns a list of global functions to add to the existing list. | |
| * | |
| * @return array An array of global functions | |
| */ | |
| public function getFunctions() | |
| { | |
| // dump is safe if var_dump is overridden by xdebug | |
| $isDumpOutputHtmlSafe = extension_loaded('xdebug') | |
| // false means that it was not set (and the default is on) or it explicitly enabled | |
| && (false === ini_get('xdebug.overload_var_dump') || ini_get('xdebug.overload_var_dump')) | |
| // false means that it was not set (and the default is on) or it explicitly enabled | |
| // xdebug.overload_var_dump produces HTML only when html_errors is also enabled | |
| && (false === ini_get('html_errors') || ini_get('html_errors')) | |
| ; | |
| return array( | |
| 'dump' => new Twig_Function_Function('twig_var_dump', array('is_safe' => $isDumpOutputHtmlSafe ? array('html') : array(), 'needs_context' => true, 'needs_environment' => true)), | |
| ); | |
| } | |
| /** | |
| * Returns the name of the extension. | |
| * | |
| * @return string The extension name | |
| */ | |
| public function getName() | |
| { | |
| return 'debug'; | |
| } | |
| } | |
| function twig_var_dump(Twig_Environment $env, $context) | |
| { | |
| if (!$env->isDebug()) { | |
| return; | |
| } | |
| ob_start(); | |
| $count = func_num_args(); | |
| if (2 === $count) { | |
| $vars = array(); | |
| foreach ($context as $key => $value) { | |
| if (!$value instanceof Twig_Template) { | |
| $vars[$key] = $value; | |
| } | |
| } | |
| var_dump($vars); | |
| } else { | |
| for ($i = 2; $i < $count; $i++) { | |
| var_dump(func_get_arg($i)); | |
| } | |
| } | |
| return ob_get_clean(); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2011 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Returns the value or the default value when it is undefined or empty. | |
| * | |
| * <pre> | |
| * {{ var.foo|default('foo item on var is not defined') }} | |
| * </pre> | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_Expression_Filter_Default extends Twig_Node_Expression_Filter | |
| { | |
| public function __construct(Twig_NodeInterface $node, Twig_Node_Expression_Constant $filterName, Twig_NodeInterface $arguments, $lineno, $tag = null) | |
| { | |
| $default = new Twig_Node_Expression_Filter($node, new Twig_Node_Expression_Constant('_default', $node->getLine()), $arguments, $node->getLine()); | |
| if ('default' === $filterName->getAttribute('value') && ($node instanceof Twig_Node_Expression_Name || $node instanceof Twig_Node_Expression_GetAttr)) { | |
| $test = new Twig_Node_Expression_Test_Defined(clone $node, 'defined', new Twig_Node(), $node->getLine()); | |
| $false = count($arguments) ? $arguments->getNode(0) : new Twig_Node_Expression_Constant('', $node->getLine()); | |
| $node = new Twig_Node_Expression_Conditional($test, $default, $false, $node->getLine()); | |
| } else { | |
| $node = $default; | |
| } | |
| parent::__construct($node, $filterName, $arguments, $lineno, $tag); | |
| } | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler->subcompile($this->getNode('node')); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2011 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Checks if a variable is defined in the current context. | |
| * | |
| * <pre> | |
| * {# defined works with variable names and variable attributes #} | |
| * {% if foo is defined %} | |
| * {# ... #} | |
| * {% endif %} | |
| * </pre> | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_Expression_Test_Defined extends Twig_Node_Expression_Test | |
| { | |
| public function __construct(Twig_NodeInterface $node, $name, Twig_NodeInterface $arguments = null, $lineno) | |
| { | |
| parent::__construct($node, $name, $arguments, $lineno); | |
| if ($node instanceof Twig_Node_Expression_Name) { | |
| $node->setAttribute('is_defined_test', true); | |
| } elseif ($node instanceof Twig_Node_Expression_GetAttr) { | |
| $node->setAttribute('is_defined_test', true); | |
| $this->changeIgnoreStrictCheck($node); | |
| } else { | |
| throw new Twig_Error_Syntax('The "defined" test only works with simple variables', $this->getLine(), $compiler->getFilename()); | |
| } | |
| } | |
| protected function changeIgnoreStrictCheck(Twig_Node_Expression_GetAttr $node) | |
| { | |
| $node->setAttribute('ignore_strict_check', true); | |
| if ($node->getNode('node') instanceof Twig_Node_Expression_GetAttr) { | |
| $this->changeIgnoreStrictCheck($node->getNode('node')); | |
| } | |
| } | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler->subcompile($this->getNode('node')); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Binary_Div extends Twig_Node_Expression_Binary | |
| { | |
| public function operator(Twig_Compiler $compiler) | |
| { | |
| return $compiler->raw('/'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2011 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Checks if a variable is divisible by a number. | |
| * | |
| * <pre> | |
| * {% if loop.index is divisibleby(3) %} | |
| * </pre> | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_Expression_Test_Divisibleby extends Twig_Node_Expression_Test | |
| { | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->raw('(0 == ') | |
| ->subcompile($this->getNode('node')) | |
| ->raw(' % ') | |
| ->subcompile($this->getNode('arguments')->getNode(0)) | |
| ->raw(')') | |
| ; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2011 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a do node. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_Do extends Twig_Node | |
| { | |
| public function __construct(Twig_Node_Expression $expr, $lineno, $tag = null) | |
| { | |
| parent::__construct(array('expr' => $expr), array(), $lineno, $tag); | |
| } | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->addDebugInfo($this) | |
| ->write('') | |
| ->subcompile($this->getNode('expr')) | |
| ->raw(";\n") | |
| ; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2011 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Evaluates an expression, disgarding the returned value. | |
| */ | |
| class Twig_TokenParser_Do extends Twig_TokenParser | |
| { | |
| /** | |
| * Parses a token and returns a node. | |
| * | |
| * @param Twig_Token $token A Twig_Token instance | |
| * | |
| * @return Twig_NodeInterface A Twig_NodeInterface instance | |
| */ | |
| public function parse(Twig_Token $token) | |
| { | |
| $expr = $this->parser->getExpressionParser()->parseExpression(); | |
| $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); | |
| return new Twig_Node_Do($expr, $token->getLine(), $this->getTag()); | |
| } | |
| /** | |
| * Gets the tag name associated with this token parser. | |
| * | |
| * @return string The tag name | |
| */ | |
| public function getTag() | |
| { | |
| return 'do'; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div class="control-group"> | |
| <label class="control-label" for="{{ field }}">{{ title }}</label> | |
| <div class="controls"> | |
| <input type="email" placeholder="{{ title }}..." name="{{ field }}" id="{{ field }}" value="{{ value | e }}" {% if required %}required="required"{% endif %}> | |
| </div> | |
| </div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2012 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents an embed node. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_Embed extends Twig_Node_Include | |
| { | |
| // we don't inject the module to avoid node visitors to traverse it twice (as it will be already visited in the main module) | |
| public function __construct($filename, $index, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null) | |
| { | |
| parent::__construct(new Twig_Node_Expression_Constant('not_used', $lineno), $variables, $only, $ignoreMissing, $lineno, $tag); | |
| $this->setAttribute('filename', $filename); | |
| $this->setAttribute('index', $index); | |
| } | |
| protected function addGetTemplate(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->write("\$this->env->loadTemplate(") | |
| ->string($this->getAttribute('filename')) | |
| ->raw(', ') | |
| ->string($this->getAttribute('index')) | |
| ->raw(")") | |
| ; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2012 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Embeds a template. | |
| */ | |
| class Twig_TokenParser_Embed extends Twig_TokenParser_Include | |
| { | |
| /** | |
| * Parses a token and returns a node. | |
| * | |
| * @param Twig_Token $token A Twig_Token instance | |
| * | |
| * @return Twig_NodeInterface A Twig_NodeInterface instance | |
| */ | |
| public function parse(Twig_Token $token) | |
| { | |
| $stream = $this->parser->getStream(); | |
| $parent = $this->parser->getExpressionParser()->parseExpression(); | |
| list($variables, $only, $ignoreMissing) = $this->parseArguments(); | |
| // inject a fake parent to make the parent() function work | |
| $stream->injectTokens(array( | |
| new Twig_Token(Twig_Token::BLOCK_START_TYPE, '', $token->getLine()), | |
| new Twig_Token(Twig_Token::NAME_TYPE, 'extends', $token->getLine()), | |
| new Twig_Token(Twig_Token::STRING_TYPE, '__parent__', $token->getLine()), | |
| new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', $token->getLine()), | |
| )); | |
| $module = $this->parser->parse($stream, array($this, 'decideBlockEnd'), true); | |
| // override the parent with the correct one | |
| $module->setNode('parent', $parent); | |
| $this->parser->embedTemplate($module); | |
| $stream->expect(Twig_Token::BLOCK_END_TYPE); | |
| return new Twig_Node_Embed($module->getAttribute('filename'), $module->getAttribute('index'), $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag()); | |
| } | |
| public function decideBlockEnd(Twig_Token $token) | |
| { | |
| return $token->test('endembed'); | |
| } | |
| /** | |
| * Gets the tag name associated with this token parser. | |
| * | |
| * @return string The tag name | |
| */ | |
| public function getTag() | |
| { | |
| return 'embed'; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Stores the Twig configuration. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Environment | |
| { | |
| const VERSION = '1.11.1'; | |
| protected $charset; | |
| protected $loader; | |
| protected $debug; | |
| protected $autoReload; | |
| protected $cache; | |
| protected $lexer; | |
| protected $parser; | |
| protected $compiler; | |
| protected $baseTemplateClass; | |
| protected $extensions; | |
| protected $parsers; | |
| protected $visitors; | |
| protected $filters; | |
| protected $tests; | |
| protected $functions; | |
| protected $globals; | |
| protected $runtimeInitialized; | |
| protected $loadedTemplates; | |
| protected $strictVariables; | |
| protected $unaryOperators; | |
| protected $binaryOperators; | |
| protected $templateClassPrefix = '__TwigTemplate_'; | |
| protected $functionCallbacks; | |
| protected $filterCallbacks; | |
| protected $staging; | |
| /** | |
| * Constructor. | |
| * | |
| * Available options: | |
| * | |
| * * debug: When set to true, it automatically set "auto_reload" to true as | |
| * well (default to false). | |
| * | |
| * * charset: The charset used by the templates (default to utf-8). | |
| * | |
| * * base_template_class: The base template class to use for generated | |
| * templates (default to Twig_Template). | |
| * | |
| * * cache: An absolute path where to store the compiled templates, or | |
| * false to disable compilation cache (default). | |
| * | |
| * * auto_reload: Whether to reload the template is the original source changed. | |
| * If you don't provide the auto_reload option, it will be | |
| * determined automatically base on the debug value. | |
| * | |
| * * strict_variables: Whether to ignore invalid variables in templates | |
| * (default to false). | |
| * | |
| * * autoescape: Whether to enable auto-escaping (default to html): | |
| * * false: disable auto-escaping | |
| * * true: equivalent to html | |
| * * html, js: set the autoescaping to one of the supported strategies | |
| * * PHP callback: a PHP callback that returns an escaping strategy based on the template "filename" | |
| * | |
| * * optimizations: A flag that indicates which optimizations to apply | |
| * (default to -1 which means that all optimizations are enabled; | |
| * set it to 0 to disable). | |
| * | |
| * @param Twig_LoaderInterface $loader A Twig_LoaderInterface instance | |
| * @param array $options An array of options | |
| */ | |
| public function __construct(Twig_LoaderInterface $loader = null, $options = array()) | |
| { | |
| if (null !== $loader) { | |
| $this->setLoader($loader); | |
| } | |
| $options = array_merge(array( | |
| 'debug' => false, | |
| 'charset' => 'UTF-8', | |
| 'base_template_class' => 'Twig_Template', | |
| 'strict_variables' => false, | |
| 'autoescape' => 'html', | |
| 'cache' => false, | |
| 'auto_reload' => null, | |
| 'optimizations' => -1, | |
| ), $options); | |
| $this->debug = (bool) $options['debug']; | |
| $this->charset = $options['charset']; | |
| $this->baseTemplateClass = $options['base_template_class']; | |
| $this->autoReload = null === $options['auto_reload'] ? $this->debug : (bool) $options['auto_reload']; | |
| $this->extensions = array( | |
| 'core' => new Twig_Extension_Core(), | |
| 'escaper' => new Twig_Extension_Escaper($options['autoescape']), | |
| 'optimizer' => new Twig_Extension_Optimizer($options['optimizations']), | |
| ); | |
| $this->strictVariables = (bool) $options['strict_variables']; | |
| $this->runtimeInitialized = false; | |
| $this->setCache($options['cache']); | |
| $this->functionCallbacks = array(); | |
| $this->filterCallbacks = array(); | |
| $this->staging = array( | |
| 'functions' => array(), | |
| 'filters' => array(), | |
| 'tests' => array(), | |
| 'token_parsers' => array(), | |
| 'visitors' => array(), | |
| 'globals' => array(), | |
| ); | |
| } | |
| /** | |
| * Gets the base template class for compiled templates. | |
| * | |
| * @return string The base template class name | |
| */ | |
| public function getBaseTemplateClass() | |
| { | |
| return $this->baseTemplateClass; | |
| } | |
| /** | |
| * Sets the base template class for compiled templates. | |
| * | |
| * @param string $class The base template class name | |
| */ | |
| public function setBaseTemplateClass($class) | |
| { | |
| $this->baseTemplateClass = $class; | |
| } | |
| /** | |
| * Enables debugging mode. | |
| */ | |
| public function enableDebug() | |
| { | |
| $this->debug = true; | |
| } | |
| /** | |
| * Disables debugging mode. | |
| */ | |
| public function disableDebug() | |
| { | |
| $this->debug = false; | |
| } | |
| /** | |
| * Checks if debug mode is enabled. | |
| * | |
| * @return Boolean true if debug mode is enabled, false otherwise | |
| */ | |
| public function isDebug() | |
| { | |
| return $this->debug; | |
| } | |
| /** | |
| * Enables the auto_reload option. | |
| */ | |
| public function enableAutoReload() | |
| { | |
| $this->autoReload = true; | |
| } | |
| /** | |
| * Disables the auto_reload option. | |
| */ | |
| public function disableAutoReload() | |
| { | |
| $this->autoReload = false; | |
| } | |
| /** | |
| * Checks if the auto_reload option is enabled. | |
| * | |
| * @return Boolean true if auto_reload is enabled, false otherwise | |
| */ | |
| public function isAutoReload() | |
| { | |
| return $this->autoReload; | |
| } | |
| /** | |
| * Enables the strict_variables option. | |
| */ | |
| public function enableStrictVariables() | |
| { | |
| $this->strictVariables = true; | |
| } | |
| /** | |
| * Disables the strict_variables option. | |
| */ | |
| public function disableStrictVariables() | |
| { | |
| $this->strictVariables = false; | |
| } | |
| /** | |
| * Checks if the strict_variables option is enabled. | |
| * | |
| * @return Boolean true if strict_variables is enabled, false otherwise | |
| */ | |
| public function isStrictVariables() | |
| { | |
| return $this->strictVariables; | |
| } | |
| /** | |
| * Gets the cache directory or false if cache is disabled. | |
| * | |
| * @return string|false | |
| */ | |
| public function getCache() | |
| { | |
| return $this->cache; | |
| } | |
| /** | |
| * Sets the cache directory or false if cache is disabled. | |
| * | |
| * @param string|false $cache The absolute path to the compiled templates, | |
| * or false to disable cache | |
| */ | |
| public function setCache($cache) | |
| { | |
| $this->cache = $cache ? $cache : false; | |
| } | |
| /** | |
| * Gets the cache filename for a given template. | |
| * | |
| * @param string $name The template name | |
| * | |
| * @return string The cache file name | |
| */ | |
| public function getCacheFilename($name) | |
| { | |
| if (false === $this->cache) { | |
| return false; | |
| } | |
| $class = substr($this->getTemplateClass($name), strlen($this->templateClassPrefix)); | |
| return $this->getCache().'/'.substr($class, 0, 2).'/'.substr($class, 2, 2).'/'.substr($class, 4).'.php'; | |
| } | |
| /** | |
| * Gets the template class associated with the given string. | |
| * | |
| * @param string $name The name for which to calculate the template class name | |
| * @param integer $index The index if it is an embedded template | |
| * | |
| * @return string The template class name | |
| */ | |
| public function getTemplateClass($name, $index = null) | |
| { | |
| return $this->templateClassPrefix.md5($this->loader->getCacheKey($name)).(null === $index ? '' : '_'.$index); | |
| } | |
| /** | |
| * Gets the template class prefix. | |
| * | |
| * @return string The template class prefix | |
| */ | |
| public function getTemplateClassPrefix() | |
| { | |
| return $this->templateClassPrefix; | |
| } | |
| /** | |
| * Renders a template. | |
| * | |
| * @param string $name The template name | |
| * @param array $context An array of parameters to pass to the template | |
| * | |
| * @return string The rendered template | |
| */ | |
| public function render($name, array $context = array()) | |
| { | |
| return $this->loadTemplate($name)->render($context); | |
| } | |
| /** | |
| * Displays a template. | |
| * | |
| * @param string $name The template name | |
| * @param array $context An array of parameters to pass to the template | |
| */ | |
| public function display($name, array $context = array()) | |
| { | |
| $this->loadTemplate($name)->display($context); | |
| } | |
| /** | |
| * Loads a template by name. | |
| * | |
| * @param string $name The template name | |
| * @param integer $index The index if it is an embedded template | |
| * | |
| * @return Twig_TemplateInterface A template instance representing the given template name | |
| */ | |
| public function loadTemplate($name, $index = null) | |
| { | |
| $cls = $this->getTemplateClass($name, $index); | |
| if (isset($this->loadedTemplates[$cls])) { | |
| return $this->loadedTemplates[$cls]; | |
| } | |
| if (!class_exists($cls, false)) { | |
| if (false === $cache = $this->getCacheFilename($name)) { | |
| eval('?>'.$this->compileSource($this->loader->getSource($name), $name)); | |
| } else { | |
| if (!is_file($cache) || ($this->isAutoReload() && !$this->isTemplateFresh($name, filemtime($cache)))) { | |
| $this->writeCacheFile($cache, $this->compileSource($this->loader->getSource($name), $name)); | |
| } | |
| require_once $cache; | |
| } | |
| } | |
| if (!$this->runtimeInitialized) { | |
| $this->initRuntime(); | |
| } | |
| return $this->loadedTemplates[$cls] = new $cls($this); | |
| } | |
| /** | |
| * Returns true if the template is still fresh. | |
| * | |
| * Besides checking the loader for freshness information, | |
| * this method also checks if the enabled extensions have | |
| * not changed. | |
| * | |
| * @param string $name The template name | |
| * @param timestamp $time The last modification time of the cached template | |
| * | |
| * @return Boolean true if the template is fresh, false otherwise | |
| */ | |
| public function isTemplateFresh($name, $time) | |
| { | |
| foreach ($this->extensions as $extension) { | |
| $r = new ReflectionObject($extension); | |
| if (filemtime($r->getFileName()) > $time) { | |
| return false; | |
| } | |
| } | |
| return $this->loader->isFresh($name, $time); | |
| } | |
| public function resolveTemplate($names) | |
| { | |
| if (!is_array($names)) { | |
| $names = array($names); | |
| } | |
| foreach ($names as $name) { | |
| if ($name instanceof Twig_Template) { | |
| return $name; | |
| } | |
| try { | |
| return $this->loadTemplate($name); | |
| } catch (Twig_Error_Loader $e) { | |
| } | |
| } | |
| if (1 === count($names)) { | |
| throw $e; | |
| } | |
| throw new Twig_Error_Loader(sprintf('Unable to find one of the following templates: "%s".', implode('", "', $names))); | |
| } | |
| /** | |
| * Clears the internal template cache. | |
| */ | |
| public function clearTemplateCache() | |
| { | |
| $this->loadedTemplates = array(); | |
| } | |
| /** | |
| * Clears the template cache files on the filesystem. | |
| */ | |
| public function clearCacheFiles() | |
| { | |
| if (false === $this->cache) { | |
| return; | |
| } | |
| foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->cache), RecursiveIteratorIterator::LEAVES_ONLY) as $file) { | |
| if ($file->isFile()) { | |
| @unlink($file->getPathname()); | |
| } | |
| } | |
| } | |
| /** | |
| * Gets the Lexer instance. | |
| * | |
| * @return Twig_LexerInterface A Twig_LexerInterface instance | |
| */ | |
| public function getLexer() | |
| { | |
| if (null === $this->lexer) { | |
| $this->lexer = new Twig_Lexer($this); | |
| } | |
| return $this->lexer; | |
| } | |
| /** | |
| * Sets the Lexer instance. | |
| * | |
| * @param Twig_LexerInterface A Twig_LexerInterface instance | |
| */ | |
| public function setLexer(Twig_LexerInterface $lexer) | |
| { | |
| $this->lexer = $lexer; | |
| } | |
| /** | |
| * Tokenizes a source code. | |
| * | |
| * @param string $source The template source code | |
| * @param string $name The template name | |
| * | |
| * @return Twig_TokenStream A Twig_TokenStream instance | |
| */ | |
| public function tokenize($source, $name = null) | |
| { | |
| return $this->getLexer()->tokenize($source, $name); | |
| } | |
| /** | |
| * Gets the Parser instance. | |
| * | |
| * @return Twig_ParserInterface A Twig_ParserInterface instance | |
| */ | |
| public function getParser() | |
| { | |
| if (null === $this->parser) { | |
| $this->parser = new Twig_Parser($this); | |
| } | |
| return $this->parser; | |
| } | |
| /** | |
| * Sets the Parser instance. | |
| * | |
| * @param Twig_ParserInterface A Twig_ParserInterface instance | |
| */ | |
| public function setParser(Twig_ParserInterface $parser) | |
| { | |
| $this->parser = $parser; | |
| } | |
| /** | |
| * Parses a token stream. | |
| * | |
| * @param Twig_TokenStream $tokens A Twig_TokenStream instance | |
| * | |
| * @return Twig_Node_Module A Node tree | |
| */ | |
| public function parse(Twig_TokenStream $tokens) | |
| { | |
| return $this->getParser()->parse($tokens); | |
| } | |
| /** | |
| * Gets the Compiler instance. | |
| * | |
| * @return Twig_CompilerInterface A Twig_CompilerInterface instance | |
| */ | |
| public function getCompiler() | |
| { | |
| if (null === $this->compiler) { | |
| $this->compiler = new Twig_Compiler($this); | |
| } | |
| return $this->compiler; | |
| } | |
| /** | |
| * Sets the Compiler instance. | |
| * | |
| * @param Twig_CompilerInterface $compiler A Twig_CompilerInterface instance | |
| */ | |
| public function setCompiler(Twig_CompilerInterface $compiler) | |
| { | |
| $this->compiler = $compiler; | |
| } | |
| /** | |
| * Compiles a Node. | |
| * | |
| * @param Twig_NodeInterface $node A Twig_NodeInterface instance | |
| * | |
| * @return string The compiled PHP source code | |
| */ | |
| public function compile(Twig_NodeInterface $node) | |
| { | |
| return $this->getCompiler()->compile($node)->getSource(); | |
| } | |
| /** | |
| * Compiles a template source code. | |
| * | |
| * @param string $source The template source code | |
| * @param string $name The template name | |
| * | |
| * @return string The compiled PHP source code | |
| */ | |
| public function compileSource($source, $name = null) | |
| { | |
| try { | |
| return $this->compile($this->parse($this->tokenize($source, $name))); | |
| } catch (Twig_Error $e) { | |
| $e->setTemplateFile($name); | |
| throw $e; | |
| } catch (Exception $e) { | |
| throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the compilation of a template ("%s").', $e->getMessage()), -1, $name, $e); | |
| } | |
| } | |
| /** | |
| * Sets the Loader instance. | |
| * | |
| * @param Twig_LoaderInterface $loader A Twig_LoaderInterface instance | |
| */ | |
| public function setLoader(Twig_LoaderInterface $loader) | |
| { | |
| $this->loader = $loader; | |
| } | |
| /** | |
| * Gets the Loader instance. | |
| * | |
| * @return Twig_LoaderInterface A Twig_LoaderInterface instance | |
| */ | |
| public function getLoader() | |
| { | |
| return $this->loader; | |
| } | |
| /** | |
| * Sets the default template charset. | |
| * | |
| * @param string $charset The default charset | |
| */ | |
| public function setCharset($charset) | |
| { | |
| $this->charset = $charset; | |
| } | |
| /** | |
| * Gets the default template charset. | |
| * | |
| * @return string The default charset | |
| */ | |
| public function getCharset() | |
| { | |
| return $this->charset; | |
| } | |
| /** | |
| * Initializes the runtime environment. | |
| */ | |
| public function initRuntime() | |
| { | |
| $this->runtimeInitialized = true; | |
| foreach ($this->getExtensions() as $extension) { | |
| $extension->initRuntime($this); | |
| } | |
| } | |
| /** | |
| * Returns true if the given extension is registered. | |
| * | |
| * @param string $name The extension name | |
| * | |
| * @return Boolean Whether the extension is registered or not | |
| */ | |
| public function hasExtension($name) | |
| { | |
| return isset($this->extensions[$name]); | |
| } | |
| /** | |
| * Gets an extension by name. | |
| * | |
| * @param string $name The extension name | |
| * | |
| * @return Twig_ExtensionInterface A Twig_ExtensionInterface instance | |
| */ | |
| public function getExtension($name) | |
| { | |
| if (!isset($this->extensions[$name])) { | |
| throw new Twig_Error_Runtime(sprintf('The "%s" extension is not enabled.', $name)); | |
| } | |
| return $this->extensions[$name]; | |
| } | |
| /** | |
| * Registers an extension. | |
| * | |
| * @param Twig_ExtensionInterface $extension A Twig_ExtensionInterface instance | |
| */ | |
| public function addExtension(Twig_ExtensionInterface $extension) | |
| { | |
| $this->extensions[$extension->getName()] = $extension; | |
| $this->parsers = null; | |
| $this->visitors = null; | |
| $this->filters = null; | |
| $this->tests = null; | |
| $this->functions = null; | |
| $this->globals = null; | |
| } | |
| /** | |
| * Removes an extension by name. | |
| * | |
| * @param string $name The extension name | |
| */ | |
| public function removeExtension($name) | |
| { | |
| unset($this->extensions[$name]); | |
| $this->parsers = null; | |
| $this->visitors = null; | |
| $this->filters = null; | |
| $this->tests = null; | |
| $this->functions = null; | |
| $this->globals = null; | |
| } | |
| /** | |
| * Registers an array of extensions. | |
| * | |
| * @param array $extensions An array of extensions | |
| */ | |
| public function setExtensions(array $extensions) | |
| { | |
| foreach ($extensions as $extension) { | |
| $this->addExtension($extension); | |
| } | |
| } | |
| /** | |
| * Returns all registered extensions. | |
| * | |
| * @return array An array of extensions | |
| */ | |
| public function getExtensions() | |
| { | |
| return $this->extensions; | |
| } | |
| /** | |
| * Registers a Token Parser. | |
| * | |
| * @param Twig_TokenParserInterface $parser A Twig_TokenParserInterface instance | |
| */ | |
| public function addTokenParser(Twig_TokenParserInterface $parser) | |
| { | |
| $this->staging['token_parsers'][] = $parser; | |
| $this->parsers = null; | |
| } | |
| /** | |
| * Gets the registered Token Parsers. | |
| * | |
| * @return Twig_TokenParserBrokerInterface A broker containing token parsers | |
| */ | |
| public function getTokenParsers() | |
| { | |
| if (null === $this->parsers) { | |
| $this->parsers = new Twig_TokenParserBroker(); | |
| if (isset($this->staging['token_parsers'])) { | |
| foreach ($this->staging['token_parsers'] as $parser) { | |
| $this->parsers->addTokenParser($parser); | |
| } | |
| } | |
| foreach ($this->getExtensions() as $extension) { | |
| $parsers = $extension->getTokenParsers(); | |
| foreach ($parsers as $parser) { | |
| if ($parser instanceof Twig_TokenParserInterface) { | |
| $this->parsers->addTokenParser($parser); | |
| } elseif ($parser instanceof Twig_TokenParserBrokerInterface) { | |
| $this->parsers->addTokenParserBroker($parser); | |
| } else { | |
| throw new LogicException('getTokenParsers() must return an array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances'); | |
| } | |
| } | |
| } | |
| } | |
| return $this->parsers; | |
| } | |
| /** | |
| * Gets registered tags. | |
| * | |
| * Be warned that this method cannot return tags defined by Twig_TokenParserBrokerInterface classes. | |
| * | |
| * @return Twig_TokenParserInterface[] An array of Twig_TokenParserInterface instances | |
| */ | |
| public function getTags() | |
| { | |
| $tags = array(); | |
| foreach ($this->getTokenParsers()->getParsers() as $parser) { | |
| if ($parser instanceof Twig_TokenParserInterface) { | |
| $tags[$parser->getTag()] = $parser; | |
| } | |
| } | |
| return $tags; | |
| } | |
| /** | |
| * Registers a Node Visitor. | |
| * | |
| * @param Twig_NodeVisitorInterface $visitor A Twig_NodeVisitorInterface instance | |
| */ | |
| public function addNodeVisitor(Twig_NodeVisitorInterface $visitor) | |
| { | |
| $this->staging['visitors'][] = $visitor; | |
| $this->visitors = null; | |
| } | |
| /** | |
| * Gets the registered Node Visitors. | |
| * | |
| * @return Twig_NodeVisitorInterface[] An array of Twig_NodeVisitorInterface instances | |
| */ | |
| public function getNodeVisitors() | |
| { | |
| if (null === $this->visitors) { | |
| foreach ($this->getExtensions() as $extension) { | |
| foreach ($extension->getNodeVisitors() as $visitor) { | |
| $this->addNodeVisitor($visitor); | |
| } | |
| } | |
| $this->visitors = $this->staging['visitors']; | |
| } | |
| return $this->visitors; | |
| } | |
| /** | |
| * Registers a Filter. | |
| * | |
| * @param string $name The filter name | |
| * @param Twig_FilterInterface $filter A Twig_FilterInterface instance | |
| */ | |
| public function addFilter($name, Twig_FilterInterface $filter) | |
| { | |
| $this->staging['filters'][$name] = $filter; | |
| $this->filters = null; | |
| } | |
| /** | |
| * Get a filter by name. | |
| * | |
| * Subclasses may override this method and load filters differently; | |
| * so no list of filters is available. | |
| * | |
| * @param string $name The filter name | |
| * | |
| * @return Twig_Filter|false A Twig_Filter instance or false if the filter does not exists | |
| */ | |
| public function getFilter($name) | |
| { | |
| if (null === $this->filters) { | |
| $this->getFilters(); | |
| } | |
| if (isset($this->filters[$name])) { | |
| return $this->filters[$name]; | |
| } | |
| foreach ($this->filters as $pattern => $filter) { | |
| $pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count); | |
| if ($count) { | |
| if (preg_match('#^'.$pattern.'$#', $name, $matches)) { | |
| array_shift($matches); | |
| $filter->setArguments($matches); | |
| return $filter; | |
| } | |
| } | |
| } | |
| foreach ($this->filterCallbacks as $callback) { | |
| if (false !== $filter = call_user_func($callback, $name)) { | |
| return $filter; | |
| } | |
| } | |
| return false; | |
| } | |
| public function registerUndefinedFilterCallback($callable) | |
| { | |
| $this->filterCallbacks[] = $callable; | |
| } | |
| /** | |
| * Gets the registered Filters. | |
| * | |
| * Be warned that this method cannot return filters defined with registerUndefinedFunctionCallback. | |
| * | |
| * @return Twig_FilterInterface[] An array of Twig_FilterInterface instances | |
| * | |
| * @see registerUndefinedFilterCallback | |
| */ | |
| public function getFilters() | |
| { | |
| if (null === $this->filters) { | |
| foreach ($this->getExtensions() as $extension) { | |
| foreach ($extension->getFilters() as $name => $filter) { | |
| $this->addFilter($name, $filter); | |
| } | |
| } | |
| $this->filters = $this->staging['filters']; | |
| } | |
| return $this->filters; | |
| } | |
| /** | |
| * Registers a Test. | |
| * | |
| * @param string $name The test name | |
| * @param Twig_TestInterface $test A Twig_TestInterface instance | |
| */ | |
| public function addTest($name, Twig_TestInterface $test) | |
| { | |
| $this->staging['tests'][$name] = $test; | |
| $this->tests = null; | |
| } | |
| /** | |
| * Gets the registered Tests. | |
| * | |
| * @return Twig_TestInterface[] An array of Twig_TestInterface instances | |
| */ | |
| public function getTests() | |
| { | |
| if (null === $this->tests) { | |
| foreach ($this->getExtensions() as $extension) { | |
| foreach ($extension->getTests() as $name => $test) { | |
| $this->addTest($name, $test); | |
| } | |
| } | |
| $this->tests = $this->staging['tests']; | |
| } | |
| return $this->tests; | |
| } | |
| /** | |
| * Registers a Function. | |
| * | |
| * @param string $name The function name | |
| * @param Twig_FunctionInterface $function A Twig_FunctionInterface instance | |
| */ | |
| public function addFunction($name, Twig_FunctionInterface $function) | |
| { | |
| $this->staging['functions'][$name] = $function; | |
| $this->functions = null; | |
| } | |
| /** | |
| * Get a function by name. | |
| * | |
| * Subclasses may override this method and load functions differently; | |
| * so no list of functions is available. | |
| * | |
| * @param string $name function name | |
| * | |
| * @return Twig_Function|false A Twig_Function instance or false if the function does not exists | |
| */ | |
| public function getFunction($name) | |
| { | |
| if (null === $this->functions) { | |
| $this->getFunctions(); | |
| } | |
| if (isset($this->functions[$name])) { | |
| return $this->functions[$name]; | |
| } | |
| foreach ($this->functions as $pattern => $function) { | |
| $pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count); | |
| if ($count) { | |
| if (preg_match('#^'.$pattern.'$#', $name, $matches)) { | |
| array_shift($matches); | |
| $function->setArguments($matches); | |
| return $function; | |
| } | |
| } | |
| } | |
| foreach ($this->functionCallbacks as $callback) { | |
| if (false !== $function = call_user_func($callback, $name)) { | |
| return $function; | |
| } | |
| } | |
| return false; | |
| } | |
| public function registerUndefinedFunctionCallback($callable) | |
| { | |
| $this->functionCallbacks[] = $callable; | |
| } | |
| /** | |
| * Gets registered functions. | |
| * | |
| * Be warned that this method cannot return functions defined with registerUndefinedFunctionCallback. | |
| * | |
| * @return Twig_FunctionInterface[] An array of Twig_FunctionInterface instances | |
| * | |
| * @see registerUndefinedFunctionCallback | |
| */ | |
| public function getFunctions() | |
| { | |
| if (null === $this->functions) { | |
| foreach ($this->getExtensions() as $extension) { | |
| foreach ($extension->getFunctions() as $name => $function) { | |
| $this->addFunction($name, $function); | |
| } | |
| } | |
| $this->functions = $this->staging['functions']; | |
| } | |
| return $this->functions; | |
| } | |
| /** | |
| * Registers a Global. | |
| * | |
| * @param string $name The global name | |
| * @param mixed $value The global value | |
| */ | |
| public function addGlobal($name, $value) | |
| { | |
| $this->staging['globals'][$name] = $value; | |
| $this->globals = null; | |
| } | |
| /** | |
| * Gets the registered Globals. | |
| * | |
| * @return array An array of globals | |
| */ | |
| public function getGlobals() | |
| { | |
| if (null === $this->globals) { | |
| $this->globals = isset($this->staging['globals']) ? $this->staging['globals'] : array(); | |
| foreach ($this->getExtensions() as $extension) { | |
| $this->globals = array_merge($this->globals, $extension->getGlobals()); | |
| } | |
| } | |
| return $this->globals; | |
| } | |
| /** | |
| * Merges a context with the defined globals. | |
| * | |
| * @param array $context An array representing the context | |
| * | |
| * @return array The context merged with the globals | |
| */ | |
| public function mergeGlobals(array $context) | |
| { | |
| // we don't use array_merge as the context being generally | |
| // bigger than globals, this code is faster. | |
| foreach ($this->getGlobals() as $key => $value) { | |
| if (!array_key_exists($key, $context)) { | |
| $context[$key] = $value; | |
| } | |
| } | |
| return $context; | |
| } | |
| /** | |
| * Gets the registered unary Operators. | |
| * | |
| * @return array An array of unary operators | |
| */ | |
| public function getUnaryOperators() | |
| { | |
| if (null === $this->unaryOperators) { | |
| $this->initOperators(); | |
| } | |
| return $this->unaryOperators; | |
| } | |
| /** | |
| * Gets the registered binary Operators. | |
| * | |
| * @return array An array of binary operators | |
| */ | |
| public function getBinaryOperators() | |
| { | |
| if (null === $this->binaryOperators) { | |
| $this->initOperators(); | |
| } | |
| return $this->binaryOperators; | |
| } | |
| public function computeAlternatives($name, $items) | |
| { | |
| $alternatives = array(); | |
| foreach ($items as $item) { | |
| $lev = levenshtein($name, $item); | |
| if ($lev <= strlen($name) / 3 || false !== strpos($item, $name)) { | |
| $alternatives[$item] = $lev; | |
| } | |
| } | |
| asort($alternatives); | |
| return array_keys($alternatives); | |
| } | |
| protected function initOperators() | |
| { | |
| $this->unaryOperators = array(); | |
| $this->binaryOperators = array(); | |
| foreach ($this->getExtensions() as $extension) { | |
| $operators = $extension->getOperators(); | |
| if (!$operators) { | |
| continue; | |
| } | |
| if (2 !== count($operators)) { | |
| throw new InvalidArgumentException(sprintf('"%s::getOperators()" does not return a valid operators array.', get_class($extension))); | |
| } | |
| $this->unaryOperators = array_merge($this->unaryOperators, $operators[0]); | |
| $this->binaryOperators = array_merge($this->binaryOperators, $operators[1]); | |
| } | |
| } | |
| protected function writeCacheFile($file, $content) | |
| { | |
| $dir = dirname($file); | |
| if (!is_dir($dir)) { | |
| if (false === @mkdir($dir, 0777, true) && !is_dir($dir)) { | |
| throw new RuntimeException(sprintf("Unable to create the cache directory (%s).", $dir)); | |
| } | |
| } elseif (!is_writable($dir)) { | |
| throw new RuntimeException(sprintf("Unable to write in the cache directory (%s).", $dir)); | |
| } | |
| $tmpFile = tempnam(dirname($file), basename($file)); | |
| if (false !== @file_put_contents($tmpFile, $content)) { | |
| // rename does not work on Win32 before 5.2.6 | |
| if (@rename($tmpFile, $file) || (@copy($tmpFile, $file) && unlink($tmpFile))) { | |
| @chmod($file, 0666 & ~umask()); | |
| return; | |
| } | |
| } | |
| throw new RuntimeException(sprintf('Failed to write cache file "%s".', $file)); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Binary_Equal extends Twig_Node_Expression_Binary | |
| { | |
| public function operator(Twig_Compiler $compiler) | |
| { | |
| return $compiler->raw('=='); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Twig base exception. | |
| * | |
| * This exception class and its children must only be used when | |
| * an error occurs during the loading of a template, when a syntax error | |
| * is detected in a template, or when rendering a template. Other | |
| * errors must use regular PHP exception classes (like when the template | |
| * cache directory is not writable for instance). | |
| * | |
| * To help debugging template issues, this class tracks the original template | |
| * name and line where the error occurred. | |
| * | |
| * Whenever possible, you must set these information (original template name | |
| * and line number) yourself by passing them to the constructor. If some or all | |
| * these information are not available from where you throw the exception, then | |
| * this class will guess them automatically (when the line number is set to -1 | |
| * and/or the filename is set to null). As this is a costly operation, this | |
| * can be disabled by passing false for both the filename and the line number | |
| * when creating a new instance of this class. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Error extends Exception | |
| { | |
| protected $lineno; | |
| protected $filename; | |
| protected $rawMessage; | |
| protected $previous; | |
| /** | |
| * Constructor. | |
| * | |
| * Set both the line number and the filename to false to | |
| * disable automatic guessing of the original template name | |
| * and line number. | |
| * | |
| * Set the line number to -1 to enable its automatic guessing. | |
| * Set the filename to null to enable its automatic guessing. | |
| * | |
| * By default, automatic guessing is enabled. | |
| * | |
| * @param string $message The error message | |
| * @param integer $lineno The template line where the error occurred | |
| * @param string $filename The template file name where the error occurred | |
| * @param Exception $previous The previous exception | |
| */ | |
| public function __construct($message, $lineno = -1, $filename = null, Exception $previous = null) | |
| { | |
| if (version_compare(PHP_VERSION, '5.3.0', '<')) { | |
| $this->previous = $previous; | |
| parent::__construct(''); | |
| } else { | |
| parent::__construct('', 0, $previous); | |
| } | |
| $this->lineno = $lineno; | |
| $this->filename = $filename; | |
| if (-1 === $this->lineno || null === $this->filename) { | |
| $this->guessTemplateInfo(); | |
| } | |
| $this->rawMessage = $message; | |
| $this->updateRepr(); | |
| } | |
| /** | |
| * Gets the raw message. | |
| * | |
| * @return string The raw message | |
| */ | |
| public function getRawMessage() | |
| { | |
| return $this->rawMessage; | |
| } | |
| /** | |
| * Gets the filename where the error occurred. | |
| * | |
| * @return string The filename | |
| */ | |
| public function getTemplateFile() | |
| { | |
| return $this->filename; | |
| } | |
| /** | |
| * Sets the filename where the error occurred. | |
| * | |
| * @param string $filename The filename | |
| */ | |
| public function setTemplateFile($filename) | |
| { | |
| $this->filename = $filename; | |
| $this->updateRepr(); | |
| } | |
| /** | |
| * Gets the template line where the error occurred. | |
| * | |
| * @return integer The template line | |
| */ | |
| public function getTemplateLine() | |
| { | |
| return $this->lineno; | |
| } | |
| /** | |
| * Sets the template line where the error occurred. | |
| * | |
| * @param integer $lineno The template line | |
| */ | |
| public function setTemplateLine($lineno) | |
| { | |
| $this->lineno = $lineno; | |
| $this->updateRepr(); | |
| } | |
| public function guess() | |
| { | |
| $this->guessTemplateInfo(); | |
| $this->updateRepr(); | |
| } | |
| /** | |
| * For PHP < 5.3.0, provides access to the getPrevious() method. | |
| * | |
| * @param string $method The method name | |
| * @param array $arguments The parameters to be passed to the method | |
| * | |
| * @return Exception The previous exception or null | |
| * | |
| * @throws BadMethodCallException | |
| */ | |
| public function __call($method, $arguments) | |
| { | |
| if ('getprevious' == strtolower($method)) { | |
| return $this->previous; | |
| } | |
| throw new BadMethodCallException(sprintf('Method "Twig_Error::%s()" does not exist.', $method)); | |
| } | |
| protected function updateRepr() | |
| { | |
| $this->message = $this->rawMessage; | |
| $dot = false; | |
| if ('.' === substr($this->message, -1)) { | |
| $this->message = substr($this->message, 0, -1); | |
| $dot = true; | |
| } | |
| if ($this->filename) { | |
| if (is_string($this->filename) || (is_object($this->filename) && method_exists($this->filename, '__toString'))) { | |
| $filename = sprintf('"%s"', $this->filename); | |
| } else { | |
| $filename = json_encode($this->filename); | |
| } | |
| $this->message .= sprintf(' in %s', $filename); | |
| } | |
| if ($this->lineno && $this->lineno >= 0) { | |
| $this->message .= sprintf(' at line %d', $this->lineno); | |
| } | |
| if ($dot) { | |
| $this->message .= '.'; | |
| } | |
| } | |
| protected function guessTemplateInfo() | |
| { | |
| $template = null; | |
| foreach (debug_backtrace() as $trace) { | |
| if (isset($trace['object']) && $trace['object'] instanceof Twig_Template && 'Twig_Template' !== get_class($trace['object'])) { | |
| if (null === $this->filename || $this->filename == $trace['object']->getTemplateName()) { | |
| $template = $trace['object']; | |
| } | |
| } | |
| } | |
| // update template filename | |
| if (null !== $template && null === $this->filename) { | |
| $this->filename = $template->getTemplateName(); | |
| } | |
| if (null === $template || $this->lineno > -1) { | |
| return; | |
| } | |
| $r = new ReflectionObject($template); | |
| $file = $r->getFileName(); | |
| $exceptions = array($e = $this); | |
| while (($e instanceof self || method_exists($e, 'getPrevious')) && $e = $e->getPrevious()) { | |
| $exceptions[] = $e; | |
| } | |
| while ($e = array_pop($exceptions)) { | |
| $traces = $e->getTrace(); | |
| while ($trace = array_shift($traces)) { | |
| if (!isset($trace['file']) || !isset($trace['line']) || $file != $trace['file']) { | |
| continue; | |
| } | |
| foreach ($template->getDebugInfo() as $codeLine => $templateLine) { | |
| if ($codeLine <= $trace['line']) { | |
| // update template line | |
| $this->lineno = $templateLine; | |
| return; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Extension_Escaper extends Twig_Extension | |
| { | |
| protected $defaultStrategy; | |
| public function __construct($defaultStrategy = 'html') | |
| { | |
| $this->setDefaultStrategy($defaultStrategy); | |
| } | |
| /** | |
| * Returns the token parser instances to add to the existing list. | |
| * | |
| * @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances | |
| */ | |
| public function getTokenParsers() | |
| { | |
| return array(new Twig_TokenParser_AutoEscape()); | |
| } | |
| /** | |
| * Returns the node visitor instances to add to the existing list. | |
| * | |
| * @return array An array of Twig_NodeVisitorInterface instances | |
| */ | |
| public function getNodeVisitors() | |
| { | |
| return array(new Twig_NodeVisitor_Escaper()); | |
| } | |
| /** | |
| * Returns a list of filters to add to the existing list. | |
| * | |
| * @return array An array of filters | |
| */ | |
| public function getFilters() | |
| { | |
| return array( | |
| 'raw' => new Twig_Filter_Function('twig_raw_filter', array('is_safe' => array('all'))), | |
| ); | |
| } | |
| /** | |
| * Sets the default strategy to use when not defined by the user. | |
| * | |
| * The strategy can be a valid PHP callback that takes the template | |
| * "filename" as an argument and returns the strategy to use. | |
| * | |
| * @param mixed $defaultStrategy An escaping strategy | |
| */ | |
| public function setDefaultStrategy($defaultStrategy) | |
| { | |
| // for BC | |
| if (true === $defaultStrategy) { | |
| $defaultStrategy = 'html'; | |
| } | |
| $this->defaultStrategy = $defaultStrategy; | |
| } | |
| /** | |
| * Gets the default strategy to use when not defined by the user. | |
| * | |
| * @param string $filename The template "filename" | |
| * | |
| * @return string The default strategy to use for the template | |
| */ | |
| public function getDefaultStrategy($filename) | |
| { | |
| // disable string callables to avoid calling a function named html or js, | |
| // or any other upcoming escaping strategy | |
| if (!is_string($this->defaultStrategy) && is_callable($this->defaultStrategy)) { | |
| return call_user_func($this->defaultStrategy, $filename); | |
| } | |
| return $this->defaultStrategy; | |
| } | |
| /** | |
| * Returns the name of the extension. | |
| * | |
| * @return string The extension name | |
| */ | |
| public function getName() | |
| { | |
| return 'escaper'; | |
| } | |
| } | |
| /** | |
| * Marks a variable as being safe. | |
| * | |
| * @param string $string A PHP variable | |
| */ | |
| function twig_raw_filter($string) | |
| { | |
| return $string; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Twig_NodeVisitor_Escaper implements output escaping. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface | |
| { | |
| protected $statusStack = array(); | |
| protected $blocks = array(); | |
| protected $safeAnalysis; | |
| protected $traverser; | |
| protected $defaultStrategy = false; | |
| protected $safeVars = array(); | |
| public function __construct() | |
| { | |
| $this->safeAnalysis = new Twig_NodeVisitor_SafeAnalysis(); | |
| } | |
| /** | |
| * Called before child nodes are visited. | |
| * | |
| * @param Twig_NodeInterface $node The node to visit | |
| * @param Twig_Environment $env The Twig environment instance | |
| * | |
| * @return Twig_NodeInterface The modified node | |
| */ | |
| public function enterNode(Twig_NodeInterface $node, Twig_Environment $env) | |
| { | |
| if ($node instanceof Twig_Node_Module) { | |
| if ($env->hasExtension('escaper') && $defaultStrategy = $env->getExtension('escaper')->getDefaultStrategy($node->getAttribute('filename'))) { | |
| $this->defaultStrategy = $defaultStrategy; | |
| } | |
| $this->safeVars = array(); | |
| } elseif ($node instanceof Twig_Node_AutoEscape) { | |
| $this->statusStack[] = $node->getAttribute('value'); | |
| } elseif ($node instanceof Twig_Node_Block) { | |
| $this->statusStack[] = isset($this->blocks[$node->getAttribute('name')]) ? $this->blocks[$node->getAttribute('name')] : $this->needEscaping($env); | |
| } elseif ($node instanceof Twig_Node_Import) { | |
| $this->safeVars[] = $node->getNode('var')->getAttribute('name'); | |
| } | |
| return $node; | |
| } | |
| /** | |
| * Called after child nodes are visited. | |
| * | |
| * @param Twig_NodeInterface $node The node to visit | |
| * @param Twig_Environment $env The Twig environment instance | |
| * | |
| * @return Twig_NodeInterface The modified node | |
| */ | |
| public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env) | |
| { | |
| if ($node instanceof Twig_Node_Module) { | |
| $this->defaultStrategy = false; | |
| $this->safeVars = array(); | |
| } elseif ($node instanceof Twig_Node_Expression_Filter) { | |
| return $this->preEscapeFilterNode($node, $env); | |
| } elseif ($node instanceof Twig_Node_Print) { | |
| return $this->escapePrintNode($node, $env, $this->needEscaping($env)); | |
| } | |
| if ($node instanceof Twig_Node_AutoEscape || $node instanceof Twig_Node_Block) { | |
| array_pop($this->statusStack); | |
| } elseif ($node instanceof Twig_Node_BlockReference) { | |
| $this->blocks[$node->getAttribute('name')] = $this->needEscaping($env); | |
| } | |
| return $node; | |
| } | |
| protected function escapePrintNode(Twig_Node_Print $node, Twig_Environment $env, $type) | |
| { | |
| if (false === $type) { | |
| return $node; | |
| } | |
| $expression = $node->getNode('expr'); | |
| if ($this->isSafeFor($type, $expression, $env)) { | |
| return $node; | |
| } | |
| $class = get_class($node); | |
| return new $class( | |
| $this->getEscaperFilter($type, $expression), | |
| $node->getLine() | |
| ); | |
| } | |
| protected function preEscapeFilterNode(Twig_Node_Expression_Filter $filter, Twig_Environment $env) | |
| { | |
| $name = $filter->getNode('filter')->getAttribute('value'); | |
| if (false !== $f = $env->getFilter($name)) { | |
| $type = $f->getPreEscape(); | |
| if (null === $type) { | |
| return $filter; | |
| } | |
| $node = $filter->getNode('node'); | |
| if ($this->isSafeFor($type, $node, $env)) { | |
| return $filter; | |
| } | |
| $filter->setNode('node', $this->getEscaperFilter($type, $node)); | |
| return $filter; | |
| } | |
| return $filter; | |
| } | |
| protected function isSafeFor($type, Twig_NodeInterface $expression, $env) | |
| { | |
| $safe = $this->safeAnalysis->getSafe($expression); | |
| if (null === $safe) { | |
| if (null === $this->traverser) { | |
| $this->traverser = new Twig_NodeTraverser($env, array($this->safeAnalysis)); | |
| } | |
| $this->safeAnalysis->setSafeVars($this->safeVars); | |
| $this->traverser->traverse($expression); | |
| $safe = $this->safeAnalysis->getSafe($expression); | |
| } | |
| return in_array($type, $safe) || in_array('all', $safe); | |
| } | |
| protected function needEscaping(Twig_Environment $env) | |
| { | |
| if (count($this->statusStack)) { | |
| return $this->statusStack[count($this->statusStack) - 1]; | |
| } | |
| return $this->defaultStrategy ? $this->defaultStrategy : false; | |
| } | |
| protected function getEscaperFilter($type, Twig_NodeInterface $node) | |
| { | |
| $line = $node->getLine(); | |
| $name = new Twig_Node_Expression_Constant('escape', $line); | |
| $args = new Twig_Node(array(new Twig_Node_Expression_Constant((string) $type, $line), new Twig_Node_Expression_Constant(null, $line), new Twig_Node_Expression_Constant(true, $line))); | |
| return new Twig_Node_Expression_Filter($node, $name, $args, $line); | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function getPriority() | |
| { | |
| return 0; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2011 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Checks if a number is even. | |
| * | |
| * <pre> | |
| * {{ var is even }} | |
| * </pre> | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_Expression_Test_Even extends Twig_Node_Expression_Test | |
| { | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->raw('(') | |
| ->subcompile($this->getNode('node')) | |
| ->raw(' % 2 == 0') | |
| ->raw(')') | |
| ; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Adds an exists() method for loaders. | |
| * | |
| * @package twig | |
| * @author Florin Patan <florinpatan@gmail.com> | |
| */ | |
| interface Twig_ExistsLoaderInterface | |
| { | |
| /** | |
| * Check if we have the source code of a template, given its name. | |
| * | |
| * @param string $name The name of the template to check if we can load | |
| * | |
| * @return boolean If the template source code is handled by this loader or not | |
| */ | |
| public function exists($name); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Abstract class for all nodes that represents an expression. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| abstract class Twig_Node_Expression extends Twig_Node | |
| { | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Parses expressions. | |
| * | |
| * This parser implements a "Precedence climbing" algorithm. | |
| * | |
| * @see http://www.engr.mun.ca/~theo/Misc/exp_parsing.htm | |
| * @see http://en.wikipedia.org/wiki/Operator-precedence_parser | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_ExpressionParser | |
| { | |
| const OPERATOR_LEFT = 1; | |
| const OPERATOR_RIGHT = 2; | |
| protected $parser; | |
| protected $unaryOperators; | |
| protected $binaryOperators; | |
| public function __construct(Twig_Parser $parser, array $unaryOperators, array $binaryOperators) | |
| { | |
| $this->parser = $parser; | |
| $this->unaryOperators = $unaryOperators; | |
| $this->binaryOperators = $binaryOperators; | |
| } | |
| public function parseExpression($precedence = 0) | |
| { | |
| $expr = $this->getPrimary(); | |
| $token = $this->parser->getCurrentToken(); | |
| while ($this->isBinary($token) && $this->binaryOperators[$token->getValue()]['precedence'] >= $precedence) { | |
| $op = $this->binaryOperators[$token->getValue()]; | |
| $this->parser->getStream()->next(); | |
| if (isset($op['callable'])) { | |
| $expr = call_user_func($op['callable'], $this->parser, $expr); | |
| } else { | |
| $expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence']); | |
| $class = $op['class']; | |
| $expr = new $class($expr, $expr1, $token->getLine()); | |
| } | |
| $token = $this->parser->getCurrentToken(); | |
| } | |
| if (0 === $precedence) { | |
| return $this->parseConditionalExpression($expr); | |
| } | |
| return $expr; | |
| } | |
| protected function getPrimary() | |
| { | |
| $token = $this->parser->getCurrentToken(); | |
| if ($this->isUnary($token)) { | |
| $operator = $this->unaryOperators[$token->getValue()]; | |
| $this->parser->getStream()->next(); | |
| $expr = $this->parseExpression($operator['precedence']); | |
| $class = $operator['class']; | |
| return $this->parsePostfixExpression(new $class($expr, $token->getLine())); | |
| } elseif ($token->test(Twig_Token::PUNCTUATION_TYPE, '(')) { | |
| $this->parser->getStream()->next(); | |
| $expr = $this->parseExpression(); | |
| $this->parser->getStream()->expect(Twig_Token::PUNCTUATION_TYPE, ')', 'An opened parenthesis is not properly closed'); | |
| return $this->parsePostfixExpression($expr); | |
| } | |
| return $this->parsePrimaryExpression(); | |
| } | |
| protected function parseConditionalExpression($expr) | |
| { | |
| while ($this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, '?')) { | |
| $this->parser->getStream()->next(); | |
| $expr2 = $this->parseExpression(); | |
| $this->parser->getStream()->expect(Twig_Token::PUNCTUATION_TYPE, ':', 'The ternary operator must have a default value'); | |
| $expr3 = $this->parseExpression(); | |
| $expr = new Twig_Node_Expression_Conditional($expr, $expr2, $expr3, $this->parser->getCurrentToken()->getLine()); | |
| } | |
| return $expr; | |
| } | |
| protected function isUnary(Twig_Token $token) | |
| { | |
| return $token->test(Twig_Token::OPERATOR_TYPE) && isset($this->unaryOperators[$token->getValue()]); | |
| } | |
| protected function isBinary(Twig_Token $token) | |
| { | |
| return $token->test(Twig_Token::OPERATOR_TYPE) && isset($this->binaryOperators[$token->getValue()]); | |
| } | |
| public function parsePrimaryExpression() | |
| { | |
| $token = $this->parser->getCurrentToken(); | |
| switch ($token->getType()) { | |
| case Twig_Token::NAME_TYPE: | |
| $this->parser->getStream()->next(); | |
| switch ($token->getValue()) { | |
| case 'true': | |
| case 'TRUE': | |
| $node = new Twig_Node_Expression_Constant(true, $token->getLine()); | |
| break; | |
| case 'false': | |
| case 'FALSE': | |
| $node = new Twig_Node_Expression_Constant(false, $token->getLine()); | |
| break; | |
| case 'none': | |
| case 'NONE': | |
| case 'null': | |
| case 'NULL': | |
| $node = new Twig_Node_Expression_Constant(null, $token->getLine()); | |
| break; | |
| default: | |
| if ('(' === $this->parser->getCurrentToken()->getValue()) { | |
| $node = $this->getFunctionNode($token->getValue(), $token->getLine()); | |
| } else { | |
| $node = new Twig_Node_Expression_Name($token->getValue(), $token->getLine()); | |
| } | |
| } | |
| break; | |
| case Twig_Token::NUMBER_TYPE: | |
| $this->parser->getStream()->next(); | |
| $node = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine()); | |
| break; | |
| case Twig_Token::STRING_TYPE: | |
| case Twig_Token::INTERPOLATION_START_TYPE: | |
| $node = $this->parseStringExpression(); | |
| break; | |
| default: | |
| if ($token->test(Twig_Token::PUNCTUATION_TYPE, '[')) { | |
| $node = $this->parseArrayExpression(); | |
| } elseif ($token->test(Twig_Token::PUNCTUATION_TYPE, '{')) { | |
| $node = $this->parseHashExpression(); | |
| } else { | |
| throw new Twig_Error_Syntax(sprintf('Unexpected token "%s" of value "%s"', Twig_Token::typeToEnglish($token->getType(), $token->getLine()), $token->getValue()), $token->getLine(), $this->parser->getFilename()); | |
| } | |
| } | |
| return $this->parsePostfixExpression($node); | |
| } | |
| public function parseStringExpression() | |
| { | |
| $stream = $this->parser->getStream(); | |
| $nodes = array(); | |
| // a string cannot be followed by another string in a single expression | |
| $nextCanBeString = true; | |
| while (true) { | |
| if ($stream->test(Twig_Token::STRING_TYPE) && $nextCanBeString) { | |
| $token = $stream->next(); | |
| $nodes[] = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine()); | |
| $nextCanBeString = false; | |
| } elseif ($stream->test(Twig_Token::INTERPOLATION_START_TYPE)) { | |
| $stream->next(); | |
| $nodes[] = $this->parseExpression(); | |
| $stream->expect(Twig_Token::INTERPOLATION_END_TYPE); | |
| $nextCanBeString = true; | |
| } else { | |
| break; | |
| } | |
| } | |
| $expr = array_shift($nodes); | |
| foreach ($nodes as $node) { | |
| $expr = new Twig_Node_Expression_Binary_Concat($expr, $node, $node->getLine()); | |
| } | |
| return $expr; | |
| } | |
| public function parseArrayExpression() | |
| { | |
| $stream = $this->parser->getStream(); | |
| $stream->expect(Twig_Token::PUNCTUATION_TYPE, '[', 'An array element was expected'); | |
| $node = new Twig_Node_Expression_Array(array(), $stream->getCurrent()->getLine()); | |
| $first = true; | |
| while (!$stream->test(Twig_Token::PUNCTUATION_TYPE, ']')) { | |
| if (!$first) { | |
| $stream->expect(Twig_Token::PUNCTUATION_TYPE, ',', 'An array element must be followed by a comma'); | |
| // trailing ,? | |
| if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ']')) { | |
| break; | |
| } | |
| } | |
| $first = false; | |
| $node->addElement($this->parseExpression()); | |
| } | |
| $stream->expect(Twig_Token::PUNCTUATION_TYPE, ']', 'An opened array is not properly closed'); | |
| return $node; | |
| } | |
| public function parseHashExpression() | |
| { | |
| $stream = $this->parser->getStream(); | |
| $stream->expect(Twig_Token::PUNCTUATION_TYPE, '{', 'A hash element was expected'); | |
| $node = new Twig_Node_Expression_Array(array(), $stream->getCurrent()->getLine()); | |
| $first = true; | |
| while (!$stream->test(Twig_Token::PUNCTUATION_TYPE, '}')) { | |
| if (!$first) { | |
| $stream->expect(Twig_Token::PUNCTUATION_TYPE, ',', 'A hash value must be followed by a comma'); | |
| // trailing ,? | |
| if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '}')) { | |
| break; | |
| } | |
| } | |
| $first = false; | |
| // a hash key can be: | |
| // | |
| // * a number -- 12 | |
| // * a string -- 'a' | |
| // * a name, which is equivalent to a string -- a | |
| // * an expression, which must be enclosed in parentheses -- (1 + 2) | |
| if ($stream->test(Twig_Token::STRING_TYPE) || $stream->test(Twig_Token::NAME_TYPE) || $stream->test(Twig_Token::NUMBER_TYPE)) { | |
| $token = $stream->next(); | |
| $key = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine()); | |
| } elseif ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) { | |
| $key = $this->parseExpression(); | |
| } else { | |
| $current = $stream->getCurrent(); | |
| throw new Twig_Error_Syntax(sprintf('A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s"', Twig_Token::typeToEnglish($current->getType(), $current->getLine()), $current->getValue()), $current->getLine(), $this->parser->getFilename()); | |
| } | |
| $stream->expect(Twig_Token::PUNCTUATION_TYPE, ':', 'A hash key must be followed by a colon (:)'); | |
| $value = $this->parseExpression(); | |
| $node->addElement($value, $key); | |
| } | |
| $stream->expect(Twig_Token::PUNCTUATION_TYPE, '}', 'An opened hash is not properly closed'); | |
| return $node; | |
| } | |
| public function parsePostfixExpression($node) | |
| { | |
| while (true) { | |
| $token = $this->parser->getCurrentToken(); | |
| if ($token->getType() == Twig_Token::PUNCTUATION_TYPE) { | |
| if ('.' == $token->getValue() || '[' == $token->getValue()) { | |
| $node = $this->parseSubscriptExpression($node); | |
| } elseif ('|' == $token->getValue()) { | |
| $node = $this->parseFilterExpression($node); | |
| } else { | |
| break; | |
| } | |
| } else { | |
| break; | |
| } | |
| } | |
| return $node; | |
| } | |
| public function getFunctionNode($name, $line) | |
| { | |
| $args = $this->parseArguments(); | |
| switch ($name) { | |
| case 'parent': | |
| if (!count($this->parser->getBlockStack())) { | |
| throw new Twig_Error_Syntax('Calling "parent" outside a block is forbidden', $line, $this->parser->getFilename()); | |
| } | |
| if (!$this->parser->getParent() && !$this->parser->hasTraits()) { | |
| throw new Twig_Error_Syntax('Calling "parent" on a template that does not extend nor "use" another template is forbidden', $line, $this->parser->getFilename()); | |
| } | |
| return new Twig_Node_Expression_Parent($this->parser->peekBlockStack(), $line); | |
| case 'block': | |
| return new Twig_Node_Expression_BlockReference($args->getNode(0), false, $line); | |
| case 'attribute': | |
| if (count($args) < 2) { | |
| throw new Twig_Error_Syntax('The "attribute" function takes at least two arguments (the variable and the attributes)', $line, $this->parser->getFilename()); | |
| } | |
| return new Twig_Node_Expression_GetAttr($args->getNode(0), $args->getNode(1), count($args) > 2 ? $args->getNode(2) : new Twig_Node_Expression_Array(array(), $line), Twig_TemplateInterface::ANY_CALL, $line); | |
| default: | |
| if (null !== $alias = $this->parser->getImportedSymbol('function', $name)) { | |
| $arguments = new Twig_Node_Expression_Array(array(), $line); | |
| foreach ($args as $n) { | |
| $arguments->addElement($n); | |
| } | |
| $node = new Twig_Node_Expression_MethodCall($alias['node'], $alias['name'], $arguments, $line); | |
| $node->setAttribute('safe', true); | |
| return $node; | |
| } | |
| $class = $this->getFunctionNodeClass($name); | |
| return new $class($name, $args, $line); | |
| } | |
| } | |
| public function parseSubscriptExpression($node) | |
| { | |
| $stream = $this->parser->getStream(); | |
| $token = $stream->next(); | |
| $lineno = $token->getLine(); | |
| $arguments = new Twig_Node_Expression_Array(array(), $lineno); | |
| $type = Twig_TemplateInterface::ANY_CALL; | |
| if ($token->getValue() == '.') { | |
| $token = $stream->next(); | |
| if ( | |
| $token->getType() == Twig_Token::NAME_TYPE | |
| || | |
| $token->getType() == Twig_Token::NUMBER_TYPE | |
| || | |
| ($token->getType() == Twig_Token::OPERATOR_TYPE && preg_match(Twig_Lexer::REGEX_NAME, $token->getValue())) | |
| ) { | |
| $arg = new Twig_Node_Expression_Constant($token->getValue(), $lineno); | |
| if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) { | |
| $type = Twig_TemplateInterface::METHOD_CALL; | |
| foreach ($this->parseArguments() as $n) { | |
| $arguments->addElement($n); | |
| } | |
| } | |
| } else { | |
| throw new Twig_Error_Syntax('Expected name or number', $lineno, $this->parser->getFilename()); | |
| } | |
| } else { | |
| $type = Twig_TemplateInterface::ARRAY_CALL; | |
| $arg = $this->parseExpression(); | |
| // slice? | |
| if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ':')) { | |
| $stream->next(); | |
| if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ']')) { | |
| $length = new Twig_Node_Expression_Constant(null, $token->getLine()); | |
| } else { | |
| $length = $this->parseExpression(); | |
| } | |
| $class = $this->getFilterNodeClass('slice'); | |
| $arguments = new Twig_Node(array($arg, $length)); | |
| $filter = new $class($node, new Twig_Node_Expression_Constant('slice', $token->getLine()), $arguments, $token->getLine()); | |
| $stream->expect(Twig_Token::PUNCTUATION_TYPE, ']'); | |
| return $filter; | |
| } | |
| $stream->expect(Twig_Token::PUNCTUATION_TYPE, ']'); | |
| } | |
| if ($node instanceof Twig_Node_Expression_Name && null !== $alias = $this->parser->getImportedSymbol('template', $node->getAttribute('name'))) { | |
| $node = new Twig_Node_Expression_MethodCall($node, 'get'.$arg->getAttribute('value'), $arguments, $lineno); | |
| $node->setAttribute('safe', true); | |
| return $node; | |
| } | |
| return new Twig_Node_Expression_GetAttr($node, $arg, $arguments, $type, $lineno); | |
| } | |
| public function parseFilterExpression($node) | |
| { | |
| $this->parser->getStream()->next(); | |
| return $this->parseFilterExpressionRaw($node); | |
| } | |
| public function parseFilterExpressionRaw($node, $tag = null) | |
| { | |
| while (true) { | |
| $token = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE); | |
| $name = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine()); | |
| if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, '(')) { | |
| $arguments = new Twig_Node(); | |
| } else { | |
| $arguments = $this->parseArguments(); | |
| } | |
| $class = $this->getFilterNodeClass($name->getAttribute('value')); | |
| $node = new $class($node, $name, $arguments, $token->getLine(), $tag); | |
| if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, '|')) { | |
| break; | |
| } | |
| $this->parser->getStream()->next(); | |
| } | |
| return $node; | |
| } | |
| public function parseArguments() | |
| { | |
| $args = array(); | |
| $stream = $this->parser->getStream(); | |
| $stream->expect(Twig_Token::PUNCTUATION_TYPE, '(', 'A list of arguments must be opened by a parenthesis'); | |
| while (!$stream->test(Twig_Token::PUNCTUATION_TYPE, ')')) { | |
| if (!empty($args)) { | |
| $stream->expect(Twig_Token::PUNCTUATION_TYPE, ',', 'Arguments must be separated by a comma'); | |
| } | |
| $args[] = $this->parseExpression(); | |
| } | |
| $stream->expect(Twig_Token::PUNCTUATION_TYPE, ')', 'A list of arguments must be closed by a parenthesis'); | |
| return new Twig_Node($args); | |
| } | |
| public function parseAssignmentExpression() | |
| { | |
| $targets = array(); | |
| while (true) { | |
| $token = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE, null, 'Only variables can be assigned to'); | |
| if (in_array($token->getValue(), array('true', 'false', 'none'))) { | |
| throw new Twig_Error_Syntax(sprintf('You cannot assign a value to "%s"', $token->getValue()), $token->getLine(), $this->parser->getFilename()); | |
| } | |
| $targets[] = new Twig_Node_Expression_AssignName($token->getValue(), $token->getLine()); | |
| if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, ',')) { | |
| break; | |
| } | |
| $this->parser->getStream()->next(); | |
| } | |
| return new Twig_Node($targets); | |
| } | |
| public function parseMultitargetExpression() | |
| { | |
| $targets = array(); | |
| while (true) { | |
| $targets[] = $this->parseExpression(); | |
| if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, ',')) { | |
| break; | |
| } | |
| $this->parser->getStream()->next(); | |
| } | |
| return new Twig_Node($targets); | |
| } | |
| protected function getFunctionNodeClass($name) | |
| { | |
| $functionMap = $this->parser->getEnvironment()->getFunctions(); | |
| if (isset($functionMap[$name]) && $functionMap[$name] instanceof Twig_Function_Node) { | |
| return $functionMap[$name]->getClass(); | |
| } | |
| return 'Twig_Node_Expression_Function'; | |
| } | |
| protected function getFilterNodeClass($name) | |
| { | |
| $filterMap = $this->parser->getEnvironment()->getFilters(); | |
| if (isset($filterMap[$name]) && $filterMap[$name] instanceof Twig_Filter_Node) { | |
| return $filterMap[$name]->getClass(); | |
| } | |
| return 'Twig_Node_Expression_Filter'; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Extends a template by another one. | |
| * | |
| * <pre> | |
| * {% extends "base.html" %} | |
| * </pre> | |
| */ | |
| class Twig_TokenParser_Extends extends Twig_TokenParser | |
| { | |
| /** | |
| * Parses a token and returns a node. | |
| * | |
| * @param Twig_Token $token A Twig_Token instance | |
| * | |
| * @return Twig_NodeInterface A Twig_NodeInterface instance | |
| */ | |
| public function parse(Twig_Token $token) | |
| { | |
| if (!$this->parser->isMainScope()) { | |
| throw new Twig_Error_Syntax('Cannot extend from a block', $token->getLine(), $this->parser->getFilename()); | |
| } | |
| if (null !== $this->parser->getParent()) { | |
| throw new Twig_Error_Syntax('Multiple extends tags are forbidden', $token->getLine(), $this->parser->getFilename()); | |
| } | |
| $this->parser->setParent($this->parser->getExpressionParser()->parseExpression()); | |
| $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); | |
| return null; | |
| } | |
| /** | |
| * Gets the tag name associated with this token parser. | |
| * | |
| * @return string The tag name | |
| */ | |
| public function getTag() | |
| { | |
| return 'extends'; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| abstract class Twig_Extension implements Twig_ExtensionInterface | |
| { | |
| /** | |
| * Initializes the runtime environment. | |
| * | |
| * This is where you can load some file that contains filter functions for instance. | |
| * | |
| * @param Twig_Environment $environment The current Twig_Environment instance | |
| */ | |
| public function initRuntime(Twig_Environment $environment) | |
| { | |
| } | |
| /** | |
| * Returns the token parser instances to add to the existing list. | |
| * | |
| * @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances | |
| */ | |
| public function getTokenParsers() | |
| { | |
| return array(); | |
| } | |
| /** | |
| * Returns the node visitor instances to add to the existing list. | |
| * | |
| * @return array An array of Twig_NodeVisitorInterface instances | |
| */ | |
| public function getNodeVisitors() | |
| { | |
| return array(); | |
| } | |
| /** | |
| * Returns a list of filters to add to the existing list. | |
| * | |
| * @return array An array of filters | |
| */ | |
| public function getFilters() | |
| { | |
| return array(); | |
| } | |
| /** | |
| * Returns a list of tests to add to the existing list. | |
| * | |
| * @return array An array of tests | |
| */ | |
| public function getTests() | |
| { | |
| return array(); | |
| } | |
| /** | |
| * Returns a list of functions to add to the existing list. | |
| * | |
| * @return array An array of functions | |
| */ | |
| public function getFunctions() | |
| { | |
| return array(); | |
| } | |
| /** | |
| * Returns a list of operators to add to the existing list. | |
| * | |
| * @return array An array of operators | |
| */ | |
| public function getOperators() | |
| { | |
| return array(); | |
| } | |
| /** | |
| * Returns a list of global variables to add to the existing list. | |
| * | |
| * @return array An array of global variables | |
| */ | |
| public function getGlobals() | |
| { | |
| return array(); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Interface implemented by extension classes. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| interface Twig_ExtensionInterface | |
| { | |
| /** | |
| * Initializes the runtime environment. | |
| * | |
| * This is where you can load some file that contains filter functions for instance. | |
| * | |
| * @param Twig_Environment $environment The current Twig_Environment instance | |
| */ | |
| public function initRuntime(Twig_Environment $environment); | |
| /** | |
| * Returns the token parser instances to add to the existing list. | |
| * | |
| * @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances | |
| */ | |
| public function getTokenParsers(); | |
| /** | |
| * Returns the node visitor instances to add to the existing list. | |
| * | |
| * @return array An array of Twig_NodeVisitorInterface instances | |
| */ | |
| public function getNodeVisitors(); | |
| /** | |
| * Returns a list of filters to add to the existing list. | |
| * | |
| * @return array An array of filters | |
| */ | |
| public function getFilters(); | |
| /** | |
| * Returns a list of tests to add to the existing list. | |
| * | |
| * @return array An array of tests | |
| */ | |
| public function getTests(); | |
| /** | |
| * Returns a list of functions to add to the existing list. | |
| * | |
| * @return array An array of functions | |
| */ | |
| public function getFunctions(); | |
| /** | |
| * Returns a list of operators to add to the existing list. | |
| * | |
| * @return array An array of operators | |
| */ | |
| public function getOperators(); | |
| /** | |
| * Returns a list of global variables to add to the existing list. | |
| * | |
| * @return array An array of global variables | |
| */ | |
| public function getGlobals(); | |
| /** | |
| * Returns the name of the extension. | |
| * | |
| * @return string The extension name | |
| */ | |
| public function getName(); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents an extension call node. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_Expression_ExtensionReference extends Twig_Node_Expression | |
| { | |
| public function __construct($name, $lineno, $tag = null) | |
| { | |
| parent::__construct(array(), array('name' => $name), $lineno, $tag); | |
| } | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler->raw(sprintf("\$this->env->getExtension('%s')", $this->getAttribute('name'))); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| require 'autoload.php'; | |
| function file_type_valid() { | |
| return ($_FILES["file"]["type"] == "image/gif") | |
| || ($_FILES["file"]["type"] == "image/jpeg") | |
| || ($_FILES["file"]["type"] == "image/png") | |
| || ($_FILES["file"]["type"] == "image/pjpeg"); | |
| } | |
| function file_mime_valid() { | |
| $mime = mime_content_type($_FILES["file"]["tmp_name"]); | |
| return ($mime == "image/gif") | |
| || ($mime == "image/jpeg") | |
| || ($mime == "image/png") | |
| || ($mime == "image/pjpeg"); | |
| } | |
| function file_size_valid() { | |
| return $_FILES["file"]["size"] < 2000000; | |
| } | |
| function file_extension_valid() { | |
| $extension = strtolower(pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION)); | |
| return in_array($extension, array("jpg", "jpeg", "gif", "png")); | |
| } | |
| function file_resolution_valid() { | |
| $size = getimagesize($FILES["file"]["tmp_name"]); | |
| debug($size); | |
| #width(0) && height(1) | |
| return $size[0] < 200 && $size[1] < 200; | |
| } | |
| $error = false; | |
| $success = false; | |
| if ($_FILES["file"]) { | |
| if ($_FILES["file"]["error"] > 0) { | |
| $error = "Error Code: {$_FILES['file']['error']}"; | |
| } else { | |
| if (file_type_valid() && file_extension_valid() && file_mime_valid()) { | |
| if (file_size_valid()) { | |
| if (file_resolution_valid()) { | |
| move_uploaded_file($_FILES["file"]["tmp_name"], "uploads/" . $_FILES["file"]["name"]); | |
| $success = "File uploaded"; | |
| } else { | |
| $error = "Invalid image resolution"; | |
| } | |
| } else { | |
| $error = "Invalid file size"; | |
| } | |
| } else { | |
| $error = "Invalid file type"; | |
| } | |
| } | |
| } | |
| $files = array(); | |
| $dir = 'uploads/'; | |
| if ($data = scandir($dir)) { | |
| foreach ($data as $ent) | |
| if (preg_match('/^.+\..+$/', $ent)) | |
| $files[$ent] = filemtime($dir . $ent); | |
| arsort($files); | |
| $files = array_keys($files); | |
| } | |
| echo $views->render_with_layout('_file_upload', array( | |
| 'submit_path' => 'file_upload.php', | |
| 'error' => $error, | |
| 'success' => $success, | |
| 'files' => $files, | |
| )); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Loads template from the filesystem. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderInterface | |
| { | |
| protected $paths; | |
| protected $cache; | |
| /** | |
| * Constructor. | |
| * | |
| * @param string|array $paths A path or an array of paths where to look for templates | |
| */ | |
| public function __construct($paths) | |
| { | |
| $this->setPaths($paths); | |
| } | |
| /** | |
| * Returns the paths to the templates. | |
| * | |
| * @param string $namespace A path namespace | |
| * | |
| * @return array The array of paths where to look for templates | |
| */ | |
| public function getPaths($namespace = '__main__') | |
| { | |
| return isset($this->paths[$namespace]) ? $this->paths[$namespace] : array(); | |
| } | |
| /** | |
| * Returns the path namespaces. | |
| * | |
| * The "__main__" namespace is always defined. | |
| * | |
| * @return array The array of defined namespaces | |
| */ | |
| public function getNamespaces() | |
| { | |
| return array_keys($this->paths); | |
| } | |
| /** | |
| * Sets the paths where templates are stored. | |
| * | |
| * @param string|array $paths A path or an array of paths where to look for templates | |
| * @param string $namespace A path namespace | |
| */ | |
| public function setPaths($paths, $namespace = '__main__') | |
| { | |
| if (!is_array($paths)) { | |
| $paths = array($paths); | |
| } | |
| $this->paths[$namespace] = array(); | |
| foreach ($paths as $path) { | |
| $this->addPath($path, $namespace); | |
| } | |
| } | |
| /** | |
| * Adds a path where templates are stored. | |
| * | |
| * @param string $path A path where to look for templates | |
| * @param string $namespace A path name | |
| * | |
| * @throws Twig_Error_Loader | |
| */ | |
| public function addPath($path, $namespace = '__main__') | |
| { | |
| // invalidate the cache | |
| $this->cache = array(); | |
| if (!is_dir($path)) { | |
| throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path)); | |
| } | |
| $this->paths[$namespace][] = rtrim($path, '/\\'); | |
| } | |
| /** | |
| * Prepends a path where templates are stored. | |
| * | |
| * @param string $path A path where to look for templates | |
| * @param string $namespace A path name | |
| * | |
| * @throws Twig_Error_Loader | |
| */ | |
| public function prependPath($path, $namespace = '__main__') | |
| { | |
| // invalidate the cache | |
| $this->cache = array(); | |
| if (!is_dir($path)) { | |
| throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path)); | |
| } | |
| $path = rtrim($path, '/\\'); | |
| if (!isset($this->paths[$namespace])) { | |
| $this->paths[$namespace][] = $path; | |
| } else { | |
| array_unshift($this->paths[$namespace], $path); | |
| } | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function getSource($name) | |
| { | |
| return file_get_contents($this->findTemplate($name)); | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function getCacheKey($name) | |
| { | |
| return $this->findTemplate($name); | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function exists($name) | |
| { | |
| $name = (string) $name; | |
| if (isset($this->cache[$name])) { | |
| return true; | |
| } | |
| try { | |
| $this->findTemplate($name); | |
| return true; | |
| } catch (Twig_Error_Loader $exception) { | |
| return false; | |
| } | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function isFresh($name, $time) | |
| { | |
| return filemtime($this->findTemplate($name)) <= $time; | |
| } | |
| protected function findTemplate($name) | |
| { | |
| $name = (string) $name; | |
| // normalize name | |
| $name = preg_replace('#/{2,}#', '/', strtr($name, '\\', '/')); | |
| if (isset($this->cache[$name])) { | |
| return $this->cache[$name]; | |
| } | |
| $this->validateName($name); | |
| $namespace = '__main__'; | |
| if (isset($name[0]) && '@' == $name[0]) { | |
| if (false === $pos = strpos($name, '/')) { | |
| throw new Twig_Error_Loader(sprintf('Malformed namespaced template name "%s" (expecting "@namespace/template_name").', $name)); | |
| } | |
| $namespace = substr($name, 1, $pos - 1); | |
| $name = substr($name, $pos + 1); | |
| } | |
| if (!isset($this->paths[$namespace])) { | |
| throw new Twig_Error_Loader(sprintf('There are no registered paths for namespace "%s".', $namespace)); | |
| } | |
| foreach ($this->paths[$namespace] as $path) { | |
| if (is_file($path.'/'.$name)) { | |
| return $this->cache[$name] = $path.'/'.$name; | |
| } | |
| } | |
| throw new Twig_Error_Loader(sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths[$namespace]))); | |
| } | |
| protected function validateName($name) | |
| { | |
| if (false !== strpos($name, "\0")) { | |
| throw new Twig_Error_Loader('A template name cannot contain NUL bytes.'); | |
| } | |
| $parts = explode('/', $name); | |
| $level = 0; | |
| foreach ($parts as $part) { | |
| if ('..' === $part) { | |
| --$level; | |
| } elseif ('.' !== $part) { | |
| ++$level; | |
| } | |
| if ($level < 0) { | |
| throw new Twig_Error_Loader(sprintf('Looks like you try to load a template outside configured directories (%s).', $name)); | |
| } | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a template filter. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| abstract class Twig_Filter implements Twig_FilterInterface | |
| { | |
| protected $options; | |
| protected $arguments = array(); | |
| public function __construct(array $options = array()) | |
| { | |
| $this->options = array_merge(array( | |
| 'needs_environment' => false, | |
| 'needs_context' => false, | |
| 'pre_escape' => null, | |
| 'preserves_safety' => null, | |
| ), $options); | |
| } | |
| public function setArguments($arguments) | |
| { | |
| $this->arguments = $arguments; | |
| } | |
| public function getArguments() | |
| { | |
| return $this->arguments; | |
| } | |
| public function needsEnvironment() | |
| { | |
| return $this->options['needs_environment']; | |
| } | |
| public function needsContext() | |
| { | |
| return $this->options['needs_context']; | |
| } | |
| public function getSafe(Twig_Node $filterArgs) | |
| { | |
| if (isset($this->options['is_safe'])) { | |
| return $this->options['is_safe']; | |
| } | |
| if (isset($this->options['is_safe_callback'])) { | |
| return call_user_func($this->options['is_safe_callback'], $filterArgs); | |
| } | |
| return null; | |
| } | |
| public function getPreservesSafety() | |
| { | |
| return $this->options['preserves_safety']; | |
| } | |
| public function getPreEscape() | |
| { | |
| return $this->options['pre_escape']; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Filter extends Twig_Node_Expression | |
| { | |
| public function __construct(Twig_NodeInterface $node, Twig_Node_Expression_Constant $filterName, Twig_NodeInterface $arguments, $lineno, $tag = null) | |
| { | |
| parent::__construct(array('node' => $node, 'filter' => $filterName, 'arguments' => $arguments), array(), $lineno, $tag); | |
| } | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $name = $this->getNode('filter')->getAttribute('value'); | |
| if (false === $filter = $compiler->getEnvironment()->getFilter($name)) { | |
| $message = sprintf('The filter "%s" does not exist', $name); | |
| if ($alternatives = $compiler->getEnvironment()->computeAlternatives($name, array_keys($compiler->getEnvironment()->getFilters()))) { | |
| $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); | |
| } | |
| throw new Twig_Error_Syntax($message, $this->getLine(), $compiler->getFilename()); | |
| } | |
| $this->compileFilter($compiler, $filter); | |
| } | |
| protected function compileFilter(Twig_Compiler $compiler, Twig_FilterInterface $filter) | |
| { | |
| $compiler | |
| ->raw($filter->compile().'(') | |
| ->raw($filter->needsEnvironment() ? '$this->env, ' : '') | |
| ->raw($filter->needsContext() ? '$context, ' : '') | |
| ; | |
| foreach ($filter->getArguments() as $argument) { | |
| $compiler | |
| ->string($argument) | |
| ->raw(', ') | |
| ; | |
| } | |
| $compiler->subcompile($this->getNode('node')); | |
| foreach ($this->getNode('arguments') as $node) { | |
| $compiler | |
| ->raw(', ') | |
| ->subcompile($node) | |
| ; | |
| } | |
| $compiler->raw(')'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Filters a section of a template by applying filters. | |
| * | |
| * <pre> | |
| * {% filter upper %} | |
| * This text becomes uppercase | |
| * {% endfilter %} | |
| * </pre> | |
| */ | |
| class Twig_TokenParser_Filter extends Twig_TokenParser | |
| { | |
| /** | |
| * Parses a token and returns a node. | |
| * | |
| * @param Twig_Token $token A Twig_Token instance | |
| * | |
| * @return Twig_NodeInterface A Twig_NodeInterface instance | |
| */ | |
| public function parse(Twig_Token $token) | |
| { | |
| $name = $this->parser->getVarName(); | |
| $ref = new Twig_Node_Expression_BlockReference(new Twig_Node_Expression_Constant($name, $token->getLine()), true, $token->getLine(), $this->getTag()); | |
| $filter = $this->parser->getExpressionParser()->parseFilterExpressionRaw($ref, $this->getTag()); | |
| $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); | |
| $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true); | |
| $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); | |
| $block = new Twig_Node_Block($name, $body, $token->getLine()); | |
| $this->parser->setBlock($name, $block); | |
| return new Twig_Node_Print($filter, $token->getLine(), $this->getTag()); | |
| } | |
| public function decideBlockEnd(Twig_Token $token) | |
| { | |
| return $token->test('endfilter'); | |
| } | |
| /** | |
| * Gets the tag name associated with this token parser. | |
| * | |
| * @return string The tag name | |
| */ | |
| public function getTag() | |
| { | |
| return 'filter'; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a template filter. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| interface Twig_FilterInterface | |
| { | |
| /** | |
| * Compiles a filter. | |
| * | |
| * @return string The PHP code for the filter | |
| */ | |
| public function compile(); | |
| public function needsEnvironment(); | |
| public function needsContext(); | |
| public function getSafe(Twig_Node $filterArgs); | |
| public function getPreservesSafety(); | |
| public function getPreEscape(); | |
| public function setArguments($arguments); | |
| public function getArguments(); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Binary_FloorDiv extends Twig_Node_Expression_Binary | |
| { | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler->raw('intval(floor('); | |
| parent::compile($compiler); | |
| $compiler->raw('))'); | |
| } | |
| public function operator(Twig_Compiler $compiler) | |
| { | |
| return $compiler->raw('/'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2011 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a flush node. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_Flush extends Twig_Node | |
| { | |
| public function __construct($lineno, $tag) | |
| { | |
| parent::__construct(array(), array(), $lineno, $tag); | |
| } | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->addDebugInfo($this) | |
| ->write("flush();\n") | |
| ; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2011 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Flushes the output to the client. | |
| * | |
| * @see flush() | |
| */ | |
| class Twig_TokenParser_Flush extends Twig_TokenParser | |
| { | |
| /** | |
| * Parses a token and returns a node. | |
| * | |
| * @param Twig_Token $token A Twig_Token instance | |
| * | |
| * @return Twig_NodeInterface A Twig_NodeInterface instance | |
| */ | |
| public function parse(Twig_Token $token) | |
| { | |
| $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); | |
| return new Twig_Node_Flush($token->getLine(), $this->getTag()); | |
| } | |
| /** | |
| * Gets the tag name associated with this token parser. | |
| * | |
| * @return string The tag name | |
| */ | |
| public function getTag() | |
| { | |
| return 'flush'; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a for node. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_For extends Twig_Node | |
| { | |
| protected $loop; | |
| public function __construct(Twig_Node_Expression_AssignName $keyTarget, Twig_Node_Expression_AssignName $valueTarget, Twig_Node_Expression $seq, Twig_Node_Expression $ifexpr = null, Twig_NodeInterface $body, Twig_NodeInterface $else = null, $lineno, $tag = null) | |
| { | |
| $body = new Twig_Node(array($body, $this->loop = new Twig_Node_ForLoop($lineno, $tag))); | |
| if (null !== $ifexpr) { | |
| $body = new Twig_Node_If(new Twig_Node(array($ifexpr, $body)), null, $lineno, $tag); | |
| } | |
| parent::__construct(array('key_target' => $keyTarget, 'value_target' => $valueTarget, 'seq' => $seq, 'body' => $body, 'else' => $else), array('with_loop' => true, 'ifexpr' => null !== $ifexpr), $lineno, $tag); | |
| } | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->addDebugInfo($this) | |
| // the (array) cast bypasses a PHP 5.2.6 bug | |
| ->write("\$context['_parent'] = (array) \$context;\n") | |
| ->write("\$context['_seq'] = twig_ensure_traversable(") | |
| ->subcompile($this->getNode('seq')) | |
| ->raw(");\n") | |
| ; | |
| if (null !== $this->getNode('else')) { | |
| $compiler->write("\$context['_iterated'] = false;\n"); | |
| } | |
| if ($this->getAttribute('with_loop')) { | |
| $compiler | |
| ->write("\$context['loop'] = array(\n") | |
| ->write(" 'parent' => \$context['_parent'],\n") | |
| ->write(" 'index0' => 0,\n") | |
| ->write(" 'index' => 1,\n") | |
| ->write(" 'first' => true,\n") | |
| ->write(");\n") | |
| ; | |
| if (!$this->getAttribute('ifexpr')) { | |
| $compiler | |
| ->write("if (is_array(\$context['_seq']) || (is_object(\$context['_seq']) && \$context['_seq'] instanceof Countable)) {\n") | |
| ->indent() | |
| ->write("\$length = count(\$context['_seq']);\n") | |
| ->write("\$context['loop']['revindex0'] = \$length - 1;\n") | |
| ->write("\$context['loop']['revindex'] = \$length;\n") | |
| ->write("\$context['loop']['length'] = \$length;\n") | |
| ->write("\$context['loop']['last'] = 1 === \$length;\n") | |
| ->outdent() | |
| ->write("}\n") | |
| ; | |
| } | |
| } | |
| $this->loop->setAttribute('else', null !== $this->getNode('else')); | |
| $this->loop->setAttribute('with_loop', $this->getAttribute('with_loop')); | |
| $this->loop->setAttribute('ifexpr', $this->getAttribute('ifexpr')); | |
| $compiler | |
| ->write("foreach (\$context['_seq'] as ") | |
| ->subcompile($this->getNode('key_target')) | |
| ->raw(" => ") | |
| ->subcompile($this->getNode('value_target')) | |
| ->raw(") {\n") | |
| ->indent() | |
| ->subcompile($this->getNode('body')) | |
| ->outdent() | |
| ->write("}\n") | |
| ; | |
| if (null !== $this->getNode('else')) { | |
| $compiler | |
| ->write("if (!\$context['_iterated']) {\n") | |
| ->indent() | |
| ->subcompile($this->getNode('else')) | |
| ->outdent() | |
| ->write("}\n") | |
| ; | |
| } | |
| $compiler->write("\$_parent = \$context['_parent'];\n"); | |
| // remove some "private" loop variables (needed for nested loops) | |
| $compiler->write('unset($context[\'_seq\'], $context[\'_iterated\'], $context[\''.$this->getNode('key_target')->getAttribute('name').'\'], $context[\''.$this->getNode('value_target')->getAttribute('name').'\'], $context[\'_parent\'], $context[\'loop\']);'."\n"); | |
| // keep the values set in the inner context for variables defined in the outer context | |
| $compiler->write("\$context = array_merge(\$_parent, array_intersect_key(\$context, \$_parent));\n"); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Loops over each item of a sequence. | |
| * | |
| * <pre> | |
| * <ul> | |
| * {% for user in users %} | |
| * <li>{{ user.username|e }}</li> | |
| * {% endfor %} | |
| * </ul> | |
| * </pre> | |
| */ | |
| class Twig_TokenParser_For extends Twig_TokenParser | |
| { | |
| /** | |
| * Parses a token and returns a node. | |
| * | |
| * @param Twig_Token $token A Twig_Token instance | |
| * | |
| * @return Twig_NodeInterface A Twig_NodeInterface instance | |
| */ | |
| public function parse(Twig_Token $token) | |
| { | |
| $lineno = $token->getLine(); | |
| $targets = $this->parser->getExpressionParser()->parseAssignmentExpression(); | |
| $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, 'in'); | |
| $seq = $this->parser->getExpressionParser()->parseExpression(); | |
| $ifexpr = null; | |
| if ($this->parser->getStream()->test(Twig_Token::NAME_TYPE, 'if')) { | |
| $this->parser->getStream()->next(); | |
| $ifexpr = $this->parser->getExpressionParser()->parseExpression(); | |
| } | |
| $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); | |
| $body = $this->parser->subparse(array($this, 'decideForFork')); | |
| if ($this->parser->getStream()->next()->getValue() == 'else') { | |
| $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); | |
| $else = $this->parser->subparse(array($this, 'decideForEnd'), true); | |
| } else { | |
| $else = null; | |
| } | |
| $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); | |
| if (count($targets) > 1) { | |
| $keyTarget = $targets->getNode(0); | |
| $keyTarget = new Twig_Node_Expression_AssignName($keyTarget->getAttribute('name'), $keyTarget->getLine()); | |
| $valueTarget = $targets->getNode(1); | |
| $valueTarget = new Twig_Node_Expression_AssignName($valueTarget->getAttribute('name'), $valueTarget->getLine()); | |
| } else { | |
| $keyTarget = new Twig_Node_Expression_AssignName('_key', $lineno); | |
| $valueTarget = $targets->getNode(0); | |
| $valueTarget = new Twig_Node_Expression_AssignName($valueTarget->getAttribute('name'), $valueTarget->getLine()); | |
| } | |
| return new Twig_Node_For($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, $lineno, $this->getTag()); | |
| } | |
| public function decideForFork(Twig_Token $token) | |
| { | |
| return $token->test(array('else', 'endfor')); | |
| } | |
| public function decideForEnd(Twig_Token $token) | |
| { | |
| return $token->test('endfor'); | |
| } | |
| /** | |
| * Gets the tag name associated with this token parser. | |
| * | |
| * @return string The tag name | |
| */ | |
| public function getTag() | |
| { | |
| return 'for'; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2011 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Internal node used by the for node. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_ForLoop extends Twig_Node | |
| { | |
| public function __construct($lineno, $tag = null) | |
| { | |
| parent::__construct(array(), array('with_loop' => false, 'ifexpr' => false, 'else' => false), $lineno, $tag); | |
| } | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| if ($this->getAttribute('else')) { | |
| $compiler->write("\$context['_iterated'] = true;\n"); | |
| } | |
| if ($this->getAttribute('with_loop')) { | |
| $compiler | |
| ->write("++\$context['loop']['index0'];\n") | |
| ->write("++\$context['loop']['index'];\n") | |
| ->write("\$context['loop']['first'] = false;\n") | |
| ; | |
| if (!$this->getAttribute('ifexpr')) { | |
| $compiler | |
| ->write("if (isset(\$context['loop']['length'])) {\n") | |
| ->indent() | |
| ->write("--\$context['loop']['revindex0'];\n") | |
| ->write("--\$context['loop']['revindex'];\n") | |
| ->write("\$context['loop']['last'] = 0 === \$context['loop']['revindex0'];\n") | |
| ->outdent() | |
| ->write("}\n") | |
| ; | |
| } | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Imports macros. | |
| * | |
| * <pre> | |
| * {% from 'forms.html' import forms %} | |
| * </pre> | |
| */ | |
| class Twig_TokenParser_From extends Twig_TokenParser | |
| { | |
| /** | |
| * Parses a token and returns a node. | |
| * | |
| * @param Twig_Token $token A Twig_Token instance | |
| * | |
| * @return Twig_NodeInterface A Twig_NodeInterface instance | |
| */ | |
| public function parse(Twig_Token $token) | |
| { | |
| $macro = $this->parser->getExpressionParser()->parseExpression(); | |
| $stream = $this->parser->getStream(); | |
| $stream->expect('import'); | |
| $targets = array(); | |
| do { | |
| $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); | |
| $alias = $name; | |
| if ($stream->test('as')) { | |
| $stream->next(); | |
| $alias = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); | |
| } | |
| $targets[$name] = $alias; | |
| if (!$stream->test(Twig_Token::PUNCTUATION_TYPE, ',')) { | |
| break; | |
| } | |
| $stream->next(); | |
| } while (true); | |
| $stream->expect(Twig_Token::BLOCK_END_TYPE); | |
| $node = new Twig_Node_Import($macro, new Twig_Node_Expression_AssignName($this->parser->getVarName(), $token->getLine()), $token->getLine(), $this->getTag()); | |
| foreach ($targets as $name => $alias) { | |
| $this->parser->addImportedSymbol('function', $alias, 'get'.$name, $node->getNode('var')); | |
| } | |
| return $node; | |
| } | |
| /** | |
| * Gets the tag name associated with this token parser. | |
| * | |
| * @return string The tag name | |
| */ | |
| public function getTag() | |
| { | |
| return 'from'; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a function template filter. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Filter_Function extends Twig_Filter | |
| { | |
| protected $function; | |
| public function __construct($function, array $options = array()) | |
| { | |
| parent::__construct($options); | |
| $this->function = $function; | |
| } | |
| public function compile() | |
| { | |
| return $this->function; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a template function. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| abstract class Twig_Function implements Twig_FunctionInterface | |
| { | |
| protected $options; | |
| protected $arguments = array(); | |
| public function __construct(array $options = array()) | |
| { | |
| $this->options = array_merge(array( | |
| 'needs_environment' => false, | |
| 'needs_context' => false, | |
| ), $options); | |
| } | |
| public function setArguments($arguments) | |
| { | |
| $this->arguments = $arguments; | |
| } | |
| public function getArguments() | |
| { | |
| return $this->arguments; | |
| } | |
| public function needsEnvironment() | |
| { | |
| return $this->options['needs_environment']; | |
| } | |
| public function needsContext() | |
| { | |
| return $this->options['needs_context']; | |
| } | |
| public function getSafe(Twig_Node $functionArgs) | |
| { | |
| if (isset($this->options['is_safe'])) { | |
| return $this->options['is_safe']; | |
| } | |
| if (isset($this->options['is_safe_callback'])) { | |
| return call_user_func($this->options['is_safe_callback'], $functionArgs); | |
| } | |
| return array(); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2010 Arnaud Le Blanc | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a function template function. | |
| * | |
| * @package twig | |
| * @author Arnaud Le Blanc <arnaud.lb@gmail.com> | |
| */ | |
| class Twig_Function_Function extends Twig_Function | |
| { | |
| protected $function; | |
| public function __construct($function, array $options = array()) | |
| { | |
| parent::__construct($options); | |
| $this->function = $function; | |
| } | |
| public function compile() | |
| { | |
| return $this->function; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Function extends Twig_Node_Expression | |
| { | |
| public function __construct($name, Twig_NodeInterface $arguments, $lineno) | |
| { | |
| parent::__construct(array('arguments' => $arguments), array('name' => $name), $lineno); | |
| } | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $name = $this->getAttribute('name'); | |
| if (false === $function = $compiler->getEnvironment()->getFunction($name)) { | |
| $message = sprintf('The function "%s" does not exist', $name); | |
| if ($alternatives = $compiler->getEnvironment()->computeAlternatives($name, array_keys($compiler->getEnvironment()->getFunctions()))) { | |
| $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); | |
| } | |
| throw new Twig_Error_Syntax($message, $this->getLine(), $compiler->getFilename()); | |
| } | |
| $compiler->raw($function->compile().'('); | |
| $first = true; | |
| if ($function->needsEnvironment()) { | |
| $compiler->raw('$this->env'); | |
| $first = false; | |
| } | |
| if ($function->needsContext()) { | |
| if (!$first) { | |
| $compiler->raw(', '); | |
| } | |
| $compiler->raw('$context'); | |
| $first = false; | |
| } | |
| foreach ($function->getArguments() as $argument) { | |
| if (!$first) { | |
| $compiler->raw(', '); | |
| } | |
| $compiler->string($argument); | |
| $first = false; | |
| } | |
| foreach ($this->getNode('arguments') as $node) { | |
| if (!$first) { | |
| $compiler->raw(', '); | |
| } | |
| $compiler->subcompile($node); | |
| $first = false; | |
| } | |
| $compiler->raw(')'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a function template test. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Test_Function implements Twig_TestInterface | |
| { | |
| protected $function; | |
| public function __construct($function) | |
| { | |
| $this->function = $function; | |
| } | |
| public function compile() | |
| { | |
| return $this->function; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * (c) 2010 Arnaud Le Blanc | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a template function. | |
| * | |
| * @package twig | |
| * @author Arnaud Le Blanc <arnaud.lb@gmail.com> | |
| */ | |
| interface Twig_FunctionInterface | |
| { | |
| /** | |
| * Compiles a function. | |
| * | |
| * @return string The PHP code for the function | |
| */ | |
| public function compile(); | |
| public function needsEnvironment(); | |
| public function needsContext(); | |
| public function getSafe(Twig_Node $filterArgs); | |
| public function setArguments($arguments); | |
| public function getArguments(); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_GetAttr extends Twig_Node_Expression | |
| { | |
| public function __construct(Twig_Node_Expression $node, Twig_Node_Expression $attribute, Twig_Node_Expression_Array $arguments, $type, $lineno) | |
| { | |
| parent::__construct(array('node' => $node, 'attribute' => $attribute, 'arguments' => $arguments), array('type' => $type, 'is_defined_test' => false, 'ignore_strict_check' => false, 'disable_c_ext' => false), $lineno); | |
| } | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| if (function_exists('twig_template_get_attributes') && !$this->getAttribute('disable_c_ext')) { | |
| $compiler->raw('twig_template_get_attributes($this, '); | |
| } else { | |
| $compiler->raw('$this->getAttribute('); | |
| } | |
| if ($this->getAttribute('ignore_strict_check')) { | |
| $this->getNode('node')->setAttribute('ignore_strict_check', true); | |
| } | |
| $compiler->subcompile($this->getNode('node')); | |
| $compiler->raw(', ')->subcompile($this->getNode('attribute')); | |
| if (count($this->getNode('arguments')) || Twig_TemplateInterface::ANY_CALL !== $this->getAttribute('type') || $this->getAttribute('is_defined_test') || $this->getAttribute('ignore_strict_check')) { | |
| $compiler->raw(', ')->subcompile($this->getNode('arguments')); | |
| if (Twig_TemplateInterface::ANY_CALL !== $this->getAttribute('type') || $this->getAttribute('is_defined_test') || $this->getAttribute('ignore_strict_check')) { | |
| $compiler->raw(', ')->repr($this->getAttribute('type')); | |
| } | |
| if ($this->getAttribute('is_defined_test') || $this->getAttribute('ignore_strict_check')) { | |
| $compiler->raw(', '.($this->getAttribute('is_defined_test') ? 'true' : 'false')); | |
| } | |
| if ($this->getAttribute('ignore_strict_check')) { | |
| $compiler->raw(', '.($this->getAttribute('ignore_strict_check') ? 'true' : 'false')); | |
| } | |
| } | |
| $compiler->raw(')'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Binary_Greater extends Twig_Node_Expression_Binary | |
| { | |
| public function operator(Twig_Compiler $compiler) | |
| { | |
| return $compiler->raw('>'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Binary_GreaterEqual extends Twig_Node_Expression_Binary | |
| { | |
| public function operator(Twig_Compiler $compiler) | |
| { | |
| return $compiler->raw('>='); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents an if node. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_If extends Twig_Node | |
| { | |
| public function __construct(Twig_NodeInterface $tests, Twig_NodeInterface $else = null, $lineno, $tag = null) | |
| { | |
| parent::__construct(array('tests' => $tests, 'else' => $else), array(), $lineno, $tag); | |
| } | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler->addDebugInfo($this); | |
| for ($i = 0; $i < count($this->getNode('tests')); $i += 2) { | |
| if ($i > 0) { | |
| $compiler | |
| ->outdent() | |
| ->write("} elseif (") | |
| ; | |
| } else { | |
| $compiler | |
| ->write('if (') | |
| ; | |
| } | |
| $compiler | |
| ->subcompile($this->getNode('tests')->getNode($i)) | |
| ->raw(") {\n") | |
| ->indent() | |
| ->subcompile($this->getNode('tests')->getNode($i + 1)) | |
| ; | |
| } | |
| if ($this->hasNode('else') && null !== $this->getNode('else')) { | |
| $compiler | |
| ->outdent() | |
| ->write("} else {\n") | |
| ->indent() | |
| ->subcompile($this->getNode('else')) | |
| ; | |
| } | |
| $compiler | |
| ->outdent() | |
| ->write("}\n"); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Tests a condition. | |
| * | |
| * <pre> | |
| * {% if users %} | |
| * <ul> | |
| * {% for user in users %} | |
| * <li>{{ user.username|e }}</li> | |
| * {% endfor %} | |
| * </ul> | |
| * {% endif %} | |
| * </pre> | |
| */ | |
| class Twig_TokenParser_If extends Twig_TokenParser | |
| { | |
| /** | |
| * Parses a token and returns a node. | |
| * | |
| * @param Twig_Token $token A Twig_Token instance | |
| * | |
| * @return Twig_NodeInterface A Twig_NodeInterface instance | |
| */ | |
| public function parse(Twig_Token $token) | |
| { | |
| $lineno = $token->getLine(); | |
| $expr = $this->parser->getExpressionParser()->parseExpression(); | |
| $stream = $this->parser->getStream(); | |
| $stream->expect(Twig_Token::BLOCK_END_TYPE); | |
| $body = $this->parser->subparse(array($this, 'decideIfFork')); | |
| $tests = array($expr, $body); | |
| $else = null; | |
| $end = false; | |
| while (!$end) { | |
| switch ($stream->next()->getValue()) { | |
| case 'else': | |
| $stream->expect(Twig_Token::BLOCK_END_TYPE); | |
| $else = $this->parser->subparse(array($this, 'decideIfEnd')); | |
| break; | |
| case 'elseif': | |
| $expr = $this->parser->getExpressionParser()->parseExpression(); | |
| $stream->expect(Twig_Token::BLOCK_END_TYPE); | |
| $body = $this->parser->subparse(array($this, 'decideIfFork')); | |
| $tests[] = $expr; | |
| $tests[] = $body; | |
| break; | |
| case 'endif': | |
| $end = true; | |
| break; | |
| default: | |
| throw new Twig_Error_Syntax(sprintf('Unexpected end of template. Twig was looking for the following tags "else", "elseif", or "endif" to close the "if" block started at line %d)', $lineno), $stream->getCurrent()->getLine(), $stream->getFilename()); | |
| } | |
| } | |
| $stream->expect(Twig_Token::BLOCK_END_TYPE); | |
| return new Twig_Node_If(new Twig_Node($tests), $else, $lineno, $this->getTag()); | |
| } | |
| public function decideIfFork(Twig_Token $token) | |
| { | |
| return $token->test(array('elseif', 'else', 'endif')); | |
| } | |
| public function decideIfEnd(Twig_Token $token) | |
| { | |
| return $token->test(array('endif')); | |
| } | |
| /** | |
| * Gets the tag name associated with this token parser. | |
| * | |
| * @return string The tag name | |
| */ | |
| public function getTag() | |
| { | |
| return 'if'; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents an import node. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_Import extends Twig_Node | |
| { | |
| public function __construct(Twig_Node_Expression $expr, Twig_Node_Expression $var, $lineno, $tag = null) | |
| { | |
| parent::__construct(array('expr' => $expr, 'var' => $var), array(), $lineno, $tag); | |
| } | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->addDebugInfo($this) | |
| ->write('') | |
| ->subcompile($this->getNode('var')) | |
| ->raw(' = ') | |
| ; | |
| if ($this->getNode('expr') instanceof Twig_Node_Expression_Name && '_self' === $this->getNode('expr')->getAttribute('name')) { | |
| $compiler->raw("\$this"); | |
| } else { | |
| $compiler | |
| ->raw('$this->env->loadTemplate(') | |
| ->subcompile($this->getNode('expr')) | |
| ->raw(")") | |
| ; | |
| } | |
| $compiler->raw(";\n"); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Imports macros. | |
| * | |
| * <pre> | |
| * {% import 'forms.html' as forms %} | |
| * </pre> | |
| */ | |
| class Twig_TokenParser_Import extends Twig_TokenParser | |
| { | |
| /** | |
| * Parses a token and returns a node. | |
| * | |
| * @param Twig_Token $token A Twig_Token instance | |
| * | |
| * @return Twig_NodeInterface A Twig_NodeInterface instance | |
| */ | |
| public function parse(Twig_Token $token) | |
| { | |
| $macro = $this->parser->getExpressionParser()->parseExpression(); | |
| $this->parser->getStream()->expect('as'); | |
| $var = new Twig_Node_Expression_AssignName($this->parser->getStream()->expect(Twig_Token::NAME_TYPE)->getValue(), $token->getLine()); | |
| $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); | |
| $this->parser->addImportedSymbol('template', $var->getAttribute('name')); | |
| return new Twig_Node_Import($macro, $var, $token->getLine(), $this->getTag()); | |
| } | |
| /** | |
| * Gets the tag name associated with this token parser. | |
| * | |
| * @return string The tag name | |
| */ | |
| public function getTag() | |
| { | |
| return 'import'; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Binary_In extends Twig_Node_Expression_Binary | |
| { | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->raw('twig_in_filter(') | |
| ->subcompile($this->getNode('left')) | |
| ->raw(', ') | |
| ->subcompile($this->getNode('right')) | |
| ->raw(')') | |
| ; | |
| } | |
| public function operator(Twig_Compiler $compiler) | |
| { | |
| return $compiler->raw('in'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents an include node. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface | |
| { | |
| public function __construct(Twig_Node_Expression $expr, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null) | |
| { | |
| parent::__construct(array('expr' => $expr, 'variables' => $variables), array('only' => (Boolean) $only, 'ignore_missing' => (Boolean) $ignoreMissing), $lineno, $tag); | |
| } | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler->addDebugInfo($this); | |
| if ($this->getAttribute('ignore_missing')) { | |
| $compiler | |
| ->write("try {\n") | |
| ->indent() | |
| ; | |
| } | |
| $this->addGetTemplate($compiler); | |
| $compiler->raw('->display('); | |
| $this->addTemplateArguments($compiler); | |
| $compiler->raw(");\n"); | |
| if ($this->getAttribute('ignore_missing')) { | |
| $compiler | |
| ->outdent() | |
| ->write("} catch (Twig_Error_Loader \$e) {\n") | |
| ->indent() | |
| ->write("// ignore missing template\n") | |
| ->outdent() | |
| ->write("}\n\n") | |
| ; | |
| } | |
| } | |
| protected function addGetTemplate(Twig_Compiler $compiler) | |
| { | |
| if ($this->getNode('expr') instanceof Twig_Node_Expression_Constant) { | |
| $compiler | |
| ->write("\$this->env->loadTemplate(") | |
| ->subcompile($this->getNode('expr')) | |
| ->raw(")") | |
| ; | |
| } else { | |
| $compiler | |
| ->write("\$template = \$this->env->resolveTemplate(") | |
| ->subcompile($this->getNode('expr')) | |
| ->raw(");\n") | |
| ->write('$template') | |
| ; | |
| } | |
| } | |
| protected function addTemplateArguments(Twig_Compiler $compiler) | |
| { | |
| if (false === $this->getAttribute('only')) { | |
| if (null === $this->getNode('variables')) { | |
| $compiler->raw('$context'); | |
| } else { | |
| $compiler | |
| ->raw('array_merge($context, ') | |
| ->subcompile($this->getNode('variables')) | |
| ->raw(')') | |
| ; | |
| } | |
| } else { | |
| if (null === $this->getNode('variables')) { | |
| $compiler->raw('array()'); | |
| } else { | |
| $compiler->subcompile($this->getNode('variables')); | |
| } | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Includes a template. | |
| * | |
| * <pre> | |
| * {% include 'header.html' %} | |
| * Body | |
| * {% include 'footer.html' %} | |
| * </pre> | |
| */ | |
| class Twig_TokenParser_Include extends Twig_TokenParser | |
| { | |
| /** | |
| * Parses a token and returns a node. | |
| * | |
| * @param Twig_Token $token A Twig_Token instance | |
| * | |
| * @return Twig_NodeInterface A Twig_NodeInterface instance | |
| */ | |
| public function parse(Twig_Token $token) | |
| { | |
| $expr = $this->parser->getExpressionParser()->parseExpression(); | |
| list($variables, $only, $ignoreMissing) = $this->parseArguments(); | |
| return new Twig_Node_Include($expr, $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag()); | |
| } | |
| protected function parseArguments() | |
| { | |
| $stream = $this->parser->getStream(); | |
| $ignoreMissing = false; | |
| if ($stream->test(Twig_Token::NAME_TYPE, 'ignore')) { | |
| $stream->next(); | |
| $stream->expect(Twig_Token::NAME_TYPE, 'missing'); | |
| $ignoreMissing = true; | |
| } | |
| $variables = null; | |
| if ($stream->test(Twig_Token::NAME_TYPE, 'with')) { | |
| $stream->next(); | |
| $variables = $this->parser->getExpressionParser()->parseExpression(); | |
| } | |
| $only = false; | |
| if ($stream->test(Twig_Token::NAME_TYPE, 'only')) { | |
| $stream->next(); | |
| $only = true; | |
| } | |
| $stream->expect(Twig_Token::BLOCK_END_TYPE); | |
| return array($variables, $only, $ignoreMissing); | |
| } | |
| /** | |
| * Gets the tag name associated with this token parser. | |
| * | |
| * @return string The tag name | |
| */ | |
| public function getTag() | |
| { | |
| return 'include'; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| require 'autoload.php'; | |
| echo $views->render_with_layout('index'); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Integration test helper | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| * @author Karma Dordrak <drak@zikula.org> | |
| */ | |
| abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase | |
| { | |
| abstract protected function getExtensions(); | |
| abstract protected function getFixturesDir(); | |
| /** | |
| * @dataProvider getTests | |
| */ | |
| public function testIntegration($file, $message, $condition, $templates, $exception, $outputs) | |
| { | |
| $this->doIntegrationTest($file, $message, $condition, $templates, $exception, $outputs); | |
| } | |
| public function getTests() | |
| { | |
| $fixturesDir = realpath($this->getFixturesDir()); | |
| $tests = array(); | |
| foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($fixturesDir), RecursiveIteratorIterator::LEAVES_ONLY) as $file) { | |
| if (!preg_match('/\.test$/', $file)) { | |
| continue; | |
| } | |
| $test = file_get_contents($file->getRealpath()); | |
| if (preg_match('/ | |
| --TEST--\s*(.*?)\s*(?:--CONDITION--\s*(.*))?\s*((?:--TEMPLATE(?:\(.*?\))?--(?:.*?))+)\s*(?:--DATA--\s*(.*))?\s*--EXCEPTION--\s*(.*)/sx', $test, $match)) { | |
| $message = $match[1]; | |
| $condition = $match[2]; | |
| $templates = $this->parseTemplates($match[3]); | |
| $exception = $match[5]; | |
| $outputs = array(array(null, $match[4], null, '')); | |
| } elseif (preg_match('/--TEST--\s*(.*?)\s*(?:--CONDITION--\s*(.*))?\s*((?:--TEMPLATE(?:\(.*?\))?--(?:.*?))+)--DATA--.*?--EXPECT--.*/s', $test, $match)) { | |
| $message = $match[1]; | |
| $condition = $match[2]; | |
| $templates = $this->parseTemplates($match[3]); | |
| $exception = false; | |
| preg_match_all('/--DATA--(.*?)(?:--CONFIG--(.*?))?--EXPECT--(.*?)(?=\-\-DATA\-\-|$)/s', $test, $outputs, PREG_SET_ORDER); | |
| } else { | |
| throw new InvalidArgumentException(sprintf('Test "%s" is not valid.', str_replace($fixturesDir.'/', '', $file))); | |
| } | |
| $tests[] = array(str_replace($fixturesDir.'/', '', $file), $message, $condition, $templates, $exception, $outputs); | |
| } | |
| return $tests; | |
| } | |
| protected function doIntegrationTest($file, $message, $condition, $templates, $exception, $outputs) | |
| { | |
| if ($condition) { | |
| eval('$ret = '.$condition.';'); | |
| if (!$ret) { | |
| $this->markTestSkipped($condition); | |
| } | |
| } | |
| $loader = new Twig_Loader_Array($templates); | |
| foreach ($outputs as $match) { | |
| $config = array_merge(array( | |
| 'cache' => false, | |
| 'strict_variables' => true, | |
| ), $match[2] ? eval($match[2].';') : array()); | |
| $twig = new Twig_Environment($loader, $config); | |
| $twig->addGlobal('global', 'global'); | |
| foreach ($this->getExtensions() as $extension) { | |
| $twig->addExtension($extension); | |
| } | |
| try { | |
| $template = $twig->loadTemplate('index.twig'); | |
| } catch (Exception $e) { | |
| if (false !== $exception) { | |
| $this->assertEquals(trim($exception), trim(sprintf('%s: %s', get_class($e), $e->getMessage()))); | |
| return; | |
| } | |
| if ($e instanceof Twig_Error_Syntax) { | |
| $e->setTemplateFile($file); | |
| throw $e; | |
| } | |
| throw new Twig_Error(sprintf('%s: %s', get_class($e), $e->getMessage()), -1, $file, $e); | |
| } | |
| try { | |
| $output = trim($template->render(eval($match[1].';')), "\n "); | |
| } catch (Exception $e) { | |
| if (false !== $exception) { | |
| $this->assertEquals(trim($exception), trim(sprintf('%s: %s', get_class($e), $e->getMessage()))); | |
| return; | |
| } | |
| if ($e instanceof Twig_Error_Syntax) { | |
| $e->setTemplateFile($file); | |
| } else { | |
| $e = new Twig_Error(sprintf('%s: %s', get_class($e), $e->getMessage()), -1, $file, $e); | |
| } | |
| $output = trim(sprintf('%s: %s', get_class($e), $e->getMessage())); | |
| } | |
| if (false !== $exception) { | |
| list($class, ) = explode(':', $exception); | |
| $this->assertThat(NULL, new PHPUnit_Framework_Constraint_Exception($class)); | |
| } | |
| $expected = trim($match[3], "\n "); | |
| if ($expected != $output) { | |
| echo 'Compiled template that failed:'; | |
| foreach (array_keys($templates) as $name) { | |
| echo "Template: $name\n"; | |
| $source = $loader->getSource($name); | |
| echo $twig->compile($twig->parse($twig->tokenize($source, $name))); | |
| } | |
| } | |
| $this->assertEquals($expected, $output, $message.' (in '.$file.')'); | |
| } | |
| } | |
| protected static function parseTemplates($test) | |
| { | |
| $templates = array(); | |
| preg_match_all('/--TEMPLATE(?:\((.*?)\))?--(.*?)(?=\-\-TEMPLATE|$)/s', $test, $matches, PREG_SET_ORDER); | |
| foreach ($matches as $match) { | |
| $templates[($match[1] ? $match[1] : 'index.twig')] = $match[2]; | |
| } | |
| return $templates; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Binary_Less extends Twig_Node_Expression_Binary | |
| { | |
| public function operator(Twig_Compiler $compiler) | |
| { | |
| return $compiler->raw('<'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Binary_LessEqual extends Twig_Node_Expression_Binary | |
| { | |
| public function operator(Twig_Compiler $compiler) | |
| { | |
| return $compiler->raw('<='); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Lexes a template string. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Lexer implements Twig_LexerInterface | |
| { | |
| protected $tokens; | |
| protected $code; | |
| protected $cursor; | |
| protected $lineno; | |
| protected $end; | |
| protected $state; | |
| protected $states; | |
| protected $brackets; | |
| protected $env; | |
| protected $filename; | |
| protected $options; | |
| protected $regexes; | |
| protected $position; | |
| protected $positions; | |
| const STATE_DATA = 0; | |
| const STATE_BLOCK = 1; | |
| const STATE_VAR = 2; | |
| const STATE_STRING = 3; | |
| const STATE_INTERPOLATION = 4; | |
| const REGEX_NAME = '/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/A'; | |
| const REGEX_NUMBER = '/[0-9]+(?:\.[0-9]+)?/A'; | |
| const REGEX_STRING = '/"([^#"\\\\]*(?:\\\\.[^#"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\'/As'; | |
| const REGEX_DQ_STRING_DELIM = '/"/A'; | |
| const REGEX_DQ_STRING_PART = '/[^#"\\\\]*(?:(?:\\\\.|#(?!\{))[^#"\\\\]*)*/As'; | |
| const PUNCTUATION = '()[]{}?:.,|'; | |
| public function __construct(Twig_Environment $env, array $options = array()) | |
| { | |
| $this->env = $env; | |
| $this->options = array_merge(array( | |
| 'tag_comment' => array('{#', '#}'), | |
| 'tag_block' => array('{%', '%}'), | |
| 'tag_variable' => array('{{', '}}'), | |
| 'whitespace_trim' => '-', | |
| 'interpolation' => array('#{', '}'), | |
| ), $options); | |
| $this->regexes = array( | |
| 'lex_var' => '/\s*'.preg_quote($this->options['whitespace_trim'].$this->options['tag_variable'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_variable'][1], '/').'/A', | |
| 'lex_block' => '/\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')\n?/A', | |
| 'lex_raw_data' => '/('.preg_quote($this->options['tag_block'][0].$this->options['whitespace_trim'], '/').'|'.preg_quote($this->options['tag_block'][0], '/').')\s*endraw\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')/s', | |
| 'operator' => $this->getOperatorRegex(), | |
| 'lex_comment' => '/(?:'.preg_quote($this->options['whitespace_trim'], '/').preg_quote($this->options['tag_comment'][1], '/').'\s*|'.preg_quote($this->options['tag_comment'][1], '/').')\n?/s', | |
| 'lex_block_raw' => '/\s*raw\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')/As', | |
| 'lex_block_line' => '/\s*line\s+(\d+)\s*'.preg_quote($this->options['tag_block'][1], '/').'/As', | |
| 'lex_tokens_start' => '/('.preg_quote($this->options['tag_variable'][0], '/').'|'.preg_quote($this->options['tag_block'][0], '/').'|'.preg_quote($this->options['tag_comment'][0], '/').')('.preg_quote($this->options['whitespace_trim'], '/').')?/s', | |
| 'interpolation_start' => '/'.preg_quote($this->options['interpolation'][0], '/').'\s*/A', | |
| 'interpolation_end' => '/\s*'.preg_quote($this->options['interpolation'][1], '/').'/A', | |
| ); | |
| } | |
| /** | |
| * Tokenizes a source code. | |
| * | |
| * @param string $code The source code | |
| * @param string $filename A unique identifier for the source code | |
| * | |
| * @return Twig_TokenStream A token stream instance | |
| */ | |
| public function tokenize($code, $filename = null) | |
| { | |
| if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) { | |
| $mbEncoding = mb_internal_encoding(); | |
| mb_internal_encoding('ASCII'); | |
| } | |
| $this->code = str_replace(array("\r\n", "\r"), "\n", $code); | |
| $this->filename = $filename; | |
| $this->cursor = 0; | |
| $this->lineno = 1; | |
| $this->end = strlen($this->code); | |
| $this->tokens = array(); | |
| $this->state = self::STATE_DATA; | |
| $this->states = array(); | |
| $this->brackets = array(); | |
| $this->position = -1; | |
| // find all token starts in one go | |
| preg_match_all($this->regexes['lex_tokens_start'], $this->code, $matches, PREG_OFFSET_CAPTURE); | |
| $this->positions = $matches; | |
| while ($this->cursor < $this->end) { | |
| // dispatch to the lexing functions depending | |
| // on the current state | |
| switch ($this->state) { | |
| case self::STATE_DATA: | |
| $this->lexData(); | |
| break; | |
| case self::STATE_BLOCK: | |
| $this->lexBlock(); | |
| break; | |
| case self::STATE_VAR: | |
| $this->lexVar(); | |
| break; | |
| case self::STATE_STRING: | |
| $this->lexString(); | |
| break; | |
| case self::STATE_INTERPOLATION: | |
| $this->lexInterpolation(); | |
| break; | |
| } | |
| } | |
| $this->pushToken(Twig_Token::EOF_TYPE); | |
| if (!empty($this->brackets)) { | |
| list($expect, $lineno) = array_pop($this->brackets); | |
| throw new Twig_Error_Syntax(sprintf('Unclosed "%s"', $expect), $lineno, $this->filename); | |
| } | |
| if (isset($mbEncoding)) { | |
| mb_internal_encoding($mbEncoding); | |
| } | |
| return new Twig_TokenStream($this->tokens, $this->filename); | |
| } | |
| protected function lexData() | |
| { | |
| // if no matches are left we return the rest of the template as simple text token | |
| if ($this->position == count($this->positions[0]) - 1) { | |
| $this->pushToken(Twig_Token::TEXT_TYPE, substr($this->code, $this->cursor)); | |
| $this->cursor = $this->end; | |
| return; | |
| } | |
| // Find the first token after the current cursor | |
| $position = $this->positions[0][++$this->position]; | |
| while ($position[1] < $this->cursor) { | |
| if ($this->position == count($this->positions[0]) - 1) { | |
| return; | |
| } | |
| $position = $this->positions[0][++$this->position]; | |
| } | |
| // push the template text first | |
| $text = $textContent = substr($this->code, $this->cursor, $position[1] - $this->cursor); | |
| if (isset($this->positions[2][$this->position][0])) { | |
| $text = rtrim($text); | |
| } | |
| $this->pushToken(Twig_Token::TEXT_TYPE, $text); | |
| $this->moveCursor($textContent.$position[0]); | |
| switch ($this->positions[1][$this->position][0]) { | |
| case $this->options['tag_comment'][0]: | |
| $this->lexComment(); | |
| break; | |
| case $this->options['tag_block'][0]: | |
| // raw data? | |
| if (preg_match($this->regexes['lex_block_raw'], $this->code, $match, null, $this->cursor)) { | |
| $this->moveCursor($match[0]); | |
| $this->lexRawData(); | |
| // {% line \d+ %} | |
| } elseif (preg_match($this->regexes['lex_block_line'], $this->code, $match, null, $this->cursor)) { | |
| $this->moveCursor($match[0]); | |
| $this->lineno = (int) $match[1]; | |
| } else { | |
| $this->pushToken(Twig_Token::BLOCK_START_TYPE); | |
| $this->pushState(self::STATE_BLOCK); | |
| } | |
| break; | |
| case $this->options['tag_variable'][0]: | |
| $this->pushToken(Twig_Token::VAR_START_TYPE); | |
| $this->pushState(self::STATE_VAR); | |
| break; | |
| } | |
| } | |
| protected function lexBlock() | |
| { | |
| if (empty($this->brackets) && preg_match($this->regexes['lex_block'], $this->code, $match, null, $this->cursor)) { | |
| $this->pushToken(Twig_Token::BLOCK_END_TYPE); | |
| $this->moveCursor($match[0]); | |
| $this->popState(); | |
| } else { | |
| $this->lexExpression(); | |
| } | |
| } | |
| protected function lexVar() | |
| { | |
| if (empty($this->brackets) && preg_match($this->regexes['lex_var'], $this->code, $match, null, $this->cursor)) { | |
| $this->pushToken(Twig_Token::VAR_END_TYPE); | |
| $this->moveCursor($match[0]); | |
| $this->popState(); | |
| } else { | |
| $this->lexExpression(); | |
| } | |
| } | |
| protected function lexExpression() | |
| { | |
| // whitespace | |
| if (preg_match('/\s+/A', $this->code, $match, null, $this->cursor)) { | |
| $this->moveCursor($match[0]); | |
| if ($this->cursor >= $this->end) { | |
| throw new Twig_Error_Syntax(sprintf('Unexpected end of file: Unclosed "%s"', $this->state === self::STATE_BLOCK ? 'block' : 'variable'), $this->lineno, $this->filename); | |
| } | |
| } | |
| // operators | |
| if (preg_match($this->regexes['operator'], $this->code, $match, null, $this->cursor)) { | |
| $this->pushToken(Twig_Token::OPERATOR_TYPE, $match[0]); | |
| $this->moveCursor($match[0]); | |
| } | |
| // names | |
| elseif (preg_match(self::REGEX_NAME, $this->code, $match, null, $this->cursor)) { | |
| $this->pushToken(Twig_Token::NAME_TYPE, $match[0]); | |
| $this->moveCursor($match[0]); | |
| } | |
| // numbers | |
| elseif (preg_match(self::REGEX_NUMBER, $this->code, $match, null, $this->cursor)) { | |
| $number = (float) $match[0]; // floats | |
| if (ctype_digit($match[0]) && $number <= PHP_INT_MAX) { | |
| $number = (int) $match[0]; // integers lower than the maximum | |
| } | |
| $this->pushToken(Twig_Token::NUMBER_TYPE, $number); | |
| $this->moveCursor($match[0]); | |
| } | |
| // punctuation | |
| elseif (false !== strpos(self::PUNCTUATION, $this->code[$this->cursor])) { | |
| // opening bracket | |
| if (false !== strpos('([{', $this->code[$this->cursor])) { | |
| $this->brackets[] = array($this->code[$this->cursor], $this->lineno); | |
| } | |
| // closing bracket | |
| elseif (false !== strpos(')]}', $this->code[$this->cursor])) { | |
| if (empty($this->brackets)) { | |
| throw new Twig_Error_Syntax(sprintf('Unexpected "%s"', $this->code[$this->cursor]), $this->lineno, $this->filename); | |
| } | |
| list($expect, $lineno) = array_pop($this->brackets); | |
| if ($this->code[$this->cursor] != strtr($expect, '([{', ')]}')) { | |
| throw new Twig_Error_Syntax(sprintf('Unclosed "%s"', $expect), $lineno, $this->filename); | |
| } | |
| } | |
| $this->pushToken(Twig_Token::PUNCTUATION_TYPE, $this->code[$this->cursor]); | |
| ++$this->cursor; | |
| } | |
| // strings | |
| elseif (preg_match(self::REGEX_STRING, $this->code, $match, null, $this->cursor)) { | |
| $this->pushToken(Twig_Token::STRING_TYPE, stripcslashes(substr($match[0], 1, -1))); | |
| $this->moveCursor($match[0]); | |
| } | |
| // opening double quoted string | |
| elseif (preg_match(self::REGEX_DQ_STRING_DELIM, $this->code, $match, null, $this->cursor)) { | |
| $this->brackets[] = array('"', $this->lineno); | |
| $this->pushState(self::STATE_STRING); | |
| $this->moveCursor($match[0]); | |
| } | |
| // unlexable | |
| else { | |
| throw new Twig_Error_Syntax(sprintf('Unexpected character "%s"', $this->code[$this->cursor]), $this->lineno, $this->filename); | |
| } | |
| } | |
| protected function lexRawData() | |
| { | |
| if (!preg_match($this->regexes['lex_raw_data'], $this->code, $match, PREG_OFFSET_CAPTURE, $this->cursor)) { | |
| throw new Twig_Error_Syntax(sprintf('Unexpected end of file: Unclosed "block"'), $this->lineno, $this->filename); | |
| } | |
| $text = substr($this->code, $this->cursor, $match[0][1] - $this->cursor); | |
| $this->moveCursor($text.$match[0][0]); | |
| if (false !== strpos($match[1][0], $this->options['whitespace_trim'])) { | |
| $text = rtrim($text); | |
| } | |
| $this->pushToken(Twig_Token::TEXT_TYPE, $text); | |
| } | |
| protected function lexComment() | |
| { | |
| if (!preg_match($this->regexes['lex_comment'], $this->code, $match, PREG_OFFSET_CAPTURE, $this->cursor)) { | |
| throw new Twig_Error_Syntax('Unclosed comment', $this->lineno, $this->filename); | |
| } | |
| $this->moveCursor(substr($this->code, $this->cursor, $match[0][1] - $this->cursor).$match[0][0]); | |
| } | |
| protected function lexString() | |
| { | |
| if (preg_match($this->regexes['interpolation_start'], $this->code, $match, null, $this->cursor)) { | |
| $this->brackets[] = array($this->options['interpolation'][0], $this->lineno); | |
| $this->pushToken(Twig_Token::INTERPOLATION_START_TYPE); | |
| $this->moveCursor($match[0]); | |
| $this->pushState(self::STATE_INTERPOLATION); | |
| } elseif (preg_match(self::REGEX_DQ_STRING_PART, $this->code, $match, null, $this->cursor) && strlen($match[0]) > 0) { | |
| $this->pushToken(Twig_Token::STRING_TYPE, stripcslashes($match[0])); | |
| $this->moveCursor($match[0]); | |
| } elseif (preg_match(self::REGEX_DQ_STRING_DELIM, $this->code, $match, null, $this->cursor)) { | |
| list($expect, $lineno) = array_pop($this->brackets); | |
| if ($this->code[$this->cursor] != '"') { | |
| throw new Twig_Error_Syntax(sprintf('Unclosed "%s"', $expect), $lineno, $this->filename); | |
| } | |
| $this->popState(); | |
| ++$this->cursor; | |
| } | |
| } | |
| protected function lexInterpolation() | |
| { | |
| $bracket = end($this->brackets); | |
| if ($this->options['interpolation'][0] === $bracket[0] && preg_match($this->regexes['interpolation_end'], $this->code, $match, null, $this->cursor)) { | |
| array_pop($this->brackets); | |
| $this->pushToken(Twig_Token::INTERPOLATION_END_TYPE); | |
| $this->moveCursor($match[0]); | |
| $this->popState(); | |
| } else { | |
| $this->lexExpression(); | |
| } | |
| } | |
| protected function pushToken($type, $value = '') | |
| { | |
| // do not push empty text tokens | |
| if (Twig_Token::TEXT_TYPE === $type && '' === $value) { | |
| return; | |
| } | |
| $this->tokens[] = new Twig_Token($type, $value, $this->lineno); | |
| } | |
| protected function moveCursor($text) | |
| { | |
| $this->cursor += strlen($text); | |
| $this->lineno += substr_count($text, "\n"); | |
| } | |
| protected function getOperatorRegex() | |
| { | |
| $operators = array_merge( | |
| array('='), | |
| array_keys($this->env->getUnaryOperators()), | |
| array_keys($this->env->getBinaryOperators()) | |
| ); | |
| $operators = array_combine($operators, array_map('strlen', $operators)); | |
| arsort($operators); | |
| $regex = array(); | |
| foreach ($operators as $operator => $length) { | |
| // an operator that ends with a character must be followed by | |
| // a whitespace or a parenthesis | |
| if (ctype_alpha($operator[$length - 1])) { | |
| $regex[] = preg_quote($operator, '/').'(?=[\s()])'; | |
| } else { | |
| $regex[] = preg_quote($operator, '/'); | |
| } | |
| } | |
| return '/'.implode('|', $regex).'/A'; | |
| } | |
| protected function pushState($state) | |
| { | |
| $this->states[] = $this->state; | |
| $this->state = $state; | |
| } | |
| protected function popState() | |
| { | |
| if (0 === count($this->states)) { | |
| throw new Exception('Cannot pop state without a previous state'); | |
| } | |
| $this->state = array_pop($this->states); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Interface implemented by lexer classes. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| interface Twig_LexerInterface | |
| { | |
| /** | |
| * Tokenizes a source code. | |
| * | |
| * @param string $code The source code | |
| * @param string $filename A unique identifier for the source code | |
| * | |
| * @return Twig_TokenStream A token stream instance | |
| */ | |
| public function tokenize($code, $filename = null); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Exception thrown when an error occurs during template loading. | |
| * | |
| * Automatic template information guessing is always turned off as | |
| * if a template cannot be loaded, there is nothing to guess. | |
| * However, when a template is loaded from another one, then, we need | |
| * to find the current context and this is automatically done by | |
| * Twig_Template::displayWithErrorHandling(). | |
| * | |
| * This strategy makes Twig_Environment::resolveTemplate() much faster. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Error_Loader extends Twig_Error | |
| { | |
| public function __construct($message, $lineno = -1, $filename = null, Exception $previous = null) | |
| { | |
| parent::__construct($message, false, false, $previous); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Interface all loaders must implement. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| interface Twig_LoaderInterface | |
| { | |
| /** | |
| * Gets the source code of a template, given its name. | |
| * | |
| * @param string $name The name of the template to load | |
| * | |
| * @return string The template source code | |
| * | |
| * @throws Twig_Error_Loader When $name is not found | |
| */ | |
| public function getSource($name); | |
| /** | |
| * Gets the cache key to use for the cache for a given template name. | |
| * | |
| * @param string $name The name of the template to load | |
| * | |
| * @return string The cache key | |
| * | |
| * @throws Twig_Error_Loader When $name is not found | |
| */ | |
| public function getCacheKey($name); | |
| /** | |
| * Returns true if the template is still fresh. | |
| * | |
| * @param string $name The template name | |
| * @param timestamp $time The last modification time of the cached template | |
| * | |
| * @return Boolean true if the template is fresh, false otherwise | |
| * | |
| * @throws Twig_Error_Loader When $name is not found | |
| */ | |
| public function isFresh($name, $time); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a macro node. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_Macro extends Twig_Node | |
| { | |
| public function __construct($name, Twig_NodeInterface $body, Twig_NodeInterface $arguments, $lineno, $tag = null) | |
| { | |
| parent::__construct(array('body' => $body, 'arguments' => $arguments), array('name' => $name), $lineno, $tag); | |
| } | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $arguments = array(); | |
| foreach ($this->getNode('arguments') as $argument) { | |
| $arguments[] = '$_'.$argument->getAttribute('name').' = null'; | |
| } | |
| $compiler | |
| ->addDebugInfo($this) | |
| ->write(sprintf("public function get%s(%s)\n", $this->getAttribute('name'), implode(', ', $arguments)), "{\n") | |
| ->indent() | |
| ; | |
| if (!count($this->getNode('arguments'))) { | |
| $compiler->write("\$context = \$this->env->getGlobals();\n\n"); | |
| } else { | |
| $compiler | |
| ->write("\$context = \$this->env->mergeGlobals(array(\n") | |
| ->indent() | |
| ; | |
| foreach ($this->getNode('arguments') as $argument) { | |
| $compiler | |
| ->write('') | |
| ->string($argument->getAttribute('name')) | |
| ->raw(' => $_'.$argument->getAttribute('name')) | |
| ->raw(",\n") | |
| ; | |
| } | |
| $compiler | |
| ->outdent() | |
| ->write("));\n\n") | |
| ; | |
| } | |
| $compiler | |
| ->write("\$blocks = array();\n\n") | |
| ->write("ob_start();\n") | |
| ->write("try {\n") | |
| ->indent() | |
| ->subcompile($this->getNode('body')) | |
| ->outdent() | |
| ->write("} catch (Exception \$e) {\n") | |
| ->indent() | |
| ->write("ob_end_clean();\n\n") | |
| ->write("throw \$e;\n") | |
| ->outdent() | |
| ->write("}\n\n") | |
| ->write("return ('' === \$tmp = ob_get_clean()) ? '' : new Twig_Markup(\$tmp, \$this->env->getCharset());\n") | |
| ->outdent() | |
| ->write("}\n\n") | |
| ; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Defines a macro. | |
| * | |
| * <pre> | |
| * {% macro input(name, value, type, size) %} | |
| * <input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" /> | |
| * {% endmacro %} | |
| * </pre> | |
| */ | |
| class Twig_TokenParser_Macro extends Twig_TokenParser | |
| { | |
| /** | |
| * Parses a token and returns a node. | |
| * | |
| * @param Twig_Token $token A Twig_Token instance | |
| * | |
| * @return Twig_NodeInterface A Twig_NodeInterface instance | |
| */ | |
| public function parse(Twig_Token $token) | |
| { | |
| $lineno = $token->getLine(); | |
| $stream = $this->parser->getStream(); | |
| $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); | |
| $arguments = $this->parser->getExpressionParser()->parseArguments(); | |
| $stream->expect(Twig_Token::BLOCK_END_TYPE); | |
| $this->parser->pushLocalScope(); | |
| $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true); | |
| if ($stream->test(Twig_Token::NAME_TYPE)) { | |
| $value = $stream->next()->getValue(); | |
| if ($value != $name) { | |
| throw new Twig_Error_Syntax(sprintf("Expected endmacro for macro '$name' (but %s given)", $value), $stream->getCurrent()->getLine(), $stream->getFilename()); | |
| } | |
| } | |
| $this->parser->popLocalScope(); | |
| $stream->expect(Twig_Token::BLOCK_END_TYPE); | |
| $this->parser->setMacro($name, new Twig_Node_Macro($name, new Twig_Node_Body(array($body)), $arguments, $lineno, $this->getTag())); | |
| return null; | |
| } | |
| public function decideBlockEnd(Twig_Token $token) | |
| { | |
| return $token->test('endmacro'); | |
| } | |
| /** | |
| * Gets the tag name associated with this token parser. | |
| * | |
| * @return string The tag name | |
| */ | |
| public function getTag() | |
| { | |
| return 'macro'; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Marks a content as safe. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Markup implements Countable | |
| { | |
| protected $content; | |
| protected $charset; | |
| public function __construct($content, $charset) | |
| { | |
| $this->content = (string) $content; | |
| $this->charset = $charset; | |
| } | |
| public function __toString() | |
| { | |
| return $this->content; | |
| } | |
| public function count() | |
| { | |
| return function_exists('mb_get_info') ? mb_strlen($this->content, $this->charset) : strlen($this->content); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a method template filter. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Filter_Method extends Twig_Filter | |
| { | |
| protected $extension; | |
| protected $method; | |
| public function __construct(Twig_ExtensionInterface $extension, $method, array $options = array()) | |
| { | |
| parent::__construct($options); | |
| $this->extension = $extension; | |
| $this->method = $method; | |
| } | |
| public function compile() | |
| { | |
| return sprintf('$this->env->getExtension(\'%s\')->%s', $this->extension->getName(), $this->method); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2010 Arnaud Le Blanc | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a method template function. | |
| * | |
| * @package twig | |
| * @author Arnaud Le Blanc <arnaud.lb@gmail.com> | |
| */ | |
| class Twig_Function_Method extends Twig_Function | |
| { | |
| protected $extension; | |
| protected $method; | |
| public function __construct(Twig_ExtensionInterface $extension, $method, array $options = array()) | |
| { | |
| parent::__construct($options); | |
| $this->extension = $extension; | |
| $this->method = $method; | |
| } | |
| public function compile() | |
| { | |
| return sprintf('$this->env->getExtension(\'%s\')->%s', $this->extension->getName(), $this->method); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a method template test. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Test_Method implements Twig_TestInterface | |
| { | |
| protected $extension; | |
| protected $method; | |
| public function __construct(Twig_ExtensionInterface $extension, $method) | |
| { | |
| $this->extension = $extension; | |
| $this->method = $method; | |
| } | |
| public function compile() | |
| { | |
| return sprintf('$this->env->getExtension(\'%s\')->%s', $this->extension->getName(), $this->method); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2012 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_MethodCall extends Twig_Node_Expression | |
| { | |
| public function __construct(Twig_Node_Expression $node, $method, Twig_Node_Expression_Array $arguments, $lineno) | |
| { | |
| parent::__construct(array('node' => $node, 'arguments' => $arguments), array('method' => $method, 'safe' => false), $lineno); | |
| if ($node instanceof Twig_Node_Expression_Name) { | |
| $node->setAttribute('always_defined', true); | |
| } | |
| } | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->subcompile($this->getNode('node')) | |
| ->raw('->') | |
| ->raw($this->getAttribute('method')) | |
| ->raw('(') | |
| ; | |
| $first = true; | |
| foreach ($this->getNode('arguments')->getKeyValuePairs() as $pair) { | |
| if (!$first) { | |
| $compiler->raw(', '); | |
| } | |
| $first = false; | |
| $compiler->subcompile($pair['value']); | |
| } | |
| $compiler->raw(')'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| require 'lib/_db_fields_table1.php'; | |
| require 'migration.php'; | |
| $result = sql_query($down); | |
| echo $views->render_with_layout('migrations', array('result' => $result)); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| require 'lib/_db_fields_table2.php'; | |
| require 'migration.php'; | |
| $result = sql_query($down); | |
| echo $views->render_with_layout('migrations', array('result' => $result)); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| require 'lib/_db_fields_table1.php'; | |
| require 'migration.php'; | |
| $result = sql_query($up); | |
| echo $views->render_with_layout('migrations', array('result' => $result)); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| require 'lib/_db_fields_table2.php'; | |
| require 'migration.php'; | |
| $result = sql_query($up); | |
| echo $views->render_with_layout('migrations', array('result' => $result)); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| require 'autoload.php'; | |
| $down = "DROP TABLE `{$table_name}`"; | |
| $up = "CREATE TABLE `{$table_name}` ( | |
| `id` int(10) UNSIGNED NULL AUTO_INCREMENT ,"; | |
| foreach ($fields as $field => $type) { | |
| $up = $up . " | |
| `{$field}` {$type} NOT NULL , | |
| "; | |
| }; | |
| $up = $up . 'PRIMARY KEY (`id`));'; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Binary_Mod extends Twig_Node_Expression_Binary | |
| { | |
| public function operator(Twig_Compiler $compiler) | |
| { | |
| return $compiler->raw('%'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a module node. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_Module extends Twig_Node | |
| { | |
| public function __construct(Twig_NodeInterface $body, Twig_Node_Expression $parent = null, Twig_NodeInterface $blocks, Twig_NodeInterface $macros, Twig_NodeInterface $traits, $embeddedTemplates, $filename) | |
| { | |
| // embedded templates are set as attributes so that they are only visited once by the visitors | |
| parent::__construct(array('parent' => $parent, 'body' => $body, 'blocks' => $blocks, 'macros' => $macros, 'traits' => $traits), array('filename' => $filename, 'index' => null, 'embedded_templates' => $embeddedTemplates), 1); | |
| } | |
| public function setIndex($index) | |
| { | |
| $this->setAttribute('index', $index); | |
| } | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $this->compileTemplate($compiler); | |
| foreach ($this->getAttribute('embedded_templates') as $template) { | |
| $compiler->subcompile($template); | |
| } | |
| } | |
| protected function compileTemplate(Twig_Compiler $compiler) | |
| { | |
| if (!$this->getAttribute('index')) { | |
| $compiler->write('<?php'); | |
| } | |
| $this->compileClassHeader($compiler); | |
| if (count($this->getNode('blocks')) || count($this->getNode('traits')) || null === $this->getNode('parent') || $this->getNode('parent') instanceof Twig_Node_Expression_Constant) { | |
| $this->compileConstructor($compiler); | |
| } | |
| $this->compileGetParent($compiler); | |
| $this->compileDisplayHeader($compiler); | |
| $this->compileDisplayBody($compiler); | |
| $this->compileDisplayFooter($compiler); | |
| $compiler->subcompile($this->getNode('blocks')); | |
| $this->compileMacros($compiler); | |
| $this->compileGetTemplateName($compiler); | |
| $this->compileIsTraitable($compiler); | |
| $this->compileDebugInfo($compiler); | |
| $this->compileClassFooter($compiler); | |
| } | |
| protected function compileGetParent(Twig_Compiler $compiler) | |
| { | |
| if (null === $this->getNode('parent')) { | |
| return; | |
| } | |
| $compiler | |
| ->write("protected function doGetParent(array \$context)\n", "{\n") | |
| ->indent() | |
| ->write("return ") | |
| ; | |
| if ($this->getNode('parent') instanceof Twig_Node_Expression_Constant) { | |
| $compiler->subcompile($this->getNode('parent')); | |
| } else { | |
| $compiler | |
| ->raw("\$this->env->resolveTemplate(") | |
| ->subcompile($this->getNode('parent')) | |
| ->raw(")") | |
| ; | |
| } | |
| $compiler | |
| ->raw(";\n") | |
| ->outdent() | |
| ->write("}\n\n") | |
| ; | |
| } | |
| protected function compileDisplayBody(Twig_Compiler $compiler) | |
| { | |
| $compiler->subcompile($this->getNode('body')); | |
| if (null !== $this->getNode('parent')) { | |
| if ($this->getNode('parent') instanceof Twig_Node_Expression_Constant) { | |
| $compiler->write("\$this->parent"); | |
| } else { | |
| $compiler->write("\$this->getParent(\$context)"); | |
| } | |
| $compiler->raw("->display(\$context, array_merge(\$this->blocks, \$blocks));\n"); | |
| } | |
| } | |
| protected function compileClassHeader(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->write("\n\n") | |
| // if the filename contains */, add a blank to avoid a PHP parse error | |
| ->write("/* ".str_replace('*/', '* /', $this->getAttribute('filename'))." */\n") | |
| ->write('class '.$compiler->getEnvironment()->getTemplateClass($this->getAttribute('filename'), $this->getAttribute('index'))) | |
| ->raw(sprintf(" extends %s\n", $compiler->getEnvironment()->getBaseTemplateClass())) | |
| ->write("{\n") | |
| ->indent() | |
| ; | |
| } | |
| protected function compileConstructor(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->write("public function __construct(Twig_Environment \$env)\n", "{\n") | |
| ->indent() | |
| ->write("parent::__construct(\$env);\n\n") | |
| ; | |
| // parent | |
| if (null === $this->getNode('parent')) { | |
| $compiler->write("\$this->parent = false;\n\n"); | |
| } elseif ($this->getNode('parent') instanceof Twig_Node_Expression_Constant) { | |
| $compiler | |
| ->write("\$this->parent = \$this->env->loadTemplate(") | |
| ->subcompile($this->getNode('parent')) | |
| ->raw(");\n\n") | |
| ; | |
| } | |
| $countTraits = count($this->getNode('traits')); | |
| if ($countTraits) { | |
| // traits | |
| foreach ($this->getNode('traits') as $i => $trait) { | |
| $this->compileLoadTemplate($compiler, $trait->getNode('template'), sprintf('$_trait_%s', $i)); | |
| $compiler | |
| ->addDebugInfo($trait->getNode('template')) | |
| ->write(sprintf("if (!\$_trait_%s->isTraitable()) {\n", $i)) | |
| ->indent() | |
| ->write("throw new Twig_Error_Runtime('Template \"'.") | |
| ->subcompile($trait->getNode('template')) | |
| ->raw(".'\" cannot be used as a trait.');\n") | |
| ->outdent() | |
| ->write("}\n") | |
| ->write(sprintf("\$_trait_%s_blocks = \$_trait_%s->getBlocks();\n\n", $i, $i)) | |
| ; | |
| foreach ($trait->getNode('targets') as $key => $value) { | |
| $compiler | |
| ->write(sprintf("\$_trait_%s_blocks[", $i)) | |
| ->subcompile($value) | |
| ->raw(sprintf("] = \$_trait_%s_blocks[", $i)) | |
| ->string($key) | |
| ->raw(sprintf("]; unset(\$_trait_%s_blocks[", $i)) | |
| ->string($key) | |
| ->raw("]);\n\n") | |
| ; | |
| } | |
| } | |
| if ($countTraits > 1) { | |
| $compiler | |
| ->write("\$this->traits = array_merge(\n") | |
| ->indent() | |
| ; | |
| for ($i = 0; $i < $countTraits; $i++) { | |
| $compiler | |
| ->write(sprintf("\$_trait_%s_blocks".($i == $countTraits - 1 ? '' : ',')."\n", $i)) | |
| ; | |
| } | |
| $compiler | |
| ->outdent() | |
| ->write(");\n\n") | |
| ; | |
| } else { | |
| $compiler | |
| ->write("\$this->traits = \$_trait_0_blocks;\n\n") | |
| ; | |
| } | |
| $compiler | |
| ->write("\$this->blocks = array_merge(\n") | |
| ->indent() | |
| ->write("\$this->traits,\n") | |
| ->write("array(\n") | |
| ; | |
| } else { | |
| $compiler | |
| ->write("\$this->blocks = array(\n") | |
| ; | |
| } | |
| // blocks | |
| $compiler | |
| ->indent() | |
| ; | |
| foreach ($this->getNode('blocks') as $name => $node) { | |
| $compiler | |
| ->write(sprintf("'%s' => array(\$this, 'block_%s'),\n", $name, $name)) | |
| ; | |
| } | |
| if ($countTraits) { | |
| $compiler | |
| ->outdent() | |
| ->write(")\n") | |
| ; | |
| } | |
| $compiler | |
| ->outdent() | |
| ->write(");\n") | |
| ->outdent() | |
| ->write("}\n\n"); | |
| ; | |
| } | |
| protected function compileDisplayHeader(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->write("protected function doDisplay(array \$context, array \$blocks = array())\n", "{\n") | |
| ->indent() | |
| ; | |
| } | |
| protected function compileDisplayFooter(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->outdent() | |
| ->write("}\n\n") | |
| ; | |
| } | |
| protected function compileClassFooter(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->outdent() | |
| ->write("}\n") | |
| ; | |
| } | |
| protected function compileMacros(Twig_Compiler $compiler) | |
| { | |
| $compiler->subcompile($this->getNode('macros')); | |
| } | |
| protected function compileGetTemplateName(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->write("public function getTemplateName()\n", "{\n") | |
| ->indent() | |
| ->write('return ') | |
| ->repr($this->getAttribute('filename')) | |
| ->raw(";\n") | |
| ->outdent() | |
| ->write("}\n\n") | |
| ; | |
| } | |
| protected function compileIsTraitable(Twig_Compiler $compiler) | |
| { | |
| // A template can be used as a trait if: | |
| // * it has no parent | |
| // * it has no macros | |
| // * it has no body | |
| // | |
| // Put another way, a template can be used as a trait if it | |
| // only contains blocks and use statements. | |
| $traitable = null === $this->getNode('parent') && 0 === count($this->getNode('macros')); | |
| if ($traitable) { | |
| if ($this->getNode('body') instanceof Twig_Node_Body) { | |
| $nodes = $this->getNode('body')->getNode(0); | |
| } else { | |
| $nodes = $this->getNode('body'); | |
| } | |
| if (!count($nodes)) { | |
| $nodes = new Twig_Node(array($nodes)); | |
| } | |
| foreach ($nodes as $node) { | |
| if (!count($node)) { | |
| continue; | |
| } | |
| if ($node instanceof Twig_Node_Text && ctype_space($node->getAttribute('data'))) { | |
| continue; | |
| } | |
| if ($node instanceof Twig_Node_BlockReference) { | |
| continue; | |
| } | |
| $traitable = false; | |
| break; | |
| } | |
| } | |
| if ($traitable) { | |
| return; | |
| } | |
| $compiler | |
| ->write("public function isTraitable()\n", "{\n") | |
| ->indent() | |
| ->write(sprintf("return %s;\n", $traitable ? 'true' : 'false')) | |
| ->outdent() | |
| ->write("}\n\n") | |
| ; | |
| } | |
| protected function compileDebugInfo(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->write("public function getDebugInfo()\n", "{\n") | |
| ->indent() | |
| ->write(sprintf("return %s;\n", str_replace("\n", '', var_export(array_reverse($compiler->getDebugInfo(), true), true)))) | |
| ->outdent() | |
| ->write("}\n") | |
| ; | |
| } | |
| protected function compileLoadTemplate(Twig_Compiler $compiler, $node, $var) | |
| { | |
| if ($node instanceof Twig_Node_Expression_Constant) { | |
| $compiler | |
| ->write(sprintf("%s = \$this->env->loadTemplate(", $var)) | |
| ->subcompile($node) | |
| ->raw(");\n") | |
| ; | |
| } else { | |
| $compiler | |
| ->write(sprintf("%s = ", $var)) | |
| ->subcompile($node) | |
| ->raw(";\n") | |
| ->write(sprintf("if (!%s", $var)) | |
| ->raw(" instanceof Twig_Template) {\n") | |
| ->indent() | |
| ->write(sprintf("%s = \$this->env->loadTemplate(%s);\n", $var, $var)) | |
| ->outdent() | |
| ->write("}\n") | |
| ; | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Binary_Mul extends Twig_Node_Expression_Binary | |
| { | |
| public function operator(Twig_Compiler $compiler) | |
| { | |
| return $compiler->raw('*'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Name extends Twig_Node_Expression | |
| { | |
| protected $specialVars = array( | |
| '_self' => '$this', | |
| '_context' => '$context', | |
| '_charset' => '$this->env->getCharset()', | |
| ); | |
| public function __construct($name, $lineno) | |
| { | |
| parent::__construct(array(), array('name' => $name, 'is_defined_test' => false, 'ignore_strict_check' => false, 'always_defined' => false), $lineno); | |
| } | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $name = $this->getAttribute('name'); | |
| if ($this->getAttribute('is_defined_test')) { | |
| if ($this->isSpecial()) { | |
| $compiler->repr(true); | |
| } else { | |
| $compiler->raw('array_key_exists(')->repr($name)->raw(', $context)'); | |
| } | |
| } elseif ($this->isSpecial()) { | |
| $compiler->raw($this->specialVars[$name]); | |
| } elseif ($this->getAttribute('always_defined')) { | |
| $compiler | |
| ->raw('$context[') | |
| ->string($name) | |
| ->raw(']') | |
| ; | |
| } else { | |
| // remove the non-PHP 5.4 version when PHP 5.3 support is dropped | |
| // as the non-optimized version is just a workaround for slow ternary operator | |
| // when the context has a lot of variables | |
| if (version_compare(phpversion(), '5.4.0RC1', '>=')) { | |
| // PHP 5.4 ternary operator performance was optimized | |
| $compiler | |
| ->raw('(isset($context[') | |
| ->string($name) | |
| ->raw(']) ? $context[') | |
| ->string($name) | |
| ->raw('] : ') | |
| ; | |
| if ($this->getAttribute('ignore_strict_check') || !$compiler->getEnvironment()->isStrictVariables()) { | |
| $compiler->raw('null)'); | |
| } else { | |
| $compiler->raw('$this->getContext($context, ')->string($name)->raw('))'); | |
| } | |
| } else { | |
| $compiler | |
| ->raw('$this->getContext($context, ') | |
| ->string($name) | |
| ; | |
| if ($this->getAttribute('ignore_strict_check')) { | |
| $compiler->raw(', true'); | |
| } | |
| $compiler | |
| ->raw(')') | |
| ; | |
| } | |
| } | |
| } | |
| public function isSpecial() | |
| { | |
| return isset($this->specialVars[$this->getAttribute('name')]); | |
| } | |
| public function isSimple() | |
| { | |
| return !$this->isSpecial() && !$this->getAttribute('is_defined_test'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Unary_Neg extends Twig_Node_Expression_Unary | |
| { | |
| public function operator(Twig_Compiler $compiler) | |
| { | |
| $compiler->raw('-'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2011 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a template filter as a node. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Filter_Node extends Twig_Filter | |
| { | |
| protected $class; | |
| public function __construct($class, array $options = array()) | |
| { | |
| parent::__construct($options); | |
| $this->class = $class; | |
| } | |
| public function getClass() | |
| { | |
| return $this->class; | |
| } | |
| public function compile() | |
| { | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2011 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a template function as a node. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Function_Node extends Twig_Function | |
| { | |
| protected $class; | |
| public function __construct($class, array $options = array()) | |
| { | |
| parent::__construct($options); | |
| $this->class = $class; | |
| } | |
| public function getClass() | |
| { | |
| return $this->class; | |
| } | |
| public function compile() | |
| { | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a node in the AST. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node implements Twig_NodeInterface | |
| { | |
| protected $nodes; | |
| protected $attributes; | |
| protected $lineno; | |
| protected $tag; | |
| /** | |
| * Constructor. | |
| * | |
| * The nodes are automatically made available as properties ($this->node). | |
| * The attributes are automatically made available as array items ($this['name']). | |
| * | |
| * @param array $nodes An array of named nodes | |
| * @param array $attributes An array of attributes (should not be nodes) | |
| * @param integer $lineno The line number | |
| * @param string $tag The tag name associated with the Node | |
| */ | |
| public function __construct(array $nodes = array(), array $attributes = array(), $lineno = 0, $tag = null) | |
| { | |
| $this->nodes = $nodes; | |
| $this->attributes = $attributes; | |
| $this->lineno = $lineno; | |
| $this->tag = $tag; | |
| } | |
| public function __toString() | |
| { | |
| $attributes = array(); | |
| foreach ($this->attributes as $name => $value) { | |
| $attributes[] = sprintf('%s: %s', $name, str_replace("\n", '', var_export($value, true))); | |
| } | |
| $repr = array(get_class($this).'('.implode(', ', $attributes)); | |
| if (count($this->nodes)) { | |
| foreach ($this->nodes as $name => $node) { | |
| $len = strlen($name) + 4; | |
| $noderepr = array(); | |
| foreach (explode("\n", (string) $node) as $line) { | |
| $noderepr[] = str_repeat(' ', $len).$line; | |
| } | |
| $repr[] = sprintf(' %s: %s', $name, ltrim(implode("\n", $noderepr))); | |
| } | |
| $repr[] = ')'; | |
| } else { | |
| $repr[0] .= ')'; | |
| } | |
| return implode("\n", $repr); | |
| } | |
| public function toXml($asDom = false) | |
| { | |
| $dom = new DOMDocument('1.0', 'UTF-8'); | |
| $dom->formatOutput = true; | |
| $dom->appendChild($xml = $dom->createElement('twig')); | |
| $xml->appendChild($node = $dom->createElement('node')); | |
| $node->setAttribute('class', get_class($this)); | |
| foreach ($this->attributes as $name => $value) { | |
| $node->appendChild($attribute = $dom->createElement('attribute')); | |
| $attribute->setAttribute('name', $name); | |
| $attribute->appendChild($dom->createTextNode($value)); | |
| } | |
| foreach ($this->nodes as $name => $n) { | |
| if (null === $n) { | |
| continue; | |
| } | |
| $child = $n->toXml(true)->getElementsByTagName('node')->item(0); | |
| $child = $dom->importNode($child, true); | |
| $child->setAttribute('name', $name); | |
| $node->appendChild($child); | |
| } | |
| return $asDom ? $dom : $dom->saveXml(); | |
| } | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| foreach ($this->nodes as $node) { | |
| $node->compile($compiler); | |
| } | |
| } | |
| public function getLine() | |
| { | |
| return $this->lineno; | |
| } | |
| public function getNodeTag() | |
| { | |
| return $this->tag; | |
| } | |
| /** | |
| * Returns true if the attribute is defined. | |
| * | |
| * @param string The attribute name | |
| * | |
| * @return Boolean true if the attribute is defined, false otherwise | |
| */ | |
| public function hasAttribute($name) | |
| { | |
| return array_key_exists($name, $this->attributes); | |
| } | |
| /** | |
| * Gets an attribute. | |
| * | |
| * @param string The attribute name | |
| * | |
| * @return mixed The attribute value | |
| */ | |
| public function getAttribute($name) | |
| { | |
| if (!array_key_exists($name, $this->attributes)) { | |
| throw new LogicException(sprintf('Attribute "%s" does not exist for Node "%s".', $name, get_class($this))); | |
| } | |
| return $this->attributes[$name]; | |
| } | |
| /** | |
| * Sets an attribute. | |
| * | |
| * @param string The attribute name | |
| * @param mixed The attribute value | |
| */ | |
| public function setAttribute($name, $value) | |
| { | |
| $this->attributes[$name] = $value; | |
| } | |
| /** | |
| * Removes an attribute. | |
| * | |
| * @param string The attribute name | |
| */ | |
| public function removeAttribute($name) | |
| { | |
| unset($this->attributes[$name]); | |
| } | |
| /** | |
| * Returns true if the node with the given identifier exists. | |
| * | |
| * @param string The node name | |
| * | |
| * @return Boolean true if the node with the given name exists, false otherwise | |
| */ | |
| public function hasNode($name) | |
| { | |
| return array_key_exists($name, $this->nodes); | |
| } | |
| /** | |
| * Gets a node by name. | |
| * | |
| * @param string The node name | |
| * | |
| * @return Twig_Node A Twig_Node instance | |
| */ | |
| public function getNode($name) | |
| { | |
| if (!array_key_exists($name, $this->nodes)) { | |
| throw new LogicException(sprintf('Node "%s" does not exist for Node "%s".', $name, get_class($this))); | |
| } | |
| return $this->nodes[$name]; | |
| } | |
| /** | |
| * Sets a node. | |
| * | |
| * @param string The node name | |
| * @param Twig_Node A Twig_Node instance | |
| */ | |
| public function setNode($name, $node = null) | |
| { | |
| $this->nodes[$name] = $node; | |
| } | |
| /** | |
| * Removes a node by name. | |
| * | |
| * @param string The node name | |
| */ | |
| public function removeNode($name) | |
| { | |
| unset($this->nodes[$name]); | |
| } | |
| public function count() | |
| { | |
| return count($this->nodes); | |
| } | |
| public function getIterator() | |
| { | |
| return new ArrayIterator($this->nodes); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a template test as a Node. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Test_Node implements Twig_TestInterface | |
| { | |
| protected $class; | |
| public function __construct($class) | |
| { | |
| $this->class = $class; | |
| } | |
| public function getClass() | |
| { | |
| return $this->class; | |
| } | |
| public function compile() | |
| { | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a node in the AST. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| interface Twig_NodeInterface extends Countable, IteratorAggregate | |
| { | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler); | |
| public function getLine(); | |
| public function getNodeTag(); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a displayable node in the AST. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| interface Twig_NodeOutputInterface | |
| { | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| abstract class Twig_Test_NodeTestCase extends PHPUnit_Framework_TestCase | |
| { | |
| abstract public function getTests(); | |
| /** | |
| * @dataProvider getTests | |
| */ | |
| public function testCompile($node, $source, $environment = null) | |
| { | |
| $this->assertNodeCompilation($source, $node, $environment); | |
| } | |
| public function assertNodeCompilation($source, Twig_Node $node, Twig_Environment $environment = null) | |
| { | |
| $compiler = $this->getCompiler($environment); | |
| $compiler->compile($node); | |
| $this->assertEquals($source, trim($compiler->getSource())); | |
| } | |
| protected function getCompiler(Twig_Environment $environment = null) | |
| { | |
| return new Twig_Compiler(null === $environment ? $this->getEnvironment() : $environment); | |
| } | |
| protected function getEnvironment() | |
| { | |
| return new Twig_Environment(); | |
| } | |
| protected function getVariableGetter($name) | |
| { | |
| if (version_compare(phpversion(), '5.4.0RC1', '>=')) { | |
| return sprintf('(isset($context["%s"]) ? $context["%s"] : null)', $name, $name); | |
| } | |
| return sprintf('$this->getContext($context, "%s")', $name); | |
| } | |
| protected function getAttributeGetter() | |
| { | |
| if (function_exists('twig_template_get_attributes')) { | |
| return 'twig_template_get_attributes($this, '; | |
| } | |
| return '$this->getAttribute('; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Twig_NodeTraverser is a node traverser. | |
| * | |
| * It visits all nodes and their children and call the given visitor for each. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_NodeTraverser | |
| { | |
| protected $env; | |
| protected $visitors; | |
| /** | |
| * Constructor. | |
| * | |
| * @param Twig_Environment $env A Twig_Environment instance | |
| * @param array $visitors An array of Twig_NodeVisitorInterface instances | |
| */ | |
| public function __construct(Twig_Environment $env, array $visitors = array()) | |
| { | |
| $this->env = $env; | |
| $this->visitors = array(); | |
| foreach ($visitors as $visitor) { | |
| $this->addVisitor($visitor); | |
| } | |
| } | |
| /** | |
| * Adds a visitor. | |
| * | |
| * @param Twig_NodeVisitorInterface $visitor A Twig_NodeVisitorInterface instance | |
| */ | |
| public function addVisitor(Twig_NodeVisitorInterface $visitor) | |
| { | |
| if (!isset($this->visitors[$visitor->getPriority()])) { | |
| $this->visitors[$visitor->getPriority()] = array(); | |
| } | |
| $this->visitors[$visitor->getPriority()][] = $visitor; | |
| } | |
| /** | |
| * Traverses a node and calls the registered visitors. | |
| * | |
| * @param Twig_NodeInterface $node A Twig_NodeInterface instance | |
| */ | |
| public function traverse(Twig_NodeInterface $node) | |
| { | |
| ksort($this->visitors); | |
| foreach ($this->visitors as $visitors) { | |
| foreach ($visitors as $visitor) { | |
| $node = $this->traverseForVisitor($visitor, $node); | |
| } | |
| } | |
| return $node; | |
| } | |
| protected function traverseForVisitor(Twig_NodeVisitorInterface $visitor, Twig_NodeInterface $node = null) | |
| { | |
| if (null === $node) { | |
| return null; | |
| } | |
| $node = $visitor->enterNode($node, $this->env); | |
| foreach ($node as $k => $n) { | |
| if (false !== $n = $this->traverseForVisitor($visitor, $n)) { | |
| $node->setNode($k, $n); | |
| } else { | |
| $node->removeNode($k); | |
| } | |
| } | |
| return $visitor->leaveNode($node, $this->env); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Twig_NodeVisitorInterface is the interface the all node visitor classes must implement. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| interface Twig_NodeVisitorInterface | |
| { | |
| /** | |
| * Called before child nodes are visited. | |
| * | |
| * @param Twig_NodeInterface $node The node to visit | |
| * @param Twig_Environment $env The Twig environment instance | |
| * | |
| * @return Twig_NodeInterface The modified node | |
| */ | |
| public function enterNode(Twig_NodeInterface $node, Twig_Environment $env); | |
| /** | |
| * Called after child nodes are visited. | |
| * | |
| * @param Twig_NodeInterface $node The node to visit | |
| * @param Twig_Environment $env The Twig environment instance | |
| * | |
| * @return Twig_NodeInterface The modified node | |
| */ | |
| public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env); | |
| /** | |
| * Returns the priority for this visitor. | |
| * | |
| * Priority should be between -10 and 10 (0 is the default). | |
| * | |
| * @return integer The priority level | |
| */ | |
| public function getPriority(); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Unary_Not extends Twig_Node_Expression_Unary | |
| { | |
| public function operator(Twig_Compiler $compiler) | |
| { | |
| $compiler->raw('!'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Binary_NotEqual extends Twig_Node_Expression_Binary | |
| { | |
| public function operator(Twig_Compiler $compiler) | |
| { | |
| return $compiler->raw('!='); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Binary_NotIn extends Twig_Node_Expression_Binary | |
| { | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->raw('!twig_in_filter(') | |
| ->subcompile($this->getNode('left')) | |
| ->raw(', ') | |
| ->subcompile($this->getNode('right')) | |
| ->raw(')') | |
| ; | |
| } | |
| public function operator(Twig_Compiler $compiler) | |
| { | |
| return $compiler->raw('not in'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2011 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Checks that a variable is null. | |
| * | |
| * <pre> | |
| * {{ var is none }} | |
| * </pre> | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_Expression_Test_Null extends Twig_Node_Expression_Test | |
| { | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->raw('(null === ') | |
| ->subcompile($this->getNode('node')) | |
| ->raw(')') | |
| ; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2011 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Checks if a number is odd. | |
| * | |
| * <pre> | |
| * {{ var is odd }} | |
| * </pre> | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_Expression_Test_Odd extends Twig_Node_Expression_Test | |
| { | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->raw('(') | |
| ->subcompile($this->getNode('node')) | |
| ->raw(' % 2 == 1') | |
| ->raw(')') | |
| ; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Extension_Optimizer extends Twig_Extension | |
| { | |
| protected $optimizers; | |
| public function __construct($optimizers = -1) | |
| { | |
| $this->optimizers = $optimizers; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function getNodeVisitors() | |
| { | |
| return array(new Twig_NodeVisitor_Optimizer($this->optimizers)); | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function getName() | |
| { | |
| return 'optimizer'; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Twig_NodeVisitor_Optimizer tries to optimizes the AST. | |
| * | |
| * This visitor is always the last registered one. | |
| * | |
| * You can configure which optimizations you want to activate via the | |
| * optimizer mode. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface | |
| { | |
| const OPTIMIZE_ALL = -1; | |
| const OPTIMIZE_NONE = 0; | |
| const OPTIMIZE_FOR = 2; | |
| const OPTIMIZE_RAW_FILTER = 4; | |
| const OPTIMIZE_VAR_ACCESS = 8; | |
| protected $loops = array(); | |
| protected $optimizers; | |
| protected $prependedNodes = array(); | |
| protected $inABody = false; | |
| /** | |
| * Constructor. | |
| * | |
| * @param integer $optimizers The optimizer mode | |
| */ | |
| public function __construct($optimizers = -1) | |
| { | |
| if (!is_int($optimizers) || $optimizers > 2) { | |
| throw new InvalidArgumentException(sprintf('Optimizer mode "%s" is not valid.', $optimizers)); | |
| } | |
| $this->optimizers = $optimizers; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function enterNode(Twig_NodeInterface $node, Twig_Environment $env) | |
| { | |
| if (self::OPTIMIZE_FOR === (self::OPTIMIZE_FOR & $this->optimizers)) { | |
| $this->enterOptimizeFor($node, $env); | |
| } | |
| if (!version_compare(phpversion(), '5.4.0RC1', '>=') && self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('sandbox')) { | |
| if ($this->inABody) { | |
| if (!$node instanceof Twig_Node_Expression) { | |
| if (get_class($node) !== 'Twig_Node') { | |
| array_unshift($this->prependedNodes, array()); | |
| } | |
| } else { | |
| $node = $this->optimizeVariables($node, $env); | |
| } | |
| } elseif ($node instanceof Twig_Node_Body) { | |
| $this->inABody = true; | |
| } | |
| } | |
| return $node; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env) | |
| { | |
| $expression = $node instanceof Twig_Node_Expression; | |
| if (self::OPTIMIZE_FOR === (self::OPTIMIZE_FOR & $this->optimizers)) { | |
| $this->leaveOptimizeFor($node, $env); | |
| } | |
| if (self::OPTIMIZE_RAW_FILTER === (self::OPTIMIZE_RAW_FILTER & $this->optimizers)) { | |
| $node = $this->optimizeRawFilter($node, $env); | |
| } | |
| $node = $this->optimizePrintNode($node, $env); | |
| if (self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('sandbox')) { | |
| if ($node instanceof Twig_Node_Body) { | |
| $this->inABody = false; | |
| } elseif ($this->inABody) { | |
| if (!$expression && get_class($node) !== 'Twig_Node' && $prependedNodes = array_shift($this->prependedNodes)) { | |
| $nodes = array(); | |
| foreach (array_unique($prependedNodes) as $name) { | |
| $nodes[] = new Twig_Node_SetTemp($name, $node->getLine()); | |
| } | |
| $nodes[] = $node; | |
| $node = new Twig_Node($nodes); | |
| } | |
| } | |
| } | |
| return $node; | |
| } | |
| protected function optimizeVariables($node, $env) | |
| { | |
| if ('Twig_Node_Expression_Name' === get_class($node) && $node->isSimple()) { | |
| $this->prependedNodes[0][] = $node->getAttribute('name'); | |
| return new Twig_Node_Expression_TempName($node->getAttribute('name'), $node->getLine()); | |
| } | |
| return $node; | |
| } | |
| /** | |
| * Optimizes print nodes. | |
| * | |
| * It replaces: | |
| * | |
| * * "echo $this->render(Parent)Block()" with "$this->display(Parent)Block()" | |
| * | |
| * @param Twig_NodeInterface $node A Node | |
| * @param Twig_Environment $env The current Twig environment | |
| */ | |
| protected function optimizePrintNode($node, $env) | |
| { | |
| if (!$node instanceof Twig_Node_Print) { | |
| return $node; | |
| } | |
| if ( | |
| $node->getNode('expr') instanceof Twig_Node_Expression_BlockReference || | |
| $node->getNode('expr') instanceof Twig_Node_Expression_Parent | |
| ) { | |
| $node->getNode('expr')->setAttribute('output', true); | |
| return $node->getNode('expr'); | |
| } | |
| return $node; | |
| } | |
| /** | |
| * Removes "raw" filters. | |
| * | |
| * @param Twig_NodeInterface $node A Node | |
| * @param Twig_Environment $env The current Twig environment | |
| */ | |
| protected function optimizeRawFilter($node, $env) | |
| { | |
| if ($node instanceof Twig_Node_Expression_Filter && 'raw' == $node->getNode('filter')->getAttribute('value')) { | |
| return $node->getNode('node'); | |
| } | |
| return $node; | |
| } | |
| /** | |
| * Optimizes "for" tag by removing the "loop" variable creation whenever possible. | |
| * | |
| * @param Twig_NodeInterface $node A Node | |
| * @param Twig_Environment $env The current Twig environment | |
| */ | |
| protected function enterOptimizeFor($node, $env) | |
| { | |
| if ($node instanceof Twig_Node_For) { | |
| // disable the loop variable by default | |
| $node->setAttribute('with_loop', false); | |
| array_unshift($this->loops, $node); | |
| } elseif (!$this->loops) { | |
| // we are outside a loop | |
| return; | |
| } | |
| // when do we need to add the loop variable back? | |
| // the loop variable is referenced for the current loop | |
| elseif ($node instanceof Twig_Node_Expression_Name && 'loop' === $node->getAttribute('name')) { | |
| $this->addLoopToCurrent(); | |
| } | |
| // block reference | |
| elseif ($node instanceof Twig_Node_BlockReference || $node instanceof Twig_Node_Expression_BlockReference) { | |
| $this->addLoopToCurrent(); | |
| } | |
| // include without the only attribute | |
| elseif ($node instanceof Twig_Node_Include && !$node->getAttribute('only')) { | |
| $this->addLoopToAll(); | |
| } | |
| // the loop variable is referenced via an attribute | |
| elseif ($node instanceof Twig_Node_Expression_GetAttr | |
| && (!$node->getNode('attribute') instanceof Twig_Node_Expression_Constant | |
| || 'parent' === $node->getNode('attribute')->getAttribute('value') | |
| ) | |
| && (true === $this->loops[0]->getAttribute('with_loop') | |
| || ($node->getNode('node') instanceof Twig_Node_Expression_Name | |
| && 'loop' === $node->getNode('node')->getAttribute('name') | |
| ) | |
| ) | |
| ) { | |
| $this->addLoopToAll(); | |
| } | |
| } | |
| /** | |
| * Optimizes "for" tag by removing the "loop" variable creation whenever possible. | |
| * | |
| * @param Twig_NodeInterface $node A Node | |
| * @param Twig_Environment $env The current Twig environment | |
| */ | |
| protected function leaveOptimizeFor($node, $env) | |
| { | |
| if ($node instanceof Twig_Node_For) { | |
| array_shift($this->loops); | |
| } | |
| } | |
| protected function addLoopToCurrent() | |
| { | |
| $this->loops[0]->setAttribute('with_loop', true); | |
| } | |
| protected function addLoopToAll() | |
| { | |
| foreach ($this->loops as $loop) { | |
| $loop->setAttribute('with_loop', true); | |
| } | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function getPriority() | |
| { | |
| return 255; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Binary_Or extends Twig_Node_Expression_Binary | |
| { | |
| public function operator(Twig_Compiler $compiler) | |
| { | |
| return $compiler->raw('||'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a parent node. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_Expression_Parent extends Twig_Node_Expression | |
| { | |
| public function __construct($name, $lineno, $tag = null) | |
| { | |
| parent::__construct(array(), array('output' => false, 'name' => $name), $lineno, $tag); | |
| } | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| if ($this->getAttribute('output')) { | |
| $compiler | |
| ->addDebugInfo($this) | |
| ->write("\$this->displayParentBlock(") | |
| ->string($this->getAttribute('name')) | |
| ->raw(", \$context, \$blocks);\n") | |
| ; | |
| } else { | |
| $compiler | |
| ->raw("\$this->renderParentBlock(") | |
| ->string($this->getAttribute('name')) | |
| ->raw(", \$context, \$blocks)") | |
| ; | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Default parser implementation. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Parser implements Twig_ParserInterface | |
| { | |
| protected $stack = array(); | |
| protected $stream; | |
| protected $parent; | |
| protected $handlers; | |
| protected $visitors; | |
| protected $expressionParser; | |
| protected $blocks; | |
| protected $blockStack; | |
| protected $macros; | |
| protected $env; | |
| protected $reservedMacroNames; | |
| protected $importedSymbols; | |
| protected $traits; | |
| protected $embeddedTemplates = array(); | |
| /** | |
| * Constructor. | |
| * | |
| * @param Twig_Environment $env A Twig_Environment instance | |
| */ | |
| public function __construct(Twig_Environment $env) | |
| { | |
| $this->env = $env; | |
| } | |
| public function getEnvironment() | |
| { | |
| return $this->env; | |
| } | |
| public function getVarName() | |
| { | |
| return sprintf('__internal_%s', hash('sha1', uniqid(mt_rand(), true), false)); | |
| } | |
| public function getFilename() | |
| { | |
| return $this->stream->getFilename(); | |
| } | |
| /** | |
| * Converts a token stream to a node tree. | |
| * | |
| * @param Twig_TokenStream $stream A token stream instance | |
| * | |
| * @return Twig_Node_Module A node tree | |
| */ | |
| public function parse(Twig_TokenStream $stream, $test = null, $dropNeedle = false) | |
| { | |
| // push all variables into the stack to keep the current state of the parser | |
| $vars = get_object_vars($this); | |
| unset($vars['stack'], $vars['env'], $vars['handlers'], $vars['visitors'], $vars['expressionParser']); | |
| $this->stack[] = $vars; | |
| // tag handlers | |
| if (null === $this->handlers) { | |
| $this->handlers = $this->env->getTokenParsers(); | |
| $this->handlers->setParser($this); | |
| } | |
| // node visitors | |
| if (null === $this->visitors) { | |
| $this->visitors = $this->env->getNodeVisitors(); | |
| } | |
| if (null === $this->expressionParser) { | |
| $this->expressionParser = new Twig_ExpressionParser($this, $this->env->getUnaryOperators(), $this->env->getBinaryOperators()); | |
| } | |
| $this->stream = $stream; | |
| $this->parent = null; | |
| $this->blocks = array(); | |
| $this->macros = array(); | |
| $this->traits = array(); | |
| $this->blockStack = array(); | |
| $this->importedSymbols = array(array()); | |
| $this->embeddedTemplates = array(); | |
| try { | |
| $body = $this->subparse($test, $dropNeedle); | |
| if (null !== $this->parent) { | |
| if (null === $body = $this->filterBodyNodes($body)) { | |
| $body = new Twig_Node(); | |
| } | |
| } | |
| } catch (Twig_Error_Syntax $e) { | |
| if (!$e->getTemplateFile()) { | |
| $e->setTemplateFile($this->getFilename()); | |
| } | |
| if (!$e->getTemplateLine()) { | |
| $e->setTemplateLine($this->stream->getCurrent()->getLine()); | |
| } | |
| throw $e; | |
| } | |
| $node = new Twig_Node_Module(new Twig_Node_Body(array($body)), $this->parent, new Twig_Node($this->blocks), new Twig_Node($this->macros), new Twig_Node($this->traits), $this->embeddedTemplates, $this->getFilename()); | |
| $traverser = new Twig_NodeTraverser($this->env, $this->visitors); | |
| $node = $traverser->traverse($node); | |
| // restore previous stack so previous parse() call can resume working | |
| foreach (array_pop($this->stack) as $key => $val) { | |
| $this->$key = $val; | |
| } | |
| return $node; | |
| } | |
| public function subparse($test, $dropNeedle = false) | |
| { | |
| $lineno = $this->getCurrentToken()->getLine(); | |
| $rv = array(); | |
| while (!$this->stream->isEOF()) { | |
| switch ($this->getCurrentToken()->getType()) { | |
| case Twig_Token::TEXT_TYPE: | |
| $token = $this->stream->next(); | |
| $rv[] = new Twig_Node_Text($token->getValue(), $token->getLine()); | |
| break; | |
| case Twig_Token::VAR_START_TYPE: | |
| $token = $this->stream->next(); | |
| $expr = $this->expressionParser->parseExpression(); | |
| $this->stream->expect(Twig_Token::VAR_END_TYPE); | |
| $rv[] = new Twig_Node_Print($expr, $token->getLine()); | |
| break; | |
| case Twig_Token::BLOCK_START_TYPE: | |
| $this->stream->next(); | |
| $token = $this->getCurrentToken(); | |
| if ($token->getType() !== Twig_Token::NAME_TYPE) { | |
| throw new Twig_Error_Syntax('A block must start with a tag name', $token->getLine(), $this->getFilename()); | |
| } | |
| if (null !== $test && call_user_func($test, $token)) { | |
| if ($dropNeedle) { | |
| $this->stream->next(); | |
| } | |
| if (1 === count($rv)) { | |
| return $rv[0]; | |
| } | |
| return new Twig_Node($rv, array(), $lineno); | |
| } | |
| $subparser = $this->handlers->getTokenParser($token->getValue()); | |
| if (null === $subparser) { | |
| if (null !== $test) { | |
| $error = sprintf('Unexpected tag name "%s"', $token->getValue()); | |
| if (is_array($test) && isset($test[0]) && $test[0] instanceof Twig_TokenParserInterface) { | |
| $error .= sprintf(' (expecting closing tag for the "%s" tag defined near line %s)', $test[0]->getTag(), $lineno); | |
| } | |
| throw new Twig_Error_Syntax($error, $token->getLine(), $this->getFilename()); | |
| } | |
| $message = sprintf('Unknown tag name "%s"', $token->getValue()); | |
| if ($alternatives = $this->env->computeAlternatives($token->getValue(), array_keys($this->env->getTags()))) { | |
| $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); | |
| } | |
| throw new Twig_Error_Syntax($message, $token->getLine(), $this->getFilename()); | |
| } | |
| $this->stream->next(); | |
| $node = $subparser->parse($token); | |
| if (null !== $node) { | |
| $rv[] = $node; | |
| } | |
| break; | |
| default: | |
| throw new Twig_Error_Syntax('Lexer or parser ended up in unsupported state.', 0, $this->getFilename()); | |
| } | |
| } | |
| if (1 === count($rv)) { | |
| return $rv[0]; | |
| } | |
| return new Twig_Node($rv, array(), $lineno); | |
| } | |
| public function addHandler($name, $class) | |
| { | |
| $this->handlers[$name] = $class; | |
| } | |
| public function addNodeVisitor(Twig_NodeVisitorInterface $visitor) | |
| { | |
| $this->visitors[] = $visitor; | |
| } | |
| public function getBlockStack() | |
| { | |
| return $this->blockStack; | |
| } | |
| public function peekBlockStack() | |
| { | |
| return $this->blockStack[count($this->blockStack) - 1]; | |
| } | |
| public function popBlockStack() | |
| { | |
| array_pop($this->blockStack); | |
| } | |
| public function pushBlockStack($name) | |
| { | |
| $this->blockStack[] = $name; | |
| } | |
| public function hasBlock($name) | |
| { | |
| return isset($this->blocks[$name]); | |
| } | |
| public function getBlock($name) | |
| { | |
| return $this->blocks[$name]; | |
| } | |
| public function setBlock($name, $value) | |
| { | |
| $this->blocks[$name] = new Twig_Node_Body(array($value), array(), $value->getLine()); | |
| } | |
| public function hasMacro($name) | |
| { | |
| return isset($this->macros[$name]); | |
| } | |
| public function setMacro($name, Twig_Node_Macro $node) | |
| { | |
| if (null === $this->reservedMacroNames) { | |
| $this->reservedMacroNames = array(); | |
| $r = new ReflectionClass($this->env->getBaseTemplateClass()); | |
| foreach ($r->getMethods() as $method) { | |
| $this->reservedMacroNames[] = $method->getName(); | |
| } | |
| } | |
| if (in_array($name, $this->reservedMacroNames)) { | |
| throw new Twig_Error_Syntax(sprintf('"%s" cannot be used as a macro name as it is a reserved keyword', $name), $node->getLine(), $this->getFilename()); | |
| } | |
| $this->macros[$name] = $node; | |
| } | |
| public function addTrait($trait) | |
| { | |
| $this->traits[] = $trait; | |
| } | |
| public function hasTraits() | |
| { | |
| return count($this->traits) > 0; | |
| } | |
| public function embedTemplate(Twig_Node_Module $template) | |
| { | |
| $template->setIndex(mt_rand()); | |
| $this->embeddedTemplates[] = $template; | |
| } | |
| public function addImportedSymbol($type, $alias, $name = null, Twig_Node_Expression $node = null) | |
| { | |
| $this->importedSymbols[0][$type][$alias] = array('name' => $name, 'node' => $node); | |
| } | |
| public function getImportedSymbol($type, $alias) | |
| { | |
| foreach ($this->importedSymbols as $functions) { | |
| if (isset($functions[$type][$alias])) { | |
| return $functions[$type][$alias]; | |
| } | |
| } | |
| } | |
| public function isMainScope() | |
| { | |
| return 1 === count($this->importedSymbols); | |
| } | |
| public function pushLocalScope() | |
| { | |
| array_unshift($this->importedSymbols, array()); | |
| } | |
| public function popLocalScope() | |
| { | |
| array_shift($this->importedSymbols); | |
| } | |
| /** | |
| * Gets the expression parser. | |
| * | |
| * @return Twig_ExpressionParser The expression parser | |
| */ | |
| public function getExpressionParser() | |
| { | |
| return $this->expressionParser; | |
| } | |
| public function getParent() | |
| { | |
| return $this->parent; | |
| } | |
| public function setParent($parent) | |
| { | |
| $this->parent = $parent; | |
| } | |
| /** | |
| * Gets the token stream. | |
| * | |
| * @return Twig_TokenStream The token stream | |
| */ | |
| public function getStream() | |
| { | |
| return $this->stream; | |
| } | |
| /** | |
| * Gets the current token. | |
| * | |
| * @return Twig_Token The current token | |
| */ | |
| public function getCurrentToken() | |
| { | |
| return $this->stream->getCurrent(); | |
| } | |
| protected function filterBodyNodes(Twig_NodeInterface $node) | |
| { | |
| // check that the body does not contain non-empty output nodes | |
| if ( | |
| ($node instanceof Twig_Node_Text && !ctype_space($node->getAttribute('data'))) | |
| || | |
| (!$node instanceof Twig_Node_Text && !$node instanceof Twig_Node_BlockReference && $node instanceof Twig_NodeOutputInterface) | |
| ) { | |
| if (false !== strpos((string) $node, chr(0xEF).chr(0xBB).chr(0xBF))) { | |
| throw new Twig_Error_Syntax('A template that extends another one cannot have a body but a byte order mark (BOM) has been detected; it must be removed.', $node->getLine(), $this->getFilename()); | |
| } | |
| throw new Twig_Error_Syntax('A template that extends another one cannot have a body.', $node->getLine(), $this->getFilename()); | |
| } | |
| // bypass "set" nodes as they "capture" the output | |
| if ($node instanceof Twig_Node_Set) { | |
| return $node; | |
| } | |
| if ($node instanceof Twig_NodeOutputInterface) { | |
| return; | |
| } | |
| foreach ($node as $k => $n) { | |
| if (null !== $n && null === $n = $this->filterBodyNodes($n)) { | |
| $node->removeNode($k); | |
| } | |
| } | |
| return $node; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Interface implemented by parser classes. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| interface Twig_ParserInterface | |
| { | |
| /** | |
| * Converts a token stream to a node tree. | |
| * | |
| * @param Twig_TokenStream $stream A token stream instance | |
| * | |
| * @return Twig_Node_Module A node tree | |
| */ | |
| public function parse(Twig_TokenStream $stream); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Unary_Pos extends Twig_Node_Expression_Unary | |
| { | |
| public function operator(Twig_Compiler $compiler) | |
| { | |
| $compiler->raw('+'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Binary_Power extends Twig_Node_Expression_Binary | |
| { | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->raw('pow(') | |
| ->subcompile($this->getNode('left')) | |
| ->raw(', ') | |
| ->subcompile($this->getNode('right')) | |
| ->raw(')') | |
| ; | |
| } | |
| public function operator(Twig_Compiler $compiler) | |
| { | |
| return $compiler->raw('**'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a node that outputs an expression. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_Print extends Twig_Node implements Twig_NodeOutputInterface | |
| { | |
| public function __construct(Twig_Node_Expression $expr, $lineno, $tag = null) | |
| { | |
| parent::__construct(array('expr' => $expr), array(), $lineno, $tag); | |
| } | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->addDebugInfo($this) | |
| ->write('echo ') | |
| ->subcompile($this->getNode('expr')) | |
| ->raw(";\n") | |
| ; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div class="control-group"> | |
| <label class="control-label" for="{{ field }}">{{ title }}</label> | |
| <div class="controls"> | |
| {% for option in type['options'] %} | |
| <label class="radio" {% if required %}required="required"{% endif %}> | |
| <input type="radio" name="{{ field }}" id="{{ field }}" value="{{ option }}" {% if value == option %} checked{% endif %}> | |
| {{ option }} | |
| </label> | |
| {% endfor %} | |
| </div> | |
| </div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Binary_Range extends Twig_Node_Expression_Binary | |
| { | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->raw('range(') | |
| ->subcompile($this->getNode('left')) | |
| ->raw(', ') | |
| ->subcompile($this->getNode('right')) | |
| ->raw(')') | |
| ; | |
| } | |
| public function operator(Twig_Compiler $compiler) | |
| { | |
| return $compiler->raw('..'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Exception thrown when an error occurs at runtime. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Error_Runtime extends Twig_Error | |
| { | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| class Twig_NodeVisitor_SafeAnalysis implements Twig_NodeVisitorInterface | |
| { | |
| protected $data = array(); | |
| protected $safeVars = array(); | |
| public function setSafeVars($safeVars) | |
| { | |
| $this->safeVars = $safeVars; | |
| } | |
| public function getSafe(Twig_NodeInterface $node) | |
| { | |
| $hash = spl_object_hash($node); | |
| if (isset($this->data[$hash])) { | |
| foreach ($this->data[$hash] as $bucket) { | |
| if ($bucket['key'] === $node) { | |
| return $bucket['value']; | |
| } | |
| } | |
| } | |
| return null; | |
| } | |
| protected function setSafe(Twig_NodeInterface $node, array $safe) | |
| { | |
| $hash = spl_object_hash($node); | |
| if (isset($this->data[$hash])) { | |
| foreach ($this->data[$hash] as &$bucket) { | |
| if ($bucket['key'] === $node) { | |
| $bucket['value'] = $safe; | |
| return; | |
| } | |
| } | |
| } | |
| $this->data[$hash][] = array( | |
| 'key' => $node, | |
| 'value' => $safe, | |
| ); | |
| } | |
| public function enterNode(Twig_NodeInterface $node, Twig_Environment $env) | |
| { | |
| return $node; | |
| } | |
| public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env) | |
| { | |
| if ($node instanceof Twig_Node_Expression_Constant) { | |
| // constants are marked safe for all | |
| $this->setSafe($node, array('all')); | |
| } elseif ($node instanceof Twig_Node_Expression_BlockReference) { | |
| // blocks are safe by definition | |
| $this->setSafe($node, array('all')); | |
| } elseif ($node instanceof Twig_Node_Expression_Parent) { | |
| // parent block is safe by definition | |
| $this->setSafe($node, array('all')); | |
| } elseif ($node instanceof Twig_Node_Expression_Conditional) { | |
| // intersect safeness of both operands | |
| $safe = $this->intersectSafe($this->getSafe($node->getNode('expr2')), $this->getSafe($node->getNode('expr3'))); | |
| $this->setSafe($node, $safe); | |
| } elseif ($node instanceof Twig_Node_Expression_Filter) { | |
| // filter expression is safe when the filter is safe | |
| $name = $node->getNode('filter')->getAttribute('value'); | |
| $args = $node->getNode('arguments'); | |
| if (false !== $filter = $env->getFilter($name)) { | |
| $safe = $filter->getSafe($args); | |
| if (null === $safe) { | |
| $safe = $this->intersectSafe($this->getSafe($node->getNode('node')), $filter->getPreservesSafety()); | |
| } | |
| $this->setSafe($node, $safe); | |
| } else { | |
| $this->setSafe($node, array()); | |
| } | |
| } elseif ($node instanceof Twig_Node_Expression_Function) { | |
| // function expression is safe when the function is safe | |
| $name = $node->getAttribute('name'); | |
| $args = $node->getNode('arguments'); | |
| $function = $env->getFunction($name); | |
| if (false !== $function) { | |
| $this->setSafe($node, $function->getSafe($args)); | |
| } else { | |
| $this->setSafe($node, array()); | |
| } | |
| } elseif ($node instanceof Twig_Node_Expression_MethodCall) { | |
| if ($node->getAttribute('safe')) { | |
| $this->setSafe($node, array('all')); | |
| } else { | |
| $this->setSafe($node, array()); | |
| } | |
| } elseif ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name) { | |
| $name = $node->getNode('node')->getAttribute('name'); | |
| // attributes on template instances are safe | |
| if ('_self' == $name || in_array($name, $this->safeVars)) { | |
| $this->setSafe($node, array('all')); | |
| } else { | |
| $this->setSafe($node, array()); | |
| } | |
| } else { | |
| $this->setSafe($node, array()); | |
| } | |
| return $node; | |
| } | |
| protected function intersectSafe(array $a = null, array $b = null) | |
| { | |
| if (null === $a || null === $b) { | |
| return array(); | |
| } | |
| if (in_array('all', $a)) { | |
| return $b; | |
| } | |
| if (in_array('all', $b)) { | |
| return $a; | |
| } | |
| return array_intersect($a, $b); | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function getPriority() | |
| { | |
| return 0; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2011 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Checks if a variable is the same as another one (=== in PHP). | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_Expression_Test_Sameas extends Twig_Node_Expression_Test | |
| { | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->raw('(') | |
| ->subcompile($this->getNode('node')) | |
| ->raw(' === ') | |
| ->subcompile($this->getNode('arguments')->getNode(0)) | |
| ->raw(')') | |
| ; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Extension_Sandbox extends Twig_Extension | |
| { | |
| protected $sandboxedGlobally; | |
| protected $sandboxed; | |
| protected $policy; | |
| public function __construct(Twig_Sandbox_SecurityPolicyInterface $policy, $sandboxed = false) | |
| { | |
| $this->policy = $policy; | |
| $this->sandboxedGlobally = $sandboxed; | |
| } | |
| /** | |
| * Returns the token parser instances to add to the existing list. | |
| * | |
| * @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances | |
| */ | |
| public function getTokenParsers() | |
| { | |
| return array(new Twig_TokenParser_Sandbox()); | |
| } | |
| /** | |
| * Returns the node visitor instances to add to the existing list. | |
| * | |
| * @return array An array of Twig_NodeVisitorInterface instances | |
| */ | |
| public function getNodeVisitors() | |
| { | |
| return array(new Twig_NodeVisitor_Sandbox()); | |
| } | |
| public function enableSandbox() | |
| { | |
| $this->sandboxed = true; | |
| } | |
| public function disableSandbox() | |
| { | |
| $this->sandboxed = false; | |
| } | |
| public function isSandboxed() | |
| { | |
| return $this->sandboxedGlobally || $this->sandboxed; | |
| } | |
| public function isSandboxedGlobally() | |
| { | |
| return $this->sandboxedGlobally; | |
| } | |
| public function setSecurityPolicy(Twig_Sandbox_SecurityPolicyInterface $policy) | |
| { | |
| $this->policy = $policy; | |
| } | |
| public function getSecurityPolicy() | |
| { | |
| return $this->policy; | |
| } | |
| public function checkSecurity($tags, $filters, $functions) | |
| { | |
| if ($this->isSandboxed()) { | |
| $this->policy->checkSecurity($tags, $filters, $functions); | |
| } | |
| } | |
| public function checkMethodAllowed($obj, $method) | |
| { | |
| if ($this->isSandboxed()) { | |
| $this->policy->checkMethodAllowed($obj, $method); | |
| } | |
| } | |
| public function checkPropertyAllowed($obj, $method) | |
| { | |
| if ($this->isSandboxed()) { | |
| $this->policy->checkPropertyAllowed($obj, $method); | |
| } | |
| } | |
| public function ensureToStringAllowed($obj) | |
| { | |
| if (is_object($obj)) { | |
| $this->policy->checkMethodAllowed($obj, '__toString'); | |
| } | |
| return $obj; | |
| } | |
| /** | |
| * Returns the name of the extension. | |
| * | |
| * @return string The extension name | |
| */ | |
| public function getName() | |
| { | |
| return 'sandbox'; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a sandbox node. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_Sandbox extends Twig_Node | |
| { | |
| public function __construct(Twig_NodeInterface $body, $lineno, $tag = null) | |
| { | |
| parent::__construct(array('body' => $body), array(), $lineno, $tag); | |
| } | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->addDebugInfo($this) | |
| ->write("\$sandbox = \$this->env->getExtension('sandbox');\n") | |
| ->write("if (!\$alreadySandboxed = \$sandbox->isSandboxed()) {\n") | |
| ->indent() | |
| ->write("\$sandbox->enableSandbox();\n") | |
| ->outdent() | |
| ->write("}\n") | |
| ->subcompile($this->getNode('body')) | |
| ->write("if (!\$alreadySandboxed) {\n") | |
| ->indent() | |
| ->write("\$sandbox->disableSandbox();\n") | |
| ->outdent() | |
| ->write("}\n") | |
| ; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Twig_NodeVisitor_Sandbox implements sandboxing. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_NodeVisitor_Sandbox implements Twig_NodeVisitorInterface | |
| { | |
| protected $inAModule = false; | |
| protected $tags; | |
| protected $filters; | |
| protected $functions; | |
| /** | |
| * Called before child nodes are visited. | |
| * | |
| * @param Twig_NodeInterface $node The node to visit | |
| * @param Twig_Environment $env The Twig environment instance | |
| * | |
| * @return Twig_NodeInterface The modified node | |
| */ | |
| public function enterNode(Twig_NodeInterface $node, Twig_Environment $env) | |
| { | |
| if ($node instanceof Twig_Node_Module) { | |
| $this->inAModule = true; | |
| $this->tags = array(); | |
| $this->filters = array(); | |
| $this->functions = array(); | |
| return $node; | |
| } elseif ($this->inAModule) { | |
| // look for tags | |
| if ($node->getNodeTag()) { | |
| $this->tags[] = $node->getNodeTag(); | |
| } | |
| // look for filters | |
| if ($node instanceof Twig_Node_Expression_Filter) { | |
| $this->filters[] = $node->getNode('filter')->getAttribute('value'); | |
| } | |
| // look for functions | |
| if ($node instanceof Twig_Node_Expression_Function) { | |
| $this->functions[] = $node->getAttribute('name'); | |
| } | |
| // wrap print to check __toString() calls | |
| if ($node instanceof Twig_Node_Print) { | |
| return new Twig_Node_SandboxedPrint($node->getNode('expr'), $node->getLine(), $node->getNodeTag()); | |
| } | |
| } | |
| return $node; | |
| } | |
| /** | |
| * Called after child nodes are visited. | |
| * | |
| * @param Twig_NodeInterface $node The node to visit | |
| * @param Twig_Environment $env The Twig environment instance | |
| * | |
| * @return Twig_NodeInterface The modified node | |
| */ | |
| public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env) | |
| { | |
| if ($node instanceof Twig_Node_Module) { | |
| $this->inAModule = false; | |
| return new Twig_Node_SandboxedModule($node, array_unique($this->filters), array_unique($this->tags), array_unique($this->functions)); | |
| } | |
| return $node; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function getPriority() | |
| { | |
| return 0; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Marks a section of a template as untrusted code that must be evaluated in the sandbox mode. | |
| * | |
| * <pre> | |
| * {% sandbox %} | |
| * {% include 'user.html' %} | |
| * {% endsandbox %} | |
| * </pre> | |
| * | |
| * @see http://www.twig-project.org/doc/api.html#sandbox-extension for details | |
| */ | |
| class Twig_TokenParser_Sandbox extends Twig_TokenParser | |
| { | |
| /** | |
| * Parses a token and returns a node. | |
| * | |
| * @param Twig_Token $token A Twig_Token instance | |
| * | |
| * @return Twig_NodeInterface A Twig_NodeInterface instance | |
| */ | |
| public function parse(Twig_Token $token) | |
| { | |
| $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); | |
| $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true); | |
| $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); | |
| // in a sandbox tag, only include tags are allowed | |
| if (!$body instanceof Twig_Node_Include) { | |
| foreach ($body as $node) { | |
| if ($node instanceof Twig_Node_Text && ctype_space($node->getAttribute('data'))) { | |
| continue; | |
| } | |
| if (!$node instanceof Twig_Node_Include) { | |
| throw new Twig_Error_Syntax('Only "include" tags are allowed within a "sandbox" section', $node->getLine(), $this->parser->getFilename()); | |
| } | |
| } | |
| } | |
| return new Twig_Node_Sandbox($body, $token->getLine(), $this->getTag()); | |
| } | |
| public function decideBlockEnd(Twig_Token $token) | |
| { | |
| return $token->test('endsandbox'); | |
| } | |
| /** | |
| * Gets the tag name associated with this token parser. | |
| * | |
| * @return string The tag name | |
| */ | |
| public function getTag() | |
| { | |
| return 'sandbox'; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a module node. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_SandboxedModule extends Twig_Node_Module | |
| { | |
| protected $usedFilters; | |
| protected $usedTags; | |
| protected $usedFunctions; | |
| public function __construct(Twig_Node_Module $node, array $usedFilters, array $usedTags, array $usedFunctions) | |
| { | |
| parent::__construct($node->getNode('body'), $node->getNode('parent'), $node->getNode('blocks'), $node->getNode('macros'), $node->getNode('traits'), $node->getAttribute('embedded_templates'), $node->getAttribute('filename'), $node->getLine(), $node->getNodeTag()); | |
| $this->setAttribute('index', $node->getAttribute('index')); | |
| $this->usedFilters = $usedFilters; | |
| $this->usedTags = $usedTags; | |
| $this->usedFunctions = $usedFunctions; | |
| } | |
| protected function compileDisplayBody(Twig_Compiler $compiler) | |
| { | |
| $compiler->write("\$this->checkSecurity();\n"); | |
| parent::compileDisplayBody($compiler); | |
| } | |
| protected function compileDisplayFooter(Twig_Compiler $compiler) | |
| { | |
| parent::compileDisplayFooter($compiler); | |
| $compiler | |
| ->write("protected function checkSecurity()\n", "{\n") | |
| ->indent() | |
| ->write("\$this->env->getExtension('sandbox')->checkSecurity(\n") | |
| ->indent() | |
| ->write(!$this->usedTags ? "array(),\n" : "array('".implode('\', \'', $this->usedTags)."'),\n") | |
| ->write(!$this->usedFilters ? "array(),\n" : "array('".implode('\', \'', $this->usedFilters)."'),\n") | |
| ->write(!$this->usedFunctions ? "array()\n" : "array('".implode('\', \'', $this->usedFunctions)."')\n") | |
| ->outdent() | |
| ->write(");\n") | |
| ->outdent() | |
| ->write("}\n\n") | |
| ; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Twig_Node_SandboxedPrint adds a check for the __toString() method | |
| * when the variable is an object and the sandbox is activated. | |
| * | |
| * When there is a simple Print statement, like {{ article }}, | |
| * and if the sandbox is enabled, we need to check that the __toString() | |
| * method is allowed if 'article' is an object. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_SandboxedPrint extends Twig_Node_Print | |
| { | |
| public function __construct(Twig_Node_Expression $expr, $lineno, $tag = null) | |
| { | |
| parent::__construct($expr, $lineno, $tag); | |
| } | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->addDebugInfo($this) | |
| ->write('echo $this->env->getExtension(\'sandbox\')->ensureToStringAllowed(') | |
| ->subcompile($this->getNode('expr')) | |
| ->raw(");\n") | |
| ; | |
| } | |
| /** | |
| * Removes node filters. | |
| * | |
| * This is mostly needed when another visitor adds filters (like the escaper one). | |
| * | |
| * @param Twig_Node $node A Node | |
| */ | |
| protected function removeNodeFilter($node) | |
| { | |
| if ($node instanceof Twig_Node_Expression_Filter) { | |
| return $this->removeNodeFilter($node->getNode('node')); | |
| } | |
| return $node; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Exception thrown when a security error occurs at runtime. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Sandbox_SecurityError extends Twig_Error | |
| { | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a security policy which need to be enforced when sandbox mode is enabled. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Sandbox_SecurityPolicy implements Twig_Sandbox_SecurityPolicyInterface | |
| { | |
| protected $allowedTags; | |
| protected $allowedFilters; | |
| protected $allowedMethods; | |
| protected $allowedProperties; | |
| protected $allowedFunctions; | |
| public function __construct(array $allowedTags = array(), array $allowedFilters = array(), array $allowedMethods = array(), array $allowedProperties = array(), array $allowedFunctions = array()) | |
| { | |
| $this->allowedTags = $allowedTags; | |
| $this->allowedFilters = $allowedFilters; | |
| $this->setAllowedMethods($allowedMethods); | |
| $this->allowedProperties = $allowedProperties; | |
| $this->allowedFunctions = $allowedFunctions; | |
| } | |
| public function setAllowedTags(array $tags) | |
| { | |
| $this->allowedTags = $tags; | |
| } | |
| public function setAllowedFilters(array $filters) | |
| { | |
| $this->allowedFilters = $filters; | |
| } | |
| public function setAllowedMethods(array $methods) | |
| { | |
| $this->allowedMethods = array(); | |
| foreach ($methods as $class => $m) { | |
| $this->allowedMethods[$class] = array_map('strtolower', is_array($m) ? $m : array($m)); | |
| } | |
| } | |
| public function setAllowedProperties(array $properties) | |
| { | |
| $this->allowedProperties = $properties; | |
| } | |
| public function setAllowedFunctions(array $functions) | |
| { | |
| $this->allowedFunctions = $functions; | |
| } | |
| public function checkSecurity($tags, $filters, $functions) | |
| { | |
| foreach ($tags as $tag) { | |
| if (!in_array($tag, $this->allowedTags)) { | |
| throw new Twig_Sandbox_SecurityError(sprintf('Tag "%s" is not allowed.', $tag)); | |
| } | |
| } | |
| foreach ($filters as $filter) { | |
| if (!in_array($filter, $this->allowedFilters)) { | |
| throw new Twig_Sandbox_SecurityError(sprintf('Filter "%s" is not allowed.', $filter)); | |
| } | |
| } | |
| foreach ($functions as $function) { | |
| if (!in_array($function, $this->allowedFunctions)) { | |
| throw new Twig_Sandbox_SecurityError(sprintf('Function "%s" is not allowed.', $function)); | |
| } | |
| } | |
| } | |
| public function checkMethodAllowed($obj, $method) | |
| { | |
| if ($obj instanceof Twig_TemplateInterface || $obj instanceof Twig_Markup) { | |
| return true; | |
| } | |
| $allowed = false; | |
| $method = strtolower($method); | |
| foreach ($this->allowedMethods as $class => $methods) { | |
| if ($obj instanceof $class) { | |
| $allowed = in_array($method, $methods); | |
| break; | |
| } | |
| } | |
| if (!$allowed) { | |
| throw new Twig_Sandbox_SecurityError(sprintf('Calling "%s" method on a "%s" object is not allowed.', $method, get_class($obj))); | |
| } | |
| } | |
| public function checkPropertyAllowed($obj, $property) | |
| { | |
| $allowed = false; | |
| foreach ($this->allowedProperties as $class => $properties) { | |
| if ($obj instanceof $class) { | |
| $allowed = in_array($property, is_array($properties) ? $properties : array($properties)); | |
| break; | |
| } | |
| } | |
| if (!$allowed) { | |
| throw new Twig_Sandbox_SecurityError(sprintf('Calling "%s" property on a "%s" object is not allowed.', $property, get_class($obj))); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Interfaces that all security policy classes must implements. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| interface Twig_Sandbox_SecurityPolicyInterface | |
| { | |
| public function checkSecurity($tags, $filters, $functions); | |
| public function checkMethodAllowed($obj, $method); | |
| public function checkPropertyAllowed($obj, $method); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div class="control-group"> | |
| <label class="control-label" for="{{ field }}">{{ title }}</label> | |
| <div class="controls"> | |
| <select name="{{ field }}" placeholder="{{ title }}..." {% if required %}required="required"{% endif %}> | |
| <option value=""></option> | |
| {% for option in type['options'] %} | |
| <option value="{{ option }}" {% if value == option %} selected{% endif %}> | |
| {{ option }} | |
| </option> | |
| {% endfor %} | |
| </select> | |
| </div> | |
| </div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a set node. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_Set extends Twig_Node | |
| { | |
| public function __construct($capture, Twig_NodeInterface $names, Twig_NodeInterface $values, $lineno, $tag = null) | |
| { | |
| parent::__construct(array('names' => $names, 'values' => $values), array('capture' => $capture, 'safe' => false), $lineno, $tag); | |
| /* | |
| * Optimizes the node when capture is used for a large block of text. | |
| * | |
| * {% set foo %}foo{% endset %} is compiled to $context['foo'] = new Twig_Markup("foo"); | |
| */ | |
| if ($this->getAttribute('capture')) { | |
| $this->setAttribute('safe', true); | |
| $values = $this->getNode('values'); | |
| if ($values instanceof Twig_Node_Text) { | |
| $this->setNode('values', new Twig_Node_Expression_Constant($values->getAttribute('data'), $values->getLine())); | |
| $this->setAttribute('capture', false); | |
| } | |
| } | |
| } | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler->addDebugInfo($this); | |
| if (count($this->getNode('names')) > 1) { | |
| $compiler->write('list('); | |
| foreach ($this->getNode('names') as $idx => $node) { | |
| if ($idx) { | |
| $compiler->raw(', '); | |
| } | |
| $compiler->subcompile($node); | |
| } | |
| $compiler->raw(')'); | |
| } else { | |
| if ($this->getAttribute('capture')) { | |
| $compiler | |
| ->write("ob_start();\n") | |
| ->subcompile($this->getNode('values')) | |
| ; | |
| } | |
| $compiler->subcompile($this->getNode('names'), false); | |
| if ($this->getAttribute('capture')) { | |
| $compiler->raw(" = ('' === \$tmp = ob_get_clean()) ? '' : new Twig_Markup(\$tmp, \$this->env->getCharset())"); | |
| } | |
| } | |
| if (!$this->getAttribute('capture')) { | |
| $compiler->raw(' = '); | |
| if (count($this->getNode('names')) > 1) { | |
| $compiler->write('array('); | |
| foreach ($this->getNode('values') as $idx => $value) { | |
| if ($idx) { | |
| $compiler->raw(', '); | |
| } | |
| $compiler->subcompile($value); | |
| } | |
| $compiler->raw(')'); | |
| } else { | |
| if ($this->getAttribute('safe')) { | |
| $compiler | |
| ->raw("('' === \$tmp = ") | |
| ->subcompile($this->getNode('values')) | |
| ->raw(") ? '' : new Twig_Markup(\$tmp, \$this->env->getCharset())") | |
| ; | |
| } else { | |
| $compiler->subcompile($this->getNode('values')); | |
| } | |
| } | |
| } | |
| $compiler->raw(";\n"); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Defines a variable. | |
| * | |
| * <pre> | |
| * {% set foo = 'foo' %} | |
| * | |
| * {% set foo = [1, 2] %} | |
| * | |
| * {% set foo = {'foo': 'bar'} %} | |
| * | |
| * {% set foo = 'foo' ~ 'bar' %} | |
| * | |
| * {% set foo, bar = 'foo', 'bar' %} | |
| * | |
| * {% set foo %}Some content{% endset %} | |
| * </pre> | |
| */ | |
| class Twig_TokenParser_Set extends Twig_TokenParser | |
| { | |
| /** | |
| * Parses a token and returns a node. | |
| * | |
| * @param Twig_Token $token A Twig_Token instance | |
| * | |
| * @return Twig_NodeInterface A Twig_NodeInterface instance | |
| */ | |
| public function parse(Twig_Token $token) | |
| { | |
| $lineno = $token->getLine(); | |
| $stream = $this->parser->getStream(); | |
| $names = $this->parser->getExpressionParser()->parseAssignmentExpression(); | |
| $capture = false; | |
| if ($stream->test(Twig_Token::OPERATOR_TYPE, '=')) { | |
| $stream->next(); | |
| $values = $this->parser->getExpressionParser()->parseMultitargetExpression(); | |
| $stream->expect(Twig_Token::BLOCK_END_TYPE); | |
| if (count($names) !== count($values)) { | |
| throw new Twig_Error_Syntax("When using set, you must have the same number of variables and assignements.", $stream->getCurrent()->getLine(), $stream->getFilename()); | |
| } | |
| } else { | |
| $capture = true; | |
| if (count($names) > 1) { | |
| throw new Twig_Error_Syntax("When using set with a block, you cannot have a multi-target.", $stream->getCurrent()->getLine(), $stream->getFilename()); | |
| } | |
| $stream->expect(Twig_Token::BLOCK_END_TYPE); | |
| $values = $this->parser->subparse(array($this, 'decideBlockEnd'), true); | |
| $stream->expect(Twig_Token::BLOCK_END_TYPE); | |
| } | |
| return new Twig_Node_Set($capture, $names, $values, $lineno, $this->getTag()); | |
| } | |
| public function decideBlockEnd(Twig_Token $token) | |
| { | |
| return $token->test('endset'); | |
| } | |
| /** | |
| * Gets the tag name associated with this token parser. | |
| * | |
| * @return string The tag name | |
| */ | |
| public function getTag() | |
| { | |
| return 'set'; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2011 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_SetTemp extends Twig_Node | |
| { | |
| public function __construct($name, $lineno) | |
| { | |
| parent::__construct(array(), array('name' => $name), $lineno); | |
| } | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $name = $this->getAttribute('name'); | |
| $compiler | |
| ->addDebugInfo($this) | |
| ->write('if (isset($context[') | |
| ->string($name) | |
| ->raw('])) { $_') | |
| ->raw($name) | |
| ->raw('_ = $context[') | |
| ->repr($name) | |
| ->raw(']; } else { $_') | |
| ->raw($name) | |
| ->raw("_ = null; }\n") | |
| ; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a spaceless node. | |
| * | |
| * It removes spaces between HTML tags. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_Spaceless extends Twig_Node | |
| { | |
| public function __construct(Twig_NodeInterface $body, $lineno, $tag = 'spaceless') | |
| { | |
| parent::__construct(array('body' => $body), array(), $lineno, $tag); | |
| } | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->addDebugInfo($this) | |
| ->write("ob_start();\n") | |
| ->subcompile($this->getNode('body')) | |
| ->write("echo trim(preg_replace('/>\s+</', '><', ob_get_clean()));\n") | |
| ; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Remove whitespaces between HTML tags. | |
| * | |
| * <pre> | |
| * {% spaceless %} | |
| * <div> | |
| * <strong>foo</strong> | |
| * </div> | |
| * {% endspaceless %} | |
| * | |
| * {# output will be <div><strong>foo</strong></div> #} | |
| * </pre> | |
| */ | |
| class Twig_TokenParser_Spaceless extends Twig_TokenParser | |
| { | |
| /** | |
| * Parses a token and returns a node. | |
| * | |
| * @param Twig_Token $token A Twig_Token instance | |
| * | |
| * @return Twig_NodeInterface A Twig_NodeInterface instance | |
| */ | |
| public function parse(Twig_Token $token) | |
| { | |
| $lineno = $token->getLine(); | |
| $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); | |
| $body = $this->parser->subparse(array($this, 'decideSpacelessEnd'), true); | |
| $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); | |
| return new Twig_Node_Spaceless($body, $lineno, $this->getTag()); | |
| } | |
| public function decideSpacelessEnd(Twig_Token $token) | |
| { | |
| return $token->test('endspaceless'); | |
| } | |
| /** | |
| * Gets the tag name associated with this token parser. | |
| * | |
| * @return string The tag name | |
| */ | |
| public function getTag() | |
| { | |
| return 'spaceless'; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Loads a template from a string. | |
| * | |
| * This loader should only be used for unit testing as it has many limitations | |
| * (for instance, the include or extends tag does not make any sense for a string | |
| * loader). | |
| * | |
| * When using this loader with a cache mechanism, you should know that a new cache | |
| * key is generated each time a template content "changes" (the cache key being the | |
| * source code of the template). If you don't want to see your cache grows out of | |
| * control, you need to take care of clearing the old cache file by yourself. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Loader_String implements Twig_LoaderInterface, Twig_ExistsLoaderInterface | |
| { | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function getSource($name) | |
| { | |
| return $name; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function exists($name) | |
| { | |
| return true; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function getCacheKey($name) | |
| { | |
| return $name; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function isFresh($name, $time) | |
| { | |
| return true; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2012 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Extension_StringLoader extends Twig_Extension | |
| { | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function getFunctions() | |
| { | |
| return array( | |
| 'template_from_string' => new Twig_Function_Function('twig_template_from_string', array('needs_environment' => true)), | |
| ); | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function getName() | |
| { | |
| return 'string_loader'; | |
| } | |
| } | |
| /** | |
| * Loads a template from a string. | |
| * | |
| * <pre> | |
| * {% include template_from_string("Hello {{ name }}") }} | |
| * </pre> | |
| * | |
| * @param Twig_Environment $env A Twig_Environment instance | |
| * @param string $template A template as a string | |
| * | |
| * @return Twig_Template A Twig_Template instance | |
| */ | |
| function twig_template_from_string(Twig_Environment $env, $template) | |
| { | |
| static $loader; | |
| if (null === $loader) { | |
| $loader = new Twig_Loader_String(); | |
| } | |
| $current = $env->getLoader(); | |
| $env->setLoader($loader); | |
| try { | |
| $template = $env->loadTemplate($template); | |
| } catch (Exception $e) { | |
| $env->setLoader($current); | |
| throw $e; | |
| } | |
| $env->setLoader($current); | |
| return $template; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| body .container-fluid { | |
| margin-top: 30px; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Binary_Sub extends Twig_Node_Expression_Binary | |
| { | |
| public function operator(Twig_Compiler $compiler) | |
| { | |
| return $compiler->raw('-'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Exception thrown when a syntax error occurs during lexing or parsing of a template. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Error_Syntax extends Twig_Error | |
| { | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| require 'lib/_db_fields_table1.php'; | |
| require 'autoload.php'; | |
| $storage = new DatabaseStorage($table_name); | |
| $controller_path = 'table1_db.php'; | |
| require 'lib/_scaffold.php'; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| require 'lib/_db_fields_table1.php'; | |
| require 'autoload.php'; | |
| $storage = new FileStorage('db/table1.data'); | |
| $controller_path = 'table1_file.php'; | |
| require 'lib/_scaffold.php'; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| require 'lib/_db_fields_table2.php'; | |
| require 'autoload.php'; | |
| $storage = new DatabaseStorage($table_name); | |
| $controller_path = 'table2_db.php'; | |
| require 'lib/_scaffold.php'; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| require 'lib/_db_fields_table2.php'; | |
| require 'autoload.php'; | |
| $storage = new FileStorage('db/table2.data'); | |
| $controller_path = 'table2_file.php'; | |
| require 'lib/_scaffold.php'; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Default base class for compiled templates. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| abstract class Twig_Template implements Twig_TemplateInterface | |
| { | |
| protected static $cache = array(); | |
| protected $parent; | |
| protected $parents; | |
| protected $env; | |
| protected $blocks; | |
| protected $traits; | |
| /** | |
| * Constructor. | |
| * | |
| * @param Twig_Environment $env A Twig_Environment instance | |
| */ | |
| public function __construct(Twig_Environment $env) | |
| { | |
| $this->env = $env; | |
| $this->blocks = array(); | |
| $this->traits = array(); | |
| } | |
| /** | |
| * Returns the template name. | |
| * | |
| * @return string The template name | |
| */ | |
| abstract public function getTemplateName(); | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function getEnvironment() | |
| { | |
| return $this->env; | |
| } | |
| /** | |
| * Returns the parent template. | |
| * | |
| * This method is for internal use only and should never be called | |
| * directly. | |
| * | |
| * @return Twig_TemplateInterface|false The parent template or false if there is no parent | |
| */ | |
| public function getParent(array $context) | |
| { | |
| if (null !== $this->parent) { | |
| return $this->parent; | |
| } | |
| $parent = $this->doGetParent($context); | |
| if (false === $parent) { | |
| return false; | |
| } elseif ($parent instanceof Twig_Template) { | |
| $name = $parent->getTemplateName(); | |
| $this->parents[$name] = $parent; | |
| $parent = $name; | |
| } elseif (!isset($this->parents[$parent])) { | |
| $this->parents[$parent] = $this->env->loadTemplate($parent); | |
| } | |
| return $this->parents[$parent]; | |
| } | |
| protected function doGetParent(array $context) | |
| { | |
| return false; | |
| } | |
| public function isTraitable() | |
| { | |
| return true; | |
| } | |
| /** | |
| * Displays a parent block. | |
| * | |
| * This method is for internal use only and should never be called | |
| * directly. | |
| * | |
| * @param string $name The block name to display from the parent | |
| * @param array $context The context | |
| * @param array $blocks The current set of blocks | |
| */ | |
| public function displayParentBlock($name, array $context, array $blocks = array()) | |
| { | |
| $name = (string) $name; | |
| if (isset($this->traits[$name])) { | |
| $this->traits[$name][0]->displayBlock($name, $context, $blocks); | |
| } elseif (false !== $parent = $this->getParent($context)) { | |
| $parent->displayBlock($name, $context, $blocks); | |
| } else { | |
| throw new Twig_Error_Runtime(sprintf('The template has no parent and no traits defining the "%s" block', $name), -1, $this->getTemplateName()); | |
| } | |
| } | |
| /** | |
| * Displays a block. | |
| * | |
| * This method is for internal use only and should never be called | |
| * directly. | |
| * | |
| * @param string $name The block name to display | |
| * @param array $context The context | |
| * @param array $blocks The current set of blocks | |
| */ | |
| public function displayBlock($name, array $context, array $blocks = array()) | |
| { | |
| $name = (string) $name; | |
| if (isset($blocks[$name])) { | |
| $b = $blocks; | |
| unset($b[$name]); | |
| call_user_func($blocks[$name], $context, $b); | |
| } elseif (isset($this->blocks[$name])) { | |
| call_user_func($this->blocks[$name], $context, $blocks); | |
| } elseif (false !== $parent = $this->getParent($context)) { | |
| $parent->displayBlock($name, $context, array_merge($this->blocks, $blocks)); | |
| } | |
| } | |
| /** | |
| * Renders a parent block. | |
| * | |
| * This method is for internal use only and should never be called | |
| * directly. | |
| * | |
| * @param string $name The block name to render from the parent | |
| * @param array $context The context | |
| * @param array $blocks The current set of blocks | |
| * | |
| * @return string The rendered block | |
| */ | |
| public function renderParentBlock($name, array $context, array $blocks = array()) | |
| { | |
| ob_start(); | |
| $this->displayParentBlock($name, $context, $blocks); | |
| return ob_get_clean(); | |
| } | |
| /** | |
| * Renders a block. | |
| * | |
| * This method is for internal use only and should never be called | |
| * directly. | |
| * | |
| * @param string $name The block name to render | |
| * @param array $context The context | |
| * @param array $blocks The current set of blocks | |
| * | |
| * @return string The rendered block | |
| */ | |
| public function renderBlock($name, array $context, array $blocks = array()) | |
| { | |
| ob_start(); | |
| $this->displayBlock($name, $context, $blocks); | |
| return ob_get_clean(); | |
| } | |
| /** | |
| * Returns whether a block exists or not. | |
| * | |
| * This method is for internal use only and should never be called | |
| * directly. | |
| * | |
| * This method does only return blocks defined in the current template | |
| * or defined in "used" traits. | |
| * | |
| * It does not return blocks from parent templates as the parent | |
| * template name can be dynamic, which is only known based on the | |
| * current context. | |
| * | |
| * @param string $name The block name | |
| * | |
| * @return Boolean true if the block exists, false otherwise | |
| */ | |
| public function hasBlock($name) | |
| { | |
| return isset($this->blocks[(string) $name]); | |
| } | |
| /** | |
| * Returns all block names. | |
| * | |
| * This method is for internal use only and should never be called | |
| * directly. | |
| * | |
| * @return array An array of block names | |
| * | |
| * @see hasBlock | |
| */ | |
| public function getBlockNames() | |
| { | |
| return array_keys($this->blocks); | |
| } | |
| /** | |
| * Returns all blocks. | |
| * | |
| * This method is for internal use only and should never be called | |
| * directly. | |
| * | |
| * @return array An array of blocks | |
| * | |
| * @see hasBlock | |
| */ | |
| public function getBlocks() | |
| { | |
| return $this->blocks; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function display(array $context, array $blocks = array()) | |
| { | |
| $this->displayWithErrorHandling($this->env->mergeGlobals($context), $blocks); | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function render(array $context) | |
| { | |
| $level = ob_get_level(); | |
| ob_start(); | |
| try { | |
| $this->display($context); | |
| } catch (Exception $e) { | |
| while (ob_get_level() > $level) { | |
| ob_end_clean(); | |
| } | |
| throw $e; | |
| } | |
| return ob_get_clean(); | |
| } | |
| protected function displayWithErrorHandling(array $context, array $blocks = array()) | |
| { | |
| try { | |
| $this->doDisplay($context, $blocks); | |
| } catch (Twig_Error $e) { | |
| if (!$e->getTemplateFile()) { | |
| $e->setTemplateFile($this->getTemplateName()); | |
| } | |
| // this is mostly useful for Twig_Error_Loader exceptions | |
| // see Twig_Error_Loader | |
| if (false === $e->getTemplateLine()) { | |
| $e->setTemplateLine(-1); | |
| $e->guess(); | |
| } | |
| throw $e; | |
| } catch (Exception $e) { | |
| throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, null, $e); | |
| } | |
| } | |
| /** | |
| * Auto-generated method to display the template with the given context. | |
| * | |
| * @param array $context An array of parameters to pass to the template | |
| * @param array $blocks An array of blocks to pass to the template | |
| */ | |
| abstract protected function doDisplay(array $context, array $blocks = array()); | |
| /** | |
| * Returns a variable from the context. | |
| * | |
| * This method is for internal use only and should never be called | |
| * directly. | |
| * | |
| * This method should not be overridden in a sub-class as this is an | |
| * implementation detail that has been introduced to optimize variable | |
| * access for versions of PHP before 5.4. This is not a way to override | |
| * the way to get a variable value. | |
| * | |
| * @param array $context The context | |
| * @param string $item The variable to return from the context | |
| * @param Boolean $ignoreStrictCheck Whether to ignore the strict variable check or not | |
| * | |
| * @return The content of the context variable | |
| * | |
| * @throws Twig_Error_Runtime if the variable does not exist and Twig is running in strict mode | |
| */ | |
| final protected function getContext($context, $item, $ignoreStrictCheck = false) | |
| { | |
| if (!array_key_exists($item, $context)) { | |
| if ($ignoreStrictCheck || !$this->env->isStrictVariables()) { | |
| return null; | |
| } | |
| throw new Twig_Error_Runtime(sprintf('Variable "%s" does not exist', $item), -1, $this->getTemplateName()); | |
| } | |
| return $context[$item]; | |
| } | |
| /** | |
| * Returns the attribute value for a given array/object. | |
| * | |
| * @param mixed $object The object or array from where to get the item | |
| * @param mixed $item The item to get from the array or object | |
| * @param array $arguments An array of arguments to pass if the item is an object method | |
| * @param string $type The type of attribute (@see Twig_TemplateInterface) | |
| * @param Boolean $isDefinedTest Whether this is only a defined check | |
| * @param Boolean $ignoreStrictCheck Whether to ignore the strict attribute check or not | |
| * | |
| * @return mixed The attribute value, or a Boolean when $isDefinedTest is true, or null when the attribute is not set and $ignoreStrictCheck is true | |
| * | |
| * @throws Twig_Error_Runtime if the attribute does not exist and Twig is running in strict mode and $isDefinedTest is false | |
| */ | |
| protected function getAttribute($object, $item, array $arguments = array(), $type = Twig_TemplateInterface::ANY_CALL, $isDefinedTest = false, $ignoreStrictCheck = false) | |
| { | |
| $item = ctype_digit((string) $item) ? (int) $item : (string) $item; | |
| // array | |
| if (Twig_TemplateInterface::METHOD_CALL !== $type) { | |
| if ((is_array($object) && array_key_exists($item, $object)) | |
| || ($object instanceof ArrayAccess && isset($object[$item])) | |
| ) { | |
| if ($isDefinedTest) { | |
| return true; | |
| } | |
| return $object[$item]; | |
| } | |
| if (Twig_TemplateInterface::ARRAY_CALL === $type) { | |
| if ($isDefinedTest) { | |
| return false; | |
| } | |
| if ($ignoreStrictCheck || !$this->env->isStrictVariables()) { | |
| return null; | |
| } | |
| if (is_object($object)) { | |
| throw new Twig_Error_Runtime(sprintf('Key "%s" in object (with ArrayAccess) of type "%s" does not exist', $item, get_class($object)), -1, $this->getTemplateName()); | |
| } elseif (is_array($object)) { | |
| throw new Twig_Error_Runtime(sprintf('Key "%s" for array with keys "%s" does not exist', $item, implode(', ', array_keys($object))), -1, $this->getTemplateName()); | |
| } else { | |
| throw new Twig_Error_Runtime(sprintf('Impossible to access a key ("%s") on a "%s" variable', $item, gettype($object)), -1, $this->getTemplateName()); | |
| } | |
| } | |
| } | |
| if (!is_object($object)) { | |
| if ($isDefinedTest) { | |
| return false; | |
| } | |
| if ($ignoreStrictCheck || !$this->env->isStrictVariables()) { | |
| return null; | |
| } | |
| throw new Twig_Error_Runtime(sprintf('Item "%s" for "%s" does not exist', $item, is_array($object) ? 'Array' : $object), -1, $this->getTemplateName()); | |
| } | |
| $class = get_class($object); | |
| // object property | |
| if (Twig_TemplateInterface::METHOD_CALL !== $type) { | |
| if (isset($object->$item) || array_key_exists($item, $object)) { | |
| if ($isDefinedTest) { | |
| return true; | |
| } | |
| if ($this->env->hasExtension('sandbox')) { | |
| $this->env->getExtension('sandbox')->checkPropertyAllowed($object, $item); | |
| } | |
| return $object->$item; | |
| } | |
| } | |
| // object method | |
| if (!isset(self::$cache[$class]['methods'])) { | |
| self::$cache[$class]['methods'] = array_change_key_case(array_flip(get_class_methods($object))); | |
| } | |
| $lcItem = strtolower($item); | |
| if (isset(self::$cache[$class]['methods'][$lcItem])) { | |
| $method = $item; | |
| } elseif (isset(self::$cache[$class]['methods']['get'.$lcItem])) { | |
| $method = 'get'.$item; | |
| } elseif (isset(self::$cache[$class]['methods']['is'.$lcItem])) { | |
| $method = 'is'.$item; | |
| } elseif (isset(self::$cache[$class]['methods']['__call'])) { | |
| $method = $item; | |
| } else { | |
| if ($isDefinedTest) { | |
| return false; | |
| } | |
| if ($ignoreStrictCheck || !$this->env->isStrictVariables()) { | |
| return null; | |
| } | |
| throw new Twig_Error_Runtime(sprintf('Method "%s" for object "%s" does not exist', $item, get_class($object)), -1, $this->getTemplateName()); | |
| } | |
| if ($isDefinedTest) { | |
| return true; | |
| } | |
| if ($this->env->hasExtension('sandbox')) { | |
| $this->env->getExtension('sandbox')->checkMethodAllowed($object, $method); | |
| } | |
| $ret = call_user_func_array(array($object, $method), $arguments); | |
| // useful when calling a template method from a template | |
| // this is not supported but unfortunately heavily used in the Symfony profiler | |
| if ($object instanceof Twig_TemplateInterface) { | |
| return $ret === '' ? '' : new Twig_Markup($ret, $this->env->getCharset()); | |
| } | |
| return $ret; | |
| } | |
| /** | |
| * This method is only useful when testing Twig. Do not use it. | |
| */ | |
| public static function clearCache() | |
| { | |
| self::$cache = array(); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Interface implemented by all compiled templates. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| interface Twig_TemplateInterface | |
| { | |
| const ANY_CALL = 'any'; | |
| const ARRAY_CALL = 'array'; | |
| const METHOD_CALL = 'method'; | |
| /** | |
| * Renders the template with the given context and returns it as string. | |
| * | |
| * @param array $context An array of parameters to pass to the template | |
| * | |
| * @return string The rendered template | |
| */ | |
| public function render(array $context); | |
| /** | |
| * Displays the template with the given context. | |
| * | |
| * @param array $context An array of parameters to pass to the template | |
| * @param array $blocks An array of blocks to pass to the template | |
| */ | |
| public function display(array $context, array $blocks = array()); | |
| /** | |
| * Returns the bound environment for this template. | |
| * | |
| * @return Twig_Environment The current environment | |
| */ | |
| public function getEnvironment(); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2011 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_TempName extends Twig_Node_Expression | |
| { | |
| public function __construct($name, $lineno) | |
| { | |
| parent::__construct(array(), array('name' => $name), $lineno); | |
| } | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->raw('$_') | |
| ->raw($this->getAttribute('name')) | |
| ->raw('_') | |
| ; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| class Twig_Node_Expression_Test extends Twig_Node_Expression | |
| { | |
| public function __construct(Twig_NodeInterface $node, $name, Twig_NodeInterface $arguments = null, $lineno) | |
| { | |
| parent::__construct(array('node' => $node, 'arguments' => $arguments), array('name' => $name), $lineno); | |
| } | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $name = $this->getAttribute('name'); | |
| $testMap = $compiler->getEnvironment()->getTests(); | |
| if (!isset($testMap[$name])) { | |
| $message = sprintf('The test "%s" does not exist', $name); | |
| if ($alternatives = $compiler->getEnvironment()->computeAlternatives($name, array_keys($compiler->getEnvironment()->getTests()))) { | |
| $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); | |
| } | |
| throw new Twig_Error_Syntax($message, $this->getLine(), $compiler->getFilename()); | |
| } | |
| $name = $this->getAttribute('name'); | |
| $node = $this->getNode('node'); | |
| $compiler | |
| ->raw($testMap[$name]->compile().'(') | |
| ->subcompile($node) | |
| ; | |
| if (null !== $this->getNode('arguments')) { | |
| $compiler->raw(', '); | |
| $max = count($this->getNode('arguments')) - 1; | |
| foreach ($this->getNode('arguments') as $i => $arg) { | |
| $compiler->subcompile($arg); | |
| if ($i != $max) { | |
| $compiler->raw(', '); | |
| } | |
| } | |
| } | |
| $compiler->raw(')'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a template test. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| interface Twig_TestInterface | |
| { | |
| /** | |
| * Compiles a test. | |
| * | |
| * @return string The PHP code for the test | |
| */ | |
| public function compile(); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div class="control-group"> | |
| <label class="control-label" for="{{ field }}">{{ title }}</label> | |
| <div class="controls"> | |
| <input type="text" placeholder="{{ title }}..." name="{{ field }}" id="{{ field }}" value="{{ value | e }}" {% if required %}required="required"{% endif %}> | |
| </div> | |
| </div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a text node. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Node_Text extends Twig_Node implements Twig_NodeOutputInterface | |
| { | |
| public function __construct($data, $lineno) | |
| { | |
| parent::__construct(array(), array('data' => $data), $lineno); | |
| } | |
| /** | |
| * Compiles the node to PHP. | |
| * | |
| * @param Twig_Compiler A Twig_Compiler instance | |
| */ | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler | |
| ->addDebugInfo($this) | |
| ->write('echo ') | |
| ->string($this->getAttribute('data')) | |
| ->raw(";\n") | |
| ; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div class="control-group"> | |
| <label class="control-label" for="{{ field }}">{{ title }}</label> | |
| <div class="controls"> | |
| <textarea type="text" placeholder="{{ title }}..." name="{{ field }}" id="{{ field }}" {% if required %}required="required"{% endif %}>{{ value | e }}</textarea> | |
| </div> | |
| </div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a Token. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_Token | |
| { | |
| protected $value; | |
| protected $type; | |
| protected $lineno; | |
| const EOF_TYPE = -1; | |
| const TEXT_TYPE = 0; | |
| const BLOCK_START_TYPE = 1; | |
| const VAR_START_TYPE = 2; | |
| const BLOCK_END_TYPE = 3; | |
| const VAR_END_TYPE = 4; | |
| const NAME_TYPE = 5; | |
| const NUMBER_TYPE = 6; | |
| const STRING_TYPE = 7; | |
| const OPERATOR_TYPE = 8; | |
| const PUNCTUATION_TYPE = 9; | |
| const INTERPOLATION_START_TYPE = 10; | |
| const INTERPOLATION_END_TYPE = 11; | |
| /** | |
| * Constructor. | |
| * | |
| * @param integer $type The type of the token | |
| * @param string $value The token value | |
| * @param integer $lineno The line position in the source | |
| */ | |
| public function __construct($type, $value, $lineno) | |
| { | |
| $this->type = $type; | |
| $this->value = $value; | |
| $this->lineno = $lineno; | |
| } | |
| /** | |
| * Returns a string representation of the token. | |
| * | |
| * @return string A string representation of the token | |
| */ | |
| public function __toString() | |
| { | |
| return sprintf('%s(%s)', self::typeToString($this->type, true, $this->lineno), $this->value); | |
| } | |
| /** | |
| * Tests the current token for a type and/or a value. | |
| * | |
| * Parameters may be: | |
| * * just type | |
| * * type and value (or array of possible values) | |
| * * just value (or array of possible values) (NAME_TYPE is used as type) | |
| * | |
| * @param array|integer $type The type to test | |
| * @param array|string|null $values The token value | |
| * | |
| * @return Boolean | |
| */ | |
| public function test($type, $values = null) | |
| { | |
| if (null === $values && !is_int($type)) { | |
| $values = $type; | |
| $type = self::NAME_TYPE; | |
| } | |
| return ($this->type === $type) && ( | |
| null === $values || | |
| (is_array($values) && in_array($this->value, $values)) || | |
| $this->value == $values | |
| ); | |
| } | |
| /** | |
| * Gets the line. | |
| * | |
| * @return integer The source line | |
| */ | |
| public function getLine() | |
| { | |
| return $this->lineno; | |
| } | |
| /** | |
| * Gets the token type. | |
| * | |
| * @return integer The token type | |
| */ | |
| public function getType() | |
| { | |
| return $this->type; | |
| } | |
| /** | |
| * Gets the token value. | |
| * | |
| * @return string The token value | |
| */ | |
| public function getValue() | |
| { | |
| return $this->value; | |
| } | |
| /** | |
| * Returns the constant representation (internal) of a given type. | |
| * | |
| * @param integer $type The type as an integer | |
| * @param Boolean $short Whether to return a short representation or not | |
| * @param integer $line The code line | |
| * | |
| * @return string The string representation | |
| */ | |
| public static function typeToString($type, $short = false, $line = -1) | |
| { | |
| switch ($type) { | |
| case self::EOF_TYPE: | |
| $name = 'EOF_TYPE'; | |
| break; | |
| case self::TEXT_TYPE: | |
| $name = 'TEXT_TYPE'; | |
| break; | |
| case self::BLOCK_START_TYPE: | |
| $name = 'BLOCK_START_TYPE'; | |
| break; | |
| case self::VAR_START_TYPE: | |
| $name = 'VAR_START_TYPE'; | |
| break; | |
| case self::BLOCK_END_TYPE: | |
| $name = 'BLOCK_END_TYPE'; | |
| break; | |
| case self::VAR_END_TYPE: | |
| $name = 'VAR_END_TYPE'; | |
| break; | |
| case self::NAME_TYPE: | |
| $name = 'NAME_TYPE'; | |
| break; | |
| case self::NUMBER_TYPE: | |
| $name = 'NUMBER_TYPE'; | |
| break; | |
| case self::STRING_TYPE: | |
| $name = 'STRING_TYPE'; | |
| break; | |
| case self::OPERATOR_TYPE: | |
| $name = 'OPERATOR_TYPE'; | |
| break; | |
| case self::PUNCTUATION_TYPE: | |
| $name = 'PUNCTUATION_TYPE'; | |
| break; | |
| case self::INTERPOLATION_START_TYPE: | |
| $name = 'INTERPOLATION_START_TYPE'; | |
| break; | |
| case self::INTERPOLATION_END_TYPE: | |
| $name = 'INTERPOLATION_END_TYPE'; | |
| break; | |
| default: | |
| throw new LogicException(sprintf('Token of type "%s" does not exist.', $type)); | |
| } | |
| return $short ? $name : 'Twig_Token::'.$name; | |
| } | |
| /** | |
| * Returns the english representation of a given type. | |
| * | |
| * @param integer $type The type as an integer | |
| * @param integer $line The code line | |
| * | |
| * @return string The string representation | |
| */ | |
| public static function typeToEnglish($type, $line = -1) | |
| { | |
| switch ($type) { | |
| case self::EOF_TYPE: | |
| return 'end of template'; | |
| case self::TEXT_TYPE: | |
| return 'text'; | |
| case self::BLOCK_START_TYPE: | |
| return 'begin of statement block'; | |
| case self::VAR_START_TYPE: | |
| return 'begin of print statement'; | |
| case self::BLOCK_END_TYPE: | |
| return 'end of statement block'; | |
| case self::VAR_END_TYPE: | |
| return 'end of print statement'; | |
| case self::NAME_TYPE: | |
| return 'name'; | |
| case self::NUMBER_TYPE: | |
| return 'number'; | |
| case self::STRING_TYPE: | |
| return 'string'; | |
| case self::OPERATOR_TYPE: | |
| return 'operator'; | |
| case self::PUNCTUATION_TYPE: | |
| return 'punctuation'; | |
| case self::INTERPOLATION_START_TYPE: | |
| return 'begin of string interpolation'; | |
| case self::INTERPOLATION_END_TYPE: | |
| return 'end of string interpolation'; | |
| default: | |
| throw new LogicException(sprintf('Token of type "%s" does not exist.', $type)); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Base class for all token parsers. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| abstract class Twig_TokenParser implements Twig_TokenParserInterface | |
| { | |
| /** | |
| * @var Twig_Parser | |
| */ | |
| protected $parser; | |
| /** | |
| * Sets the parser associated with this token parser | |
| * | |
| * @param $parser A Twig_Parser instance | |
| */ | |
| public function setParser(Twig_Parser $parser) | |
| { | |
| $this->parser = $parser; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * (c) 2010 Arnaud Le Blanc | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Default implementation of a token parser broker. | |
| * | |
| * @package twig | |
| * @author Arnaud Le Blanc <arnaud.lb@gmail.com> | |
| */ | |
| class Twig_TokenParserBroker implements Twig_TokenParserBrokerInterface | |
| { | |
| protected $parser; | |
| protected $parsers = array(); | |
| protected $brokers = array(); | |
| /** | |
| * Constructor. | |
| * | |
| * @param array|Traversable $parsers A Traversable of Twig_TokenParserInterface instances | |
| * @param array|Traversable $brokers A Traversable of Twig_TokenParserBrokerInterface instances | |
| */ | |
| public function __construct($parsers = array(), $brokers = array()) | |
| { | |
| foreach ($parsers as $parser) { | |
| if (!$parser instanceof Twig_TokenParserInterface) { | |
| throw new LogicException('$parsers must a an array of Twig_TokenParserInterface'); | |
| } | |
| $this->parsers[$parser->getTag()] = $parser; | |
| } | |
| foreach ($brokers as $broker) { | |
| if (!$broker instanceof Twig_TokenParserBrokerInterface) { | |
| throw new LogicException('$brokers must a an array of Twig_TokenParserBrokerInterface'); | |
| } | |
| $this->brokers[] = $broker; | |
| } | |
| } | |
| /** | |
| * Adds a TokenParser. | |
| * | |
| * @param Twig_TokenParserInterface $parser A Twig_TokenParserInterface instance | |
| */ | |
| public function addTokenParser(Twig_TokenParserInterface $parser) | |
| { | |
| $this->parsers[$parser->getTag()] = $parser; | |
| } | |
| /** | |
| * Adds a TokenParserBroker. | |
| * | |
| * @param Twig_TokenParserBroker $broker A Twig_TokenParserBroker instance | |
| */ | |
| public function addTokenParserBroker(Twig_TokenParserBroker $broker) | |
| { | |
| $this->brokers[] = $broker; | |
| } | |
| /** | |
| * Gets a suitable TokenParser for a tag. | |
| * | |
| * First looks in parsers, then in brokers. | |
| * | |
| * @param string $tag A tag name | |
| * | |
| * @return null|Twig_TokenParserInterface A Twig_TokenParserInterface or null if no suitable TokenParser was found | |
| */ | |
| public function getTokenParser($tag) | |
| { | |
| if (isset($this->parsers[$tag])) { | |
| return $this->parsers[$tag]; | |
| } | |
| $broker = end($this->brokers); | |
| while (false !== $broker) { | |
| $parser = $broker->getTokenParser($tag); | |
| if (null !== $parser) { | |
| return $parser; | |
| } | |
| $broker = prev($this->brokers); | |
| } | |
| return null; | |
| } | |
| public function getParsers() | |
| { | |
| return $this->parsers; | |
| } | |
| public function getParser() | |
| { | |
| return $this->parser; | |
| } | |
| public function setParser(Twig_ParserInterface $parser) | |
| { | |
| $this->parser = $parser; | |
| foreach ($this->parsers as $tokenParser) { | |
| $tokenParser->setParser($parser); | |
| } | |
| foreach ($this->brokers as $broker) { | |
| $broker->setParser($parser); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * (c) 2010 Arnaud Le Blanc | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Interface implemented by token parser brokers. | |
| * | |
| * Token parser brokers allows to implement custom logic in the process of resolving a token parser for a given tag name. | |
| * | |
| * @package twig | |
| * @author Arnaud Le Blanc <arnaud.lb@gmail.com> | |
| */ | |
| interface Twig_TokenParserBrokerInterface | |
| { | |
| /** | |
| * Gets a TokenParser suitable for a tag. | |
| * | |
| * @param string $tag A tag name | |
| * | |
| * @return null|Twig_TokenParserInterface A Twig_TokenParserInterface or null if no suitable TokenParser was found | |
| */ | |
| public function getTokenParser($tag); | |
| /** | |
| * Calls Twig_TokenParserInterface::setParser on all parsers the implementation knows of. | |
| * | |
| * @param Twig_ParserInterface $parser A Twig_ParserInterface interface | |
| */ | |
| public function setParser(Twig_ParserInterface $parser); | |
| /** | |
| * Gets the Twig_ParserInterface. | |
| * | |
| * @return null|Twig_ParserInterface A Twig_ParserInterface instance or null | |
| */ | |
| public function getParser(); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2010 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Interface implemented by token parsers. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| interface Twig_TokenParserInterface | |
| { | |
| /** | |
| * Sets the parser associated with this token parser | |
| * | |
| * @param $parser A Twig_Parser instance | |
| */ | |
| public function setParser(Twig_Parser $parser); | |
| /** | |
| * Parses a token and returns a node. | |
| * | |
| * @param Twig_Token $token A Twig_Token instance | |
| * | |
| * @return Twig_NodeInterface A Twig_NodeInterface instance | |
| */ | |
| public function parse(Twig_Token $token); | |
| /** | |
| * Gets the tag name associated with this token parser. | |
| * | |
| * @return string The tag name | |
| */ | |
| public function getTag(); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Represents a token stream. | |
| * | |
| * @package twig | |
| * @author Fabien Potencier <fabien@symfony.com> | |
| */ | |
| class Twig_TokenStream | |
| { | |
| protected $tokens; | |
| protected $current; | |
| protected $filename; | |
| /** | |
| * Constructor. | |
| * | |
| * @param array $tokens An array of tokens | |
| * @param string $filename The name of the filename which tokens are associated with | |
| */ | |
| public function __construct(array $tokens, $filename = null) | |
| { | |
| $this->tokens = $tokens; | |
| $this->current = 0; | |
| $this->filename = $filename; | |
| } | |
| /** | |
| * Returns a string representation of the token stream. | |
| * | |
| * @return string | |
| */ | |
| public function __toString() | |
| { | |
| return implode("\n", $this->tokens); | |
| } | |
| public function injectTokens(array $tokens) | |
| { | |
| $this->tokens = array_merge(array_slice($this->tokens, 0, $this->current), $tokens, array_slice($this->tokens, $this->current)); | |
| } | |
| /** | |
| * Sets the pointer to the next token and returns the old one. | |
| * | |
| * @return Twig_Token | |
| */ | |
| public function next() | |
| { | |
| if (!isset($this->tokens[++$this->current])) { | |
| throw new Twig_Error_Syntax('Unexpected end of template', $this->token[$this->current - 1]->getLine(), $this->filename); | |
| } | |
| return $this->tokens[$this->current - 1]; | |
| } | |
| /** | |
| * Tests a token and returns it or throws a syntax error. | |
| * | |
| * @return Twig_Token | |
| */ | |
| public function expect($type, $value = null, $message = null) | |
| { | |
| $token = $this->tokens[$this->current]; | |
| if (!$token->test($type, $value)) { | |
| $line = $token->getLine(); | |
| throw new Twig_Error_Syntax(sprintf('%sUnexpected token "%s" of value "%s" ("%s" expected%s)', | |
| $message ? $message.'. ' : '', | |
| Twig_Token::typeToEnglish($token->getType(), $line), $token->getValue(), | |
| Twig_Token::typeToEnglish($type, $line), $value ? sprintf(' with value "%s"', $value) : ''), | |
| $line, | |
| $this->filename | |
| ); | |
| } | |
| $this->next(); | |
| return $token; | |
| } | |
| /** | |
| * Looks at the next token. | |
| * | |
| * @param integer $number | |
| * | |
| * @return Twig_Token | |
| */ | |
| public function look($number = 1) | |
| { | |
| if (!isset($this->tokens[$this->current + $number])) { | |
| throw new Twig_Error_Syntax('Unexpected end of template', $this->token[$this->current + $number - 1]->getLine(), $this->filename); | |
| } | |
| return $this->tokens[$this->current + $number]; | |
| } | |
| /** | |
| * Tests the current token | |
| * | |
| * @return bool | |
| */ | |
| public function test($primary, $secondary = null) | |
| { | |
| return $this->tokens[$this->current]->test($primary, $secondary); | |
| } | |
| /** | |
| * Checks if end of stream was reached | |
| * | |
| * @return bool | |
| */ | |
| public function isEOF() | |
| { | |
| return $this->tokens[$this->current]->getType() === Twig_Token::EOF_TYPE; | |
| } | |
| /** | |
| * Gets the current token | |
| * | |
| * @return Twig_Token | |
| */ | |
| public function getCurrent() | |
| { | |
| return $this->tokens[$this->current]; | |
| } | |
| /** | |
| * Gets the filename associated with this stream | |
| * | |
| * @return string | |
| */ | |
| public function getFilename() | |
| { | |
| return $this->filename; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2009 Fabien Potencier | |
| * (c) 2009 Armin Ronacher | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| abstract class Twig_Node_Expression_Unary extends Twig_Node_Expression | |
| { | |
| public function __construct(Twig_NodeInterface $node, $lineno) | |
| { | |
| parent::__construct(array('node' => $node), array(), $lineno); | |
| } | |
| public function compile(Twig_Compiler $compiler) | |
| { | |
| $compiler->raw('('); | |
| $this->operator($compiler); | |
| $compiler | |
| ->subcompile($this->getNode('node')) | |
| ->raw(')') | |
| ; | |
| } | |
| abstract public function operator(Twig_Compiler $compiler); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * This file is part of Twig. | |
| * | |
| * (c) 2011 Fabien Potencier | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| /** | |
| * Imports blocks defined in another template into the current template. | |
| * | |
| * <pre> | |
| * {% extends "base.html" %} | |
| * | |
| * {% use "blocks.html" %} | |
| * | |
| * {% block title %}{% endblock %} | |
| * {% block content %}{% endblock %} | |
| * </pre> | |
| * | |
| * @see http://www.twig-project.org/doc/templates.html#horizontal-reuse for details. | |
| */ | |
| class Twig_TokenParser_Use extends Twig_TokenParser | |
| { | |
| /** | |
| * Parses a token and returns a node. | |
| * | |
| * @param Twig_Token $token A Twig_Token instance | |
| * | |
| * @return Twig_NodeInterface A Twig_NodeInterface instance | |
| */ | |
| public function parse(Twig_Token $token) | |
| { | |
| $template = $this->parser->getExpressionParser()->parseExpression(); | |
| $stream = $this->parser->getStream(); | |
| if (!$template instanceof Twig_Node_Expression_Constant) { | |
| throw new Twig_Error_Syntax('The template references in a "use" statement must be a string.', $stream->getCurrent()->getLine(), $stream->getFilename()); | |
| } | |
| $targets = array(); | |
| if ($stream->test('with')) { | |
| $stream->next(); | |
| do { | |
| $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); | |
| $alias = $name; | |
| if ($stream->test('as')) { | |
| $stream->next(); | |
| $alias = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); | |
| } | |
| $targets[$name] = new Twig_Node_Expression_Constant($alias, -1); | |
| if (!$stream->test(Twig_Token::PUNCTUATION_TYPE, ',')) { | |
| break; | |
| } | |
| $stream->next(); | |
| } while (true); | |
| } | |
| $stream->expect(Twig_Token::BLOCK_END_TYPE); | |
| $this->parser->addTrait(new Twig_Node(array('template' => $template, 'targets' => new Twig_Node($targets)))); | |
| return null; | |
| } | |
| /** | |
| * Gets the tag name associated with this token parser. | |
| * | |
| * @return string The tag name | |
| */ | |
| public function getTag() | |
| { | |
| return 'use'; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment