From 23f5b504c024b2162ea29f3d4d04bcf85a80c554 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Wed, 1 May 2013 18:50:30 +0400 Subject: [PATCH 01/87] Twig: added path() function, exposed app and this in templates --- docs/view_renderers.md | 16 ++++++++++++++++ framework/renderers/TwigViewRenderer.php | 8 ++++++++ 2 files changed, 24 insertions(+) diff --git a/docs/view_renderers.md b/docs/view_renderers.md index a953c45..979cead 100644 --- a/docs/view_renderers.md +++ b/docs/view_renderers.md @@ -18,6 +18,7 @@ array( ), 'twig' => array( 'class' => 'yii\renderers\TwigViewRenderer', + 'twigPath' => '@app/vendors/Twig', ), // ... ), @@ -38,6 +39,21 @@ or `$this->renderPartial()` from your controller: echo $this->render('renderer.twig', array('username' => 'Alex')); ``` +### Additional functions + +Additionally to regular Twig syntax the following is available in Yii: + +```php +{{ post.title }} +``` + +path function calls `Html::url()` internally. + +### Additional variables + +- `app` = `\Yii::$app` +- `this` = current `View` object + Smarty ------ diff --git a/framework/renderers/TwigViewRenderer.php b/framework/renderers/TwigViewRenderer.php index b92998d..79faa9f 100644 --- a/framework/renderers/TwigViewRenderer.php +++ b/framework/renderers/TwigViewRenderer.php @@ -12,6 +12,7 @@ namespace yii\renderers; use Yii; use yii\base\View; use yii\base\ViewRenderer; +use yii\helpers\Html; /** * TwigViewRenderer allows you to use Twig templates in views. @@ -53,6 +54,12 @@ class TwigViewRenderer extends ViewRenderer $this->twig = new \Twig_Environment($loader, array_merge(array( 'cache' => Yii::getAlias($this->cachePath), ), $this->options)); + + $this->twig->addFunction('path', new \Twig_Function_Function(function($path, $args = array()){ + return Html::url(array_merge(array($path), $args)); + })); + + $this->twig->addGlobal('app', \Yii::$app); } /** @@ -69,6 +76,7 @@ class TwigViewRenderer extends ViewRenderer */ public function render($view, $file, $params) { + $this->twig->addGlobal('this', $view); return $this->twig->render(file_get_contents($file), $params); } } From ed8b5bd7a33a61882e002c3151aae123cdf35f5f Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Wed, 1 May 2013 19:23:45 +0400 Subject: [PATCH 02/87] Smarty: added path function and exposed $app and $this --- docs/view_renderers.md | 15 ++++++++++++++ framework/renderers/SmartyViewRenderer.php | 33 ++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/docs/view_renderers.md b/docs/view_renderers.md index 979cead..1d88d21 100644 --- a/docs/view_renderers.md +++ b/docs/view_renderers.md @@ -65,3 +65,18 @@ or `$this->renderPartial()` from your controller: ```php echo $this->render('renderer.tpl', array('username' => 'Alex')); ``` + +### Additional functions + +Additionally to regular Smarty syntax the following is available in Yii: + +```php +{$post.title} +``` + +path function calls `Html::url()` internally. + +### Additional variables + +- `$app` = `\Yii::$app` +- `$this` = current `View` object \ No newline at end of file diff --git a/framework/renderers/SmartyViewRenderer.php b/framework/renderers/SmartyViewRenderer.php index ab9125a..920f3c6 100644 --- a/framework/renderers/SmartyViewRenderer.php +++ b/framework/renderers/SmartyViewRenderer.php @@ -13,6 +13,7 @@ use Yii; use Smarty; use yii\base\View; use yii\base\ViewRenderer; +use yii\helpers\Html; /** * SmartyViewRenderer allows you to use Smarty templates in views. @@ -48,6 +49,34 @@ class SmartyViewRenderer extends ViewRenderer $this->smarty = new Smarty(); $this->smarty->setCompileDir(Yii::getAlias($this->compilePath)); $this->smarty->setCacheDir(Yii::getAlias($this->cachePath)); + + $this->smarty->registerPlugin('function', 'path', array($this, 'smarty_function_path')); + } + + /** + * Smarty template function to get a path for using in links + * + * Usage is the following: + * + * {path route='blog/view' alias=$post.alias user=$user.id} + * + * where route is Yii route and the rest of parameters are passed as is. + * + * @param $params + * @param \Smarty_Internal_Template $template + * + * @return string + */ + public function smarty_function_path($params, \Smarty_Internal_Template $template) + { + if(!isset($params['route'])) { + trigger_error("path: missing 'route' parameter"); + } + + array_unshift($params, $params['route']) ; + unset($params['route']); + + return Html::url($params); } /** @@ -67,6 +96,10 @@ class SmartyViewRenderer extends ViewRenderer $ext = pathinfo($file, PATHINFO_EXTENSION); /** @var \Smarty_Internal_Template $template */ $template = $this->smarty->createTemplate($file, null, null, $params, true); + + $template->assign('app', \Yii::$app); + $template->assign('this', $view); + return $template->fetch(); } } \ No newline at end of file From 8a07bce836301d7bf1faa8f8c6a83ea2a072ad65 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Wed, 1 May 2013 11:30:49 -0400 Subject: [PATCH 03/87] form wip --- framework/assets/yii.activeForm.js | 149 ++++++++++++++++++++----------------- framework/widgets/ActiveField.php | 5 +- 2 files changed, 83 insertions(+), 71 deletions(-) diff --git a/framework/assets/yii.activeForm.js b/framework/assets/yii.activeForm.js index a011650..12bbbf9 100644 --- a/framework/assets/yii.activeForm.js +++ b/framework/assets/yii.activeForm.js @@ -67,7 +67,7 @@ settings.validationUrl = $form.attr('action'); } $.each(attributes, function (i) { - this.value = getInputValue($form.find('#' + this.inputID)); + this.value = getInputValue($form.find(this.inputSelector)); attributes[i] = $.extend(settings, this); }); $form.data('yiiActiveForm', { @@ -77,6 +77,10 @@ bindAttributes(attributes); + /** + * Clean up error status when resetting the form. + * Note that neither $form.reset(...) nor $form.on('reset', ...) works. + */ $form.bind('reset', resetForm); if (settings.validateOnSubmit) { @@ -84,42 +88,7 @@ $form.data('submitObject', $(this)); }); var validated = false; - $form.submit(function () { - if (validated) { - validated = false; - return true; - } - if (settings.timer !== undefined) { - clearTimeout(settings.timer); - } - settings.submitting = true; - if (settings.beforeValidate === undefined || settings.beforeValidate($form)) { - $.fn.yiiactiveform.validate($form, function (data) { - var hasError = false; - $.each(settings.attributes, function () { - hasError = $.fn.yiiactiveform.updateInput(this, data, $form) || hasError; - }); - $.fn.yiiactiveform.updateSummary($form, data); - if (settings.afterValidate === undefined || settings.afterValidate($form, data, hasError)) { - if (!hasError) { - validated = true; - var $button = $form.data('submitObject') || $form.find(':submit:first'); - // TODO: if the submission is caused by "change" event, it will not work - if ($button.length) { - $button.click(); - } else { // no submit button in the form - $form.submit(); - } - return; - } - } - settings.submitting = false; - }); - } else { - settings.submitting = false; - } - return false; - }); + $form.submit(submitForm); } }); }, @@ -139,7 +108,8 @@ * @param $e jQuery the jQuery object of the input element * @return string the input value */ - var getInputValue = function ($e) { + var getInputValue = function ($input) { + // TBD var type, c = []; if (!$e.length) { @@ -159,19 +129,32 @@ } }; + var findInput = function ($form, attribute) { + var $e = $form.find(attribute.inputSelector); + if (!$e.length) { + return undefined; + } + if ($e[0].tagName.toLowerCase() === 'div') { + // checkbox list or radio list + return $e.find('input'); + } else { + return $e; + } + }; + var bindAttributes = function (attributes) { $.each(attributes, function (i, attribute) { if (this.validateOnChange) { - $form.find('#' + this.inputID).change(function () { + $form.find(this.inputSelector).change(function () { validateAttribute(attribute, false); }).blur(function () { - if (attribute.status !== 2 && attribute.status !== 3) { - validateAttribute(attribute, !attribute.status); - } - }); + if (attribute.status !== 2 && attribute.status !== 3) { + validateAttribute(attribute, !attribute.status); + } + }); } if (this.validateOnType) { - $form.find('#' + this.inputID).keyup(function () { + $form.find(this.inputSelector).keyup(function () { if (attribute.value !== getAFValue($(this))) { validateAttribute(attribute, false); } @@ -293,27 +276,61 @@ }, attribute.validationDelay); }; + var submitForm = function () { + if (validated) { + validated = false; + return true; + } + if (settings.timer !== undefined) { + clearTimeout(settings.timer); + } + settings.submitting = true; + if (settings.beforeValidate === undefined || settings.beforeValidate($form)) { + $.fn.yiiactiveform.validate($form, function (data) { + var hasError = false; + $.each(settings.attributes, function () { + hasError = $.fn.yiiactiveform.updateInput(this, data, $form) || hasError; + }); + $.fn.yiiactiveform.updateSummary($form, data); + if (settings.afterValidate === undefined || settings.afterValidate($form, data, hasError)) { + if (!hasError) { + validated = true; + var $button = $form.data('submitObject') || $form.find(':submit:first'); + // TODO: if the submission is caused by "change" event, it will not work + if ($button.length) { + $button.click(); + } else { // no submit button in the form + $form.submit(); + } + return; + } + } + settings.submitting = false; + }); + } else { + settings.submitting = false; + } + return false; + }; + var resetForm = function () { - /* - * In case of resetting the form we need to reset error messages - * NOTE1: $form.reset - does not exist - * NOTE2: $form.on('reset', ...) does not work - */ + var settings = $(this).data('yiiActiveForm').settings; + var attributes = $(this).data('yiiActiveForm').attributes; /* * because we bind directly to a form reset event, not to a reset button (that could or could not exist), * when this function is executed form elements values have not been reset yet, * because of that we use the setTimeout */ setTimeout(function () { - $.each(settings.attributes, function () { + $.each(attributes, function () { this.status = 0; var $error = $form.find('#' + this.errorID), - $container = $.fn.yiiactiveform.getInputContainer(this, $form); + $container = getInputContainer(this, $form); $container.removeClass( - this.validatingCssClass + ' ' + - this.errorCssClass + ' ' + - this.successCssClass + settings.validatingCssClass + ' ' + + settings.errorCssClass + ' ' + + settings.successCssClass ); $error.html('').hide(); @@ -321,20 +338,10 @@ /* * without the setTimeout() we would get here the current entered value before the reset instead of the reseted value */ - this.value = getAFValue($form.find('#' + this.inputID)); - }); - /* - * If the form is submited (non ajax) with errors, labels and input gets the class 'error' - */ - $form.find('label, input').each(function () { - $(this).removeClass(settings.errorCss); + this.value = getInputValue($form.find('#' + this.inputID)); }); $('#' + settings.summaryID).hide().find('ul').html(''); - //.. set to initial focus on reset - if (settings.focus !== undefined && !window.location.hash) { - $form.find(settings.focus).focus(); - } - }, 1); + }, 10); }; @@ -401,7 +408,7 @@ * @param messages array the json data obtained from the ajax validation request */ var updateSummary = function (form, messages) { - var settings = $(form).data('settings'), + var settings = $(form).data('yiiActiveForm'), content = ''; if (settings.summaryID === undefined) { return; @@ -418,4 +425,12 @@ $('#' + settings.summaryID).toggle(content !== '').find('ul').html(content); }; + var getSettings = function (form) { + return $(form).data('yiiActiveForm').settings; + }; + + var getAttributes = function (form) { + return $(form).data('yiiActiveForm').attributes; + }; + })(window.jQuery); \ No newline at end of file diff --git a/framework/widgets/ActiveField.php b/framework/widgets/ActiveField.php index b851800..bf3ea28 100644 --- a/framework/widgets/ActiveField.php +++ b/framework/widgets/ActiveField.php @@ -103,7 +103,7 @@ class ActiveField extends Component /** * Generates a tag that contains the first validation error of [[attribute]]. - * If there is no validation, the tag will be returned and styled as hidden. + * Note that even if there is no validation error, this method will still return an empty error tag. * @param array $options the tag options in terms of name-value pairs. If this is null, [[errorOptions]] will be used. * The options will be rendered as the attributes of the resulting tag. The values will be HTML-encoded * using [[encode()]]. If a value is null, the corresponding attribute will not be rendered. @@ -121,9 +121,6 @@ class ActiveField extends Component } $attribute = Html::getAttributeName($this->attribute); $error = $this->model->getFirstError($attribute); - if ($error === null) { - $options['style'] = isset($options['style']) ? rtrim($options['style'], ';') . '; display:none' : 'display:none'; - } $tag = isset($options['tag']) ? $options['tag'] : 'span'; unset($options['tag']); return Html::tag($tag, Html::encode($error), $options); From c486cf410f171fe7977ffbbca45140c80390e031 Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Wed, 1 May 2013 18:44:30 +0200 Subject: [PATCH 04/87] added missing init() method to Cache class --- framework/caching/Cache.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/framework/caching/Cache.php b/framework/caching/Cache.php index 70cf8cb..fb56d5e 100644 --- a/framework/caching/Cache.php +++ b/framework/caching/Cache.php @@ -71,6 +71,18 @@ abstract class Cache extends Component implements \ArrayAccess /** + * Initializes the application component. + * This method overrides the parent implementation by setting default cache key prefix. + */ + public function init() + { + parent::init(); + if ($this->keyPrefix === null) { + $this->keyPrefix = \Yii::$app->id; + } + } + + /** * Builds a normalized cache key from a given key. * * The generated key contains letters and digits only, and its length is no more than 32. From 5fd27b7cbbff43f05d81ab9e8ce2087a5b4214f3 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Wed, 1 May 2013 14:18:23 -0400 Subject: [PATCH 05/87] Added Json and JsonExpression. --- framework/assets/yii.activeForm.js | 22 +++--- framework/helpers/Json.php | 18 +++++ framework/helpers/JsonExpression.php | 45 +++++++++++++ framework/helpers/base/Json.php | 107 ++++++++++++++++++++++++++++++ tests/unit/framework/helpers/JsonTest.php | 60 +++++++++++++++++ 5 files changed, 242 insertions(+), 10 deletions(-) create mode 100644 framework/helpers/Json.php create mode 100644 framework/helpers/JsonExpression.php create mode 100644 framework/helpers/base/Json.php create mode 100644 tests/unit/framework/helpers/JsonTest.php diff --git a/framework/assets/yii.activeForm.js b/framework/assets/yii.activeForm.js index 12bbbf9..0834a14 100644 --- a/framework/assets/yii.activeForm.js +++ b/framework/assets/yii.activeForm.js @@ -23,6 +23,12 @@ }; var defaults = { + // the container CSS class representing the corresponding attribute has validation error + errorCssClass: 'error', + // the container CSS class representing the corresponding attribute passes validation + successCssClass: 'success', + // the container CSS class representing the corresponding attribute is being validated + validatingCssClass: 'validating', // whether it is waiting for ajax submission result submitting: false }; @@ -32,21 +38,17 @@ * Initializes the plugin. * @param attributes array attribute configurations. Each attribute may contain the following options: * - * - id: 'ModelClass_attribute', // the unique attribute ID - * - model: 'ModelClass', // the model class name - * - name: 'name', // attribute name - * - inputID: 'input-tag-id', - * - errorID: 'error-tag-id', - * - value: undefined, - * - status: 0, // 0: empty, not entered before, 1: validated, 2: pending validation, 3: validating + * - name: string, attribute name or expression (e.g. "[0]content" for tabular input) + * - container: string, the jQuery selector of the container of the input field + * - input: string, the jQuery selector of the input field + * - error: string, the jQuery selector of the error tag + * - value: string|array, the value of the input + * - status: integer, 0: empty, not entered before, 1: validated, 2: pending validation, 3: validating * - validationDelay: 200, * - validateOnChange: true, * - validateOnType: false, * - hideErrorMessage: false, * - inputContainer: undefined, - * - errorCssClass: 'error', - * - successCssClass: 'success', - * - validatingCssClass: 'validating', * - enableAjaxValidation: true, * - enableClientValidation: true, * - clientValidation: undefined, // function (value, messages, attribute) | client-side validation diff --git a/framework/helpers/Json.php b/framework/helpers/Json.php new file mode 100644 index 0000000..2a20f3c --- /dev/null +++ b/framework/helpers/Json.php @@ -0,0 +1,18 @@ + + * @since 2.0 + */ +class Json extends base\Json +{ + +} \ No newline at end of file diff --git a/framework/helpers/JsonExpression.php b/framework/helpers/JsonExpression.php new file mode 100644 index 0000000..eee57a1 --- /dev/null +++ b/framework/helpers/JsonExpression.php @@ -0,0 +1,45 @@ + + * @since 2.0 + */ +class JsonExpression extends Object +{ + /** + * @var string the JavaScript expression represented by this object + */ + public $expression; + + /** + * Constructor. + * @param string $expression the JavaScript expression represented by this object + * @param array $config additional configurations for this object + */ + public function __construct($expression, $config = array()) + { + $this->expression = $expression; + parent::__construct($config); + } + + /** + * The PHP magic function converting an object into a string. + * @return string the JavaScript expression. + */ + public function __toString() + { + return $this->expression; + } +} \ No newline at end of file diff --git a/framework/helpers/base/Json.php b/framework/helpers/base/Json.php new file mode 100644 index 0000000..d39b2b3 --- /dev/null +++ b/framework/helpers/base/Json.php @@ -0,0 +1,107 @@ + + * @since 2.0 + */ +class Json +{ + /** + * Encodes the given value into a JSON string. + * The method enhances `json_encode()` by supporting JavaScript expressions. + * In particular, the method will not encode a JavaScript expression that is + * represented in terms of a [[JsonExpression]] object. + * @param mixed $value the data to be encoded + * @param integer $options the encoding options. For more details please refer to + * [[http://www.php.net/manual/en/function.json-encode.php]] + * @return string the encoding result + */ + public static function encode($value, $options = 0) + { + $expressions = array(); + $value = static::processData($value, $expressions); + $json = json_encode($value, $options); + return $expressions === array() ? $json : strtr($json, $expressions); + } + + /** + * Decodes the given JSON string into a PHP data structure. + * @param string $json the JSON string to be decoded + * @param boolean $asArray whether to return objects in terms of associative arrays. + * @return mixed the PHP data + * @throws InvalidParamException if there is any decoding error + */ + public static function decode($json, $asArray = true) + { + if (is_array($json)) { + throw new InvalidParamException('Invalid JSON data.'); + } + $decode = json_decode((string)$json, $asArray); + switch (json_last_error()) { + case JSON_ERROR_NONE: + break; + case JSON_ERROR_DEPTH: + throw new InvalidParamException('The maximum stack depth has been exceeded.'); + case JSON_ERROR_CTRL_CHAR: + throw new InvalidParamException('Control character error, possibly incorrectly encoded.'); + case JSON_ERROR_SYNTAX: + throw new InvalidParamException('Syntax error.'); + case JSON_ERROR_STATE_MISMATCH: + throw new InvalidParamException('Invalid or malformed JSON.'); + case JSON_ERROR_UTF8: + throw new InvalidParamException('Malformed UTF-8 characters, possibly incorrectly encoded.'); + default: + throw new InvalidParamException('Unknown JSON decoding error.'); + } + + return $decode; + } + + /** + * Pre-processes the data before sending it to `json_encode()`. + * @param mixed $data the data to be processed + * @param array $expressions collection of JavaScript expressions + * @return mixed the processed data + */ + protected static function processData($data, &$expressions) + { + if (is_array($data)) { + foreach ($data as $key => $value) { + if (is_array($value) || is_object($value)) { + $data[$key] = static::processData($value, $expressions); + } + } + return $data; + } elseif (is_object($data)) { + if ($data instanceof JsonExpression) { + $token = '!{[' . count($expressions) . ']}!'; + $expressions['"' . $token . '"'] = $data->expression; + return $token; + } + $result = array(); + foreach ($data as $key => $value) { + if (is_array($value) || is_object($value)) { + $result[$key] = static::processData($value, $expressions); + } else { + $result[$key] = $value; + } + } + return $result; + } else { + return $data; + } + } +} \ No newline at end of file diff --git a/tests/unit/framework/helpers/JsonTest.php b/tests/unit/framework/helpers/JsonTest.php new file mode 100644 index 0000000..3459a54 --- /dev/null +++ b/tests/unit/framework/helpers/JsonTest.php @@ -0,0 +1,60 @@ +assertSame('"1"', Json::encode($data)); + + // simple array encoding + $data = array(1, 2); + $this->assertSame('[1,2]', Json::encode($data)); + $data = array('a' => 1, 'b' => 2); + $this->assertSame('{"a":1,"b":2}', Json::encode($data)); + + // simple object encoding + $data = new \stdClass(); + $data->a = 1; $data->b = 2; + $this->assertSame('{"a":1,"b":2}', Json::encode($data)); + + // expression encoding + $expression = 'function () {}'; + $data = new JsonExpression($expression); + $this->assertSame($expression, Json::encode($data)); + + // complex data + $expression1 = 'function (a) {}'; + $expression2 = 'function (b) {}'; + $data = array( + 'a' => array( + 1, new JsonExpression($expression1) + ), + 'b' => new JsonExpression($expression2), + ); + $this->assertSame("{\"a\":[1,$expression1],\"b\":$expression2}", Json::encode($data)); + } + + public function testDecode() + { + // basic data decoding + $json = '"1"'; + $this->assertSame('1', Json::decode($json)); + + // array decoding + $json = '{"a":1,"b":2}'; + $this->assertSame(array('a' => 1, 'b' => 2), Json::decode($json)); + + // exception + $json = '{"a":1,"b":2'; + $this->setExpectedException('yii\base\InvalidParamException'); + Json::decode($json); + } +} \ No newline at end of file From 53a7b826720f921ab836cc2a5b94b56ac25ffd7d Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Wed, 1 May 2013 14:46:24 -0400 Subject: [PATCH 06/87] Renamed JsonExpression to JsExpression. --- framework/helpers/JsExpression.php | 45 +++++++++++++++++++++++++++++++ framework/helpers/JsonExpression.php | 45 ------------------------------- framework/helpers/base/Json.php | 6 ++--- tests/unit/framework/helpers/JsonTest.php | 8 +++--- 4 files changed, 52 insertions(+), 52 deletions(-) create mode 100644 framework/helpers/JsExpression.php delete mode 100644 framework/helpers/JsonExpression.php diff --git a/framework/helpers/JsExpression.php b/framework/helpers/JsExpression.php new file mode 100644 index 0000000..0054b64 --- /dev/null +++ b/framework/helpers/JsExpression.php @@ -0,0 +1,45 @@ + + * @since 2.0 + */ +class JsExpression extends Object +{ + /** + * @var string the JavaScript expression represented by this object + */ + public $expression; + + /** + * Constructor. + * @param string $expression the JavaScript expression represented by this object + * @param array $config additional configurations for this object + */ + public function __construct($expression, $config = array()) + { + $this->expression = $expression; + parent::__construct($config); + } + + /** + * The PHP magic function converting an object into a string. + * @return string the JavaScript expression. + */ + public function __toString() + { + return $this->expression; + } +} \ No newline at end of file diff --git a/framework/helpers/JsonExpression.php b/framework/helpers/JsonExpression.php deleted file mode 100644 index eee57a1..0000000 --- a/framework/helpers/JsonExpression.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @since 2.0 - */ -class JsonExpression extends Object -{ - /** - * @var string the JavaScript expression represented by this object - */ - public $expression; - - /** - * Constructor. - * @param string $expression the JavaScript expression represented by this object - * @param array $config additional configurations for this object - */ - public function __construct($expression, $config = array()) - { - $this->expression = $expression; - parent::__construct($config); - } - - /** - * The PHP magic function converting an object into a string. - * @return string the JavaScript expression. - */ - public function __toString() - { - return $this->expression; - } -} \ No newline at end of file diff --git a/framework/helpers/base/Json.php b/framework/helpers/base/Json.php index d39b2b3..1deb5c2 100644 --- a/framework/helpers/base/Json.php +++ b/framework/helpers/base/Json.php @@ -8,7 +8,7 @@ namespace yii\helpers\base; use yii\base\InvalidParamException; -use yii\helpers\JsonExpression; +use yii\helpers\JsExpression; /** * Json is a helper class providing JSON data encoding and decoding. @@ -23,7 +23,7 @@ class Json * Encodes the given value into a JSON string. * The method enhances `json_encode()` by supporting JavaScript expressions. * In particular, the method will not encode a JavaScript expression that is - * represented in terms of a [[JsonExpression]] object. + * represented in terms of a [[JsExpression]] object. * @param mixed $value the data to be encoded * @param integer $options the encoding options. For more details please refer to * [[http://www.php.net/manual/en/function.json-encode.php]] @@ -86,7 +86,7 @@ class Json } return $data; } elseif (is_object($data)) { - if ($data instanceof JsonExpression) { + if ($data instanceof JsExpression) { $token = '!{[' . count($expressions) . ']}!'; $expressions['"' . $token . '"'] = $data->expression; return $token; diff --git a/tests/unit/framework/helpers/JsonTest.php b/tests/unit/framework/helpers/JsonTest.php index 3459a54..0e06eb3 100644 --- a/tests/unit/framework/helpers/JsonTest.php +++ b/tests/unit/framework/helpers/JsonTest.php @@ -4,7 +4,7 @@ namespace yiiunit\framework\helpers; use yii\helpers\Json; -use yii\helpers\JsonExpression; +use yii\helpers\JsExpression; class JsonTest extends \yii\test\TestCase { @@ -27,7 +27,7 @@ class JsonTest extends \yii\test\TestCase // expression encoding $expression = 'function () {}'; - $data = new JsonExpression($expression); + $data = new JsExpression($expression); $this->assertSame($expression, Json::encode($data)); // complex data @@ -35,9 +35,9 @@ class JsonTest extends \yii\test\TestCase $expression2 = 'function (b) {}'; $data = array( 'a' => array( - 1, new JsonExpression($expression1) + 1, new JsExpression($expression1) ), - 'b' => new JsonExpression($expression2), + 'b' => new JsExpression($expression2), ); $this->assertSame("{\"a\":[1,$expression1],\"b\":$expression2}", Json::encode($data)); } From e7c1777a9f69bac0385390abb76fbbf0c67f8480 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Wed, 1 May 2013 16:05:03 -0400 Subject: [PATCH 07/87] form wip --- framework/assets/yii.activeForm.js | 35 +++++++++++++++++-------- framework/assets/yii.validation.js | 30 ++++++++++++++++++++-- framework/validators/BooleanValidator.php | 30 ++++++++++++++-------- framework/validators/RequiredValidator.php | 41 +++++++++++++----------------- 4 files changed, 90 insertions(+), 46 deletions(-) diff --git a/framework/assets/yii.activeForm.js b/framework/assets/yii.activeForm.js index 0834a14..f99c62b 100644 --- a/framework/assets/yii.activeForm.js +++ b/framework/assets/yii.activeForm.js @@ -23,6 +23,16 @@ }; var defaults = { + enableAjaxValidation: false, + enableClientValidation: true, + // the URL for performing AJAX validation. If not set, it will use the the form's action + validationUrl: undefined, + // number of milliseconds of validation delay. This is used when validateOnType is true. + validationDelay: 200, + // whether to perform validation when a change is detected on the input. + validateOnChange: true, + // whether to perform validation when the user is typing. + validateOnType: false, // the container CSS class representing the corresponding attribute has validation error errorCssClass: 'error', // the container CSS class representing the corresponding attribute passes validation @@ -43,17 +53,22 @@ * - input: string, the jQuery selector of the input field * - error: string, the jQuery selector of the error tag * - value: string|array, the value of the input + * - validationDelay: integer, number of milliseconds of validation delay. + * This is used when validateOnType is true. If not set, it will take the value + * of the corresponding global setting. + * - validateOnChange: boolean, whether to perform validation when a change is detected on the input. + * If not set, it will take the value of the corresponding global setting. + * - validateOnType: boolean, defaults to false, whether to perform validation when the user is typing. + * If not set, it will take the value of the corresponding global setting. + * - enableAjaxValidation: boolean, whether to enable AJAX-based validation. + * If not set, it will take the value of the corresponding global setting. + * - enableClientValidation: boolean, whether to enable client-side validation. + * If not set, it will take the value of the corresponding global setting. + * - validate: function (attribute, value, messages), the client-side validation function. + * - beforeValidate: function ($form, attribute), callback called before validating an attribute. If it + * returns false, the validation will be cancelled. + * - afterValidate: function ($form, attribute, data, hasError), callback called after validating an attribute. * - status: integer, 0: empty, not entered before, 1: validated, 2: pending validation, 3: validating - * - validationDelay: 200, - * - validateOnChange: true, - * - validateOnType: false, - * - hideErrorMessage: false, - * - inputContainer: undefined, - * - enableAjaxValidation: true, - * - enableClientValidation: true, - * - clientValidation: undefined, // function (value, messages, attribute) | client-side validation - * - beforeValidateAttribute: undefined, // function (form, attribute) | boolean - * - afterValidateAttribute: undefined, // function (form, attribute, data, hasError) * * @param options object the configuration for the plugin. The following options can be set: */ diff --git a/framework/assets/yii.validation.js b/framework/assets/yii.validation.js index acfc261..83e0497 100644 --- a/framework/assets/yii.validation.js +++ b/framework/assets/yii.validation.js @@ -11,7 +11,33 @@ */ yii.validation = (function ($) { - var pub = { + var isEmpty = function (value, trim) { + return value === null || value === undefined || value == [] + || value === '' || trim && $.trim(value) === ''; + }; + + return { + required: function (value, messages, options) { + var valid = false; + if (options.requiredValue === undefined) { + if (options.strict && value !== undefined || !options.strict && !isEmpty(value, true)) { + valid = true; + } + } else if (!options.strict && value == options.requiredValue || options.strict && value === options.requiredValue) { + valid = true; + } + + valid || messages.push(options.message); + }, + + boolean: function (value, messages, options) { + if (options.skipOnEmpty && isEmpty(value)) { + return; + } + var valid = !options.strict && (value == options.trueValue || value == options.falseValue) + || options.strict && (value === options.trueValue || value === options.falseValue); + + valid || messages.push(options.message); + } }; - return pub; })(jQuery); diff --git a/framework/validators/BooleanValidator.php b/framework/validators/BooleanValidator.php index e336cf5..dd72c67 100644 --- a/framework/validators/BooleanValidator.php +++ b/framework/validators/BooleanValidator.php @@ -8,6 +8,7 @@ namespace yii\validators; use Yii; +use yii\helpers\Html; /** * BooleanValidator checks if the attribute value is a boolean value. @@ -82,16 +83,23 @@ class BooleanValidator extends Validator */ public function clientValidateAttribute($object, $attribute) { - $message = strtr($this->message, array( - '{attribute}' => $object->getAttributeLabel($attribute), - '{value}' => $object->$attribute, - '{true}' => $this->trueValue, - '{false}' => $this->falseValue, - )); - return " -if(" . ($this->skipOnEmpty ? "$.trim(value)!='' && " : '') . "value!=" . json_encode($this->trueValue) . " && value!=" . json_encode($this->falseValue) . ") { - messages.push(" . json_encode($message) . "); -} -"; + $options['message'] = array( + 'trueValue' => $this->trueValue, + 'falseValue' => $this->falseValue, + 'message' => Html::encode(strtr($this->message, array( + '{attribute}' => $object->getAttributeLabel($attribute), + '{value}' => $object->$attribute, + '{true}' => $this->trueValue, + '{false}' => $this->falseValue, + ))), + ); + if ($this->skipOnEmpty) { + $options['skipOnEmpty'] = 1; + } + if ($this->strict) { + $options['strict'] = 1; + } + + return 'yii.validation.boolean(value, messages, ' . json_encode($options) . ');'; } } diff --git a/framework/validators/RequiredValidator.php b/framework/validators/RequiredValidator.php index f4746e6..7202ec3 100644 --- a/framework/validators/RequiredValidator.php +++ b/framework/validators/RequiredValidator.php @@ -8,6 +8,7 @@ namespace yii\validators; use Yii; +use yii\helpers\Html; /** * RequiredValidator validates that the specified attribute does not have null or empty value. @@ -60,13 +61,10 @@ class RequiredValidator extends Validator */ public function validateAttribute($object, $attribute) { - $value = $object->$attribute; - if ($this->requiredValue === null) { - if ($this->strict && $value === null || !$this->strict && $this->isEmpty($value, true)) { + if (!$this->validateValue($object->$attribute)) { + if ($this->requiredValue === null) { $this->addError($object, $attribute, $this->message); - } - } else { - if (!$this->strict && $value != $this->requiredValue || $this->strict && $value !== $this->requiredValue) { + } else { $this->addError($object, $attribute, $this->message, array( '{requiredValue}' => $this->requiredValue, )); @@ -99,27 +97,24 @@ class RequiredValidator extends Validator */ public function clientValidateAttribute($object, $attribute) { + $options = array(); if ($this->requiredValue !== null) { - $message = strtr($this->message, array( - '{attribute}' => $object->getAttributeLabel($attribute), - '{value}' => $object->$attribute, + $options['message'] = strtr($this->message, array( '{requiredValue}' => $this->requiredValue, )); - return " -if (value != " . json_encode($this->requiredValue) . ") { - messages.push(" . json_encode($message) . "); -} -"; + $options['requiredValue'] = $this->requiredValue; } else { - $message = strtr($this->message, array( - '{attribute}' => $object->getAttributeLabel($attribute), - '{value}' => $object->$attribute, - )); - return " -if($.trim(value) == '') { - messages.push(" . json_encode($message) . "); -} -"; + $options['message'] = $this->message; + } + if ($this->strict) { + $options['strict'] = 1; } + + $options['message'] = Html::encode(strtr($options['message'], array( + '{attribute}' => $object->getAttributeLabel($attribute), + '{value}' => $object->$attribute, + ))); + + return 'yii.validation.required(value, messages, ' . json_encode($options) . ');'; } } From b869f4e72ebd3dbdd70d299872a77e60614bc109 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Wed, 1 May 2013 16:15:30 -0400 Subject: [PATCH 08/87] form wip --- framework/assets/yii.activeForm.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/framework/assets/yii.activeForm.js b/framework/assets/yii.activeForm.js index f99c62b..9072c50 100644 --- a/framework/assets/yii.activeForm.js +++ b/framework/assets/yii.activeForm.js @@ -92,7 +92,7 @@ attributes: attributes }); - bindAttributes(attributes); + bindAttributes($form, attributes); /** * Clean up error status when resetting the form. @@ -101,10 +101,9 @@ $form.bind('reset', resetForm); if (settings.validateOnSubmit) { - $form.on('mouseup keyup', ':submit', function () { + $form.on('mouseup.yiiActiveForm keyup.yiiActiveForm', ':submit', function () { $form.data('submitObject', $(this)); }); - var validated = false; $form.submit(submitForm); } }); @@ -159,10 +158,11 @@ } }; - var bindAttributes = function (attributes) { + var bindAttributes = function ($form, attributes) { $.each(attributes, function (i, attribute) { - if (this.validateOnChange) { - $form.find(this.inputSelector).change(function () { + var $input = findInput($form, attribute); + if (attribute.validateOnChange) { + $input.change(function () { validateAttribute(attribute, false); }).blur(function () { if (attribute.status !== 2 && attribute.status !== 3) { @@ -170,9 +170,9 @@ } }); } - if (this.validateOnType) { - $form.find(this.inputSelector).keyup(function () { - if (attribute.value !== getAFValue($(this))) { + if (attribute.validateOnType) { + $input.keyup(function () { + if (attribute.value !== getInputValue($input)) { validateAttribute(attribute, false); } }); From b4925d78db28fdf9b51b2e75fe4dc6d9a01191ab Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Wed, 1 May 2013 23:48:33 +0200 Subject: [PATCH 09/87] better documentation for php expressions related to issue yiisoft/yii#1921 Explain what a php expression is an refer to the php manual for more details. --- framework/caching/ExpressionDependency.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/framework/caching/ExpressionDependency.php b/framework/caching/ExpressionDependency.php index e13c962..303ccdc 100644 --- a/framework/caching/ExpressionDependency.php +++ b/framework/caching/ExpressionDependency.php @@ -14,13 +14,18 @@ namespace yii\caching; * The dependency is reported as unchanged if and only if the result of the expression is * the same as the one evaluated when storing the data to cache. * + * A PHP expression can be any PHP code that has a value. To learn more about what an expression is, + * please refer to the [php manual](http://www.php.net/manual/en/language.expressions.php). + * * @author Qiang Xue * @since 2.0 */ class ExpressionDependency extends Dependency { /** - * @var string the PHP expression whose result is used to determine the dependency. + * @var string the string representation of a PHP expression whose result is used to determine the dependency. + * A PHP expression can be any PHP code that has a value. To learn more about what an expression is, + * please refer to the [php manual](http://www.php.net/manual/en/language.expressions.php). */ public $expression; From 86330471fe9c51c03bdb057b4dc103d13d4079f3 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Thu, 2 May 2013 00:04:38 -0400 Subject: [PATCH 10/87] form wip --- framework/assets/yii.activeForm.js | 378 ++++++++++++++++--------------------- framework/validators/Validator.php | 7 - framework/widgets/ActiveField.php | 31 ++- framework/widgets/ActiveForm.php | 42 +++-- 4 files changed, 220 insertions(+), 238 deletions(-) diff --git a/framework/assets/yii.activeForm.js b/framework/assets/yii.activeForm.js index 9072c50..e5df863 100644 --- a/framework/assets/yii.activeForm.js +++ b/framework/assets/yii.activeForm.js @@ -23,9 +23,11 @@ }; var defaults = { - enableAjaxValidation: false, + // whether to enable client-side (JavaScript) validation enableClientValidation: true, - // the URL for performing AJAX validation. If not set, it will use the the form's action + // whether to enable AJAX-based validation + enableAjaxValidation: false, + // the URL for performing AJAX-based validation. If not set, it will use the the form's action validationUrl: undefined, // number of milliseconds of validation delay. This is used when validateOnType is true. validationDelay: 200, @@ -33,14 +35,20 @@ validateOnChange: true, // whether to perform validation when the user is typing. validateOnType: false, + // whether to perform validation before submitting the form. + validateOnSubmit: true, // the container CSS class representing the corresponding attribute has validation error errorCssClass: 'error', // the container CSS class representing the corresponding attribute passes validation successCssClass: 'success', // the container CSS class representing the corresponding attribute is being validated validatingCssClass: 'validating', - // whether it is waiting for ajax submission result - submitting: false + // a callback that is called before validating any attribute + beforeValidate: undefined, + // a callback that is called after validating any attribute + afterValidate: undefined, + // the GET parameter name indicating an AJAX-based validation + ajaxVar: 'ajax' }; var methods = { @@ -53,9 +61,6 @@ * - input: string, the jQuery selector of the input field * - error: string, the jQuery selector of the error tag * - value: string|array, the value of the input - * - validationDelay: integer, number of milliseconds of validation delay. - * This is used when validateOnType is true. If not set, it will take the value - * of the corresponding global setting. * - validateOnChange: boolean, whether to perform validation when a change is detected on the input. * If not set, it will take the value of the corresponding global setting. * - validateOnType: boolean, defaults to false, whether to perform validation when the user is typing. @@ -84,27 +89,33 @@ settings.validationUrl = $form.attr('action'); } $.each(attributes, function (i) { - this.value = getInputValue($form.find(this.inputSelector)); - attributes[i] = $.extend(settings, this); + attributes[i] = $.extend({ + validateOnChange: settings.validateOnChange, + validateOnType: settings.validateOnType, + enableAjaxValidation: settings.enableAjaxValidation, + enableClientValidation: settings.enableClientValidation, + value: getValue($form, this) + }, this); }); $form.data('yiiActiveForm', { settings: settings, - attributes: attributes + attributes: attributes, + submitting: false }); bindAttributes($form, attributes); /** - * Clean up error status when resetting the form. - * Note that neither $form.reset(...) nor $form.on('reset', ...) works. + * Clean up error status when the form is reset. + * Note that $form.on('reset', ...) does work because the "reset" event does not bubble on IE. */ - $form.bind('reset', resetForm); + $form.bind('reset.yiiActiveForm', resetForm); if (settings.validateOnSubmit) { $form.on('mouseup.yiiActiveForm keyup.yiiActiveForm', ':submit', function () { - $form.data('submitObject', $(this)); + $form.data('yiiActiveForm').submitObject = $(this); }); - $form.submit(submitForm); + $form.on('submit', submitForm); } }); }, @@ -117,44 +128,23 @@ } }; - /** - * Returns the value of the specified input element. - * This method will perform additional checks to get proper values - * for checkbox, radio, checkbox list and radio list. - * @param $e jQuery the jQuery object of the input element - * @return string the input value - */ - var getInputValue = function ($input) { - // TBD - var type, - c = []; - if (!$e.length) { - return undefined; - } - if ($e[0].tagName.toLowerCase() === 'div') { - $e.find(':checked').each(function () { - c.push(this.value); - }); - return c.join(','); - } - type = $e.attr('type'); + var getValue = function ($form, attribute) { + var $input = findInput($form, attribute); + var type = $input.attr('type'); if (type === 'checkbox' || type === 'radio') { - return $e.filter(':checked').val(); + return $input.filter(':checked').val(); } else { - return $e.val(); + return $input.val(); } }; var findInput = function ($form, attribute) { - var $e = $form.find(attribute.inputSelector); - if (!$e.length) { - return undefined; - } - if ($e[0].tagName.toLowerCase() === 'div') { + var $input = $form.find(attribute.input); + if ($input.length && $input[0].tagName.toLowerCase() === 'div') { // checkbox list or radio list - return $e.find('input'); + return $input.find('input'); } else { - return $e; + return $input; } }; @@ -162,24 +152,69 @@ $.each(attributes, function (i, attribute) { var $input = findInput($form, attribute); if (attribute.validateOnChange) { - $input.change(function () { - validateAttribute(attribute, false); - }).blur(function () { - if (attribute.status !== 2 && attribute.status !== 3) { - validateAttribute(attribute, !attribute.status); + $input.on('change.yiiActiveForm', function () { + validateAttribute($form, attribute, false); + }).on('blur.yiiActiveForm', function () { + if (attribute.status == 0 || attribute.status == 1) { + validateAttribute($form, attribute, !attribute.status); } }); } if (attribute.validateOnType) { - $input.keyup(function () { - if (attribute.value !== getInputValue($input)) { - validateAttribute(attribute, false); + $input.on('keyup.yiiActiveForm', function () { + if (attribute.value !== getValue($form, attribute)) { + validateAttribute($form, attribute, false); } }); } }); }; + var validateAttribute = function ($form, attribute, forceValidate) { + var data = $form.data('yiiActiveForm'); + + if (forceValidate) { + attribute.status = 2; + } + $.each(data.attributes, function () { + if (this.value !== getValue($form, this)) { + this.status = 2; + forceValidate = true; + } + }); + if (!forceValidate) { + return; + } + + if (data.settings.timer !== undefined) { + clearTimeout(data.settings.timer); + } + data.settings.timer = setTimeout(function () { + if (data.submitting || $form.is(':hidden')) { + return; + } + if (!attribute.beforeValidate || attribute.beforeValidate($form, attribute)) { + $.each(data.attributes, function () { + if (this.status === 2) { + this.status = 3; + $form.find(this.container).addClass(data.settings.validatingCssClass); + } + }); + validateForm($form, function (messages) { + var hasError = false; + $.each(data.attributes, function () { + if (this.status === 2 || this.status === 3) { + hasError = updateInput($form, this, messages) || hasError; + } + }); + if (attribute.afterValidate) { + attribute.afterValidate($form, attribute, messages, hasError); + } + }); + } + }, data.settings.validationDelay); + }; + /** * Performs the ajax validation request. * This method is invoked internally to trigger the ajax validation. @@ -187,28 +222,26 @@ * @param successCallback function the function to be invoked if the ajax request succeeds * @param errorCallback function the function to be invoked if the ajax request fails */ - var validateForm = function (form, successCallback, errorCallback) { - var $form = $(form), - settings = $form.data('settings'), + var validateForm = function ($form, successCallback, errorCallback) { + var data = $form.data('yiiActiveForm'), needAjaxValidation = false, messages = {}; - $.each(settings.attributes, function () { - var value, - msg = []; - if (this.clientValidation !== undefined && (settings.submitting || this.status === 2 || this.status === 3)) { - value = getInputValue($form.find('#' + this.inputID)); - this.clientValidation(value, msg, this); + + $.each(data.attributes, function () { + var msg = []; + if (this.validate && (data.submitting || this.status === 2 || this.status === 3)) { + this.validate(this, getValue($form, this), msg); if (msg.length) { - messages[this.id] = msg; + messages[this.name] = msg; } } - if (this.enableAjaxValidation && !msg.length && (settings.submitting || this.status === 2 || this.status === 3)) { + if (this.enableAjaxValidation && !msg.length && (data.submitting || this.status === 2 || this.status === 3)) { needAjaxValidation = true; } }); - if (!needAjaxValidation || settings.submitting && !$.isEmptyObject(messages)) { - if (settings.submitting) { + if (!needAjaxValidation || data.submitting && !$.isEmptyObject(messages)) { + if (data.submitting) { // delay callback so that the form can be submitted without problem setTimeout(function () { successCallback(messages); @@ -219,22 +252,22 @@ return; } - var $button = $form.data('submitObject'), - extData = '&' + settings.ajaxVar + '=' + $form.attr('id'); - if ($button && $button.length) { + var $button = data.submitObject, + extData = '&' + data.settings.ajaxVar + '=' + $form.attr('id'); + if ($button && $button.length && $button.attr('name')) { extData += '&' + $button.attr('name') + '=' + $button.attr('value'); } $.ajax({ - url: settings.validationUrl, + url: data.settings.validationUrl, type: $form.attr('method'), data: $form.serialize() + extData, dataType: 'json', success: function (data) { if (data !== null && typeof data === 'object') { - $.each(settings.attributes, function () { + $.each(data.attributes, function () { if (!this.enableAjaxValidation) { - delete data[this.id]; + delete data[this.name]; } }); successCallback($.extend({}, messages, data)); @@ -242,138 +275,75 @@ successCallback(messages); } }, - error: function () { - if (errorCallback !== undefined) { - errorCallback(); - } - } + error: errorCallback }); }; - var validateAttribute = function (attribute, forceValidate) { - if (forceValidate) { - attribute.status = 2; - } - $.each(attributes, function () { - if (this.value !== getInputValue($form.find('#' + this.inputID))) { - this.status = 2; - forceValidate = true; - } - }); - if (!forceValidate) { - return; - } - - if (settings.timer !== undefined) { - clearTimeout(settings.timer); - } - settings.timer = setTimeout(function () { - if (settings.submitting || $form.is(':hidden')) { - return; - } - if (attribute.beforeValidateAttribute === undefined || attribute.beforeValidateAttribute($form, attribute)) { - $.each(settings.attributes, function () { - if (this.status === 2) { - this.status = 3; - $.fn.yiiactiveform.getInputContainer(this, $form).addClass(this.validatingCssClass); - } - }); - $.fn.yiiactiveform.validate($form, function (data) { - var hasError = false; - $.each(settings.attributes, function () { - if (this.status === 2 || this.status === 3) { - hasError = $.fn.yiiactiveform.updateInput(this, data, $form) || hasError; - } - }); - if (attribute.afterValidateAttribute !== undefined) { - attribute.afterValidateAttribute($form, attribute, data, hasError); - } - }); - } - }, attribute.validationDelay); - }; - + var validated = false; var submitForm = function () { + var $form = $(this), + data = $form.data('yiiActiveForm'); if (validated) { validated = false; return true; } - if (settings.timer !== undefined) { - clearTimeout(settings.timer); + if (data.settings.timer !== undefined) { + clearTimeout(data.settings.timer); } - settings.submitting = true; - if (settings.beforeValidate === undefined || settings.beforeValidate($form)) { - $.fn.yiiactiveform.validate($form, function (data) { + data.submitting = true; + if (!data.settings.beforeValidate || data.settings.beforeValidate($form)) { + validateForm($form, function (messages) { var hasError = false; - $.each(settings.attributes, function () { - hasError = $.fn.yiiactiveform.updateInput(this, data, $form) || hasError; + $.each(data.attributes, function () { + hasError = updateInput($form, this, messages) || hasError; }); - $.fn.yiiactiveform.updateSummary($form, data); - if (settings.afterValidate === undefined || settings.afterValidate($form, data, hasError)) { + updateSummary($form, messages); + if (!data.settings.afterValidate || data.settings.afterValidate($form, data, hasError)) { if (!hasError) { validated = true; - var $button = $form.data('submitObject') || $form.find(':submit:first'); + var $button = data.submitObject || $form.find(':submit:first'); // TODO: if the submission is caused by "change" event, it will not work if ($button.length) { $button.click(); - } else { // no submit button in the form + } else { + // no submit button in the form $form.submit(); } return; } } - settings.submitting = false; + data.submitting = false; }); } else { - settings.submitting = false; + data.submitting = false; } return false; }; var resetForm = function () { - var settings = $(this).data('yiiActiveForm').settings; - var attributes = $(this).data('yiiActiveForm').attributes; - /* + var $form = $(this); + var data = $form.data('yiiActiveForm'); + /** * because we bind directly to a form reset event, not to a reset button (that could or could not exist), * when this function is executed form elements values have not been reset yet, * because of that we use the setTimeout */ setTimeout(function () { - $.each(attributes, function () { + $.each(data.attributes, function () { this.status = 0; - var $error = $form.find('#' + this.errorID), - $container = getInputContainer(this, $form); - - $container.removeClass( - settings.validatingCssClass + ' ' + - settings.errorCssClass + ' ' + - settings.successCssClass + $form.find(this.container).removeClass( + data.settings.validatingCssClass + ' ' + + data.settings.errorCssClass + ' ' + + data.settings.successCssClass ); - - $error.html('').hide(); - + $form.find(this.error).html(''); /* - * without the setTimeout() we would get here the current entered value before the reset instead of the reseted value + * without the setTimeout() we would get here the current entered value before the reset instead of the reset value */ - this.value = getInputValue($form.find('#' + this.inputID)); + this.value = getValue($form, this); }); - $('#' + settings.summaryID).hide().find('ul').html(''); - }, 10); - }; - - - /** - * Returns the container element of the specified attribute. - * @param attribute object the configuration for a particular attribute. - * @param form the form jQuery object - * @return jQuery the jQuery representation of the container - */ - var getInputContainer = function (attribute, form) { - if (attribute.inputContainer === undefined) { - return form.find('#' + attribute.inputID).closest('div'); - } else { - return form.find(attribute.inputContainer).filter(':has("#' + attribute.inputID + '")'); - } + $form.find(data.settings.summary).hide().find('ul').html(''); + }, 1); }; /** @@ -383,71 +353,45 @@ * @param form the form jQuery object * @return boolean whether there is a validation error for the specified attribute */ - var updateInput = function (attribute, messages, form) { - attribute.status = 1; - var $error, $container, - hasError = false, - $el = form.find('#' + attribute.inputID), - errorCss = form.data('settings').errorCss; - - if ($el.length) { - hasError = messages !== null && $.isArray(messages[attribute.id]) && messages[attribute.id].length > 0; - $error = form.find('#' + attribute.errorID); - $container = $.fn.yiiactiveform.getInputContainer(attribute, form); + var updateInput = function ($form, attribute, messages) { + var data = $form.data('yiiActiveForm'), + $input = findInput($form, attribute), + hasError = false; + attribute.status = 1; + if ($input.length) { + hasError = messages && $.isArray(messages[attribute.id]) && messages[attribute.name].length; + var $container = $form.find(attribute.container); $container.removeClass( - attribute.validatingCssClass + ' ' + - attribute.errorCssClass + ' ' + - attribute.successCssClass + data.settings.validatingCssClass + ' ' + + data.settings.errorCssClass + ' ' + + data.settings.successCssClass ); - $container.find('label, input').each(function () { - $(this).removeClass(errorCss); - }); if (hasError) { - $error.html(messages[attribute.id][0]); - $container.addClass(attribute.errorCssClass); - } else if (attribute.enableAjaxValidation || attribute.clientValidation) { - $container.addClass(attribute.successCssClass); - } - if (!attribute.hideErrorMessage) { - $error.toggle(hasError); + $form.find(attribute.error).html(messages[attribute.name][0]); + $container.addClass(data.settings.errorCssClass); + } else if (attribute.enableAjaxValidation || attribute.enableClientValidation && attribute.validate) { + $container.addClass(data.settings.successCssClass); } - - attribute.value = getAFValue($el); + attribute.value = getValue($form, attribute); } return hasError; }; - /** - * updates the error summary, if any. - * @param form jquery the jquery representation of the form - * @param messages array the json data obtained from the ajax validation request - */ - var updateSummary = function (form, messages) { - var settings = $(form).data('yiiActiveForm'), + var updateSummary = function ($form, messages) { + var data = $form.data('yiiActiveForm'), + $summary = $form.find(data.settings.summary), content = ''; - if (settings.summaryID === undefined) { - return; - } - if (messages) { - $.each(settings.attributes, function () { - if ($.isArray(messages[this.id])) { - $.each(messages[this.id], function (j, message) { - content = content + '
  • ' + message + '
  • '; - }); + + if ($summary.length && messages) { + $.each(data.attributes, function () { + if ($.isArray(messages[this.name])) { + content += '
  • ' + messages[this.name].join('
  • ') + '
  • '; } }); + $summary.toggle(content !== '').find('ul').html(content); } - $('#' + settings.summaryID).toggle(content !== '').find('ul').html(content); - }; - - var getSettings = function (form) { - return $(form).data('yiiActiveForm').settings; - }; - - var getAttributes = function (form) { - return $(form).data('yiiActiveForm').attributes; }; })(window.jQuery); \ No newline at end of file diff --git a/framework/validators/Validator.php b/framework/validators/Validator.php index 5ab8dfe..22da00a 100644 --- a/framework/validators/Validator.php +++ b/framework/validators/Validator.php @@ -102,12 +102,6 @@ abstract class Validator extends Component public $skipOnEmpty = true; /** - * @var boolean whether to enable client-side validation. Defaults to null, meaning - * its actual value inherits from that of [[\yii\web\ActiveForm::enableClientValidation]]. - */ - public $enableClientValidation; - - /** * Validates a single attribute. * Child classes must implement this method to provide the actual validation logic. * @param \yii\base\Model $object the data object to be validated @@ -211,7 +205,6 @@ abstract class Validator extends Component * @param string $attribute the name of the attribute to be validated. * @return string the client-side validation script. Null if the validator does not support * client-side validation. - * @see enableClientValidation * @see \yii\web\ActiveForm::enableClientValidation */ public function clientValidateAttribute($object, $attribute) diff --git a/framework/widgets/ActiveField.php b/framework/widgets/ActiveField.php index bf3ea28..a6ef58e 100644 --- a/framework/widgets/ActiveField.php +++ b/framework/widgets/ActiveField.php @@ -10,6 +10,7 @@ namespace yii\widgets; use yii\base\Component; use yii\helpers\Html; use yii\base\Model; +use yii\helpers\JsExpression; /** * @author Qiang Xue @@ -60,15 +61,39 @@ class ActiveField extends Component public function begin() { + $inputID = Html::getInputId($this->model, $this->attribute); + $attribute = Html::getAttributeName($this->attribute); + + $validators = array(); + foreach ($this->model->getValidators($attribute) as $validator) { + /** @var \yii\validators\Validator $validator */ + if (($js = $validator->clientValidateAttribute($this->model, $attribute)) != '') { + $validators[] = $js; + } + } + $jsOptions = array( + 'name' => $this->attribute, + 'container' => ".field-$inputID", + 'input' => "#$inputID", + 'error' => '.help-inline', + ); + if ($validators !== array()) { + $jsOptions['validate'] = new JsExpression("function(attribute, value, messages) {" . implode('', $validators) . '}'); + } + $this->form->attributes[$this->attribute] = $jsOptions; + + $options = $this->options; $class = isset($options['class']) ? array($options['class']) : array(); - $class[] = 'field-' . Html::getInputId($this->model, $this->attribute); - if ($this->model->isAttributeRequired($this->attribute)) { + $class[] = "field-$inputID"; + if ($this->model->isAttributeRequired($attribute)) { $class[] = $this->form->requiredCssClass; } - if ($this->model->hasErrors($this->attribute)) { + if ($this->model->hasErrors($attribute)) { $class[] = $this->form->errorCssClass; } + + $options['class'] = implode(' ', $class); return Html::beginTag($this->tag, $options); } diff --git a/framework/widgets/ActiveForm.php b/framework/widgets/ActiveForm.php index 97ee634..bc55e82 100644 --- a/framework/widgets/ActiveForm.php +++ b/framework/widgets/ActiveForm.php @@ -11,6 +11,7 @@ use Yii; use yii\base\Widget; use yii\base\Model; use yii\helpers\Html; +use yii\helpers\Json; /** * ActiveForm ... @@ -41,17 +42,20 @@ class ActiveForm extends Widget */ public $errorSummaryCssClass = 'yii-error-summary'; /** - * @var boolean whether to enable client-side data validation. - * Client-side validation will be performed by validators that support it - * (see [[\yii\validators\Validator::enableClientValidation]] and [[\yii\validators\Validator::clientValidateAttribute()]]). - */ - public $enableClientValidation = true; - /** * @var array the default configuration used by [[field()]] when creating a new field object. */ public $fieldConfig = array( 'class' => 'yii\widgets\ActiveField', ); + + /** + * @var boolean whether to enable client-side data validation. + * Client-side validation will be performed by validators that support it + * (see [[\yii\validators\Validator::enableClientValidation]] and [[\yii\validators\Validator::clientValidateAttribute()]]). + */ + public $enableClientValidation = true; + public $enableAjaxValidation = false; + /** * @var string the CSS class that is added to a field container when the associated attribute is required. */ @@ -69,13 +73,22 @@ class ActiveForm extends Widget */ public $validatingCssClass = 'validating'; + public $validationUrl; + public $validationDelay; + public $validateOnChange; + public $validateOnType; + + public $attributes = array(); + /** * Initializes the widget. * This renders the form open tag. */ public function init() { - $this->options['id'] = $this->getId(); + if (!isset($this->options['id'])) { + $this->options['id'] = $this->getId(); + } echo Html::beginForm($this->action, $this->method, $this->options); } @@ -85,11 +98,18 @@ class ActiveForm extends Widget */ public function run() { - $id = $this->getId(); - $options = array(); - $options = json_encode($options); + $id = $this->options['id']; + $options = array( + 'enableClientValidation' => $this->enableClientValidation, + 'enableAjaxValidation' => $this->enableAjaxValidation, + 'errorCssClass' => $this->errorCssClass, + 'successCssClass' => $this->successCssClass, + 'validatingCssClass' => $this->validatingCssClass, + ); + $options = Json::encode($options); + $attributes = Json::encode($this->attributes); $this->view->registerAssetBundle('yii/form'); - $this->view->registerJs("jQuery('#$id').yii.form($options);"); + $this->view->registerJs("jQuery('#$id').yiiActiveForm($attributes, $options);"); echo Html::endForm(); } From 7d999b265281d4b4183110ebbbdc4da7930b19c2 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Thu, 2 May 2013 07:40:29 -0400 Subject: [PATCH 11/87] form fix. --- framework/assets/yii.activeForm.js | 4 ++-- framework/widgets/ActiveField.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/framework/assets/yii.activeForm.js b/framework/assets/yii.activeForm.js index e5df863..901deac 100644 --- a/framework/assets/yii.activeForm.js +++ b/framework/assets/yii.activeForm.js @@ -360,7 +360,7 @@ attribute.status = 1; if ($input.length) { - hasError = messages && $.isArray(messages[attribute.id]) && messages[attribute.name].length; + hasError = messages && $.isArray(messages[attribute.name]) && messages[attribute.name].length; var $container = $form.find(attribute.container); $container.removeClass( data.settings.validatingCssClass + ' ' + @@ -369,7 +369,7 @@ ); if (hasError) { - $form.find(attribute.error).html(messages[attribute.name][0]); + $container.find(attribute.error).html(messages[attribute.name][0]); $container.addClass(data.settings.errorCssClass); } else if (attribute.enableAjaxValidation || attribute.enableClientValidation && attribute.validate) { $container.addClass(data.settings.successCssClass); diff --git a/framework/widgets/ActiveField.php b/framework/widgets/ActiveField.php index a6ef58e..90c6db4 100644 --- a/framework/widgets/ActiveField.php +++ b/framework/widgets/ActiveField.php @@ -65,7 +65,7 @@ class ActiveField extends Component $attribute = Html::getAttributeName($this->attribute); $validators = array(); - foreach ($this->model->getValidators($attribute) as $validator) { + foreach ($this->model->getActiveValidators($attribute) as $validator) { /** @var \yii\validators\Validator $validator */ if (($js = $validator->clientValidateAttribute($this->model, $attribute)) != '') { $validators[] = $js; From fe98f60f2e38ca93a8db69c9ce4bf099b5e5b337 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Thu, 2 May 2013 09:37:02 -0400 Subject: [PATCH 12/87] Added ExpressionDependency::data. --- framework/caching/ExpressionDependency.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/framework/caching/ExpressionDependency.php b/framework/caching/ExpressionDependency.php index 303ccdc..ec4736c 100644 --- a/framework/caching/ExpressionDependency.php +++ b/framework/caching/ExpressionDependency.php @@ -28,15 +28,22 @@ class ExpressionDependency extends Dependency * please refer to the [php manual](http://www.php.net/manual/en/language.expressions.php). */ public $expression; + /** + * @var mixed custom data associated with this dependency. In [[expression]], you may compare the value of + * this property with the latest data to determine if the dependency has changed or not. + */ + public $data; /** * Constructor. * @param string $expression the PHP expression whose result is used to determine the dependency. + * @param mixed $data the custom data associated with this dependency * @param array $config name-value pairs that will be used to initialize the object properties */ - public function __construct($expression = 'true', $config = array()) + public function __construct($expression = 'true', $data = null, $config = array()) { $this->expression = $expression; + $this->data = $data; parent::__construct($config); } From 41b127b922d58ae7286a6a7b74d101788d7e7711 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Thu, 2 May 2013 10:23:47 -0400 Subject: [PATCH 13/87] Finished js validation for compare validator. --- framework/assets/yii.validation.js | 41 +++++++++++++++++++++++++++++++ framework/validators/BooleanValidator.php | 2 +- framework/validators/CompareValidator.php | 39 +++++++++++++++++++---------- framework/validators/Validator.php | 9 ++++--- 4 files changed, 73 insertions(+), 18 deletions(-) diff --git a/framework/assets/yii.validation.js b/framework/assets/yii.validation.js index 83e0497..0865237 100644 --- a/framework/assets/yii.validation.js +++ b/framework/assets/yii.validation.js @@ -30,6 +30,47 @@ yii.validation = (function ($) { valid || messages.push(options.message); }, + compare: function (value, messages, options) { + if (options.skipOnEmpty && isEmpty(value)) { + return; + } + + var compareValue, valid = true; + if (options.compareAttribute === undefined) { + compareValue = options.compareValue; + } else { + compareValue = $('#' + options.compareAttribute).val(); + } + switch (options.operator) { + case '==': + valid = value == compareValue; + break; + case '===': + valid = value === compareValue; + break; + case '!=': + valid = value != compareValue; + break; + case '!==': + valid = value !== compareValue; + break; + case '>': + valid = value > compareValue; + break; + case '>=': + valid = value >= compareValue; + break; + case '<': + valid = value < compareValue; + break; + case '<=': + valid = value <= compareValue; + break; + } + + valid || messages.push(options.message); + }, + boolean: function (value, messages, options) { if (options.skipOnEmpty && isEmpty(value)) { return; diff --git a/framework/validators/BooleanValidator.php b/framework/validators/BooleanValidator.php index dd72c67..1420739 100644 --- a/framework/validators/BooleanValidator.php +++ b/framework/validators/BooleanValidator.php @@ -83,7 +83,7 @@ class BooleanValidator extends Validator */ public function clientValidateAttribute($object, $attribute) { - $options['message'] = array( + $options = array( 'trueValue' => $this->trueValue, 'falseValue' => $this->falseValue, 'message' => Html::encode(strtr($this->message, array( diff --git a/framework/validators/CompareValidator.php b/framework/validators/CompareValidator.php index 1df09c4..720ab56 100644 --- a/framework/validators/CompareValidator.php +++ b/framework/validators/CompareValidator.php @@ -9,6 +9,7 @@ namespace yii\validators; use Yii; use yii\base\InvalidConfigException; +use yii\helpers\Html; /** * CompareValidator compares the specified attribute value with another value and validates if they are equal. @@ -58,6 +59,15 @@ class CompareValidator extends Validator * - `<=`: validates to see if the value being validated is less than or equal to the value being compared with. */ public $operator = '='; + /** + * @var string the user-defined error message. It may contain the following placeholders which + * will be replaced accordingly by the validator: + * + * - `{attribute}`: the label of the attribute being validated + * - `{value}`: the value of the attribute being validated + * - `{compareValue}`: the value or the attribute label to be compared with + */ + public $message; /** @@ -172,24 +182,27 @@ class CompareValidator extends Validator */ public function clientValidateAttribute($object, $attribute) { + $options = array('operator' => $this->operator); + if ($this->compareValue !== null) { - $compareLabel = $this->compareValue; - $compareValue = json_encode($this->compareValue); + $options['compareValue'] = $this->compareValue; + $compareValue = $this->compareValue; } else { $compareAttribute = $this->compareAttribute === null ? $attribute . '_repeat' : $this->compareAttribute; - $compareValue = "\$('#" . (CHtml::activeId($object, $compareAttribute)) . "').val()"; - $compareLabel = $object->getAttributeLabel($compareAttribute); + $compareValue = $object->getAttributeLabel($compareAttribute); + $options['compareAttribute'] = Html::getInputId($object, $compareAttribute); } - $condition = "value {$this->operator} $compareValue"; - $message = strtr($this->message, array( + + if ($this->skipOnEmpty) { + $options['skipOnEmpty'] = 1; + } + + $options['message'] = Html::encode(strtr($options['message'], array( '{attribute}' => $object->getAttributeLabel($attribute), - '{compareValue}' => $compareLabel, - )); + '{value}' => $object->$attribute, + '{compareValue}' => $compareValue, + ))); - return " -if (" . ($this->skipOnEmpty ? "$.trim(value)!='' && " : '') . $condition . ") { - messages.push(" . json_encode($message) . "); -} -"; + return 'yii.validation.compare(value, messages, ' . json_encode($options) . ');'; } } diff --git a/framework/validators/Validator.php b/framework/validators/Validator.php index 22da00a..2460081 100644 --- a/framework/validators/Validator.php +++ b/framework/validators/Validator.php @@ -76,10 +76,11 @@ abstract class Validator extends Component */ public $attributes; /** - * @var string the user-defined error message. Error message may contain some placeholders - * that will be replaced with the actual values by the validator. - * The `{attribute}` and `{value}` are placeholders supported by all validators. - * They will be replaced with the attribute label and value, respectively. + * @var string the user-defined error message. It may contain the following placeholders which + * will be replaced accordingly by the validator: + * + * - `{attribute}`: the label of the attribute being validated + * - `{value}`: the value of the attribute being validated */ public $message; /** From 4b30fe8b5a49fd8edda6202a0c27dc0d4002374a Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Thu, 2 May 2013 10:52:25 -0400 Subject: [PATCH 14/87] Finished js validation for email and regular expression validators. --- framework/assets/yii.validation.js | 20 ++++++++++++++++ framework/validators/CompareValidator.php | 2 +- framework/validators/EmailValidator.php | 28 ++++++++++++---------- .../validators/RegularExpressionValidator.php | 25 +++++++++++-------- framework/validators/RequiredValidator.php | 9 +++++++ 5 files changed, 60 insertions(+), 24 deletions(-) diff --git a/framework/assets/yii.validation.js b/framework/assets/yii.validation.js index 0865237..8ed7f61 100644 --- a/framework/assets/yii.validation.js +++ b/framework/assets/yii.validation.js @@ -79,6 +79,26 @@ yii.validation = (function ($) { || options.strict && (value === options.trueValue || value === options.falseValue); valid || messages.push(options.message); + }, + + email: function (value, messages, options) { + if (options.skipOnEmpty && isEmpty(value)) { + return; + } + + var valid = value.match(options.pattern) && (!options.allowName || value.match(options.fullPattern)); + + valid || messages.push(options.message); + }, + + regularExpression: function (value, messages, options) { + if (options.skipOnEmpty && isEmpty(value)) { + return; + } + + if (!value.match(options.pattern)) { + messages.push(options.message) + } } }; })(jQuery); diff --git a/framework/validators/CompareValidator.php b/framework/validators/CompareValidator.php index 720ab56..68504e5 100644 --- a/framework/validators/CompareValidator.php +++ b/framework/validators/CompareValidator.php @@ -197,7 +197,7 @@ class CompareValidator extends Validator $options['skipOnEmpty'] = 1; } - $options['message'] = Html::encode(strtr($options['message'], array( + $options['message'] = Html::encode(strtr($this->message, array( '{attribute}' => $object->getAttributeLabel($attribute), '{value}' => $object->$attribute, '{compareValue}' => $compareValue, diff --git a/framework/validators/EmailValidator.php b/framework/validators/EmailValidator.php index e498975..ad74dd6 100644 --- a/framework/validators/EmailValidator.php +++ b/framework/validators/EmailValidator.php @@ -8,6 +8,9 @@ namespace yii\validators; use Yii; +use yii\helpers\Html; +use yii\helpers\JsExpression; +use yii\helpers\Json; /** * EmailValidator validates that the attribute value is a valid email address. @@ -100,20 +103,19 @@ class EmailValidator extends Validator */ public function clientValidateAttribute($object, $attribute) { - $message = strtr($this->message, array( - '{attribute}' => $object->getAttributeLabel($attribute), - '{value}' => $object->$attribute, - )); - - $condition = "!value.match( {$this->pattern})"; - if ($this->allowName) { - $condition .= " && !value.match( {$this->fullPattern})"; + $options = array( + 'pattern' => new JsExpression($this->pattern), + 'fullPattern' => new JsExpression($this->fullPattern), + 'allowName' => $this->allowName, + 'message' => Html::encode(strtr($this->message, array( + '{attribute}' => $object->getAttributeLabel($attribute), + '{value}' => $object->$attribute, + ))), + ); + if ($this->skipOnEmpty) { + $options['skipOnEmpty'] = 1; } - return " -if(" . ($this->skipOnEmpty ? "$.trim(value)!='' && " : '') . $condition . ") { - messages.push(" . json_encode($message) . "); -} -"; + return 'yii.validation.email(value, messages, ' . Json::encode($options) . ');'; } } diff --git a/framework/validators/RegularExpressionValidator.php b/framework/validators/RegularExpressionValidator.php index 6c69be3..f3f34f6 100644 --- a/framework/validators/RegularExpressionValidator.php +++ b/framework/validators/RegularExpressionValidator.php @@ -9,6 +9,9 @@ namespace yii\validators; use Yii; use yii\base\InvalidConfigException; +use yii\helpers\Html; +use yii\helpers\JsExpression; +use yii\helpers\Json; /** * RegularExpressionValidator validates that the attribute value matches the specified [[pattern]]. @@ -81,11 +84,6 @@ class RegularExpressionValidator extends Validator */ public function clientValidateAttribute($object, $attribute) { - $message = strtr($this->message, array( - '{attribute}' => $object->getAttributeLabel($attribute), - '{value}' => $object->$attribute, - )); - $pattern = $this->pattern; $pattern = preg_replace('/\\\\x\{?([0-9a-fA-F]+)\}?/', '\u$1', $pattern); $deliminator = substr($pattern, 0, 1); @@ -100,10 +98,17 @@ class RegularExpressionValidator extends Validator $pattern .= preg_replace('/[^igm]/', '', $flag); } - return " -if (" . ($this->skipOnEmpty ? "$.trim(value)!='' && " : '') . ($this->not ? '' : '!') . "value.match($pattern)) { - messages.push(" . json_encode($message) . "); -} -"; + $options = array( + 'pattern' => new JsExpression($pattern), + 'message' => Html::encode(strtr($this->message, array( + '{attribute}' => $object->getAttributeLabel($attribute), + '{value}' => $object->$attribute, + ))), + ); + if ($this->skipOnEmpty) { + $options['skipOnEmpty'] = 1; + } + + return 'yii.validation.regularExpression(value, messages, ' . Json::encode($options) . ');'; } } diff --git a/framework/validators/RequiredValidator.php b/framework/validators/RequiredValidator.php index 7202ec3..4c14a8d 100644 --- a/framework/validators/RequiredValidator.php +++ b/framework/validators/RequiredValidator.php @@ -40,6 +40,15 @@ class RequiredValidator extends Validator * to check if the attribute value is empty. */ public $strict = false; + /** + * @var string the user-defined error message. It may contain the following placeholders which + * will be replaced accordingly by the validator: + * + * - `{attribute}`: the label of the attribute being validated + * - `{value}`: the value of the attribute being validated + * - `{requiredValue}`: the value of [[requiredValue]] + */ + public $message; /** * Initializes the validator. From 5069c29b989978d40953d7dbc4599d9e70d8fc60 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Thu, 2 May 2013 11:03:36 -0400 Subject: [PATCH 15/87] Finished js validation for URL validator. --- framework/assets/yii.validation.js | 20 ++++++++++++++--- framework/validators/FileValidator.php | 1 - framework/validators/UrlValidator.php | 40 +++++++++++++--------------------- 3 files changed, 32 insertions(+), 29 deletions(-) diff --git a/framework/assets/yii.validation.js b/framework/assets/yii.validation.js index 8ed7f61..b663470 100644 --- a/framework/assets/yii.validation.js +++ b/framework/assets/yii.validation.js @@ -81,6 +81,16 @@ yii.validation = (function ($) { valid || messages.push(options.message); }, + regularExpression: function (value, messages, options) { + if (options.skipOnEmpty && isEmpty(value)) { + return; + } + + if (!value.match(options.pattern)) { + messages.push(options.message) + } + }, + email: function (value, messages, options) { if (options.skipOnEmpty && isEmpty(value)) { return; @@ -91,14 +101,18 @@ yii.validation = (function ($) { valid || messages.push(options.message); }, - regularExpression: function (value, messages, options) { + url: function (value, messages, options) { if (options.skipOnEmpty && isEmpty(value)) { return; } + if (options.defaultScheme && !value.match(/:\/\//)) { + value = options.defaultScheme + '://' + value; + } + if (!value.match(options.pattern)) { - messages.push(options.message) + messages.push(options.message); } - } + }, }; })(jQuery); diff --git a/framework/validators/FileValidator.php b/framework/validators/FileValidator.php index b3de0b2..0fddcf5 100644 --- a/framework/validators/FileValidator.php +++ b/framework/validators/FileValidator.php @@ -8,7 +8,6 @@ namespace yii\validators; use Yii; -use yii\helpers\FileHelper; use yii\web\UploadedFile; /** diff --git a/framework/validators/UrlValidator.php b/framework/validators/UrlValidator.php index cd6bfef..0ed59bd 100644 --- a/framework/validators/UrlValidator.php +++ b/framework/validators/UrlValidator.php @@ -8,6 +8,9 @@ namespace yii\validators; use Yii; +use yii\helpers\Html; +use yii\helpers\JsExpression; +use yii\helpers\Json; /** * UrlValidator validates that the attribute value is a valid http or https URL. @@ -100,40 +103,27 @@ class UrlValidator extends Validator */ public function clientValidateAttribute($object, $attribute) { - $message = strtr($this->message, array( - '{attribute}' => $object->getAttributeLabel($attribute), - '{value}' => $object->$attribute, - )); - if (strpos($this->pattern, '{schemes}') !== false) { $pattern = str_replace('{schemes}', '(' . implode('|', $this->validSchemes) . ')', $this->pattern); } else { $pattern = $this->pattern; } - $js = " -if(!value.match($pattern)) { - messages.push(" . json_encode($message) . "); -} -"; - if ($this->defaultScheme !== null) { - $js = " -if(!value.match(/:\\/\\//)) { - value=" . json_encode($this->defaultScheme) . "+'://'+value; -} -$js -"; - } - + $options = array( + 'pattern' => new JsExpression($pattern), + 'message' => Html::encode(strtr($this->message, array( + '{attribute}' => $object->getAttributeLabel($attribute), + '{value}' => $object->$attribute, + ))), + ); if ($this->skipOnEmpty) { - $js = " -if($.trim(value)!='') { - $js -} -"; + $options['skipOnEmpty'] = 1; + } + if ($this->defaultScheme !== null) { + $options['defaultScheme'] = $this->defaultScheme; } - return $js; + return 'yii.validation.url(value, messages, ' . Json::encode($options) . ');'; } } From 4e7a33bcf5b9be7fb0ccde5301a935a9574cb048 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Thu, 2 May 2013 11:16:31 -0400 Subject: [PATCH 16/87] Finished js validation for string validator. --- framework/assets/yii.validation.js | 21 ++++++++++++++++ framework/validators/StringValidator.php | 42 +++++++++++++------------------- 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/framework/assets/yii.validation.js b/framework/assets/yii.validation.js index b663470..858c028 100644 --- a/framework/assets/yii.validation.js +++ b/framework/assets/yii.validation.js @@ -114,5 +114,26 @@ yii.validation = (function ($) { messages.push(options.message); } }, + + string: function (value, messages, options) { + if (options.skipOnEmpty && isEmpty(value)) { + return; + } + + if (typeof value !== 'string') { + messages.push(options.message); + return; + } + + if (options.min !== undefined && value.length < options.min) { + messages.push(options.tooShort); + } + if (options.max !== undefined && value.length > options.max) { + messages.push(options.tooLong); + } + if (options.is !== undefined && value.length != options.is) { + messages.push(options.is); + } + } }; })(jQuery); diff --git a/framework/validators/StringValidator.php b/framework/validators/StringValidator.php index 8b8c73b..83a5eba 100644 --- a/framework/validators/StringValidator.php +++ b/framework/validators/StringValidator.php @@ -8,6 +8,7 @@ namespace yii\validators; use Yii; +use yii\helpers\Html; /** * StringValidator validates that the attribute value is of certain length. @@ -132,56 +133,47 @@ class StringValidator extends Validator $label = $object->getAttributeLabel($attribute); $value = $object->$attribute; + $message = strtr($this->message, array( + '{attribute}' => $label, + '{value}' => $value, + )); $notEqual = strtr($this->notEqual, array( '{attribute}' => $label, '{value}' => $value, '{length}' => $this->is, )); - $tooShort = strtr($this->tooShort, array( '{attribute}' => $label, '{value}' => $value, '{min}' => $this->min, )); - $tooLong = strtr($this->tooLong, array( '{attribute}' => $label, '{value}' => $value, '{max}' => $this->max, )); - $js = ''; + $options = array( + 'message' => Html::encode($message), + 'notEqual' => Html::encode($notEqual), + 'tooShort' => Html::encode($tooShort), + 'tooLong' => Html::encode($tooLong), + ); + if ($this->min !== null) { - $js .= " -if(value.length< {$this->min}) { - messages.push(" . json_encode($tooShort) . "); -} -"; + $options['min'] = $this->min; } if ($this->max !== null) { - $js .= " -if(value.length> {$this->max}) { - messages.push(" . json_encode($tooLong) . "); -} -"; + $options['max'] = $this->max; } if ($this->is !== null) { - $js .= " -if(value.length!= {$this->is}) { - messages.push(" . json_encode($notEqual) . "); -} -"; + $options['is'] = $this->is; } - if ($this->skipOnEmpty) { - $js = " -if($.trim(value)!='') { - $js -} -"; + $options['skipOnEmpty'] = 1; } - return $js; + return 'yii.validation.string(value, messages, ' . json_encode($options) . ');'; } } From 08c3f90d4853268fc4be2742453abd14e3470f6b Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Thu, 2 May 2013 11:29:23 -0400 Subject: [PATCH 17/87] Finished js validation for number validator. --- framework/assets/yii.validation.js | 20 +++++++- framework/validators/NumberValidator.php | 53 +++++++++------------- .../validators/RegularExpressionValidator.php | 1 + framework/validators/StringValidator.php | 43 ++++++++---------- 4 files changed, 61 insertions(+), 56 deletions(-) diff --git a/framework/assets/yii.validation.js b/framework/assets/yii.validation.js index 858c028..495a72c 100644 --- a/framework/assets/yii.validation.js +++ b/framework/assets/yii.validation.js @@ -86,7 +86,7 @@ yii.validation = (function ($) { return; } - if (!value.match(options.pattern)) { + if (!options.not && !value.match(options.pattern) || options.not && value.match(options.pattern)) { messages.push(options.message) } }, @@ -134,6 +134,24 @@ yii.validation = (function ($) { if (options.is !== undefined && value.length != options.is) { messages.push(options.is); } + }, + + number: function (value, messages, options) { + if (options.skipOnEmpty && isEmpty(value)) { + return; + } + + if (typeof value === 'string' && !value.match(options.pattern)) { + messages.push(options.message); + return; + } + + if (options.min !== undefined && value < options.min) { + messages.push(options.tooSmall); + } + if (options.max !== undefined && value > options.max) { + messages.push(options.tooBig); + } } }; })(jQuery); diff --git a/framework/validators/NumberValidator.php b/framework/validators/NumberValidator.php index 915419e..d0a4002 100644 --- a/framework/validators/NumberValidator.php +++ b/framework/validators/NumberValidator.php @@ -8,6 +8,9 @@ namespace yii\validators; use Yii; +use yii\helpers\Html; +use yii\helpers\JsExpression; +use yii\helpers\Json; /** * NumberValidator validates that the attribute value is a number. @@ -116,48 +119,36 @@ class NumberValidator extends Validator public function clientValidateAttribute($object, $attribute) { $label = $object->getAttributeLabel($attribute); - $message = strtr($this->message, array( - '{attribute}' => $label, - )); + $value = $object->$attribute; + + $options = array( + 'pattern' => new JsExpression($this->integerOnly ? $this->integerPattern : $this->numberPattern), + 'message' => Html::encode(strtr($this->message, array( + '{attribute}' => $label, + '{value}' => $value, + ))), + ); - $pattern = $this->integerOnly ? $this->integerPattern : $this->numberPattern; - $js = " -if(!value.match($pattern)) { - messages.push(" . json_encode($message) . "); -} -"; if ($this->min !== null) { - $tooSmall = strtr($this->tooSmall, array( + $options['min'] = $this->min; + $options['tooSmall'] = Html::encode(strtr($this->tooSmall, array( '{attribute}' => $label, + '{value}' => $value, '{min}' => $this->min, - )); - - $js .= " -if(value<{$this->min}) { - messages.push(" . json_encode($tooSmall) . "); -} -"; + ))); } if ($this->max !== null) { - $tooBig = strtr($this->tooBig, array( + $options['max'] = $this->max; + $options['tooBig'] = Html::encode(strtr($this->tooBig, array( '{attribute}' => $label, + '{value}' => $value, '{max}' => $this->max, - )); - $js .= " -if(value>{$this->max}) { - messages.push(" . json_encode($tooBig) . "); -} -"; + ))); } - if ($this->skipOnEmpty) { - $js = " -if(jQuery.trim(value)!='') { - $js -} -"; + $options['skipOnEmpty'] = 1; } - return $js; + return 'yii.validation.number(value, messages, ' . Json::encode($options) . ');'; } } \ No newline at end of file diff --git a/framework/validators/RegularExpressionValidator.php b/framework/validators/RegularExpressionValidator.php index f3f34f6..79a1a3c 100644 --- a/framework/validators/RegularExpressionValidator.php +++ b/framework/validators/RegularExpressionValidator.php @@ -100,6 +100,7 @@ class RegularExpressionValidator extends Validator $options = array( 'pattern' => new JsExpression($pattern), + 'not' => $this->not, 'message' => Html::encode(strtr($this->message, array( '{attribute}' => $object->getAttributeLabel($attribute), '{value}' => $object->$attribute, diff --git a/framework/validators/StringValidator.php b/framework/validators/StringValidator.php index 83a5eba..5d0fa1a 100644 --- a/framework/validators/StringValidator.php +++ b/framework/validators/StringValidator.php @@ -133,41 +133,36 @@ class StringValidator extends Validator $label = $object->getAttributeLabel($attribute); $value = $object->$attribute; - $message = strtr($this->message, array( - '{attribute}' => $label, - '{value}' => $value, - )); - $notEqual = strtr($this->notEqual, array( - '{attribute}' => $label, - '{value}' => $value, - '{length}' => $this->is, - )); - $tooShort = strtr($this->tooShort, array( - '{attribute}' => $label, - '{value}' => $value, - '{min}' => $this->min, - )); - $tooLong = strtr($this->tooLong, array( - '{attribute}' => $label, - '{value}' => $value, - '{max}' => $this->max, - )); - $options = array( - 'message' => Html::encode($message), - 'notEqual' => Html::encode($notEqual), - 'tooShort' => Html::encode($tooShort), - 'tooLong' => Html::encode($tooLong), + 'message' => Html::encode(strtr($this->message, array( + '{attribute}' => $label, + '{value}' => $value, + ))), ); if ($this->min !== null) { $options['min'] = $this->min; + $options['tooShort'] = Html::encode(strtr($this->tooShort, array( + '{attribute}' => $label, + '{value}' => $value, + '{min}' => $this->min, + ))); } if ($this->max !== null) { $options['max'] = $this->max; + $options['tooLong'] = Html::encode(strtr($this->tooLong, array( + '{attribute}' => $label, + '{value}' => $value, + '{max}' => $this->max, + ))); } if ($this->is !== null) { $options['is'] = $this->is; + $options['notEqual'] = Html::encode(strtr($this->notEqual, array( + '{attribute}' => $label, + '{value}' => $value, + '{length}' => $this->is, + ))); } if ($this->skipOnEmpty) { $options['skipOnEmpty'] = 1; From 263e8c7f7e4c8f1e69a860e229c7649223ee6f39 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Thu, 2 May 2013 11:57:18 -0400 Subject: [PATCH 18/87] Finished CaptchaValidator. --- framework/assets/yii.validation.js | 145 ++++++++++++++++++------------ framework/validators/CaptchaValidator.php | 34 +++---- framework/validators/RangeValidator.php | 28 +++--- 3 files changed, 114 insertions(+), 93 deletions(-) diff --git a/framework/assets/yii.validation.js b/framework/assets/yii.validation.js index 495a72c..8490ba1 100644 --- a/framework/assets/yii.validation.js +++ b/framework/assets/yii.validation.js @@ -30,53 +30,61 @@ yii.validation = (function ($) { valid || messages.push(options.message); }, - compare: function (value, messages, options) { + boolean: function (value, messages, options) { if (options.skipOnEmpty && isEmpty(value)) { return; } + var valid = !options.strict && (value == options.trueValue || value == options.falseValue) + || options.strict && (value === options.trueValue || value === options.falseValue); - var compareValue, valid = true; - if (options.compareAttribute === undefined) { - compareValue = options.compareValue; - } else { - compareValue = $('#' + options.compareAttribute).val(); + valid || messages.push(options.message); + }, + + string: function (value, messages, options) { + if (options.skipOnEmpty && isEmpty(value)) { + return; } - switch (options.operator) { - case '==': - valid = value == compareValue; - break; - case '===': - valid = value === compareValue; - break; - case '!=': - valid = value != compareValue; - break; - case '!==': - valid = value !== compareValue; - break; - case '>': - valid = value > compareValue; - break; - case '>=': - valid = value >= compareValue; - break; - case '<': - valid = value < compareValue; - break; - case '<=': - valid = value <= compareValue; - break; + + if (typeof value !== 'string') { + messages.push(options.message); + return; } - valid || messages.push(options.message); + if (options.min !== undefined && value.length < options.min) { + messages.push(options.tooShort); + } + if (options.max !== undefined && value.length > options.max) { + messages.push(options.tooLong); + } + if (options.is !== undefined && value.length != options.is) { + messages.push(options.is); + } }, - boolean: function (value, messages, options) { + number: function (value, messages, options) { if (options.skipOnEmpty && isEmpty(value)) { return; } - var valid = !options.strict && (value == options.trueValue || value == options.falseValue) - || options.strict && (value === options.trueValue || value === options.falseValue); + + if (typeof value === 'string' && !value.match(options.pattern)) { + messages.push(options.message); + return; + } + + if (options.min !== undefined && value < options.min) { + messages.push(options.tooSmall); + } + if (options.max !== undefined && value > options.max) { + messages.push(options.tooBig); + } + }, + + range: function (value, messages, options) { + if (options.skipOnEmpty && isEmpty(value)) { + return; + } + var valid = !options.not && $.inArray(value, options.range) + || options.not && !$.inArray(value, options.range); valid || messages.push(options.message); }, @@ -115,43 +123,66 @@ yii.validation = (function ($) { } }, - string: function (value, messages, options) { + captcha: function (value, messages, options) { if (options.skipOnEmpty && isEmpty(value)) { return; } - if (typeof value !== 'string') { - messages.push(options.message); - return; - } - - if (options.min !== undefined && value.length < options.min) { - messages.push(options.tooShort); + // CAPTCHA may be updated via AJAX and the updated hash is stored in body data + var hash = $('body').data(options.hashKey); + if (hash == null) { + hash = options.hash; + } else { + hash = hash[options.caseSensitive ? 0 : 1]; } - if (options.max !== undefined && value.length > options.max) { - messages.push(options.tooLong); + var v = options.caseSensitive ? value : value.toLowerCase(); + for (var i = v.length - 1, h = 0; i >= 0; --i) { + h += v.charCodeAt(i); } - if (options.is !== undefined && value.length != options.is) { - messages.push(options.is); + if(h != hash) { + messages.push(options.message); } }, - number: function (value, messages, options) { + compare: function (value, messages, options) { if (options.skipOnEmpty && isEmpty(value)) { return; } - if (typeof value === 'string' && !value.match(options.pattern)) { - messages.push(options.message); - return; - } - - if (options.min !== undefined && value < options.min) { - messages.push(options.tooSmall); + var compareValue, valid = true; + if (options.compareAttribute === undefined) { + compareValue = options.compareValue; + } else { + compareValue = $('#' + options.compareAttribute).val(); } - if (options.max !== undefined && value > options.max) { - messages.push(options.tooBig); + switch (options.operator) { + case '==': + valid = value == compareValue; + break; + case '===': + valid = value === compareValue; + break; + case '!=': + valid = value != compareValue; + break; + case '!==': + valid = value !== compareValue; + break; + case '>': + valid = value > compareValue; + break; + case '>=': + valid = value >= compareValue; + break; + case '<': + valid = value < compareValue; + break; + case '<=': + valid = value <= compareValue; + break; } + + valid || messages.push(options.message); } }; })(jQuery); diff --git a/framework/validators/CaptchaValidator.php b/framework/validators/CaptchaValidator.php index ebb0039..4eba9df 100644 --- a/framework/validators/CaptchaValidator.php +++ b/framework/validators/CaptchaValidator.php @@ -9,6 +9,7 @@ namespace yii\validators; use Yii; use yii\base\InvalidConfigException; +use yii\helpers\Html; /** * CaptchaValidator validates that the attribute value is the same as the verification code displayed in the CAPTCHA. @@ -94,33 +95,22 @@ class CaptchaValidator extends Validator public function clientValidateAttribute($object, $attribute) { $captcha = $this->getCaptchaAction(); - $message = strtr($this->message, array( - '{attribute}' => $object->getAttributeLabel($attribute), - '{value}' => $object->$attribute, - )); $code = $captcha->getVerifyCode(false); $hash = $captcha->generateValidationHash($this->caseSensitive ? $code : strtolower($code)); - $js = " -var hash = $('body').data(' {$this->captchaAction}.hash'); -if (hash == null) - hash = $hash; -else - hash = hash[" . ($this->caseSensitive ? 0 : 1) . "]; -for(var i=value.length-1, h=0; i >= 0; --i) h+=value." . ($this->caseSensitive ? '' : 'toLowerCase().') . "charCodeAt(i); -if(h != hash) { - messages.push(" . json_encode($message) . "); -} -"; - + $options = array( + 'hash' => $hash, + 'hashKey' => 'yiiCaptcha/' . $this->captchaAction, + 'caseSensitive' => $this->caseSensitive, + 'message' => Html::encode(strtr($this->message, array( + '{attribute}' => $object->getAttributeLabel($attribute), + '{value}' => $object->$attribute, + ))), + ); if ($this->skipOnEmpty) { - $js = " -if($.trim(value)!='') { - $js -} -"; + $options['skipOnEmpty'] = 1; } - return $js; + return 'yii.validation.captcha(value, messages, ' . json_encode($options) . ');'; } } diff --git a/framework/validators/RangeValidator.php b/framework/validators/RangeValidator.php index 18742ae..2a9e15f 100644 --- a/framework/validators/RangeValidator.php +++ b/framework/validators/RangeValidator.php @@ -9,6 +9,7 @@ namespace yii\validators; use Yii; use yii\base\InvalidConfigException; +use yii\helpers\Html; /** * RangeValidator validates that the attribute value is among a list of values. @@ -60,9 +61,7 @@ class RangeValidator extends Validator public function validateAttribute($object, $attribute) { $value = $object->$attribute; - if (!$this->not && !in_array($value, $this->range, $this->strict)) { - $this->addError($object, $attribute, $this->message); - } elseif ($this->not && in_array($value, $this->range, $this->strict)) { + if (!$this->validateValue($value)) { $this->addError($object, $attribute, $this->message); } } @@ -86,21 +85,22 @@ class RangeValidator extends Validator */ public function clientValidateAttribute($object, $attribute) { - $message = strtr($this->message, array( - '{attribute}' => $object->getAttributeLabel($attribute), - '{value}' => $object->$attribute, - )); - $range = array(); foreach ($this->range as $value) { $range[] = (string)$value; } - $range = json_encode($range); + $options = array( + 'range' => $range, + 'not' => $this->not, + 'message' => Html::encode(strtr($this->message, array( + '{attribute}' => $object->getAttributeLabel($attribute), + '{value}' => $object->$attribute, + ))), + ); + if ($this->skipOnEmpty) { + $options['skipOnEmpty'] = 1; + } - return " -if (" . ($this->skipOnEmpty ? "$.trim(value)!='' && " : '') . ($this->not ? "$.inArray(value, $range)>=0" : "$.inArray(value, $range)<0") . ") { - messages.push(" . json_encode($message) . "); -} -"; + return 'yii.validation.range(value, messages, ' . json_encode($options) . ');'; } } From 66b123bce75ab36b2e503a9f28597ae248b49ae0 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Fri, 3 May 2013 00:09:42 +0400 Subject: [PATCH 19/87] Minor JS code style issues --- framework/assets/yii.activeForm.js | 8 ++++---- framework/assets/yii.validation.js | 20 +++++++++++++++----- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/framework/assets/yii.activeForm.js b/framework/assets/yii.activeForm.js index 901deac..d26e221 100644 --- a/framework/assets/yii.activeForm.js +++ b/framework/assets/yii.activeForm.js @@ -40,7 +40,7 @@ // the container CSS class representing the corresponding attribute has validation error errorCssClass: 'error', // the container CSS class representing the corresponding attribute passes validation - successCssClass: 'success', + successCssClass: 'success', // the container CSS class representing the corresponding attribute is being validated validatingCssClass: 'validating', // a callback that is called before validating any attribute @@ -124,7 +124,7 @@ return this.each(function () { $(window).unbind('.yiiActiveForm'); $(this).removeData('yiiActiveForm'); - }) + }); } }; @@ -218,7 +218,7 @@ /** * Performs the ajax validation request. * This method is invoked internally to trigger the ajax validation. - * @param form jquery the jquery representation of the form + * @param $form jquery the jquery representation of the form * @param successCallback function the function to be invoked if the ajax request succeeds * @param errorCallback function the function to be invoked if the ajax request fails */ @@ -350,7 +350,7 @@ * updates the error message and the input container for a particular attribute. * @param attribute object the configuration for a particular attribute. * @param messages array the json data obtained from the ajax validation request - * @param form the form jQuery object + * @param $form the form jQuery object * @return boolean whether there is a validation error for the specified attribute */ var updateInput = function ($form, attribute, messages) { diff --git a/framework/assets/yii.validation.js b/framework/assets/yii.validation.js index 8490ba1..118ad00 100644 --- a/framework/assets/yii.validation.js +++ b/framework/assets/yii.validation.js @@ -27,7 +27,9 @@ yii.validation = (function ($) { valid = true; } - valid || messages.push(options.message); + if(!valid) { + messages.push(options.message); + } }, boolean: function (value, messages, options) { @@ -37,7 +39,9 @@ yii.validation = (function ($) { var valid = !options.strict && (value == options.trueValue || value == options.falseValue) || options.strict && (value === options.trueValue || value === options.falseValue); - valid || messages.push(options.message); + if(!valid) { + messages.push(options.message); + } }, string: function (value, messages, options) { @@ -86,7 +90,9 @@ yii.validation = (function ($) { var valid = !options.not && $.inArray(value, options.range) || options.not && !$.inArray(value, options.range); - valid || messages.push(options.message); + if(!valid) { + messages.push(options.message); + } }, regularExpression: function (value, messages, options) { @@ -106,7 +112,9 @@ yii.validation = (function ($) { var valid = value.match(options.pattern) && (!options.allowName || value.match(options.fullPattern)); - valid || messages.push(options.message); + if(!valid) { + messages.push(options.message); + } }, url: function (value, messages, options) { @@ -182,7 +190,9 @@ yii.validation = (function ($) { break; } - valid || messages.push(options.message); + if(!valid) { + messages.push(options.message); + } } }; })(jQuery); From e6af955bdc632ce72f419510371b4cc4b77b0af6 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Thu, 2 May 2013 16:10:57 -0400 Subject: [PATCH 20/87] form wip --- framework/assets/yii.activeForm.js | 4 +- framework/validators/Validator.php | 7 +++ framework/widgets/ActiveField.php | 62 ++++++++++++++++++- framework/widgets/ActiveForm.php | 124 ++++++++++++++++++++++++++++++------- 4 files changed, 172 insertions(+), 25 deletions(-) diff --git a/framework/assets/yii.activeForm.js b/framework/assets/yii.activeForm.js index 901deac..5569447 100644 --- a/framework/assets/yii.activeForm.js +++ b/framework/assets/yii.activeForm.js @@ -23,6 +23,8 @@ }; var defaults = { + // the jQuery selector for the error summary + errorSummary: undefined, // whether to enable client-side (JavaScript) validation enableClientValidation: true, // whether to enable AJAX-based validation @@ -381,7 +383,7 @@ var updateSummary = function ($form, messages) { var data = $form.data('yiiActiveForm'), - $summary = $form.find(data.settings.summary), + $summary = $form.find(data.settings.errorSummary), content = ''; if ($summary.length && messages) { diff --git a/framework/validators/Validator.php b/framework/validators/Validator.php index 2460081..677191b 100644 --- a/framework/validators/Validator.php +++ b/framework/validators/Validator.php @@ -101,6 +101,13 @@ abstract class Validator extends Component * is null or an empty string. */ public $skipOnEmpty = true; + /** + * @var boolean whether to enable client-side validation for this validator. + * The actual client-side validation is done via the JavaScript code returned + * by [[clientValidateAttribute()]]. If that method returns null, even if this property + * is true, no client-side validation will be done by this validator. + */ + public $enableClientValidation = true; /** * Validates a single attribute. diff --git a/framework/widgets/ActiveField.php b/framework/widgets/ActiveField.php index 90c6db4..060fe7e 100644 --- a/framework/widgets/ActiveField.php +++ b/framework/widgets/ActiveField.php @@ -57,7 +57,67 @@ class ActiveField extends Component * without the `$options` parameter. */ public $labelOptions = array('class' => 'control-label'); - + /** + * @var boolean whether to enable client-side data validation. + * If not set, it will take the value of [[ActiveForm::enableClientValidation]]. + */ + public $enableClientValidation; + /** + * @var boolean whether to enable AJAX-based data validation. + * If not set, it will take the value of [[ActiveForm::enableAjaxValidation]]. + */ + public $enableAjaxValidation; + /** + * @var boolean whether to perform validation when the input field loses focus and its value is found changed. + * If not set, it will take the value of [[ActiveForm::validateOnChange]]. + */ + public $validateOnChange; + /** + * @var boolean whether to perform validation while the user is typing in the input field. + * If not set, it will take the value of [[ActiveForm::validateOnType]]. + * @see validationDelay + */ + public $validateOnType; + /** + * @var integer number of milliseconds that the validation should be delayed when a user is typing in an input field. + * This property is used only when [[validateOnType]] is true. + * If not set, it will take the value of [[ActiveForm::validationDelay]]. + */ + public $validationDelay; + /** + * @var JsExpression|string a [[JsExpression]] object or a JavaScript expression string representing + * the callback that will be invoked BEFORE validating the attribute associated with this field on the client side. + * + * This callback is called after [[ActiveForm::beforeValidateAttribute]]. + * + * The signature of the callback should be like the following: + * + * ~~~ + * ~~~ + */ + public $beforeValidate; + /** + * @var JsExpression|string a [[JsExpression]] object or a JavaScript expression string representing + * the callback that will be invoked AFTER validating the attribute associated with this field on the client side. + * + * This callback is called before [[ActiveForm::afterValidateAttribute]]. + * + * The signature of the callback should be like the following: + * + * ~~~ + * ~~~ + */ + public $afterValidate; + /** + * @var array the jQuery selectors for selecting the container, input and error tags. + * The array keys should be "container", "input", and/or "error", and the array values + * are the corresponding selectors. For example, `array('input' => '#my-input')`. + * + * The selectors are used under the context of the form. + * + * You normally do not need to set this property as the default selectors should work well for most cases. + */ + public $selectors; public function begin() { diff --git a/framework/widgets/ActiveForm.php b/framework/widgets/ActiveForm.php index bc55e82..aefa9e9 100644 --- a/framework/widgets/ActiveForm.php +++ b/framework/widgets/ActiveForm.php @@ -12,6 +12,7 @@ use yii\base\Widget; use yii\base\Model; use yii\helpers\Html; use yii\helpers\Json; +use yii\helpers\JsExpression; /** * ActiveForm ... @@ -37,25 +38,16 @@ class ActiveForm extends Widget */ public $options = array(); /** - * @var string the default CSS class for the error summary container. - * @see errorSummary() - */ - public $errorSummaryCssClass = 'yii-error-summary'; - /** * @var array the default configuration used by [[field()]] when creating a new field object. */ public $fieldConfig = array( 'class' => 'yii\widgets\ActiveField', ); - /** - * @var boolean whether to enable client-side data validation. - * Client-side validation will be performed by validators that support it - * (see [[\yii\validators\Validator::enableClientValidation]] and [[\yii\validators\Validator::clientValidateAttribute()]]). + * @var string the default CSS class for the error summary container. + * @see errorSummary() */ - public $enableClientValidation = true; - public $enableAjaxValidation = false; - + public $errorSummaryCssClass = 'yii-error-summary'; /** * @var string the CSS class that is added to a field container when the associated attribute is required. */ @@ -72,12 +64,92 @@ class ActiveForm extends Widget * @var string the CSS class that is added to a field container when the associated attribute is being validated. */ public $validatingCssClass = 'validating'; - + /** + * @var boolean whether to enable client-side data validation. + * If [[ActiveField::enableClientValidation]] is set, its value will take precedence for that input field. + */ + public $enableClientValidation = true; + /** + * @var boolean whether to enable AJAX-based data validation. + * If [[ActiveField::enableAjaxValidation]] is set, its value will take precedence for that input field. + */ + public $enableAjaxValidation = false; + /** + * @var array|string the URL for performing AJAX-based validation. This property will be processed by + * [[Html::url()]]. Please refer to [[Html::url()]] for more details on how to configure this property. + * If this property is not set, it will take the value of the form's action attribute. + */ public $validationUrl; - public $validationDelay; - public $validateOnChange; - public $validateOnType; - + /** + * @var boolean whether to perform validation when the form is submitted. + */ + public $validateOnSubmit = true; + /** + * @var boolean whether to perform validation when an input field loses focus and its value is found changed. + * If [[ActiveField::validateOnChange]] is set, its value will take precedence for that input field. + */ + public $validateOnChange = false; + /** + * @var boolean whether to perform validation while the user is typing in an input field. + * If [[ActiveField::validateOnType]] is set, its value will take precedence for that input field. + * @see validationDelay + */ + public $validateOnType = false; + /** + * @var integer number of milliseconds that the validation should be delayed when a user is typing in an input field. + * This property is used only when [[validateOnType]] is true. + * If [[ActiveField::validationDelay]] is set, its value will take precedence for that input field. + */ + public $validationDelay = 200; + /** + * @var JsExpression|string a [[JsExpression]] object or a JavaScript expression string representing + * the callback that will be invoked BEFORE validating EACH attribute on the client side. + * The signature of the callback should be like the following: + * + * ~~~ + * ~~~ + */ + public $beforeValidateAttribute; + /** + * @var JsExpression|string a [[JsExpression]] object or a JavaScript expression string representing + * the callback that will be invoked AFTER validating EACH attribute on the client side. + * The signature of the callback should be like the following: + * + * ~~~ + * ~~~ + */ + public $afterValidateAttribute; + /** + * @var JsExpression|string a [[JsExpression]] object or a JavaScript expression string representing + * the callback that will be invoked BEFORE validating ALL attributes on the client side when the validation + * is triggered by form submission (that is, [[validateOnSubmit]] is set true). + * + * This callback is called before [[beforeValidateAttribute]]. + * + * The signature of the callback should be like the following: + * + * ~~~ + * ~~~ + */ + public $beforeValidate; + /** + * @var JsExpression|string a [[JsExpression]] object or a JavaScript expression string representing + * the callback that will be invoked AFTER validating ALL attributes on the client side when the validation + * is triggered by form submission (that is, [[validateOnSubmit]] is set true). + * + * This callback is called after [[afterValidateAttribute]]. + * + * The signature of the callback should be like the following: + * + * ~~~ + * ~~~ + */ + public $afterValidate; + /** + * @var array list of attributes that need to be validated on the client side. Each element of the array + * represents the validation options for a particular attribute. + * @internal + */ public $attributes = array(); /** @@ -98,7 +170,18 @@ class ActiveForm extends Widget */ public function run() { - $id = $this->options['id']; + if ($this->attributes !== array()) { + $id = $this->options['id']; + $options = Json::encode($this->getClientOptions()); + $attributes = Json::encode($this->attributes); + $this->view->registerAssetBundle('yii/form'); + $this->view->registerJs("jQuery('#$id').yiiActiveForm($attributes, $options);"); + } + echo Html::endForm(); + } + + protected function getClientOptions() + { $options = array( 'enableClientValidation' => $this->enableClientValidation, 'enableAjaxValidation' => $this->enableAjaxValidation, @@ -106,11 +189,6 @@ class ActiveForm extends Widget 'successCssClass' => $this->successCssClass, 'validatingCssClass' => $this->validatingCssClass, ); - $options = Json::encode($options); - $attributes = Json::encode($this->attributes); - $this->view->registerAssetBundle('yii/form'); - $this->view->registerJs("jQuery('#$id').yiiActiveForm($attributes, $options);"); - echo Html::endForm(); } /** From 74f97ce5a99d4d16d67ef5db058faaac1d150a0b Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Thu, 2 May 2013 16:40:57 -0400 Subject: [PATCH 21/87] refactored yii module. --- framework/assets/yii.js | 63 +++++++++++++++++++++++++++++--------- framework/assets/yii.validation.js | 2 +- 2 files changed, 50 insertions(+), 15 deletions(-) diff --git a/framework/assets/yii.js b/framework/assets/yii.js index 3a23763..1e847c4 100644 --- a/framework/assets/yii.js +++ b/framework/assets/yii.js @@ -7,24 +7,59 @@ * @author Qiang Xue * @since 2.0 */ + +/** + * yii is the root module for all Yii JavaScript modules. + * It implements a mechanism of organizing JavaScript code in modules through the function "yii.initModule()". + * + * Each module should be named as "x.y.z", where "x" stands for the root module (for the Yii core code, this is "yii"). + * + * A module may be structured as follows: + * + * ~~~ + * yii.sample = (function($) { + * var pub = { + * // whether this module is currently active. If false, init() will not be called for this module + * // it will also not be called for all its child modules. If this property is undefined, it means true. + * isActive: true, + * init: function() { + * // ... module initialization code go here ... + * }, + * + * // ... other public functions and properties go here ... + * }; + * + * // ... private functions and properties go here ... + * + * return pub; + * }); + * ~~~ + * + * Using this structure, you can define public and private functions/properties for a module. + * Private functions/properties are only visible within the module, while public functions/properties + * may be accessed outside of the module. For example, you can access "yii.sample.init()". + * + * You must call "yii.initModule()" once for the root module of all your modules. + */ yii = (function ($) { var pub = { - version: '2.0' + version: '2.0', + initModule: function (module) { + if (module.isActive === undefined || module.isActive) { + if ($.isFunction(module.init)) { + module.init(); + } + $.each(module, function () { + if ($.isPlainObject(this)) { + pub.initModule(this); + } + }); + } + } }; return pub; })(jQuery); -jQuery(document).ready(function ($) { - // call the init() method of every module - var init = function (module) { - if ($.isFunction(module.init) && (module.trigger == undefined || $(module.trigger).length)) { - module.init(); - } - $.each(module, function () { - if ($.isPlainObject(this)) { - init(this); - } - }); - }; - init(yii); +jQuery(document).ready(function () { + yii.initModule(yii); }); diff --git a/framework/assets/yii.validation.js b/framework/assets/yii.validation.js index 118ad00..5ca8e4e 100644 --- a/framework/assets/yii.validation.js +++ b/framework/assets/yii.validation.js @@ -1,7 +1,7 @@ /** * Yii validation module. * - * This is the JavaScript widget used by the yii\widgets\ActiveForm widget. + * This JavaScript module provides the validation methods for the built-in validaotrs. * * @link http://www.yiiframework.com/ * @copyright Copyright (c) 2008 Yii Software LLC From 62fc5cf6eaf542547b27663cf38afcae54ba63c5 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Thu, 2 May 2013 16:50:46 -0400 Subject: [PATCH 22/87] form WIP --- framework/widgets/ActiveForm.php | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/framework/widgets/ActiveForm.php b/framework/widgets/ActiveForm.php index aefa9e9..80de64b 100644 --- a/framework/widgets/ActiveForm.php +++ b/framework/widgets/ActiveForm.php @@ -47,7 +47,7 @@ class ActiveForm extends Widget * @var string the default CSS class for the error summary container. * @see errorSummary() */ - public $errorSummaryCssClass = 'yii-error-summary'; + public $errorSummaryCssClass = 'error-summary'; /** * @var string the CSS class that is added to a field container when the associated attribute is required. */ @@ -180,15 +180,39 @@ class ActiveForm extends Widget echo Html::endForm(); } + /** + * Returns the options for the form JS widget. + * @return array the options + */ protected function getClientOptions() { $options = array( - 'enableClientValidation' => $this->enableClientValidation, - 'enableAjaxValidation' => $this->enableAjaxValidation, + 'errorSummary' => '.' . $this->errorSummaryCssClass, + 'validateOnSubmit' => $this->validateOnSubmit, 'errorCssClass' => $this->errorCssClass, 'successCssClass' => $this->successCssClass, 'validatingCssClass' => $this->validatingCssClass, ); + if ($this->validationUrl !== null) { + $options['validationUrl'] = Html::url($this->validationUrl); + } + $callbacks = array( + 'beforeValidateAttribute', + 'afterValidateAttribute', + 'beforeValidate', + 'afterValidate', + ); + foreach ($callbacks as $callback) { + $value = $this->$callback; + if (is_string($value)) { + $value = new JsExpression($value); + } + if ($value instanceof JsExpression) { + $options[$callback] = $value; + } + } + + return $options; } /** @@ -245,7 +269,9 @@ class ActiveForm extends Widget * @param Model $model the data model * @param string $attribute the attribute name or expression. See [[Html::getAttributeName()]] for the format * about attribute expression. + * @param array $options the additional configurations for the field object * @return ActiveField the created ActiveField object + * @see fieldConfig */ public function field($model, $attribute, $options = array()) { From aa8061b002916cfbf8ceb4008af7bdbd7f406566 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Fri, 3 May 2013 00:03:16 -0400 Subject: [PATCH 23/87] form wip --- framework/assets/yii.activeForm.js | 355 ++++++++++++++++++------------------- framework/assets/yii.validation.js | 14 +- framework/widgets/ActiveField.php | 93 +++++++--- framework/widgets/ActiveForm.php | 16 +- 4 files changed, 259 insertions(+), 219 deletions(-) diff --git a/framework/assets/yii.activeForm.js b/framework/assets/yii.activeForm.js index f43d98d..8de93c8 100644 --- a/framework/assets/yii.activeForm.js +++ b/framework/assets/yii.activeForm.js @@ -25,18 +25,6 @@ var defaults = { // the jQuery selector for the error summary errorSummary: undefined, - // whether to enable client-side (JavaScript) validation - enableClientValidation: true, - // whether to enable AJAX-based validation - enableAjaxValidation: false, - // the URL for performing AJAX-based validation. If not set, it will use the the form's action - validationUrl: undefined, - // number of milliseconds of validation delay. This is used when validateOnType is true. - validationDelay: 200, - // whether to perform validation when a change is detected on the input. - validateOnChange: true, - // whether to perform validation when the user is typing. - validateOnType: false, // whether to perform validation before submitting the form. validateOnSubmit: true, // the container CSS class representing the corresponding attribute has validation error @@ -45,40 +33,50 @@ successCssClass: 'success', // the container CSS class representing the corresponding attribute is being validated validatingCssClass: 'validating', - // a callback that is called before validating any attribute + // the URL for performing AJAX-based validation. If not set, it will use the the form's action + validationUrl: undefined, + // a callback that is called before validating every attribute + beforeValidateAttribute: undefined, + // a callback that is called after validating every attribute + afterValidateAttribute: undefined, + // a callback that is called before validating ALL attributes when submitting the form beforeValidate: undefined, - // a callback that is called after validating any attribute + // a callback that is called after validating ALL attributes when submitting the form afterValidate: undefined, // the GET parameter name indicating an AJAX-based validation ajaxVar: 'ajax' }; + var attributeDefaults = { + // attribute name or expression (e.g. "[0]content" for tabular input) + name: undefined, + // the jQuery selector of the container of the input field + container: undefined, + // the jQuery selector of the input field + input: undefined, + // the jQuery selector of the error tag + error: undefined, + // whether to perform validation when a change is detected on the input + validateOnChange: false, + // whether to perform validation when the user is typing. + validateOnType: false, + // number of milliseconds that the validation should be delayed when a user is typing in the input field. + validationDelay: 200, + // whether to enable AJAX-based validation. + enableAjaxValidation: false, + // function (attribute, value, messages), the client-side validation function. + validate: undefined, + // callback called before validating the attribute + beforeValidate: undefined, + // callback called after validating an attribute. + afterValidate: undefined, + // status of the input field, 0: empty, not entered before, 1: validated, 2: pending validation, 3: validating + status: 0, + // the value of the input + value: undefined + }; + var methods = { - /** - * Initializes the plugin. - * @param attributes array attribute configurations. Each attribute may contain the following options: - * - * - name: string, attribute name or expression (e.g. "[0]content" for tabular input) - * - container: string, the jQuery selector of the container of the input field - * - input: string, the jQuery selector of the input field - * - error: string, the jQuery selector of the error tag - * - value: string|array, the value of the input - * - validateOnChange: boolean, whether to perform validation when a change is detected on the input. - * If not set, it will take the value of the corresponding global setting. - * - validateOnType: boolean, defaults to false, whether to perform validation when the user is typing. - * If not set, it will take the value of the corresponding global setting. - * - enableAjaxValidation: boolean, whether to enable AJAX-based validation. - * If not set, it will take the value of the corresponding global setting. - * - enableClientValidation: boolean, whether to enable client-side validation. - * If not set, it will take the value of the corresponding global setting. - * - validate: function (attribute, value, messages), the client-side validation function. - * - beforeValidate: function ($form, attribute), callback called before validating an attribute. If it - * returns false, the validation will be cancelled. - * - afterValidate: function ($form, attribute, data, hasError), callback called after validating an attribute. - * - status: integer, 0: empty, not entered before, 1: validated, 2: pending validation, 3: validating - * - * @param options object the configuration for the plugin. The following options can be set: - */ init: function (attributes, options) { return this.each(function () { var $form = $(this); @@ -86,38 +84,33 @@ return; } - var settings = $.extend(defaults, options || {}); + var settings = $.extend({}, defaults, options || {}); if (settings.validationUrl === undefined) { settings.validationUrl = $form.attr('action'); } $.each(attributes, function (i) { - attributes[i] = $.extend({ - validateOnChange: settings.validateOnChange, - validateOnType: settings.validateOnType, - enableAjaxValidation: settings.enableAjaxValidation, - enableClientValidation: settings.enableClientValidation, - value: getValue($form, this) - }, this); + attributes[i] = $.extend({}, attributeDefaults, this); }); $form.data('yiiActiveForm', { settings: settings, attributes: attributes, - submitting: false + submitting: false, + validated: false }); - bindAttributes($form, attributes); + watchAttributes($form, attributes); /** * Clean up error status when the form is reset. * Note that $form.on('reset', ...) does work because the "reset" event does not bubble on IE. */ - $form.bind('reset.yiiActiveForm', resetForm); + $form.bind('reset.yiiActiveForm', methods.resetForm); if (settings.validateOnSubmit) { $form.on('mouseup.yiiActiveForm keyup.yiiActiveForm', ':submit', function () { $form.data('yiiActiveForm').submitObject = $(this); }); - $form.on('submit', submitForm); + $form.on('submit', methods.submitForm); } }); }, @@ -127,6 +120,73 @@ $(window).unbind('.yiiActiveForm'); $(this).removeData('yiiActiveForm'); }); + }, + + submitForm: function () { + var $form = $(this), + data = $form.data('yiiActiveForm'); + if (data.validated) { + // continue submitting the form since validation passes + data.validated = false; + return true; + } + + if (data.settings.timer !== undefined) { + clearTimeout(data.settings.timer); + } + data.submitting = true; + if (!data.settings.beforeValidate || data.settings.beforeValidate($form)) { + validate($form, function (messages) { + var hasError = false; + $.each(data.attributes, function () { + hasError = updateInput($form, this, messages) || hasError; + }); + updateSummary($form, messages); + if (!data.settings.afterValidate || data.settings.afterValidate($form, data, hasError)) { + if (!hasError) { + data.validated = true; + var $button = data.submitObject || $form.find(':submit:first'); + // TODO: if the submission is caused by "change" event, it will not work + if ($button.length) { + $button.click(); + } else { + // no submit button in the form + $form.submit(); + } + return; + } + } + data.submitting = false; + }, function () { + data.submitting = false; + }); + } else { + data.submitting = false; + } + return false; + }, + + resetForm: function () { + var $form = $(this); + var data = $form.data('yiiActiveForm'); + // Because we bind directly to a form reset event instead of a reset button (that may not exist), + // when this function is executed form input values have not been reset yet. + // Therefore we do the actual reset work through setTimeout. + setTimeout(function () { + $.each(data.attributes, function () { + // Without setTimeout() we would get the input values that are not reset yet. + this.value = getValue($form, this); + this.status = 0; + var $container = $form.find(this.container); + $container.removeClass( + data.settings.validatingCssClass + ' ' + + data.settings.errorCssClass + ' ' + + data.settings.successCssClass + ); + $container.find(this.error).html(''); + }); + $form.find(data.settings.summary).hide().find('ul').html(''); + }, 1); } }; @@ -150,7 +210,7 @@ } }; - var bindAttributes = function ($form, attributes) { + var watchAttributes = function ($form, attributes) { $.each(attributes, function (i, attribute) { var $input = findInput($form, attribute); if (attribute.validateOnChange) { @@ -202,7 +262,7 @@ $form.find(this.container).addClass(data.settings.validatingCssClass); } }); - validateForm($form, function (messages) { + validate($form, function (messages) { var hasError = false; $.each(data.attributes, function () { if (this.status === 2 || this.status === 3) { @@ -218,141 +278,71 @@ }; /** - * Performs the ajax validation request. - * This method is invoked internally to trigger the ajax validation. - * @param $form jquery the jquery representation of the form - * @param successCallback function the function to be invoked if the ajax request succeeds - * @param errorCallback function the function to be invoked if the ajax request fails + * Performs validation. + * @param $form jQuery the jquery representation of the form + * @param successCallback function the function to be invoked if the validation completes + * @param errorCallback function the function to be invoked if the ajax validation request fails */ - var validateForm = function ($form, successCallback, errorCallback) { + var validate = function ($form, successCallback, errorCallback) { var data = $form.data('yiiActiveForm'), needAjaxValidation = false, messages = {}; $.each(data.attributes, function () { - var msg = []; - if (this.validate && (data.submitting || this.status === 2 || this.status === 3)) { - this.validate(this, getValue($form, this), msg); - if (msg.length) { - messages[this.name] = msg; + if (data.submitting || this.status === 2 || this.status === 3) { + var msg = []; + if (this.validate) { + this.validate(this, getValue($form, this), msg); + if (msg.length) { + messages[this.name] = msg; + } + } + if (this.enableAjaxValidation && !msg.length) { + needAjaxValidation = true; } - } - if (this.enableAjaxValidation && !msg.length && (data.submitting || this.status === 2 || this.status === 3)) { - needAjaxValidation = true; } }); - if (!needAjaxValidation || data.submitting && !$.isEmptyObject(messages)) { - if (data.submitting) { - // delay callback so that the form can be submitted without problem - setTimeout(function () { - successCallback(messages); - }, 200); - } else { - successCallback(messages); + if (needAjaxValidation && (!data.submitting || $.isEmptyObject(messages))) { + var $button = data.submitObject, + extData = '&' + data.settings.ajaxVar + '=' + $form.attr('id'); + if ($button && $button.length && $button.attr('name')) { + extData += '&' + $button.attr('name') + '=' + $button.attr('value'); } - return; - } - - var $button = data.submitObject, - extData = '&' + data.settings.ajaxVar + '=' + $form.attr('id'); - if ($button && $button.length && $button.attr('name')) { - extData += '&' + $button.attr('name') + '=' + $button.attr('value'); - } - - $.ajax({ - url: data.settings.validationUrl, - type: $form.attr('method'), - data: $form.serialize() + extData, - dataType: 'json', - success: function (data) { - if (data !== null && typeof data === 'object') { - $.each(data.attributes, function () { - if (!this.enableAjaxValidation) { - delete data[this.name]; - } - }); - successCallback($.extend({}, messages, data)); - } else { - successCallback(messages); - } - }, - error: errorCallback - }); - }; - - var validated = false; - var submitForm = function () { - var $form = $(this), - data = $form.data('yiiActiveForm'); - if (validated) { - validated = false; - return true; - } - if (data.settings.timer !== undefined) { - clearTimeout(data.settings.timer); - } - data.submitting = true; - if (!data.settings.beforeValidate || data.settings.beforeValidate($form)) { - validateForm($form, function (messages) { - var hasError = false; - $.each(data.attributes, function () { - hasError = updateInput($form, this, messages) || hasError; - }); - updateSummary($form, messages); - if (!data.settings.afterValidate || data.settings.afterValidate($form, data, hasError)) { - if (!hasError) { - validated = true; - var $button = data.submitObject || $form.find(':submit:first'); - // TODO: if the submission is caused by "change" event, it will not work - if ($button.length) { - $button.click(); - } else { - // no submit button in the form - $form.submit(); - } - return; + $.ajax({ + url: data.settings.validationUrl, + type: $form.attr('method'), + data: $form.serialize() + extData, + dataType: 'json', + success: function (msgs) { + if (msgs !== null && typeof msgs === 'object') { + $.each(data.attributes, function () { + if (!this.enableAjaxValidation) { + delete msgs[this.name]; + } + }); + successCallback($.extend({}, messages, msgs)); + } else { + successCallback(messages); } - } - data.submitting = false; + }, + error: errorCallback }); + } else if (data.submitting) { + // delay callback so that the form can be submitted without problem + setTimeout(function () { + successCallback(messages); + }, 200); } else { - data.submitting = false; + successCallback(messages); } - return false; - }; - - var resetForm = function () { - var $form = $(this); - var data = $form.data('yiiActiveForm'); - /** - * because we bind directly to a form reset event, not to a reset button (that could or could not exist), - * when this function is executed form elements values have not been reset yet, - * because of that we use the setTimeout - */ - setTimeout(function () { - $.each(data.attributes, function () { - this.status = 0; - $form.find(this.container).removeClass( - data.settings.validatingCssClass + ' ' + - data.settings.errorCssClass + ' ' + - data.settings.successCssClass - ); - $form.find(this.error).html(''); - /* - * without the setTimeout() we would get here the current entered value before the reset instead of the reset value - */ - this.value = getValue($form, this); - }); - $form.find(data.settings.summary).hide().find('ul').html(''); - }, 1); }; /** - * updates the error message and the input container for a particular attribute. - * @param attribute object the configuration for a particular attribute. - * @param messages array the json data obtained from the ajax validation request + * Updates the error message and the input container for a particular attribute. * @param $form the form jQuery object + * @param attribute object the configuration for a particular attribute. + * @param messages array the validation error messages * @return boolean whether there is a validation error for the specified attribute */ var updateInput = function ($form, attribute, messages) { @@ -364,23 +354,26 @@ if ($input.length) { hasError = messages && $.isArray(messages[attribute.name]) && messages[attribute.name].length; var $container = $form.find(attribute.container); - $container.removeClass( - data.settings.validatingCssClass + ' ' + - data.settings.errorCssClass + ' ' + - data.settings.successCssClass - ); - + var $error = $container.find(attribute.error); if (hasError) { - $container.find(attribute.error).html(messages[attribute.name][0]); - $container.addClass(data.settings.errorCssClass); - } else if (attribute.enableAjaxValidation || attribute.enableClientValidation && attribute.validate) { - $container.addClass(data.settings.successCssClass); + $error.html(messages[attribute.name][0]); + $container.removeClass(data.settings.validatingCssClass + ' ' + data.settings.successCssClass) + .addClass(data.settings.errorCssClass); + } else { + $error.html(''); + $container.removeClass(data.settings.validatingCssClass + ' ' + data.settings.errorCssClass + ' ') + .addClass(data.settings.successCssClass); } attribute.value = getValue($form, attribute); } return hasError; }; + /** + * Updates the error summary. + * @param $form the form jQuery object + * @param messages array the validation error messages + */ var updateSummary = function ($form, messages) { var data = $form.data('yiiActiveForm'), $summary = $form.find(data.settings.errorSummary), @@ -388,8 +381,8 @@ if ($summary.length && messages) { $.each(data.attributes, function () { - if ($.isArray(messages[this.name])) { - content += '
  • ' + messages[this.name].join('
  • ') + '
  • '; + if ($.isArray(messages[this.name]) && messages[this.name].length) { + content += '
  • ' + messages[this.name][0] + '
  • '; } }); $summary.toggle(content !== '').find('ul').html(content); diff --git a/framework/assets/yii.validation.js b/framework/assets/yii.validation.js index 5ca8e4e..fd098be 100644 --- a/framework/assets/yii.validation.js +++ b/framework/assets/yii.validation.js @@ -18,7 +18,7 @@ yii.validation = (function ($) { return { required: function (value, messages, options) { - var valid = false; + var valid = false; if (options.requiredValue === undefined) { if (options.strict && value !== undefined || !options.strict && !isEmpty(value, true)) { valid = true; @@ -27,7 +27,7 @@ yii.validation = (function ($) { valid = true; } - if(!valid) { + if (!valid) { messages.push(options.message); } }, @@ -39,7 +39,7 @@ yii.validation = (function ($) { var valid = !options.strict && (value == options.trueValue || value == options.falseValue) || options.strict && (value === options.trueValue || value === options.falseValue); - if(!valid) { + if (!valid) { messages.push(options.message); } }, @@ -90,7 +90,7 @@ yii.validation = (function ($) { var valid = !options.not && $.inArray(value, options.range) || options.not && !$.inArray(value, options.range); - if(!valid) { + if (!valid) { messages.push(options.message); } }, @@ -112,7 +112,7 @@ yii.validation = (function ($) { var valid = value.match(options.pattern) && (!options.allowName || value.match(options.fullPattern)); - if(!valid) { + if (!valid) { messages.push(options.message); } }, @@ -147,7 +147,7 @@ yii.validation = (function ($) { for (var i = v.length - 1, h = 0; i >= 0; --i) { h += v.charCodeAt(i); } - if(h != hash) { + if (h != hash) { messages.push(options.message); } }, @@ -190,7 +190,7 @@ yii.validation = (function ($) { break; } - if(!valid) { + if (!valid) { messages.push(options.message); } } diff --git a/framework/widgets/ActiveField.php b/framework/widgets/ActiveField.php index 060fe7e..bc7d696 100644 --- a/framework/widgets/ActiveField.php +++ b/framework/widgets/ActiveField.php @@ -4,10 +4,10 @@ * @copyright Copyright (c) 2008 Yii Software LLC * @license http://www.yiiframework.com/license/ */ - namespace yii\widgets; use yii\base\Component; +use yii\db\ActiveRecord; use yii\helpers\Html; use yii\base\Model; use yii\helpers\JsExpression; @@ -79,8 +79,8 @@ class ActiveField extends Component */ public $validateOnType; /** - * @var integer number of milliseconds that the validation should be delayed when a user is typing in an input field. - * This property is used only when [[validateOnType]] is true. + * @var integer number of milliseconds that the validation should be delayed when the input field + * is changed or the user types in the field. * If not set, it will take the value of [[ActiveForm::validationDelay]]. */ public $validationDelay; @@ -121,28 +121,13 @@ class ActiveField extends Component public function begin() { - $inputID = Html::getInputId($this->model, $this->attribute); - $attribute = Html::getAttributeName($this->attribute); - - $validators = array(); - foreach ($this->model->getActiveValidators($attribute) as $validator) { - /** @var \yii\validators\Validator $validator */ - if (($js = $validator->clientValidateAttribute($this->model, $attribute)) != '') { - $validators[] = $js; - } - } - $jsOptions = array( - 'name' => $this->attribute, - 'container' => ".field-$inputID", - 'input' => "#$inputID", - 'error' => '.help-inline', - ); - if ($validators !== array()) { - $jsOptions['validate'] = new JsExpression("function(attribute, value, messages) {" . implode('', $validators) . '}'); + $options = $this->getClientOptions(); + if ($options !== array()) { + $this->form->attributes[$this->attribute] = $options; } - $this->form->attributes[$this->attribute] = $jsOptions; - + $inputID = Html::getInputId($this->model, $this->attribute); + $attribute = Html::getAttributeName($this->attribute); $options = $this->options; $class = isset($options['class']) ? array($options['class']) : array(); $class[] = "field-$inputID"; @@ -152,9 +137,8 @@ class ActiveField extends Component if ($this->model->hasErrors($attribute)) { $class[] = $this->form->errorCssClass; } - - $options['class'] = implode(' ', $class); + return Html::beginTag($this->tag, $options); } @@ -163,6 +147,65 @@ class ActiveField extends Component return Html::endTag($this->tag); } + protected function getClientOptions() + { + if ($this->enableClientValidation || $this->enableClientValidation === null && $this->form->enableClientValidation) { + $attribute = Html::getAttributeName($this->attribute); + $validators = array(); + foreach ($this->model->getActiveValidators($attribute) as $validator) { + /** @var \yii\validators\Validator $validator */ + $js = $validator->clientValidateAttribute($this->model, $attribute); + if ($validator->enableClientValidation && $js != '') { + $validators[] = $js; + } + } + if ($validators !== array()) { + $options['validate'] = new JsExpression("function(attribute,value,messages){" . implode('', $validators) . '}'); + } + } + + if ($this->enableAjaxValidation || $this->enableAjaxValidation === null && $this->form->enableAjaxValidation) { + $options['enableAjaxValidation'] = 1; + } + + if (isset($options['validate']) || isset($options['enableAjaxValidation'])) { + $inputID = Html::getInputId($this->model, $this->attribute); + $options['name'] = $inputID; + if ($this->model instanceof ActiveRecord && !$this->model->getIsNewRecord()) { + $option['status'] = 1; + } + + $names = array( + 'enableAjaxValidation', + 'validateOnChange', + 'validateOnType', + 'validationDelay', + ); + foreach ($names as $name) { + $options[$name] = $this->$name === null ? $this->form->$name : $this->$name; + } + $options['container'] = isset($this->selectors['container']) ? $this->selectors['container'] : ".field-$inputID"; + $options['input'] = isset($this->selectors['input']) ? $this->selectors['input'] : "#$inputID"; + if (isset($this->errorOptions['class'])) { + $options['error'] = '.' . implode('.', preg_split('/\s+/', $this->errorOptions['class'], -1, PREG_SPLIT_NO_EMPTY)); + } else { + $options['error'] = isset($this->errorOptions['tag']) ? $this->errorOptions['tag'] : 'span'; + } + + foreach (array('beforeValidate', 'afterValidate') as $callback) { + $value = $this->$callback; + if ($value instanceof JsExpression) { + $options[$callback] = $value; + } elseif (is_string($value)) { + $options[$callback] = new JsExpression($value); + } + } + return $options; + } else { + return array(); + } + } + /** * Generates a label tag for [[attribute]]. * The label text is the label associated with the attribute, obtained via [[Model::getAttributeLabel()]]. diff --git a/framework/widgets/ActiveForm.php b/framework/widgets/ActiveForm.php index 80de64b..a735982 100644 --- a/framework/widgets/ActiveForm.php +++ b/framework/widgets/ActiveForm.php @@ -88,7 +88,7 @@ class ActiveForm extends Widget * @var boolean whether to perform validation when an input field loses focus and its value is found changed. * If [[ActiveField::validateOnChange]] is set, its value will take precedence for that input field. */ - public $validateOnChange = false; + public $validateOnChange = true; /** * @var boolean whether to perform validation while the user is typing in an input field. * If [[ActiveField::validateOnType]] is set, its value will take precedence for that input field. @@ -96,12 +96,16 @@ class ActiveForm extends Widget */ public $validateOnType = false; /** - * @var integer number of milliseconds that the validation should be delayed when a user is typing in an input field. - * This property is used only when [[validateOnType]] is true. + * @var integer number of milliseconds that the validation should be delayed when an input field + * is changed or the user types in the field. * If [[ActiveField::validationDelay]] is set, its value will take precedence for that input field. */ public $validationDelay = 200; /** + * @var string the name of the GET parameter indicating the validation request is an AJAX request. + */ + public $ajaxVar = 'ajax'; + /** * @var JsExpression|string a [[JsExpression]] object or a JavaScript expression string representing * the callback that will be invoked BEFORE validating EACH attribute on the client side. * The signature of the callback should be like the following: @@ -192,6 +196,7 @@ class ActiveForm extends Widget 'errorCssClass' => $this->errorCssClass, 'successCssClass' => $this->successCssClass, 'validatingCssClass' => $this->validatingCssClass, + 'ajaxVar' => $this->ajaxVar, ); if ($this->validationUrl !== null) { $options['validationUrl'] = Html::url($this->validationUrl); @@ -204,11 +209,10 @@ class ActiveForm extends Widget ); foreach ($callbacks as $callback) { $value = $this->$callback; - if (is_string($value)) { - $value = new JsExpression($value); - } if ($value instanceof JsExpression) { $options[$callback] = $value; + } elseif (is_string($value)) { + $options[$callback] = new JsExpression($value); } } From 9fc4c3807b86df641fb6c16a4b39f5e450fa6159 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Fri, 3 May 2013 08:52:41 -0400 Subject: [PATCH 24/87] form wip --- framework/assets/yii.activeForm.js | 49 ++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/framework/assets/yii.activeForm.js b/framework/assets/yii.activeForm.js index 8de93c8..a835be2 100644 --- a/framework/assets/yii.activeForm.js +++ b/framework/assets/yii.activeForm.js @@ -123,7 +123,7 @@ }, submitForm: function () { - var $form = $(this), + var $form = this, data = $form.data('yiiActiveForm'); if (data.validated) { // continue submitting the form since validation passes @@ -142,7 +142,7 @@ hasError = updateInput($form, this, messages) || hasError; }); updateSummary($form, messages); - if (!data.settings.afterValidate || data.settings.afterValidate($form, data, hasError)) { + if (!data.settings.afterValidate || data.settings.afterValidate($form, messages, hasError)) { if (!hasError) { data.validated = true; var $button = data.submitObject || $form.find(':submit:first'); @@ -167,7 +167,7 @@ }, resetForm: function () { - var $form = $(this); + var $form = this; var data = $form.data('yiiActiveForm'); // Because we bind directly to a form reset event instead of a reset button (that may not exist), // when this function is executed form input values have not been reset yet. @@ -190,26 +190,6 @@ } }; - var getValue = function ($form, attribute) { - var $input = findInput($form, attribute); - var type = $input.attr('type'); - if (type === 'checkbox' || type === 'radio') { - return $input.filter(':checked').val(); - } else { - return $input.val(); - } - }; - - var findInput = function ($form, attribute) { - var $input = $form.find(attribute.input); - if ($input.length && $input[0].tagName.toLowerCase() === 'div') { - // checkbox list or radio list - return $input.find('input'); - } else { - return $input; - } - }; - var watchAttributes = function ($form, attributes) { $.each(attributes, function (i, attribute) { var $input = findInput($form, attribute); @@ -304,6 +284,9 @@ }); if (needAjaxValidation && (!data.submitting || $.isEmptyObject(messages))) { + // Perform ajax validation when at least one input needs it. + // If the validation is triggered by form submission, ajax validation + // should be done only when all inputs pass client validation var $button = data.submitObject, extData = '&' + data.settings.ajaxVar + '=' + $form.attr('id'); if ($button && $button.length && $button.attr('name')) { @@ -389,4 +372,24 @@ } }; + var getValue = function ($form, attribute) { + var $input = findInput($form, attribute); + var type = $input.attr('type'); + if (type === 'checkbox' || type === 'radio') { + return $input.filter(':checked').val(); + } else { + return $input.val(); + } + }; + + var findInput = function ($form, attribute) { + var $input = $form.find(attribute.input); + if ($input.length && $input[0].tagName.toLowerCase() === 'div') { + // checkbox list or radio list + return $input.find('input'); + } else { + return $input; + } + }; + })(window.jQuery); \ No newline at end of file From 9100217229fb0231400ebde6cecfaf05200192ee Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Fri, 3 May 2013 14:35:53 -0400 Subject: [PATCH 25/87] Finished ActiveForm. --- framework/assets/yii.activeForm.js | 82 +++++++++++++++------------------ framework/helpers/base/Html.php | 1 + framework/widgets/ActiveField.php | 93 +++++++++++++++++++------------------- framework/widgets/ActiveForm.php | 61 +------------------------ 4 files changed, 86 insertions(+), 151 deletions(-) diff --git a/framework/assets/yii.activeForm.js b/framework/assets/yii.activeForm.js index a835be2..922bc92 100644 --- a/framework/assets/yii.activeForm.js +++ b/framework/assets/yii.activeForm.js @@ -35,14 +35,12 @@ validatingCssClass: 'validating', // the URL for performing AJAX-based validation. If not set, it will use the the form's action validationUrl: undefined, - // a callback that is called before validating every attribute - beforeValidateAttribute: undefined, - // a callback that is called after validating every attribute - afterValidateAttribute: undefined, - // a callback that is called before validating ALL attributes when submitting the form + // a callback that is called before submitting the form. The signature of the callback should be: + // function ($form) { ...return false to cancel submission...} + beforeSubmit: undefined, + // a callback that is called before validating each attribute. The signature of the callback should be: + // function ($form, attribute, messages) { ...return false to cancel the validation...} beforeValidate: undefined, - // a callback that is called after validating ALL attributes when submitting the form - afterValidate: undefined, // the GET parameter name indicating an AJAX-based validation ajaxVar: 'ajax' }; @@ -66,10 +64,6 @@ enableAjaxValidation: false, // function (attribute, value, messages), the client-side validation function. validate: undefined, - // callback called before validating the attribute - beforeValidate: undefined, - // callback called after validating an attribute. - afterValidate: undefined, // status of the input field, 0: empty, not entered before, 1: validated, 2: pending validation, 3: validating status: 0, // the value of the input @@ -122,6 +116,10 @@ }); }, + options: function() { + return this.data('yiiActiveForm').settings; + }, + submitForm: function () { var $form = this, data = $form.data('yiiActiveForm'); @@ -135,26 +133,24 @@ clearTimeout(data.settings.timer); } data.submitting = true; - if (!data.settings.beforeValidate || data.settings.beforeValidate($form)) { + if (!data.settings.beforeSubmit || data.settings.beforeSubmit($form)) { validate($form, function (messages) { var hasError = false; $.each(data.attributes, function () { hasError = updateInput($form, this, messages) || hasError; }); updateSummary($form, messages); - if (!data.settings.afterValidate || data.settings.afterValidate($form, messages, hasError)) { - if (!hasError) { - data.validated = true; - var $button = data.submitObject || $form.find(':submit:first'); - // TODO: if the submission is caused by "change" event, it will not work - if ($button.length) { - $button.click(); - } else { - // no submit button in the form - $form.submit(); - } - return; + if (!hasError) { + data.validated = true; + var $button = data.submitObject || $form.find(':submit:first'); + // TODO: if the submission is caused by "change" event, it will not work + if ($button.length) { + $button.click(); + } else { + // no submit button in the form + $form.submit(); } + return; } data.submitting = false; }, function () { @@ -235,25 +231,20 @@ if (data.submitting || $form.is(':hidden')) { return; } - if (!attribute.beforeValidate || attribute.beforeValidate($form, attribute)) { + $.each(data.attributes, function () { + if (this.status === 2) { + this.status = 3; + $form.find(this.container).addClass(data.settings.validatingCssClass); + } + }); + validate($form, function (messages) { + var hasError = false; $.each(data.attributes, function () { - if (this.status === 2) { - this.status = 3; - $form.find(this.container).addClass(data.settings.validatingCssClass); - } - }); - validate($form, function (messages) { - var hasError = false; - $.each(data.attributes, function () { - if (this.status === 2 || this.status === 3) { - hasError = updateInput($form, this, messages) || hasError; - } - }); - if (attribute.afterValidate) { - attribute.afterValidate($form, attribute, messages, hasError); + if (this.status === 2 || this.status === 3) { + hasError = updateInput($form, this, messages) || hasError; } }); - } + }); }, data.settings.validationDelay); }; @@ -271,15 +262,16 @@ $.each(data.attributes, function () { if (data.submitting || this.status === 2 || this.status === 3) { var msg = []; - if (this.validate) { - this.validate(this, getValue($form, this), msg); + if (!data.settings.beforeValidate || data.settings.beforeValidate($form, this, msg)) { + if (this.validate) { + this.validate(this, getValue($form, this), msg); + } if (msg.length) { messages[this.name] = msg; + } else if (this.enableAjaxValidation) { + needAjaxValidation = true; } } - if (this.enableAjaxValidation && !msg.length) { - needAjaxValidation = true; - } } }); diff --git a/framework/helpers/base/Html.php b/framework/helpers/base/Html.php index fd06226..6c875bb 100644 --- a/framework/helpers/base/Html.php +++ b/framework/helpers/base/Html.php @@ -896,6 +896,7 @@ class Html $attribute = static::getAttributeName($attribute); $label = isset($options['label']) ? $options['label'] : static::encode($model->getAttributeLabel($attribute)); $for = array_key_exists('for', $options) ? $options['for'] : static::getInputId($model, $attribute); + unset($options['label'], $options['for']); return static::label($label, $for, $options); } diff --git a/framework/widgets/ActiveField.php b/framework/widgets/ActiveField.php index bc7d696..55ff8e2 100644 --- a/framework/widgets/ActiveField.php +++ b/framework/widgets/ActiveField.php @@ -85,35 +85,12 @@ class ActiveField extends Component */ public $validationDelay; /** - * @var JsExpression|string a [[JsExpression]] object or a JavaScript expression string representing - * the callback that will be invoked BEFORE validating the attribute associated with this field on the client side. - * - * This callback is called after [[ActiveForm::beforeValidateAttribute]]. - * - * The signature of the callback should be like the following: - * - * ~~~ - * ~~~ - */ - public $beforeValidate; - /** - * @var JsExpression|string a [[JsExpression]] object or a JavaScript expression string representing - * the callback that will be invoked AFTER validating the attribute associated with this field on the client side. - * - * This callback is called before [[ActiveForm::afterValidateAttribute]]. - * - * The signature of the callback should be like the following: - * - * ~~~ - * ~~~ - */ - public $afterValidate; - /** * @var array the jQuery selectors for selecting the container, input and error tags. * The array keys should be "container", "input", and/or "error", and the array values * are the corresponding selectors. For example, `array('input' => '#my-input')`. * - * The selectors are used under the context of the form. + * The container selector is used under the context of the form, while the input and the error + * selectors are used under the context of the container. * * You normally do not need to set this property as the default selectors should work well for most cases. */ @@ -149,7 +126,9 @@ class ActiveField extends Component protected function getClientOptions() { - if ($this->enableClientValidation || $this->enableClientValidation === null && $this->form->enableClientValidation) { + $enableClientValidation = $this->enableClientValidation || $this->enableClientValidation === null && $this->form->enableClientValidation; + $enableAjaxValidation = $this->enableAjaxValidation || $this->enableAjaxValidation === null && $this->form->enableAjaxValidation; + if ($enableClientValidation) { $attribute = Html::getAttributeName($this->attribute); $validators = array(); foreach ($this->model->getActiveValidators($attribute) as $validator) { @@ -164,19 +143,14 @@ class ActiveField extends Component } } - if ($this->enableAjaxValidation || $this->enableAjaxValidation === null && $this->form->enableAjaxValidation) { + if ($enableAjaxValidation) { $options['enableAjaxValidation'] = 1; } - if (isset($options['validate']) || isset($options['enableAjaxValidation'])) { + if ($enableClientValidation || $enableAjaxValidation) { $inputID = Html::getInputId($this->model, $this->attribute); $options['name'] = $inputID; - if ($this->model instanceof ActiveRecord && !$this->model->getIsNewRecord()) { - $option['status'] = 1; - } - $names = array( - 'enableAjaxValidation', 'validateOnChange', 'validateOnType', 'validationDelay', @@ -191,15 +165,6 @@ class ActiveField extends Component } else { $options['error'] = isset($this->errorOptions['tag']) ? $this->errorOptions['tag'] : 'span'; } - - foreach (array('beforeValidate', 'afterValidate') as $callback) { - $value = $this->$callback; - if ($value instanceof JsExpression) { - $options[$callback] = $value; - } elseif (is_string($value)) { - $options[$callback] = new JsExpression($value); - } - } return $options; } else { return array(); @@ -359,11 +324,29 @@ class ActiveField extends Component * * The rest of the options will be rendered as the attributes of the resulting tag. The values will * be HTML-encoded using [[encode()]]. If a value is null, the corresponding attribute will not be rendered. + * @param boolean $enclosedByLabel whether to enclose the radio within the label. + * If true, the method will still use [[template]] to layout the checkbox and the error message + * except that the radio is enclosed by the label tag. * @return string the generated radio button tag */ - public function radio($options = array()) + public function radio($options = array(), $enclosedByLabel = true) { - return $this->render(Html::activeRadio($this->model, $this->attribute, $options)); + if ($enclosedByLabel) { + $hidden = ''; + $radio = Html::activeRadio($this->model, $this->attribute, $options); + if (($pos = strpos($radio, '><')) !== false) { + $hidden = substr($radio, 0, $pos + 1); + $radio = substr($radio, $pos + 1); + } + $label = isset($this->labelOptions['label']) ? $this->labelOptions['label'] : Html::encode($this->model->getAttributeLabel($this->attribute)); + return $this->begin() . "\n" . $hidden . strtr($this->template, array( + '{input}' => Html::label("$radio $label", null, array('class' => 'radio')), + '{label}' => '', + '{error}' => $this->error(), + )) . "\n" . $this->end(); + } else { + return $this->render(Html::activeRadio($this->model, $this->attribute, $options)); + } } /** @@ -379,11 +362,29 @@ class ActiveField extends Component * * The rest of the options will be rendered as the attributes of the resulting tag. The values will * be HTML-encoded using [[encode()]]. If a value is null, the corresponding attribute will not be rendered. + * @param boolean $enclosedByLabel whether to enclose the checkbox within the label. + * If true, the method will still use [[template]] to layout the checkbox and the error message + * except that the checkbox is enclosed by the label tag. * @return string the generated checkbox tag */ - public function checkbox($options = array()) + public function checkbox($options = array(), $enclosedByLabel = true) { - return $this->render(Html::activeCheckbox($this->model, $this->attribute, $options)); + if ($enclosedByLabel) { + $hidden = ''; + $checkbox = Html::activeCheckbox($this->model, $this->attribute, $options); + if (($pos = strpos($checkbox, '><')) !== false) { + $hidden = substr($checkbox, 0, $pos + 1); + $checkbox = substr($checkbox, $pos + 1); + } + $label = isset($this->labelOptions['label']) ? $this->labelOptions['label'] : Html::encode($this->model->getAttributeLabel($this->attribute)); + return $this->begin() . "\n" . $hidden . strtr($this->template, array( + '{input}' => Html::label("$checkbox $label", null, array('class' => 'checkbox')), + '{label}' => '', + '{error}' => $this->error(), + )) . "\n" . $this->end(); + } else { + return $this->render(Html::activeCheckbox($this->model, $this->attribute, $options)); + } } /** diff --git a/framework/widgets/ActiveForm.php b/framework/widgets/ActiveForm.php index a735982..7e284ba 100644 --- a/framework/widgets/ActiveForm.php +++ b/framework/widgets/ActiveForm.php @@ -106,51 +106,7 @@ class ActiveForm extends Widget */ public $ajaxVar = 'ajax'; /** - * @var JsExpression|string a [[JsExpression]] object or a JavaScript expression string representing - * the callback that will be invoked BEFORE validating EACH attribute on the client side. - * The signature of the callback should be like the following: - * - * ~~~ - * ~~~ - */ - public $beforeValidateAttribute; - /** - * @var JsExpression|string a [[JsExpression]] object or a JavaScript expression string representing - * the callback that will be invoked AFTER validating EACH attribute on the client side. - * The signature of the callback should be like the following: - * - * ~~~ - * ~~~ - */ - public $afterValidateAttribute; - /** - * @var JsExpression|string a [[JsExpression]] object or a JavaScript expression string representing - * the callback that will be invoked BEFORE validating ALL attributes on the client side when the validation - * is triggered by form submission (that is, [[validateOnSubmit]] is set true). - * - * This callback is called before [[beforeValidateAttribute]]. - * - * The signature of the callback should be like the following: - * - * ~~~ - * ~~~ - */ - public $beforeValidate; - /** - * @var JsExpression|string a [[JsExpression]] object or a JavaScript expression string representing - * the callback that will be invoked AFTER validating ALL attributes on the client side when the validation - * is triggered by form submission (that is, [[validateOnSubmit]] is set true). - * - * This callback is called after [[afterValidateAttribute]]. - * - * The signature of the callback should be like the following: - * - * ~~~ - * ~~~ - */ - public $afterValidate; - /** - * @var array list of attributes that need to be validated on the client side. Each element of the array + * @var array the client validation options for individual attributes. Each element of the array * represents the validation options for a particular attribute. * @internal */ @@ -201,21 +157,6 @@ class ActiveForm extends Widget if ($this->validationUrl !== null) { $options['validationUrl'] = Html::url($this->validationUrl); } - $callbacks = array( - 'beforeValidateAttribute', - 'afterValidateAttribute', - 'beforeValidate', - 'afterValidate', - ); - foreach ($callbacks as $callback) { - $value = $this->$callback; - if ($value instanceof JsExpression) { - $options[$callback] = $value; - } elseif (is_string($value)) { - $options[$callback] = new JsExpression($value); - } - } - return $options; } From 0d182ace4090df3d2c0767e0ab7578dfdb03efdd Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Fri, 3 May 2013 15:13:18 -0400 Subject: [PATCH 26/87] basic app WIP --- app/css/site.css | 78 ++++++++++++++++++++++++++++ app/protected/config/assets.php | 19 +++++++ app/protected/config/main.php | 5 +- app/protected/controllers/SiteController.php | 10 ++++ app/protected/views/layouts/main.php | 43 ++++++++++++--- app/protected/views/site/about.php | 8 +++ app/protected/views/site/contact.php | 10 ++++ app/protected/views/site/index.php | 54 +++++++++++++++---- app/protected/views/site/login.php | 3 +- 9 files changed, 210 insertions(+), 20 deletions(-) create mode 100644 app/css/site.css create mode 100644 app/protected/config/assets.php create mode 100644 app/protected/views/site/about.php create mode 100644 app/protected/views/site/contact.php diff --git a/app/css/site.css b/app/css/site.css new file mode 100644 index 0000000..890a953 --- /dev/null +++ b/app/css/site.css @@ -0,0 +1,78 @@ +body { + padding-top: 20px; + padding-bottom: 60px; +} + +/* Custom container */ +.container { + margin: 0 auto; + max-width: 1000px; +} + +.container > hr { + margin: 60px 0; +} + +/* Main marketing message and sign up button */ +.jumbotron { + margin: 80px 0; + text-align: center; +} + +.jumbotron h1 { + font-size: 100px; + line-height: 1; +} + +.jumbotron .lead { + font-size: 24px; + line-height: 1.25; +} + +.jumbotron .btn { + font-size: 21px; + padding: 14px 24px; +} + +/* Supporting marketing content */ +.marketing { + margin: 60px 0; +} + +.marketing p + h4 { + margin-top: 28px; +} + +/* Customize the navbar links to be fill the entire space of the .navbar */ +.navbar .navbar-inner { + padding: 0; +} + +.navbar .nav { + margin: 0; + display: table; + width: 100%; +} + +.navbar .nav li { + display: table-cell; + width: 1%; + float: none; +} + +.navbar .nav li a { + font-weight: bold; + text-align: center; + border-left: 1px solid rgba(255, 255, 255, .75); + border-right: 1px solid rgba(0, 0, 0, .1); +} + +.navbar .nav li:first-child a { + border-left: 0; + border-radius: 3px 0 0 3px; +} + +.navbar .nav li:last-child a { + border-right: 0; + border-radius: 0 3px 3px 0; +} diff --git a/app/protected/config/assets.php b/app/protected/config/assets.php new file mode 100644 index 0000000..6602a6e --- /dev/null +++ b/app/protected/config/assets.php @@ -0,0 +1,19 @@ + array( + 'basePath' => '@wwwroot', + 'baseUrl' => '@www', + 'css' => array( + 'css/bootstrap.min.css', + 'css/bootstrap-responsive.min.css', + 'css/site.css', + ), + 'js' => array( + + ), + 'depends' => array( + 'yii', + ), + ), +); \ No newline at end of file diff --git a/app/protected/config/main.php b/app/protected/config/main.php index e18ead8..7722331 100644 --- a/app/protected/config/main.php +++ b/app/protected/config/main.php @@ -10,6 +10,9 @@ return array( 'user' => array( 'class' => 'yii\web\User', 'identityClass' => 'app\models\User', - ) + ), + 'assetManager' => array( + 'bundles' => require(__DIR__ . '/assets.php'), + ), ), ); \ No newline at end of file diff --git a/app/protected/controllers/SiteController.php b/app/protected/controllers/SiteController.php index 39e9c1f..fb5e0ce 100644 --- a/app/protected/controllers/SiteController.php +++ b/app/protected/controllers/SiteController.php @@ -27,4 +27,14 @@ class SiteController extends Controller Yii::$app->getUser()->logout(); Yii::$app->getResponse()->redirect(array('site/index')); } + + public function actionContact() + { + echo $this->render('contact'); + } + + public function actionAbout() + { + echo $this->render('about'); + } } \ No newline at end of file diff --git a/app/protected/views/layouts/main.php b/app/protected/views/layouts/main.php index 89c141f..a09b610 100644 --- a/app/protected/views/layouts/main.php +++ b/app/protected/views/layouts/main.php @@ -4,23 +4,52 @@ * @var $content string */ use yii\helpers\Html; +$this->registerAssetBundle('app'); ?> beginPage(); ?> - + <?php echo Html::encode($this->title); ?> - 'screen')); ?> head(); ?> -
    -

    Welcome

    - beginBody(); ?> - - endBody(); ?> +
    + beginBody(); ?> +
    +

    My Company

    + + +
    + + + + + endBody(); ?> +
    endPage(); ?> \ No newline at end of file diff --git a/app/protected/views/site/about.php b/app/protected/views/site/about.php new file mode 100644 index 0000000..66c66dc --- /dev/null +++ b/app/protected/views/site/about.php @@ -0,0 +1,8 @@ +title = 'About'; +?> +

    title); ?>

    \ No newline at end of file diff --git a/app/protected/views/site/contact.php b/app/protected/views/site/contact.php new file mode 100644 index 0000000..c6109cb --- /dev/null +++ b/app/protected/views/site/contact.php @@ -0,0 +1,10 @@ +title = 'Contact'; +?> +

    title); ?>

    diff --git a/app/protected/views/site/index.php b/app/protected/views/site/index.php index 66e4dd1..4444fe3 100644 --- a/app/protected/views/site/index.php +++ b/app/protected/views/site/index.php @@ -1,17 +1,49 @@ title = 'Welcome'; +?> +
    +

    Marketing stuff!

    -use yii\helpers\Html; +

    Cras justo odio, dapibus ac facilisis in, egestas eget quam. Fusce dapibus, tellus ac cursus + commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.

    + Get started today +
    -$this->title = 'Hello World'; +
    -$user = Yii::$app->getUser(); -if ($user->isGuest) { - echo Html::a('login', array('login')); -} else { - echo "You are logged in as " . $user->identity->username . "
    "; - echo Html::a('logout', array('logout')); -} -?> + +
    +
    +

    Heading

    + +

    Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris + condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. + Donec sed odio dui.

    + +

    View details »

    +
    +
    +

    Heading

    + +

    Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris + condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. + Donec sed odio dui.

    + +

    View details »

    +
    +
    +

    Heading

    + +

    Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta + felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum + massa.

    + +

    View details »

    +
    +
    +
    diff --git a/app/protected/views/site/login.php b/app/protected/views/site/login.php index e6da8ef..68272b4 100644 --- a/app/protected/views/site/login.php +++ b/app/protected/views/site/login.php @@ -5,8 +5,9 @@ use yii\helpers\Html; * @var yii\widgets\ActiveForm $form * @var app\models\LoginForm $model */ +$this->title = 'Login'; ?> -

    Login

    +

    title); ?>

    Please fill out the following fields to login:

    From 147b3155c8e23b189ca3b4447518f3e091aa7b0a Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Fri, 3 May 2013 17:09:02 -0400 Subject: [PATCH 27/87] Added contact page. Fixed various form bugs. --- app/protected/config/main.php | 3 ++ app/protected/controllers/SiteController.php | 13 +++++- app/protected/models/ContactForm.php | 63 ++++++++++++++++++++++++++++ app/protected/models/LoginForm.php | 27 +++++++----- app/protected/views/layouts/main.php | 2 + app/protected/views/site/about.php | 9 +++- app/protected/views/site/contact.php | 17 ++++++++ app/protected/views/site/index.php | 6 +-- framework/assets/yii.activeForm.js | 6 +-- framework/helpers/base/Html.php | 2 +- framework/web/Controller.php | 1 - framework/web/Response.php | 14 +++++++ framework/widgets/ActiveField.php | 39 ++++++++++------- framework/widgets/ActiveForm.php | 7 ++-- 14 files changed, 170 insertions(+), 39 deletions(-) create mode 100644 app/protected/models/ContactForm.php diff --git a/app/protected/config/main.php b/app/protected/config/main.php index 7722331..b982506 100644 --- a/app/protected/config/main.php +++ b/app/protected/config/main.php @@ -15,4 +15,7 @@ return array( 'bundles' => require(__DIR__ . '/assets.php'), ), ), + 'params' => array( + 'adminEmail' => 'admin@example.com', + ), ); \ No newline at end of file diff --git a/app/protected/controllers/SiteController.php b/app/protected/controllers/SiteController.php index fb5e0ce..33a87c9 100644 --- a/app/protected/controllers/SiteController.php +++ b/app/protected/controllers/SiteController.php @@ -2,6 +2,7 @@ use yii\web\Controller; use app\models\LoginForm; +use app\models\ContactForm; class SiteController extends Controller { @@ -14,7 +15,7 @@ class SiteController extends Controller { $model = new LoginForm(); if ($this->populate($_POST, $model) && $model->login()) { - Yii::$app->getResponse()->redirect(array('site/index')); + Yii::$app->response->redirect(array('site/index')); } else { echo $this->render('login', array( 'model' => $model, @@ -30,7 +31,15 @@ class SiteController extends Controller public function actionContact() { - echo $this->render('contact'); + $model = new ContactForm; + if ($this->populate($_POST, $model) && $model->contact(Yii::$app->params['adminEmail'])) { + Yii::$app->session->setFlash('contact', 'Thank you for contacting us. We will respond to you as soon as possible.'); + Yii::$app->response->refresh(); + } else { + echo $this->render('contact', array( + 'model' => $model, + )); + } } public function actionAbout() diff --git a/app/protected/models/ContactForm.php b/app/protected/models/ContactForm.php new file mode 100644 index 0000000..8e8f831 --- /dev/null +++ b/app/protected/models/ContactForm.php @@ -0,0 +1,63 @@ + !Captcha::checkRequirements()), + ); + } + + /** + * @return array customized attribute labels + */ + public function attributeLabels() + { + return array( + 'verifyCode' => 'Verification Code', + ); + } + + /** + * Sends an email to the specified email address using the information collected by this model. + * @param string $email the target email address + * @return boolean whether the model passes validation + */ + public function contact($email) + { + if ($this->validate()) { + $name = '=?UTF-8?B?' . base64_encode($this->name) . '?='; + $subject = '=?UTF-8?B?' . base64_encode($this->subject) . '?='; + $headers = "From: $name <{$this->email}>\r\n" . + "Reply-To: {$this->email}\r\n" . + "MIME-Version: 1.0\r\n" . + "Content-type: text/plain; charset=UTF-8"; + mail($email, $subject, $this->body, $headers); + return true; + } else { + return false; + } + } +} \ No newline at end of file diff --git a/app/protected/models/LoginForm.php b/app/protected/models/LoginForm.php index b68e146..23e8c92 100644 --- a/app/protected/models/LoginForm.php +++ b/app/protected/models/LoginForm.php @@ -1,9 +1,4 @@ - * @since 2.0 + * LoginForm is the model behind the login form. */ class LoginForm extends Model { @@ -20,16 +14,25 @@ class LoginForm extends Model public $password; public $rememberMe = true; + /** + * @return array the validation rules. + */ public function rules() { return array( - array('username', 'required'), - array('password', 'required'), + // username and password are both required + array('username, password', 'required'), + // password is validated by validatePassword() array('password', 'validatePassword'), + // rememberMe must be a boolean value array('rememberMe', 'boolean'), ); } + /** + * Validates the password. + * This method serves as the inline validation for password. + */ public function validatePassword() { $user = User::findByUsername($this->username); @@ -38,11 +41,15 @@ class LoginForm extends Model } } + /** + * Logs in a user using the provided username and password. + * @return boolean whether the user is logged in successfully + */ public function login() { if ($this->validate()) { $user = User::findByUsername($this->username); - Yii::$app->getUser()->login($user, $this->rememberMe ? 3600*24*30 : 0); + Yii::$app->user->login($user, $this->rememberMe ? 3600*24*30 : 0); return true; } else { return false; diff --git a/app/protected/views/layouts/main.php b/app/protected/views/layouts/main.php index a09b610..a455f20 100644 --- a/app/protected/views/layouts/main.php +++ b/app/protected/views/layouts/main.php @@ -41,6 +41,8 @@ $this->registerAssetBundle('app'); +
    +
    -
    - diff --git a/framework/assets/yii.activeForm.js b/framework/assets/yii.activeForm.js index 922bc92..158ea74 100644 --- a/framework/assets/yii.activeForm.js +++ b/framework/assets/yii.activeForm.js @@ -83,7 +83,7 @@ settings.validationUrl = $form.attr('action'); } $.each(attributes, function (i) { - attributes[i] = $.extend({}, attributeDefaults, this); + attributes[i] = $.extend({value: getValue($form, this)}, attributeDefaults, this); }); $form.data('yiiActiveForm', { settings: settings, @@ -121,7 +121,7 @@ }, submitForm: function () { - var $form = this, + var $form = $(this), data = $form.data('yiiActiveForm'); if (data.validated) { // continue submitting the form since validation passes @@ -163,7 +163,7 @@ }, resetForm: function () { - var $form = this; + var $form = $(this); var data = $form.data('yiiActiveForm'); // Because we bind directly to a form reset event instead of a reset button (that may not exist), // when this function is executed form input values have not been reset yet. diff --git a/framework/helpers/base/Html.php b/framework/helpers/base/Html.php index 6c875bb..5b8e7db 100644 --- a/framework/helpers/base/Html.php +++ b/framework/helpers/base/Html.php @@ -95,9 +95,9 @@ class Html public static $attributeOrder = array( 'type', 'id', - 'class', 'name', 'value', + 'class', 'href', 'src', diff --git a/framework/web/Controller.php b/framework/web/Controller.php index 8049299..099bf96 100644 --- a/framework/web/Controller.php +++ b/framework/web/Controller.php @@ -8,7 +8,6 @@ namespace yii\web; use Yii; -use yii\helpers\Html; /** * Controller is the base class of Web controllers. diff --git a/framework/web/Response.php b/framework/web/Response.php index 1d604e9..0503755 100644 --- a/framework/web/Response.php +++ b/framework/web/Response.php @@ -115,6 +115,7 @@ class Response extends \yii\base\Response *
  • forceDownload: specifies whether the file will be downloaded or shown inline, defaults to true
  • *
  • addHeaders: an array of additional http headers in header-value pairs
  • * + * @todo */ public function xSendFile($filePath, $options = array()) { @@ -196,6 +197,19 @@ class Response extends \yii\base\Response } /** + * Refreshes the current page. + * The effect of this method call is the same as the user pressing the refresh button of his browser + * (without re-posting data). + * @param boolean $terminate whether to terminate the current application after calling this method + * @param string $anchor the anchor that should be appended to the redirection URL. + * Defaults to empty. Make sure the anchor starts with '#' if you want to specify it. + */ + public function refresh($terminate = true, $anchor = '') + { + $this->redirect(Yii::$app->getRequest()->getUrl() . $anchor, $terminate); + } + + /** * Returns the cookie collection. * Through the returned cookie collection, you add or remove cookies as follows, * diff --git a/framework/widgets/ActiveField.php b/framework/widgets/ActiveField.php index 55ff8e2..da17012 100644 --- a/framework/widgets/ActiveField.php +++ b/framework/widgets/ActiveField.php @@ -48,13 +48,18 @@ class ActiveField extends Component */ public $template = "{label}\n
    \n{input}\n{error}\n
    "; /** - * @var array the default options for the error message. This property is used when calling [[error()]] - * without the `$options` parameter. + * @var array the default options for the input tags. The parameter passed to individual input methods + * (e.g. [[textInput()]]) will be merged with this property when rendering the input tag. + */ + public $inputOptions = array(); + /** + * @var array the default options for the error tags. The parameter passed to [[error()]] will be + * merged with this property when rendering the error tag. */ public $errorOptions = array('tag' => 'span', 'class' => 'help-inline'); /** - * @var array the default options for the label. This property is used when calling [[label()]] - * without the `$options` parameter. + * @var array the default options for the label tags. The parameter passed to [[label()]] will be + * merged with this property when rendering the label tag. */ public $labelOptions = array('class' => 'control-label'); /** @@ -174,7 +179,7 @@ class ActiveField extends Component /** * Generates a label tag for [[attribute]]. * The label text is the label associated with the attribute, obtained via [[Model::getAttributeLabel()]]. - * @param array $options the tag options in terms of name-value pairs. If this is null, [[labelOptions]] will be used. + * @param array $options the tag options in terms of name-value pairs. It will be merged with [[labelOptions]]. * The options will be rendered as the attributes of the resulting tag. The values will be HTML-encoded * using [[encode()]]. If a value is null, the corresponding attribute will not be rendered. * @@ -186,18 +191,16 @@ class ActiveField extends Component * * @return string the generated label tag */ - public function label($options = null) + public function label($options = array()) { - if ($options === null) { - $options = $this->labelOptions; - } + $options = array_merge($this->labelOptions, $options); return Html::activeLabel($this->model, $this->attribute, $options); } /** * Generates a tag that contains the first validation error of [[attribute]]. * Note that even if there is no validation error, this method will still return an empty error tag. - * @param array $options the tag options in terms of name-value pairs. If this is null, [[errorOptions]] will be used. + * @param array $options the tag options in terms of name-value pairs. It will be merged with [[errorOptions]]. * The options will be rendered as the attributes of the resulting tag. The values will be HTML-encoded * using [[encode()]]. If a value is null, the corresponding attribute will not be rendered. * @@ -207,11 +210,9 @@ class ActiveField extends Component * * @return string the generated label tag */ - public function error($options = null) + public function error($options = array()) { - if ($options === null) { - $options = $this->errorOptions; - } + $options = array_merge($this->errorOptions, $options); $attribute = Html::getAttributeName($this->attribute); $error = $this->model->getFirstError($attribute); $tag = isset($options['tag']) ? $options['tag'] : 'span'; @@ -244,6 +245,7 @@ class ActiveField extends Component */ public function input($type, $options = array()) { + $options = array_merge($this->inputOptions, $options); return $this->render(Html::activeInput($type, $this->model, $this->attribute, $options)); } @@ -257,6 +259,7 @@ class ActiveField extends Component */ public function textInput($options = array()) { + $options = array_merge($this->inputOptions, $options); return $this->render(Html::activeTextInput($this->model, $this->attribute, $options)); } @@ -270,6 +273,7 @@ class ActiveField extends Component */ public function hiddenInput($options = array()) { + $options = array_merge($this->inputOptions, $options); return $this->render(Html::activeHiddenInput($this->model, $this->attribute, $options)); } @@ -283,6 +287,7 @@ class ActiveField extends Component */ public function passwordInput($options = array()) { + $options = array_merge($this->inputOptions, $options); return $this->render(Html::activePasswordInput($this->model, $this->attribute, $options)); } @@ -296,6 +301,7 @@ class ActiveField extends Component */ public function fileInput($options = array()) { + $options = array_merge($this->inputOptions, $options); return $this->render(Html::activeFileInput($this->model, $this->attribute, $options)); } @@ -308,6 +314,7 @@ class ActiveField extends Component */ public function textarea($options = array()) { + $options = array_merge($this->inputOptions, $options); return $this->render(Html::activeTextarea($this->model, $this->attribute, $options)); } @@ -331,6 +338,7 @@ class ActiveField extends Component */ public function radio($options = array(), $enclosedByLabel = true) { + $options = array_merge($this->inputOptions, $options); if ($enclosedByLabel) { $hidden = ''; $radio = Html::activeRadio($this->model, $this->attribute, $options); @@ -369,6 +377,7 @@ class ActiveField extends Component */ public function checkbox($options = array(), $enclosedByLabel = true) { + $options = array_merge($this->inputOptions, $options); if ($enclosedByLabel) { $hidden = ''; $checkbox = Html::activeCheckbox($this->model, $this->attribute, $options); @@ -421,6 +430,7 @@ class ActiveField extends Component */ public function dropDownList($items, $options = array()) { + $options = array_merge($this->inputOptions, $options); return $this->render(Html::activeDropDownList($this->model, $this->attribute, $items, $options)); } @@ -461,6 +471,7 @@ class ActiveField extends Component */ public function listBox($items, $options = array()) { + $options = array_merge($this->inputOptions, $options); return $this->render(Html::activeListBox($this->model, $this->attribute, $items, $options)); } diff --git a/framework/widgets/ActiveForm.php b/framework/widgets/ActiveForm.php index 7e284ba..c11bceb 100644 --- a/framework/widgets/ActiveForm.php +++ b/framework/widgets/ActiveForm.php @@ -40,9 +40,7 @@ class ActiveForm extends Widget /** * @var array the default configuration used by [[field()]] when creating a new field object. */ - public $fieldConfig = array( - 'class' => 'yii\widgets\ActiveField', - ); + public $fieldConfig; /** * @var string the default CSS class for the error summary container. * @see errorSummary() @@ -121,6 +119,9 @@ class ActiveForm extends Widget if (!isset($this->options['id'])) { $this->options['id'] = $this->getId(); } + if (!isset($this->fieldConfig['class'])) { + $this->fieldConfig['class'] = 'yii\widgets\ActiveField'; + } echo Html::beginForm($this->action, $this->method, $this->options); } From 6e997cb428563cd67d61c3f90fc25563ad141e70 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Fri, 3 May 2013 17:28:19 -0400 Subject: [PATCH 28/87] improved contact page. --- app/protected/controllers/SiteController.php | 2 +- app/protected/views/site/contact.php | 16 +++++++++++----- app/protected/views/site/login.php | 6 ++---- framework/web/Session.php | 2 +- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/app/protected/controllers/SiteController.php b/app/protected/controllers/SiteController.php index 33a87c9..7e6bb15 100644 --- a/app/protected/controllers/SiteController.php +++ b/app/protected/controllers/SiteController.php @@ -33,7 +33,7 @@ class SiteController extends Controller { $model = new ContactForm; if ($this->populate($_POST, $model) && $model->contact(Yii::$app->params['adminEmail'])) { - Yii::$app->session->setFlash('contact', 'Thank you for contacting us. We will respond to you as soon as possible.'); + Yii::$app->session->setFlash('contactFormSubmitted'); Yii::$app->response->refresh(); } else { echo $this->render('contact', array( diff --git a/app/protected/views/site/contact.php b/app/protected/views/site/contact.php index 726498e..246570d 100644 --- a/app/protected/views/site/contact.php +++ b/app/protected/views/site/contact.php @@ -9,7 +9,15 @@ $this->title = 'Contact'; ?>

    title); ?>

    -

    Please fill out the following fields:

    +session->hasFlash('contactFormSubmitted')): ?> +
    + Thank you for contacting us. We will respond to you as soon as possible. +
    + + +

    + If you have business inquiries or other questions, please fill out the following form to contact us. Thank you. +

    beginWidget('yii\widgets\ActiveForm', array( 'options' => array('class' => 'form-horizontal'), @@ -19,9 +27,7 @@ $this->title = 'Contact'; field($model, 'email')->textInput(); ?> field($model, 'subject')->textInput(); ?> field($model, 'body')->textArea(array('rows' => 6)); ?> -
    -
    - 'btn btn-primary')); ?> -
    +
    + 'btn btn-primary')); ?>
    endWidget(); ?> \ No newline at end of file diff --git a/app/protected/views/site/login.php b/app/protected/views/site/login.php index 68272b4..5608ffb 100644 --- a/app/protected/views/site/login.php +++ b/app/protected/views/site/login.php @@ -15,9 +15,7 @@ $this->title = 'Login'; field($model, 'username')->textInput(); ?> field($model, 'password')->passwordInput(); ?> field($model, 'rememberMe')->checkbox(); ?> -
    -
    - 'btn btn-primary')); ?> -
    +
    + 'btn btn-primary')); ?>
    endWidget(); ?> \ No newline at end of file diff --git a/framework/web/Session.php b/framework/web/Session.php index 4c0505f..1b48433 100644 --- a/framework/web/Session.php +++ b/framework/web/Session.php @@ -587,7 +587,7 @@ class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Co * session variable using the same name, its value will be overwritten by this method. * @param mixed $value flash message */ - public function setFlash($key, $value) + public function setFlash($key, $value = true) { $counters = $this->get($this->flashVar, array()); $counters[$key] = 0; From 6d362bf1a7aba877bb79d0b7952de534aeca7d60 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Fri, 3 May 2013 17:40:57 -0400 Subject: [PATCH 29/87] Added htaccess files. --- app/protected/.htaccess | 1 + framework/.htaccess | 1 + 2 files changed, 2 insertions(+) create mode 100644 app/protected/.htaccess create mode 100644 framework/.htaccess diff --git a/app/protected/.htaccess b/app/protected/.htaccess new file mode 100644 index 0000000..e019832 --- /dev/null +++ b/app/protected/.htaccess @@ -0,0 +1 @@ +deny from all diff --git a/framework/.htaccess b/framework/.htaccess new file mode 100644 index 0000000..e019832 --- /dev/null +++ b/framework/.htaccess @@ -0,0 +1 @@ +deny from all From 05d5962cfa3a3b6888c42a59e6cdcc43dbf78419 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Fri, 3 May 2013 20:58:49 -0400 Subject: [PATCH 30/87] guide wip --- docs/guide/application.md | 0 docs/guide/bootstrap.md | 63 +++++++++++++++++++++++++ docs/guide/controller.md | 0 docs/guide/index.md | 30 ++++++++++++ docs/guide/installation.md | 111 +++++++++++++++++++++++++++++++++++++++++++++ docs/guide/model.md | 0 docs/guide/mvc.md | 51 +++++++++++++++++++++ docs/guide/overview.md | 36 +++++++++++++++ docs/guide/title.md | 8 ++++ docs/guide/view.md | 0 todo.md | 49 -------------------- 11 files changed, 299 insertions(+), 49 deletions(-) create mode 100644 docs/guide/application.md create mode 100644 docs/guide/bootstrap.md create mode 100644 docs/guide/controller.md create mode 100644 docs/guide/index.md create mode 100644 docs/guide/installation.md create mode 100644 docs/guide/model.md create mode 100644 docs/guide/mvc.md create mode 100644 docs/guide/overview.md create mode 100644 docs/guide/title.md create mode 100644 docs/guide/view.md delete mode 100644 todo.md diff --git a/docs/guide/application.md b/docs/guide/application.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/bootstrap.md b/docs/guide/bootstrap.md new file mode 100644 index 0000000..5f00a75 --- /dev/null +++ b/docs/guide/bootstrap.md @@ -0,0 +1,63 @@ +Bootstrap with Yii +================== + +A ready-to-use Web application is distributed together with Yii. You may find +its source code under the `app` folder after you expand the Yii release file. +If you have installed Yii under a Web-accessible folder, you should be able to +access this application through the following URL: + +~~~ +http://localhost/yii/app/index.php +~~~ + + +As you can see, the application has four pages: the homepage, the about page, +the contact page and the login page. The contact page displays a contact +form that users can fill in to submit their inquiries to the webmaster, +and the login page allows users to be authenticated before accessing privileged contents. + + +The following diagram shows the directory structure of this application. + +~~~ +app/ + index.php Web application entry script file + index-test.php entry script file for the functional tests + assets/ containing published resource files + css/ containing CSS files + img/ containing image files + themes/ containing application themes + protected/ containing protected application files + yiic yiic command line script for Unix/Linux + yiic.bat yiic command line script for Windows + yiic.php yiic command line PHP script + commands/ containing customized 'yiic' commands + components/ containing reusable user components + config/ containing configuration files + console.php the console application configuration + main.php the Web application configuration + controllers/ containing controller class files + SiteController.php the default controller class + data/ containing the sample database + schema.mysql.sql the DB schema for the sample MySQL database + schema.sqlite.sql the DB schema for the sample SQLite database + bootstrap.db the sample SQLite database file + vendor/ containing third-party extensions and libraries + messages/ containing translated messages + models/ containing model class files + User.php the User model + LoginForm.php the form model for 'login' action + ContactForm.php the form model for 'contact' action + runtime/ containing temporarily generated files + views/ containing controller view and layout files + layouts/ containing layout view files + main.php the base layout shared by all pages + site/ containing view files for the 'site' controller + about.php the view for the 'about' action + contact.php the view for the 'contact' action + index.php the view for the 'index' action + login.php the view for the 'login' action +~~~ + + +TBD \ No newline at end of file diff --git a/docs/guide/controller.md b/docs/guide/controller.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/index.md b/docs/guide/index.md new file mode 100644 index 0000000..6ad733c --- /dev/null +++ b/docs/guide/index.md @@ -0,0 +1,30 @@ +* [Overview](overview.md) +* [Installation](installation.md) +* [Bootstrap with Yii](bootstrap.md) +* [MVC Overview](mvc.md) +* [Controller](controller.md) +* [Model](model.md) +* [View](view.md) +* [Application](application.md) +* [Form](form.md) +* [Data Validation](validation.md) +* [Database Access Objects](dao.md) +* [Query Builder](query-builder.md) +* [ActiveRecord](active-record.md) +* [Database Migration](migration.md) +* [Caching](caching.md) +* [Internationalization](i18n.md) +* [Extending Yii](extension.md) +* [Authentication](authentication.md) +* [Authorization](authorization.md) +* [Logging](logging.md) +* [URL Management](url.md) +* [Theming](theming.md) +* [Error Handling](error.md) +* [Template](template.md) +* [Console Application](console.md) +* [Security](security.md) +* [Performance Tuning](performance.md) +* [Testing](testing.md) +* [Automatic Code Generation](gii.md) +* [Upgrading from 1.1 to 2.0](upgrade.md) diff --git a/docs/guide/installation.md b/docs/guide/installation.md new file mode 100644 index 0000000..6cc5ef8 --- /dev/null +++ b/docs/guide/installation.md @@ -0,0 +1,111 @@ +Installation +============ + +Installation of Yii mainly involves the following two steps: + + 1. Download Yii Framework from [yiiframework.com](http://www.yiiframework.com/). + 2. Unpack the Yii release file to a Web-accessible directory. + +> Tip: Yii does not need to be installed under a Web-accessible directory. +A Yii application has one entry script which is usually the only file that +needs to be exposed to Web users. Other PHP scripts, including those from +Yii, should be protected from Web access; otherwise they might be exploited +by hackers. + + +Requirements +------------ + +After installing Yii, you may want to verify that your server satisfies +Yii's requirements. You can do so by accessing the requirement checker +script via the following URL in a Web browser: + +~~~ +http://hostname/path/to/yii/requirements/index.php +~~~ + +Yii requires PHP 5.3, so the server must have PHP 5.3 or above installed and +available to the web server. Yii has been tested with [Apache HTTP server](http://httpd.apache.org/) +on Windows and Linux. It may also run on other Web servers and platforms, +provided PHP 5.3 is supported. + + +Recommended Apache Configuration +-------------------------------- + +Yii is ready to work with a default Apache web server configuration. +The `.htaccess` files in Yii framework and application folders restrict +access to the restricted resources. To hide the bootstrap file (usually `index.php`) +in your URLs you can add `mod_rewrite` instructions to the `.htaccess` file +in your document root or to the virtual host configuration: + +~~~ +RewriteEngine on + +# if a directory or a file exists, use it directly +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d +# otherwise forward it to index.php +RewriteRule . index.php +~~~ + + +Recommended Nginx Configuration +------------------------------- + +You can use Yii with [Nginx](http://wiki.nginx.org/) and PHP with [FPM SAPI](http://php.net/install.fpm). +Here is a sample host configuration. It defines the bootstrap file and makes +Yii to catch all requests to nonexistent files, which allows us to have nice-looking URLs. + +~~~ +server { + set $host_path "/www/mysite"; + access_log /www/mysite/log/access.log main; + + server_name mysite; + root $host_path/htdocs; + set $yii_bootstrap "index.php"; + + charset utf-8; + + location / { + index index.html $yii_bootstrap; + try_files $uri $uri/ /$yii_bootstrap?$args; + } + + location ~ ^/(protected|framework|themes/\w+/views) { + deny all; + } + + #avoid processing of calls to unexisting static files by yii + location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ { + try_files $uri =404; + } + + # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 + # + location ~ \.php { + fastcgi_split_path_info ^(.+\.php)(.*)$; + + #let yii catch the calls to unexising PHP files + set $fsn /$yii_bootstrap; + if (-f $document_root$fastcgi_script_name){ + set $fsn $fastcgi_script_name; + } + + fastcgi_pass 127.0.0.1:9000; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fsn; + + #PATH_INFO and PATH_TRANSLATED can be omitted, but RFC 3875 specifies them for CGI + fastcgi_param PATH_INFO $fastcgi_path_info; + fastcgi_param PATH_TRANSLATED $document_root$fsn; + } + + location ~ /\.ht { + deny all; + } +} +~~~ + +Using this configuration you can set `cgi.fix_pathinfo=0` in php.ini to avoid many unnecessary system stat() calls. diff --git a/docs/guide/model.md b/docs/guide/model.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/mvc.md b/docs/guide/mvc.md new file mode 100644 index 0000000..79140ce --- /dev/null +++ b/docs/guide/mvc.md @@ -0,0 +1,51 @@ +MVC Overview +============ + +Yii implements the model-view-controller (MVC) design pattern, which is +widely adopted in Web programming. MVC aims to separate business logic from +user interface considerations, so that developers can more easily change +each part without affecting the other. In MVC, the model represents the +information (the data) and the business rules; the view contains elements +of the user interface such as text, form inputs; and the controller manages +the communication between the model and the view. + +Besides implementing MVC, Yii also introduces a front-controller, called +`Application`, which encapsulates the execution context for the processing +of a request. Application collects some information about a user request and +then dispatches it to an appropriate controller for further handling. + +The following diagram shows the static structure of a Yii application: + +![Static structure of Yii application](structure.png) + + +A Typical Workflow +------------------ +The following diagram shows a typical workflow of a Yii application when +it is handling a user request: + +![Typical workflow of a Yii application](flow.png) + + 1. A user makes a request with the URL `http://www.example.com/index.php?r=post/show&id=1` +and the Web server handles the request by executing the bootstrap script `index.php`. + 2. The bootstrap script creates an [Application](/doc/guide/basics.application) +instance and runs it. + 3. The Application obtains detailed user request information from +an [application component](/doc/guide/basics.application#application-component) +named `request`. + 4. The application determines the requested [controller](/doc/guide/basics.controller) +and [action](/doc/guide/basics.controller#action) with the help +of an application component named `urlManager`. For this example, the controller +is `post`, which refers to the `PostController` class; and the action is `show`, +whose actual meaning is determined by the controller. + 5. The application creates an instance of the requested controller +to further handle the user request. The controller determines that the action +`show` refers to a method named `actionShow` in the controller class. It then +creates and executes filters (e.g. access control, benchmarking) associated +with this action. The action is executed if it is allowed by the filters. + 6. The action reads a `Post` [model](/doc/guide/basics.model) whose ID is `1` from the database. + 7. The action renders a [view](/doc/guide/basics.view) named `show` with the `Post` model. + 8. The view reads and displays the attributes of the `Post` model. + 9. The view executes some [widgets](/doc/guide/basics.view#widget). + 10. The view rendering result is embedded in a [layout](/doc/guide/basics.view#layout). + 11. The action completes the view rendering and displays the result to the user. diff --git a/docs/guide/overview.md b/docs/guide/overview.md new file mode 100644 index 0000000..9e54fd4 --- /dev/null +++ b/docs/guide/overview.md @@ -0,0 +1,36 @@ +What is Yii +=========== + +Yii is a high-performance, component-based PHP framework for developing +large-scale Web applications rapidly. It enables maximum reusability in Web +programming and can significantly accelerate your Web application development +process. The name Yii (pronounced `Yee` or `[ji:]`) is an acronym for +"**Yes It Is!**". + + +Requirements +------------ + +To run a Yii-powered Web application, you need a Web server that supports +PHP 5.3.?. + +For developers who want to use Yii, understanding object-oriented +programming (OOP) is very helpful, because Yii is a pure OOP framework. + + +What is Yii Best for? +--------------------- + +Yii is a generic Web programming framework that can be used for developing +virtually any type of Web application. Because it is light-weight and +equipped with sophisticated caching mechanisms, it is especially suited +to high-traffic applications, such as portals, forums, content +management systems (CMS), e-commerce systems, etc. + + +How does Yii Compare with Other Frameworks? +------------------------------------------- + +Like most PHP frameworks, Yii is an MVC (Model-View-Controller) framework. + +TBD \ No newline at end of file diff --git a/docs/guide/title.md b/docs/guide/title.md new file mode 100644 index 0000000..a3e55a1 --- /dev/null +++ b/docs/guide/title.md @@ -0,0 +1,8 @@ +The Definitive Guide to Yii 2.0 +=============================== + +This tutorial is released under [the Terms of Yii Documentation](http://www.yiiframework.com/doc/terms/). + +All Rights Reserved. + +2008 (c) Yii Software LLC. diff --git a/docs/guide/view.md b/docs/guide/view.md new file mode 100644 index 0000000..e69de29 diff --git a/todo.md b/todo.md deleted file mode 100644 index f66d3c1..0000000 --- a/todo.md +++ /dev/null @@ -1,49 +0,0 @@ -- caching - * dependency unit tests -- validators - * Refactor validators to add validateValue() for every validator, if possible. Check if value is an array. - * FileValidator: depends on CUploadedFile - * CaptchaValidator: depends on CaptchaAction - * DateValidator: should we use CDateTimeParser, or simply use strtotime()? - * CompareValidator::clientValidateAttribute(): depends on CHtml::activeId() - -memo - * Minimal PHP version required: 5.3.7 (http://www.php.net/manual/en/function.crypt.php) ---- - -- base - * module - - Module should be able to define its own configuration including routes. Application should be able to overwrite it. - * application -- built-in console commands - + api doc builder - * support for markdown syntax - * support for [[name]] - * consider to be released as a separate tool for user app docs -- i18n - * consider using PHP built-in support and data - * formatting: number and date - * parsing?? - * make dates/date patterns uniform application-wide including JUI, formats etc. -- helpers - * image - * string - * file -- web: TBD - * get/setFlash() should be moved to session component - * support optional parameter in URL patterns - * Response object. - * ErrorAction -- gii - * move generation API out of gii, provide yiic commands to use it. Use same templates for gii/yiic. - * i18n variant of templates - * allow to generate module-specific CRUD -- assets - * ability to manage scripts order (store these in a vector?) - * http://ryanbigg.com/guides/asset_pipeline.html, http://guides.rubyonrails.org/asset_pipeline.html, use content hash instead of mtime + directory hash. -- Requirement checker -- Optional configurable input filtering in request -- widgets - * if we're going to supply default ones, these should generate really unique IDs. This will solve a lot of AJAX-nesting problems. -- Make sure type hinting is used when components are passed to methods -- Decouple controller from application (by passing web application instance to controller and if not passed, using Yii::app())? From 3e6dcccdeb5342144acaf3720e9cc6bf25db35f9 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Fri, 3 May 2013 22:37:18 -0400 Subject: [PATCH 31/87] updated readme. --- readme.md | 69 +++++++++++++++++++++------------------------------------------ 1 file changed, 23 insertions(+), 46 deletions(-) diff --git a/readme.md b/readme.md index 2e6fcc0..90bca0c 100644 --- a/readme.md +++ b/readme.md @@ -1,64 +1,41 @@ -Yii 2 Web Programming Framework -=============================== +Yii PHP Framework Version 2 +=========================== -Thank you for choosing Yii 2 — a high-performance component-based PHP framework. +Thank you for choosing Yii - a high-performance component-based PHP framework. +If you are looking for a production-ready PHP framework, please use +[Yii v1.1](https://github.com/yiisoft/yii). + +Yii 2 is still under heavy development. We may make significant changes +without prior notices. **Yii 2 is not ready for production yet.** -INSTALLATION ------------- -Please make sure the release file is unpacked under a Web-accessible -directory. You shall see the following files and directories: +DIRECTORY STRUCTURE +------------------- - demos/ demos + app/ a ready-to-use application built on Yii 2 + build/ internally used build tools + docs/ documentation framework/ framework source files - requirements/ requirement checker - changelog.md describing changes in every Yii release - license.md license of Yii - readme.md this file - upgrade.md upgrading instructions + tests/ tests of the core framework code REQUIREMENTS ------------ -The minimum requirement by Yii is that your Web server supports -PHP 5.3.8 or above. Yii has been tested with Apache HTTP server -on Windows and Linux operating systems. - -Please access the following URL to check if your Web server reaches -the requirements by Yii, assuming "YiiPath" is where Yii is installed: - - http://hostname/YiiPath/requirements/index.php - - -QUICK START ------------ - -Yii comes with a command line tool called "yiic" that can create -a skeleton Yii application for you to start with. - -On a command line, type in the following commands: - - for Linux - $ cd YiiPath/framework - $ ./yiic webapp ../testdrive - - for Windows - cd YiiPath\framework - yiic webapp ..\testdrive - -The new Yii application will be created at "YiiPath/testdrive". -You can access it with the following URL: +The minimum requirement by Yii is that your Web server supports PHP 5.3.?. - http://hostname/YiiPath/testdrive/index.php +HOW TO PARTICIPATE +------------------ -WHAT's NEXT ------------ +You are welcome to participate in Yii 2 development in the following ways: -Please visit the project website for tutorials, class reference -and join discussions with other Yii users. +* [Report issues](https://github.com/yiisoft/yii2/issues) +* [Give us feedback or start a design discussion](http://www.yiiframework.com/forum/index.php/forum/42-design-discussions-for-yii-20/) +* Fix issues, develop features, write/polish documentation + - Before you start, please adopt an existing issue or start a new one to avoid duplicated efforts. + - Please submit a merge request after you finish development. From ac8c6c16dc7746d13dc0eccf2b02bda5a577d5c0 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Fri, 3 May 2013 22:40:31 -0400 Subject: [PATCH 32/87] readme fix. --- readme.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/readme.md b/readme.md index 90bca0c..dfb9c45 100644 --- a/readme.md +++ b/readme.md @@ -1,13 +1,13 @@ -Yii PHP Framework Version 2 -=========================== +Yii 2.0 Public Preview +====================== Thank you for choosing Yii - a high-performance component-based PHP framework. If you are looking for a production-ready PHP framework, please use [Yii v1.1](https://github.com/yiisoft/yii). -Yii 2 is still under heavy development. We may make significant changes -without prior notices. **Yii 2 is not ready for production yet.** +Yii 2.0 is still under heavy development. We may make significant changes +without prior notices. **Yii 2.0 is not ready for production use yet.** DIRECTORY STRUCTURE @@ -37,7 +37,3 @@ You are welcome to participate in Yii 2 development in the following ways: - Before you start, please adopt an existing issue or start a new one to avoid duplicated efforts. - Please submit a merge request after you finish development. - - -The Yii Developer Team -http://www.yiiframework.com \ No newline at end of file From 97992bdc89ecec7f742835d0184f521aac4c91ac Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sat, 4 May 2013 08:03:40 -0400 Subject: [PATCH 33/87] Fixes for issue #81. --- framework/YiiBase.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/framework/YiiBase.php b/framework/YiiBase.php index 9d501b1..ed975c9 100644 --- a/framework/YiiBase.php +++ b/framework/YiiBase.php @@ -600,6 +600,13 @@ class YiiBase */ public static function t($message, $params = array(), $language = null) { - return self::$app->getI18N()->translate($message, $params, $language); + if (self::$app !== null) { + return self::$app->getI18N()->translate($message, $params, $language); + } else { + if (strpos($message, '|') !== false && preg_match('/^([\w\-\\/\.\\\\]+)\|(.*)/', $message, $matches)) { + $message = $matches[2]; + } + return is_array($params) ? strtr($message, $params) : $message; + } } } From 0454d03177ce7acf431a1b279a75f3db29b97561 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sat, 4 May 2013 08:08:46 -0400 Subject: [PATCH 34/87] Fixed test break. --- framework/helpers/base/Html.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/framework/helpers/base/Html.php b/framework/helpers/base/Html.php index 5b8e7db..3e7c7a2 100644 --- a/framework/helpers/base/Html.php +++ b/framework/helpers/base/Html.php @@ -95,9 +95,9 @@ class Html public static $attributeOrder = array( 'type', 'id', + 'class', 'name', 'value', - 'class', 'href', 'src', @@ -375,7 +375,8 @@ class Html */ public static function mailto($text, $email = null, $options = array()) { - return static::a($text, 'mailto:' . ($email === null ? $text : $email), $options); + $options['href'] = 'mailto:' . ($email === null ? $text : $email); + return static::tag('a', $text, $options); } /** From 2da3cbecdfb9ec5044f4f8e184a57b9bb8919276 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sat, 4 May 2013 09:23:43 -0300 Subject: [PATCH 35/87] Update readme.md --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index dfb9c45..6293292 100644 --- a/readme.md +++ b/readme.md @@ -34,6 +34,6 @@ You are welcome to participate in Yii 2 development in the following ways: * [Report issues](https://github.com/yiisoft/yii2/issues) * [Give us feedback or start a design discussion](http://www.yiiframework.com/forum/index.php/forum/42-design-discussions-for-yii-20/) * Fix issues, develop features, write/polish documentation - - Before you start, please adopt an existing issue or start a new one to avoid duplicated efforts. + - Before you start, please adopt an existing issue (labelled with "ready for adoption") or start a new one to avoid duplicated efforts. - Please submit a merge request after you finish development. From 2bdfc27692731da995f61bef103681b5c0aca184 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sat, 4 May 2013 08:28:27 -0400 Subject: [PATCH 36/87] Fixes for issue #78. --- framework/helpers/base/Html.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/framework/helpers/base/Html.php b/framework/helpers/base/Html.php index 3e7c7a2..15db823 100644 --- a/framework/helpers/base/Html.php +++ b/framework/helpers/base/Html.php @@ -127,13 +127,15 @@ class Html * Encodes special characters into HTML entities. * The [[yii\base\Application::charset|application charset]] will be used for encoding. * @param string $content the content to be encoded + * @param boolean $doubleEncode whether to encode HTML entities in `$content`. If false, + * HTML entities in `$content` will not be further encoded. * @return string the encoded content * @see decode * @see http://www.php.net/manual/en/function.htmlspecialchars.php */ - public static function encode($content) + public static function encode($content, $doubleEncode = true) { - return htmlspecialchars($content, ENT_QUOTES, Yii::$app->charset); + return htmlspecialchars($content, ENT_QUOTES, Yii::$app->charset, $doubleEncode); } /** From 992992b4a3f3912119a54aa542a2946cf3ee3843 Mon Sep 17 00:00:00 2001 From: Suralc Date: Sat, 4 May 2013 15:55:01 +0200 Subject: [PATCH 37/87] Fix build command. --- build/build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build b/build/build index fff4282..691eba9 100755 --- a/build/build +++ b/build/build @@ -16,5 +16,5 @@ require(__DIR__ . '/../framework/yii.php'); $id = 'yiic-build'; $basePath = __DIR__; -$application = new yii\console\Application($id, $basePath); +$application = new yii\console\Application(array('id' => $id, 'basePath' => $basePath)); $application->run(); From 985f076b2db578bd44c896a1d80faa3a772d6761 Mon Sep 17 00:00:00 2001 From: Taufan Aditya Date: Sat, 4 May 2013 21:47:01 +0700 Subject: [PATCH 38/87] Testsuite config --- phpunit.xml.dist | 13 +++++++++++++ tests/unit/phpunit.xml | 7 ------- 2 files changed, 13 insertions(+), 7 deletions(-) create mode 100644 phpunit.xml.dist delete mode 100644 tests/unit/phpunit.xml diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..bf37a26 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,13 @@ + + + + + ./tests/unit + + + \ No newline at end of file diff --git a/tests/unit/phpunit.xml b/tests/unit/phpunit.xml deleted file mode 100644 index 17db94e..0000000 --- a/tests/unit/phpunit.xml +++ /dev/null @@ -1,7 +0,0 @@ - - \ No newline at end of file From 305028b5c81463b977493de208167d87c28f47c0 Mon Sep 17 00:00:00 2001 From: Taufan Aditya Date: Sun, 5 May 2013 00:09:12 +0700 Subject: [PATCH 39/87] Travis configuration --- .travis.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..e4b8278 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,14 @@ +language: php + +php: + - 5.3 + - 5.4 + - 5.5 + +env: + - DB=mysql + +before_script: + - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'create database IF NOT EXISTS yiitest;'; fi" + +script: phpunit \ No newline at end of file From 51de7571401fea3ca272f5862cfb12e4dc0774a4 Mon Sep 17 00:00:00 2001 From: Taufan Aditya Date: Sun, 5 May 2013 00:10:17 +0700 Subject: [PATCH 40/87] Use travis as user instead root within DSN --- tests/unit/data/config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/data/config.php b/tests/unit/data/config.php index fc15690..238a7cc 100644 --- a/tests/unit/data/config.php +++ b/tests/unit/data/config.php @@ -3,7 +3,7 @@ return array( 'mysql' => array( 'dsn' => 'mysql:host=127.0.0.1;dbname=yiitest', - 'username' => 'root', + 'username' => 'travis', 'password' => '', 'fixture' => __DIR__ . '/mysql.sql', ), From 88bfce96d43b5c067ea8a0c6fed3f103320f534d Mon Sep 17 00:00:00 2001 From: ekerazha Date: Sat, 4 May 2013 21:15:24 +0300 Subject: [PATCH 41/87] Use AES-192 for encryption --- framework/helpers/base/SecurityHelper.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/framework/helpers/base/SecurityHelper.php b/framework/helpers/base/SecurityHelper.php index 6ba48ba..e2f2215 100644 --- a/framework/helpers/base/SecurityHelper.php +++ b/framework/helpers/base/SecurityHelper.php @@ -42,7 +42,8 @@ class SecurityHelper public static function encrypt($data, $key) { $module = static::openCryptModule(); - $key = StringHelper::substr($key, 0, mcrypt_enc_get_key_size($module)); + // 192-bit (24 bytes) key size + $key = StringHelper::substr($key, 0, 24); srand(); $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($module), MCRYPT_RAND); mcrypt_generic_init($module, $key, $iv); @@ -63,7 +64,8 @@ class SecurityHelper public static function decrypt($data, $key) { $module = static::openCryptModule(); - $key = StringHelper::substr($key, 0, mcrypt_enc_get_key_size($module)); + // 192-bit (24 bytes) key size + $key = StringHelper::substr($key, 0, 24); $ivSize = mcrypt_enc_get_iv_size($module); $iv = StringHelper::substr($data, 0, $ivSize); mcrypt_generic_init($module, $key, $iv); @@ -148,7 +150,8 @@ class SecurityHelper if (!extension_loaded('mcrypt')) { throw new InvalidConfigException('The mcrypt PHP extension is not installed.'); } - $module = @mcrypt_module_open('rijndael-256', '', MCRYPT_MODE_CBC, ''); + // AES uses a 128-bit block size + $module = @mcrypt_module_open('rijndael-128', '', MCRYPT_MODE_CBC, ''); if ($module === false) { throw new Exception('Failed to initialize the mcrypt module.'); } @@ -269,4 +272,4 @@ class SecurityHelper $salt .= str_replace('+', '.', substr(base64_encode($rand), 0, 22)); return $salt; } -} \ No newline at end of file +} From 3b12bbd8f22196ff5ee894d5b12088f787b93602 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sat, 4 May 2013 14:28:09 -0400 Subject: [PATCH 42/87] Fixes issue #90 --- framework/base/Widget.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/framework/base/Widget.php b/framework/base/Widget.php index 13e6d30..1aabd4f 100644 --- a/framework/base/Widget.php +++ b/framework/base/Widget.php @@ -83,7 +83,8 @@ class Widget extends Component */ public function render($view, $params = array()) { - return $this->view->render($view, $params, $this); + $viewFile = $this->findViewFile($view); + return $this->view->renderFile($viewFile, $params, $this); } /** From 14781584f9bacdff21ee03ec14dbb8c9bcf79e96 Mon Sep 17 00:00:00 2001 From: ekerazha Date: Sat, 4 May 2013 22:02:39 +0300 Subject: [PATCH 43/87] Use a string for the mode too The cipher is already specified as string --- framework/helpers/base/SecurityHelper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/helpers/base/SecurityHelper.php b/framework/helpers/base/SecurityHelper.php index e2f2215..ed5bfd6 100644 --- a/framework/helpers/base/SecurityHelper.php +++ b/framework/helpers/base/SecurityHelper.php @@ -151,7 +151,7 @@ class SecurityHelper throw new InvalidConfigException('The mcrypt PHP extension is not installed.'); } // AES uses a 128-bit block size - $module = @mcrypt_module_open('rijndael-128', '', MCRYPT_MODE_CBC, ''); + $module = @mcrypt_module_open('rijndael-128', '', 'cbc', ''); if ($module === false) { throw new Exception('Failed to initialize the mcrypt module.'); } From d8beaa648e5ec8e1aa7fe14513b47ba1ea2fb897 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Sat, 4 May 2013 23:23:29 +0400 Subject: [PATCH 44/87] added doc files --- docs/guide/active-record.md | 0 docs/guide/authentication.md | 0 docs/guide/authorization.md | 0 docs/guide/caching.md | 3 +++ docs/guide/console.md | 0 docs/guide/dao.md | 0 docs/guide/error.md | 3 +++ docs/guide/extension.md | 0 docs/guide/form.md | 0 docs/guide/gii.md | 0 docs/guide/i18n.md | 0 docs/guide/installation.md | 11 ++++++----- docs/guide/logging.md | 0 docs/guide/migration.md | 3 +++ docs/guide/mvc.md | 3 ++- docs/guide/performance.md | 0 docs/guide/query-builder.md | 0 docs/guide/security.md | 0 docs/guide/template.md | 0 docs/guide/testing.md | 0 docs/guide/theming.md | 0 docs/guide/upgrade.md | 0 docs/guide/url.md | 3 +++ docs/guide/validation.md | 0 24 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 docs/guide/active-record.md create mode 100644 docs/guide/authentication.md create mode 100644 docs/guide/authorization.md create mode 100644 docs/guide/caching.md create mode 100644 docs/guide/console.md create mode 100644 docs/guide/dao.md create mode 100644 docs/guide/error.md create mode 100644 docs/guide/extension.md create mode 100644 docs/guide/form.md create mode 100644 docs/guide/gii.md create mode 100644 docs/guide/i18n.md create mode 100644 docs/guide/logging.md create mode 100644 docs/guide/migration.md create mode 100644 docs/guide/performance.md create mode 100644 docs/guide/query-builder.md create mode 100644 docs/guide/security.md create mode 100644 docs/guide/template.md create mode 100644 docs/guide/testing.md create mode 100644 docs/guide/theming.md create mode 100644 docs/guide/upgrade.md create mode 100644 docs/guide/url.md create mode 100644 docs/guide/validation.md diff --git a/docs/guide/active-record.md b/docs/guide/active-record.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/authentication.md b/docs/guide/authentication.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/authorization.md b/docs/guide/authorization.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/caching.md b/docs/guide/caching.md new file mode 100644 index 0000000..cd945e7 --- /dev/null +++ b/docs/guide/caching.md @@ -0,0 +1,3 @@ +Caching +======= + diff --git a/docs/guide/console.md b/docs/guide/console.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/dao.md b/docs/guide/dao.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/error.md b/docs/guide/error.md new file mode 100644 index 0000000..c97fada --- /dev/null +++ b/docs/guide/error.md @@ -0,0 +1,3 @@ +Error Handling +============== + diff --git a/docs/guide/extension.md b/docs/guide/extension.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/form.md b/docs/guide/form.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/gii.md b/docs/guide/gii.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/i18n.md b/docs/guide/i18n.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/installation.md b/docs/guide/installation.md index 6cc5ef8..3f9a803 100644 --- a/docs/guide/installation.md +++ b/docs/guide/installation.md @@ -25,8 +25,8 @@ http://hostname/path/to/yii/requirements/index.php ~~~ Yii requires PHP 5.3, so the server must have PHP 5.3 or above installed and -available to the web server. Yii has been tested with [Apache HTTP server](http://httpd.apache.org/) -on Windows and Linux. It may also run on other Web servers and platforms, +available to the web server. Yii has been tested with [Apache HTTP server](http://httpd.apache.org/) +on Windows and Linux. It may also run on other Web servers and platforms, provided PHP 5.3 is supported. @@ -34,7 +34,7 @@ Recommended Apache Configuration -------------------------------- Yii is ready to work with a default Apache web server configuration. -The `.htaccess` files in Yii framework and application folders restrict +The `.htaccess` files in Yii framework and application folders deny access to the restricted resources. To hide the bootstrap file (usually `index.php`) in your URLs you can add `mod_rewrite` instructions to the `.htaccess` file in your document root or to the virtual host configuration: @@ -63,7 +63,7 @@ server { access_log /www/mysite/log/access.log main; server_name mysite; - root $host_path/htdocs; + root $host_path/htdocs; set $yii_bootstrap "index.php"; charset utf-8; @@ -108,4 +108,5 @@ server { } ~~~ -Using this configuration you can set `cgi.fix_pathinfo=0` in php.ini to avoid many unnecessary system stat() calls. +Using this configuration you can set `cgi.fix_pathinfo=0` in php.ini to avoid +many unnecessary system `stat()` calls. diff --git a/docs/guide/logging.md b/docs/guide/logging.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/migration.md b/docs/guide/migration.md new file mode 100644 index 0000000..0fe2fb3 --- /dev/null +++ b/docs/guide/migration.md @@ -0,0 +1,3 @@ +Database Migration +================== + diff --git a/docs/guide/mvc.md b/docs/guide/mvc.md index 79140ce..a99d043 100644 --- a/docs/guide/mvc.md +++ b/docs/guide/mvc.md @@ -11,7 +11,7 @@ the communication between the model and the view. Besides implementing MVC, Yii also introduces a front-controller, called `Application`, which encapsulates the execution context for the processing -of a request. Application collects some information about a user request and +of a request. Application collects information about a user request and then dispatches it to an appropriate controller for further handling. The following diagram shows the static structure of a Yii application: @@ -21,6 +21,7 @@ The following diagram shows the static structure of a Yii application: A Typical Workflow ------------------ + The following diagram shows a typical workflow of a Yii application when it is handling a user request: diff --git a/docs/guide/performance.md b/docs/guide/performance.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/query-builder.md b/docs/guide/query-builder.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/security.md b/docs/guide/security.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/template.md b/docs/guide/template.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/testing.md b/docs/guide/testing.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/theming.md b/docs/guide/theming.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/upgrade.md b/docs/guide/upgrade.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/guide/url.md b/docs/guide/url.md new file mode 100644 index 0000000..46bb177 --- /dev/null +++ b/docs/guide/url.md @@ -0,0 +1,3 @@ +URL Management +============== + diff --git a/docs/guide/validation.md b/docs/guide/validation.md new file mode 100644 index 0000000..e69de29 From 1a317ebe313252c08fcbf3f89388b06414975d0f Mon Sep 17 00:00:00 2001 From: Rinat Silnov Date: Sat, 4 May 2013 23:54:59 +0400 Subject: [PATCH 45/87] Fixed VarDumper::dump for objects Otherwise it throws an exception that "Object of class ClassName could not be converted to string" --- framework/helpers/base/VarDumper.php | 2 +- tests/unit/framework/helpers/VarDumperTest.php | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 tests/unit/framework/helpers/VarDumperTest.php diff --git a/framework/helpers/base/VarDumper.php b/framework/helpers/base/VarDumper.php index fe15d98..43b0cd8 100644 --- a/framework/helpers/base/VarDumper.php +++ b/framework/helpers/base/VarDumper.php @@ -116,7 +116,7 @@ class VarDumper } elseif (self::$_depth <= $level) { self::$_output .= get_class($var) . '(...)'; } else { - $id = self::$_objects[] = $var; + $id = array_push(self::$_objects, $var); $className = get_class($var); $members = (array)$var; $spaces = str_repeat(' ', $level * 4); diff --git a/tests/unit/framework/helpers/VarDumperTest.php b/tests/unit/framework/helpers/VarDumperTest.php new file mode 100644 index 0000000..8757588 --- /dev/null +++ b/tests/unit/framework/helpers/VarDumperTest.php @@ -0,0 +1,12 @@ + Date: Sun, 5 May 2013 00:02:14 +0400 Subject: [PATCH 46/87] started performance section of the guide --- docs/guide/performance.md | 100 ++++++++++++++++++++++++++++++++++++++++++++++ docs/guide/template.md | 3 ++ 2 files changed, 103 insertions(+) diff --git a/docs/guide/performance.md b/docs/guide/performance.md index e69de29..a480a0b 100644 --- a/docs/guide/performance.md +++ b/docs/guide/performance.md @@ -0,0 +1,100 @@ +Performance Tuning +================== + +Application performance consists of two parts. First is the framework performance +and the second is the application itself. Yii has a pretty low performance impact +on your application out of the box and can be fine-tuned further for production +environment. As for the application, we'll provide some of the best practices +along with examples on how to apply them to Yii. + +Preparing framework for production +---------------------------------- + +### Disabling Debug Mode + +First thing you should do before deploying your application to production environment +is to disable debug mode. A Yii application runs in debug mode if the constant +`YII_DEBUG` is defined as `true` in `index.php`. Debug mode is useful during +development stage, but it would impact performance because some components +cause extra burden in debug mode. For example, the message logger may record +additional debug information for every message being logged. + +### Enabling PHP opcode cache + +Enabling the PHP opcode cache improves any PHP application performance and lowers +memory usage. Yii is no exception. It was tested with APC extension that caches +and optimizes PHP intermediate code and avoids the time spent in parsing PHP +scripts for every incoming request. + +### Turning on ActiveRecord database schema caching + +If the application is using Active Record, we should turn on the schema caching +to save the time of parsing database schema. This can be done by setting the +`Connection::enableSchemaCache` property to be `true` via application configuration +`protected/config/main.php`: + +```php + +``` + +### Combining and Minimizing Assets + + +### Using better storage for sessions + +By default PHP uses plain files to handle sessions. It is OK for development and +small projects but when it comes to handling concurrent requests it's better to +switch to another storage such as database. You can do so by configuring your +application via `protected/config/main.php`: + + +```php +``` + + +Improving application +--------------------- + +### Using Caching Techniques + +As described in the Caching section, Yii provides several caching solutions that +may improve the performance of a Web application significantly. If the generation +of some data takes long time, we can use the data caching approach to reduce the +data generation frequency; If a portion of page remains relatively static, we +can use the fragment caching approach to reduce its rendering frequency; +If a whole page remains relative static, we can use the page caching approach to +save the rendering cost for the whole page. + + +### Database Optimization + +Fetching data from database is often the main performance bottleneck in +a Web application. Although using caching may alleviate the performance hit, +it does not fully solve the problem. When the database contains enormous data +and the cached data is invalid, fetching the latest data could be prohibitively +expensive without proper database and query design. + +Design index wisely in a database. Indexing can make SELECT queries much faster, +but it may slow down INSERT, UPDATE or DELETE queries. + +For complex queries, it is recommended to create a database view for it instead +of issuing the queries inside the PHP code and asking DBMS to parse them repetitively. + +Do not overuse Active Record. Although Active Record is good at modelling data +in an OOP fashion, it actually degrades performance due to the fact that it needs +to create one or several objects to represent each row of query result. For data +intensive applications, using DAO or database APIs at lower level could be +a better choice. + +Last but not least, use LIMIT in your SELECT queries. This avoids fetching +overwhelming data from database and exhausting the memory allocated to PHP. + +### Using asArray + +### Processing data in background + +In order to respond to user requests faster you can process heavy parts of the +request later if there's no need for immediate response. + +- Cron jobs + console. +- queues + handlers. \ No newline at end of file diff --git a/docs/guide/template.md b/docs/guide/template.md index e69de29..dc83d15 100644 --- a/docs/guide/template.md +++ b/docs/guide/template.md @@ -0,0 +1,3 @@ +Template +======== + From 958aeb76b6c866615a2f428b3c60e1e8d768845f Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Sun, 5 May 2013 00:26:18 +0400 Subject: [PATCH 47/87] more on performance tuning --- docs/guide/performance.md | 82 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 72 insertions(+), 10 deletions(-) diff --git a/docs/guide/performance.md b/docs/guide/performance.md index a480a0b..58e8258 100644 --- a/docs/guide/performance.md +++ b/docs/guide/performance.md @@ -14,15 +14,22 @@ Preparing framework for production First thing you should do before deploying your application to production environment is to disable debug mode. A Yii application runs in debug mode if the constant -`YII_DEBUG` is defined as `true` in `index.php`. Debug mode is useful during -development stage, but it would impact performance because some components -cause extra burden in debug mode. For example, the message logger may record -additional debug information for every message being logged. +`YII_DEBUG` is defined as `true` in `index.php` so to disable debug the following +should be in your `index.php`: + +```php +defined('YII_DEBUG') or define('YII_DEBUG', false); +``` + +Debug mode is very useful during development stage, but it would impact performance +because some components cause extra burden in debug mode. For example, the message +logger may record additional debug information for every message being logged. ### Enabling PHP opcode cache Enabling the PHP opcode cache improves any PHP application performance and lowers -memory usage. Yii is no exception. It was tested with APC extension that caches +memory usage significantly. Yii is no exception. It was tested with +[APC PHP extension](http://php.net/manual/en/book.apc.php) that caches and optimizes PHP intermediate code and avoids the time spent in parsing PHP scripts for every incoming request. @@ -34,28 +41,69 @@ to save the time of parsing database schema. This can be done by setting the `protected/config/main.php`: ```php - +return array( + // ... + 'components' => array( + // ... + 'db' => array( + 'class' => 'yii\db\Connection', + 'dsn' => 'mysql:host=localhost;dbname=mydatabase', + 'username' => 'root', + 'password' => '', + 'enableSchemaCache' => true, + + // Duration of schema cache. + // 'schemaCacheDuration' => 3600, + + // Name of the cache component used. Default is 'cache'. + //'schemaCache' => 'cache', + ), + 'cache' => array( + 'class' => 'yii\caching\FileCache', + ), + ), +); ``` +Note that `cache` application component should be configured. + ### Combining and Minimizing Assets +TBD ### Using better storage for sessions -By default PHP uses plain files to handle sessions. It is OK for development and +By default PHP uses files to handle sessions. It is OK for development and small projects but when it comes to handling concurrent requests it's better to switch to another storage such as database. You can do so by configuring your application via `protected/config/main.php`: - ```php +return array( + // ... + 'components' => array( + 'session' => array( + 'class' => 'yii\web\DbSession', + + // Set the following if want to use DB component other than + // default 'db'. + // 'db' => 'mydb', + + // To override default session table set the following + // 'sessionTable' => 'my_session', + ), + ), +); ``` +You can use `CacheSession` to store sessions using cache. Note that some +cache storages such as memcached has no guaranteee that session data will not +be lost leading to unexpected logouts. Improving application --------------------- -### Using Caching Techniques +### Using Serverside Caching Techniques As described in the Caching section, Yii provides several caching solutions that may improve the performance of a Web application significantly. If the generation @@ -66,6 +114,10 @@ If a whole page remains relative static, we can use the page caching approach to save the rendering cost for the whole page. +### Leveraging HTTP to save procesing time and bandwidth + +TBD + ### Database Optimization Fetching data from database is often the main performance bottleneck in @@ -91,10 +143,20 @@ overwhelming data from database and exhausting the memory allocated to PHP. ### Using asArray +A good way to save memory and processing time on read-only pages is to use +ActiveRecord's `asArray` method. + +```php +``` + +TBD + ### Processing data in background In order to respond to user requests faster you can process heavy parts of the request later if there's no need for immediate response. - Cron jobs + console. -- queues + handlers. \ No newline at end of file +- queues + handlers. + +TBD \ No newline at end of file From 03cd47aed94512ddc117815bcca631c1a5763807 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Sun, 5 May 2013 01:26:40 +0400 Subject: [PATCH 48/87] phpdoc typos --- framework/db/Query.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/db/Query.php b/framework/db/Query.php index 2239f5d..6f76265 100644 --- a/framework/db/Query.php +++ b/framework/db/Query.php @@ -483,7 +483,7 @@ class Query extends \yii\base\Component * Sets the ORDER BY part of the query. * @param string|array $columns the columns (and the directions) to be ordered by. * Columns can be specified in either a string (e.g. "id ASC, name DESC") or an array - * (e.g. `array('id' => Query::SORT_ASC ASC, 'name' => Query::SORT_DESC)`). + * (e.g. `array('id' => Query::SORT_ASC, 'name' => Query::SORT_DESC)`). * The method will automatically quote the column names unless a column contains some parenthesis * (which means the column contains a DB expression). * @return Query the query object itself @@ -499,7 +499,7 @@ class Query extends \yii\base\Component * Adds additional ORDER BY columns to the query. * @param string|array $columns the columns (and the directions) to be ordered by. * Columns can be specified in either a string (e.g. "id ASC, name DESC") or an array - * (e.g. `array('id' => Query::SORT_ASC ASC, 'name' => Query::SORT_DESC)`). + * (e.g. `array('id' => Query::SORT_ASC, 'name' => Query::SORT_DESC)`). * The method will automatically quote the column names unless a column contains some parenthesis * (which means the column contains a DB expression). * @return Query the query object itself From a948e7387231ee49d0664c114c40a9cce7b41eb8 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Sun, 5 May 2013 01:27:13 +0400 Subject: [PATCH 49/87] example for using asArray --- docs/guide/performance.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/docs/guide/performance.md b/docs/guide/performance.md index 58e8258..9a871dc 100644 --- a/docs/guide/performance.md +++ b/docs/guide/performance.md @@ -147,9 +147,28 @@ A good way to save memory and processing time on read-only pages is to use ActiveRecord's `asArray` method. ```php +class PostController extends Controller +{ + public function actionIndex() + { + $posts = Post::find()->orderBy('id DESC')->limit(100)->asArray()->all(); + echo $this->render('index', array( + 'posts' => $posts, + )); + } +} ``` -TBD +In the view you should access fields of each invidual record from `$posts` as array: + +```php +foreach($posts as $post) { + echo $post['title']."
    "; +} +``` + +Note that you can use array notation even if `asArray` wasn't specified and you're +working with AR objects. ### Processing data in background From f3286df32880b46ec117d2eab8c5d783eec64952 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Sun, 5 May 2013 01:44:34 +0400 Subject: [PATCH 50/87] Fixes #76 --- docs/view_renderers.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/view_renderers.md b/docs/view_renderers.md index 1d88d21..e26fe83 100644 --- a/docs/view_renderers.md +++ b/docs/view_renderers.md @@ -27,6 +27,9 @@ array( ) ``` +Note that Smarty and Twig are not bundled with Yii and you have to download and +unpack these yourself and then specify `twigPath` and `smartyPath` respectively. + Twig ---- From ddf67f0833d96d16a4f01667c1237d51558fa481 Mon Sep 17 00:00:00 2001 From: Alexander Kochetov Date: Sun, 5 May 2013 03:18:37 +0400 Subject: [PATCH 51/87] Code style fix --- framework/db/ActiveRelation.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/db/ActiveRelation.php b/framework/db/ActiveRelation.php index f1b198b..97e2a8c 100644 --- a/framework/db/ActiveRelation.php +++ b/framework/db/ActiveRelation.php @@ -266,7 +266,7 @@ class ActiveRelation extends ActiveQuery { $attributes = array_keys($this->link); $values = array(); - if (count($attributes) ===1) { + if (count($attributes) === 1) { // single key $attribute = reset($this->link); foreach ($models as $model) { From 932ed70a7279056b2de4942f5282584a528580e7 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sat, 4 May 2013 19:25:35 -0400 Subject: [PATCH 52/87] Fixes issue #99. --- framework/web/Request.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/web/Request.php b/framework/web/Request.php index ac19d5a..5e2f064 100644 --- a/framework/web/Request.php +++ b/framework/web/Request.php @@ -96,7 +96,7 @@ class Request extends \yii\base\Request */ public function getIsPostRequest() { - return isset($_SERVER['REQUEST_METHOD']) && !strcasecmp($_SERVER['REQUEST_METHOD'], 'POST'); + return $this->getRequestMethod() === 'POST'; } /** From 6166e70f201817c74cb4f5109ee7fb337196c40a Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sat, 4 May 2013 20:17:43 -0400 Subject: [PATCH 53/87] Fixes issue #80 --- framework/db/Connection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/db/Connection.php b/framework/db/Connection.php index 797508a..f71b940 100644 --- a/framework/db/Connection.php +++ b/framework/db/Connection.php @@ -517,7 +517,7 @@ class Connection extends Component public function quoteSql($sql) { $db = $this; - return preg_replace_callback('/(\\{\\{([\w\-\. ]+)\\}\\}|\\[\\[([\w\-\. ]+)\\]\\])/', + return preg_replace_callback('/(\\{\\{([%\w\-\. ]+)\\}\\}|\\[\\[([\w\-\. ]+)\\]\\])/', function($matches) use($db) { if (isset($matches[3])) { return $db->quoteColumnName($matches[3]); From 6e779e02d655a222157aeeb38112325ba0ae997c Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sat, 4 May 2013 21:24:00 -0400 Subject: [PATCH 54/87] Fixed issue #7: ArrayHelper::multisort is not compatible with PHP 5.3 --- framework/helpers/base/ArrayHelper.php | 40 +++++++++++++++--------- tests/unit/framework/helpers/ArrayHelperTest.php | 11 ++++++- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/framework/helpers/base/ArrayHelper.php b/framework/helpers/base/ArrayHelper.php index 9870542..8a9a38c 100644 --- a/framework/helpers/base/ArrayHelper.php +++ b/framework/helpers/base/ArrayHelper.php @@ -236,15 +236,17 @@ class ArrayHelper * To sort by multiple keys, provide an array of keys here. * @param boolean|array $ascending whether to sort in ascending or descending order. When * sorting by multiple keys with different ascending orders, use an array of ascending flags. - * @param integer|array $sortFlag the PHP sort flag. Valid values include: - * `SORT_REGULAR`, `SORT_NUMERIC`, `SORT_STRING`, and `SORT_STRING | SORT_FLAG_CASE`. The last - * value is for sorting strings in case-insensitive manner. Please refer to - * See [PHP manual](http://php.net/manual/en/function.sort.php) for more details. - * When sorting by multiple keys with different sort flags, use an array of sort flags. + * @param integer|array $sortFlag the PHP sort flag. Valid values include + * `SORT_REGULAR`, `SORT_NUMERIC`, `SORT_STRING`, `SORT_LOCALE_STRING` and `SORT_NATURAL`. + * and `SORT_STRING | SORT_FLAG_CASE`. Please refer to [PHP manual](http://php.net/manual/en/function.sort.php) + * for more details. When sorting by multiple keys with different sort flags, use an array of sort flags. + * @param boolean|array $caseSensitive whether to sort string in case-sensitive manner. This parameter + * is used only when `$sortFlag` is either `SORT_STRING` or `SORT_NATURAL`. + * When sorting by multiple keys with different case sensitivities, use an array of boolean values. * @throws InvalidParamException if the $ascending or $sortFlag parameters do not have * correct number of elements as that of $key. */ - public static function multisort(&$array, $key, $ascending = true, $sortFlag = SORT_REGULAR) + public static function multisort(&$array, $key, $ascending = true, $sortFlag = SORT_REGULAR, $caseSensitive = true) { $keys = is_array($key) ? $key : array($key); if (empty($keys) || empty($array)) { @@ -259,20 +261,30 @@ class ArrayHelper if (is_scalar($sortFlag)) { $sortFlag = array_fill(0, $n, $sortFlag); } elseif (count($sortFlag) !== $n) { - throw new InvalidParamException('The length of $ascending parameter must be the same as that of $keys.'); + throw new InvalidParamException('The length of $sortFlag parameter must be the same as that of $keys.'); + } + if (is_scalar($caseSensitive)) { + $caseSensitive = array_fill(0, $n, $caseSensitive); + } elseif (count($caseSensitive) !== $n) { + throw new InvalidParamException('The length of $caseSensitive parameter must be the same as that of $keys.'); } $args = array(); foreach ($keys as $i => $key) { $flag = $sortFlag[$i]; - if ($flag == (SORT_STRING | SORT_FLAG_CASE)) { - $flag = SORT_STRING; - $column = array(); - foreach (static::getColumn($array, $key) as $k => $value) { - $column[$k] = strtolower($value); + $cs = $caseSensitive[$i]; + if (!$cs && ($flag === SORT_STRING || $flag === SORT_NATURAL)) { + if (defined('SORT_FLAG_CASE')) { + $flag = $flag | SORT_FLAG_CASE; + $args[] = static::getColumn($array, $key); + } else { + $column = array(); + foreach (static::getColumn($array, $key) as $k => $value) { + $column[$k] = mb_strtolower($value); + } + $args[] = $column; } - $args[] = $column; } else { - $args[] = static::getColumn($array, $key); + $args[] = static::getColumn($array, $key); } $args[] = $ascending[$i] ? SORT_ASC : SORT_DESC; $args[] = $flag; diff --git a/tests/unit/framework/helpers/ArrayHelperTest.php b/tests/unit/framework/helpers/ArrayHelperTest.php index 187217f..b3ffabf 100644 --- a/tests/unit/framework/helpers/ArrayHelperTest.php +++ b/tests/unit/framework/helpers/ArrayHelperTest.php @@ -40,11 +40,20 @@ class ArrayHelperTest extends \yii\test\TestCase $array = array( array('name' => 'a', 'age' => 3), array('name' => 'b', 'age' => 2), + array('name' => 'B', 'age' => 4), array('name' => 'A', 'age' => 1), ); - ArrayHelper::multisort($array, array('name', 'age'), SORT_ASC, array(SORT_STRING|SORT_FLAG_CASE, SORT_REGULAR)); + + ArrayHelper::multisort($array, array('name', 'age'), SORT_ASC, array(SORT_STRING, SORT_REGULAR)); + $this->assertEquals(array('name' => 'A', 'age' => 1), $array[0]); + $this->assertEquals(array('name' => 'B', 'age' => 4), $array[1]); + $this->assertEquals(array('name' => 'a', 'age' => 3), $array[2]); + $this->assertEquals(array('name' => 'b', 'age' => 2), $array[3]); + + ArrayHelper::multisort($array, array('name', 'age'), SORT_ASC, array(SORT_STRING, SORT_REGULAR), false); $this->assertEquals(array('name' => 'A', 'age' => 1), $array[0]); $this->assertEquals(array('name' => 'a', 'age' => 3), $array[1]); $this->assertEquals(array('name' => 'b', 'age' => 2), $array[2]); + $this->assertEquals(array('name' => 'B', 'age' => 4), $array[3]); } } From dc73c916fc4a864ac6c9f15b521931fb884360f2 Mon Sep 17 00:00:00 2001 From: Taufan Aditya Date: Sun, 5 May 2013 09:39:43 +0700 Subject: [PATCH 55/87] Fix unsupported flag in php 5.3.x environment [ArrayHelper::multisort] --- framework/helpers/base/ArrayHelper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/helpers/base/ArrayHelper.php b/framework/helpers/base/ArrayHelper.php index 8a9a38c..5c94887 100644 --- a/framework/helpers/base/ArrayHelper.php +++ b/framework/helpers/base/ArrayHelper.php @@ -272,7 +272,7 @@ class ArrayHelper foreach ($keys as $i => $key) { $flag = $sortFlag[$i]; $cs = $caseSensitive[$i]; - if (!$cs && ($flag === SORT_STRING || $flag === SORT_NATURAL)) { + if (!$cs && ($flag === SORT_STRING)) { if (defined('SORT_FLAG_CASE')) { $flag = $flag | SORT_FLAG_CASE; $args[] = static::getColumn($array, $key); From cfc958201fb32f089cc5bbec2f5ccdf75f44f7c1 Mon Sep 17 00:00:00 2001 From: Taufan Aditya Date: Sun, 5 May 2013 10:00:59 +0700 Subject: [PATCH 56/87] Remove reference to php 5.4-only constants in arrayhelper --- framework/helpers/base/ArrayHelper.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/framework/helpers/base/ArrayHelper.php b/framework/helpers/base/ArrayHelper.php index 5c94887..5f72fe4 100644 --- a/framework/helpers/base/ArrayHelper.php +++ b/framework/helpers/base/ArrayHelper.php @@ -237,11 +237,11 @@ class ArrayHelper * @param boolean|array $ascending whether to sort in ascending or descending order. When * sorting by multiple keys with different ascending orders, use an array of ascending flags. * @param integer|array $sortFlag the PHP sort flag. Valid values include - * `SORT_REGULAR`, `SORT_NUMERIC`, `SORT_STRING`, `SORT_LOCALE_STRING` and `SORT_NATURAL`. - * and `SORT_STRING | SORT_FLAG_CASE`. Please refer to [PHP manual](http://php.net/manual/en/function.sort.php) + * `SORT_REGULAR`, `SORT_NUMERIC`, `SORT_STRING` and `SORT_LOCALE_STRING`. + * Please refer to [PHP manual](http://php.net/manual/en/function.sort.php) * for more details. When sorting by multiple keys with different sort flags, use an array of sort flags. * @param boolean|array $caseSensitive whether to sort string in case-sensitive manner. This parameter - * is used only when `$sortFlag` is either `SORT_STRING` or `SORT_NATURAL`. + * is used only when `$sortFlag` is `SORT_STRING`. * When sorting by multiple keys with different case sensitivities, use an array of boolean values. * @throws InvalidParamException if the $ascending or $sortFlag parameters do not have * correct number of elements as that of $key. From 3ed7b62233ffdf5eb1905067c7e10ab3f1c15744 Mon Sep 17 00:00:00 2001 From: FrediL Date: Sun, 5 May 2013 06:36:48 +0300 Subject: [PATCH 57/87] Use Html::getInputName instead ActiveForm::getInputName --- framework/web/UploadedFile.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/framework/web/UploadedFile.php b/framework/web/UploadedFile.php index c67281c..6e685a3 100644 --- a/framework/web/UploadedFile.php +++ b/framework/web/UploadedFile.php @@ -7,7 +7,7 @@ namespace yii\web; -use yii\widgets\ActiveForm; +use yii\widgets\Html; /** * @author Qiang Xue @@ -66,7 +66,7 @@ class UploadedFile extends \yii\base\Object */ public static function getInstance($model, $attribute) { - $name = ActiveForm::getInputName($model, $attribute); + $name = Html::getInputName($model, $attribute); return static::getInstanceByName($name); } @@ -80,7 +80,7 @@ class UploadedFile extends \yii\base\Object */ public static function getInstances($model, $attribute) { - $name = ActiveForm::getInputName($model, $attribute); + $name = Html::getInputName($model, $attribute); return static::getInstancesByName($name); } From 64217b855fc411727ac71c341fedac6cf49efa41 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Sun, 5 May 2013 12:08:59 +0400 Subject: [PATCH 58/87] migration docs --- docs/guide/migration.md | 316 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 316 insertions(+) diff --git a/docs/guide/migration.md b/docs/guide/migration.md index 0fe2fb3..bafd293 100644 --- a/docs/guide/migration.md +++ b/docs/guide/migration.md @@ -1,3 +1,319 @@ Database Migration ================== +Like source code, the structure of a database is evolving as we develop and maintain +a database-driven application. For example, during development, we may want to +add a new table; or after the application is put into production, we may realize +the need of adding an index on a column. It is important to keep track of these +structural database changes (called **migration**) like we do with our source +code. If the source code and the database are out of sync, it is very likely +the whole system may break. For this reason, Yii provides a database migration +tool that can keep track of database migration history, apply new migrations, +or revert existing ones. + +The following steps show how we can use database migration during development: + +1. Tim creates a new migration (e.g. create a new table) +2. Tim commits the new migration into source control system (e.g. GIT, Mercurial) +3. Doug updates from source control system and receives the new migration +4. Doug applies the migration to his local development database + + +Yii supports database migration via the `yiic migrate` command line tool. This +tool supports creating new migrations, applying/reverting/redoing migrations, and +showing migration history and new migrations. + +Creating Migrations +------------------- + +To create a new migration (e.g. create a news table), we run the following command: + +~~~ +yiic migrate/create +~~~ + +The required `name` parameter specifies a very brief description of the migration +(e.g. `create_news_table`). As we will show in the following, the `name` parameter +is used as part of a PHP class name. Therefore, it should only contain letters, +digits and/or underscore characters. + +~~~ +yiic migrate/create create_news_table +~~~ + +The above command will create under the `protected/migrations` directory a new +file named `m101129_185401_create_news_table.php` which contains the following +initial code: + +~~~ +[php] +class m101129_185401_create_news_table extends \yii\db\Migration +{ + public function up() + { + } + + public function down() + { + echo "m101129_185401_create_news_table cannot be reverted.\n"; + return false; + } +} +~~~ + +Notice that the class name is the same as the file name which is of the pattern +`m_`, where `` refers to the UTC timestamp (in the +format of `yymmdd_hhmmss`) when the migration is created, and `` is taken +from the command's `name` parameter. + +The `up()` method should contain the code implementing the actual database +migration, while the `down()` method may contain the code reverting what is +done in `up()`. + +Sometimes, it is impossible to implement `down()`. For example, if we delete +table rows in `up()`, we will not be able to recover them in `down()`. In this +case, the migration is called irreversible, meaning we cannot roll back to +a previous state of the database. In the above generated code, the `down()` +method returns `false` to indicate that the migration cannot be reverted. + +As an example, let's show the migration about creating a news table. + +~~~ +[php] +class m101129_185401_create_news_table extends \yii\db\Migration +{ + public function up() + { + $this->db->createCommand()->createTable('tbl_news, array( + 'id' => 'pk', + 'title' => 'string NOT NULL', + 'content' => 'text', + ))->execute(); + } + + public function down() + { + $this->db->createCommand()->dropTable('tbl_news')->execute(); + } +} +~~~ + +The base class [\yii\db\Migration] exposes a database connection via `db` +property. You can use it for manipulating data and schema of a database. + +Transactional Migrations +------------------------ + +While performing complex DB migrations, we usually want to make sure that each +migration succeed or fail as a whole so that the database maintains the +consistency and integrity. In order to achieve this goal, we can exploit +DB transactions. + +We could explicitly start a DB transaction and enclose the rest of the DB-related +code within the transaction, like the following: + +~~~ +[php] +class m101129_185401_create_news_table extends \yii\db\Migration +{ + public function up() + { + $transaction=$this->getDbConnection()->beginTransaction(); + try + { + $this->db->createCommand()->createTable('tbl_news, array( + 'id' => 'pk', + 'title' => 'string NOT NULL', + 'content' => 'text', + ))->execute(); + $transaction->commit(); + } + catch(Exception $e) + { + echo "Exception: ".$e->getMessage()."\n"; + $transaction->rollback(); + return false; + } + } + + // ...similar code for down() +} +~~~ + +> Note: Not all DBMS support transactions. And some DB queries cannot be put +> into a transaction. In this case, you will have to implement `up()` and +> `down()`, instead. And for MySQL, some SQL statements may cause +> [implicit commit](http://dev.mysql.com/doc/refman/5.1/en/implicit-commit.html). + + +Applying Migrations +------------------- + +To apply all available new migrations (i.e., make the local database up-to-date), +run the following command: + +~~~ +yiic migrate +~~~ + +The command will show the list of all new migrations. If you confirm to apply +the migrations, it will run the `up()` method in every new migration class, one +after another, in the order of the timestamp value in the class name. + +After applying a migration, the migration tool will keep a record in a database +table named `tbl_migration`. This allows the tool to identify which migrations +have been applied and which are not. If the `tbl_migration` table does not exist, +the tool will automatically create it in the database specified by the `db` +application component. + +Sometimes, we may only want to apply one or a few new migrations. We can use the +following command: + +~~~ +yiic migrate/up 3 +~~~ + +This command will apply the 3 new migrations. Changing the value 3 will allow +us to change the number of migrations to be applied. + +We can also migrate the database to a specific version with the following command: + +~~~ +yiic migrate/to 101129_185401 +~~~ + +That is, we use the timestamp part of a migration name to specify the version +that we want to migrate the database to. If there are multiple migrations between +the last applied migration and the specified migration, all these migrations +will be applied. If the specified migration has been applied before, then all +migrations applied after it will be reverted (to be described in the next section). + + +Reverting Migrations +-------------------- + +To revert the last one or several applied migrations, we can use the following +command: + +~~~ +yiic migrate/down [step] +~~~ + +where the optional `step` parameter specifies how many migrations to be reverted +back. It defaults to 1, meaning reverting back the last applied migration. + +As we described before, not all migrations can be reverted. Trying to revert +such migrations will throw an exception and stop the whole reverting process. + + +Redoing Migrations +------------------ + +Redoing migrations means first reverting and then applying the specified migrations. +This can be done with the following command: + +~~~ +yiic migrate/redo [step] +~~~ + +where the optional `step` parameter specifies how many migrations to be redone. +It defaults to 1, meaning redoing the last migration. + + +Showing Migration Information +----------------------------- + +Besides applying and reverting migrations, the migration tool can also display +the migration history and the new migrations to be applied. + +~~~ +yiic migrate/history [limit] +yiic migrate/new [limit] +~~~ + +where the optional parameter `limit` specifies the number of migrations to be +displayed. If `limit` is not specified, all available migrations will be displayed. + +The first command shows the migrations that have been applied, while the second +command shows the migrations that have not been applied. + + +Modifying Migration History +--------------------------- + +Sometimes, we may want to modify the migration history to a specific migration +version without actually applying or reverting the relevant migrations. This +often happens when developing a new migration. We can use the following command +to achieve this goal. + +~~~ +yiic migrate/mark 101129_185401 +~~~ + +This command is very similar to `yiic migrate/to` command, except that it only +modifies the migration history table to the specified version without applying +or reverting the migrations. + + +Customizing Migration Command +----------------------------- + +There are several ways to customize the migration command. + +### Use Command Line Options + +The migration command comes with four options that can be specified in command +line: + +* `interactive`: boolean, specifies whether to perform migrations in an + interactive mode. Defaults to true, meaning the user will be prompted when + performing a specific migration. You may set this to false should the + migrations be done in a background process. + +* `migrationPath`: string, specifies the directory storing all migration class + files. This must be specified in terms of a path alias, and the corresponding + directory must exist. If not specified, it will use the `migrations` + sub-directory under the application base path. + +* `migrationTable`: string, specifies the name of the database table for storing + migration history information. It defaults to `tbl_migration`. The table + structure is `version varchar(255) primary key, apply_time integer`. + +* `connectionID`: string, specifies the ID of the database application component. + Defaults to 'db'. + +* `templateFile`: string, specifies the path of the file to be served as the code + template for generating the migration classes. This must be specified in terms + of a path alias (e.g. `application.migrations.template`). If not set, an + internal template will be used. Inside the template, the token `{ClassName}` + will be replaced with the actual migration class name. + +To specify these options, execute the migrate command using the following format + +~~~ +yiic migrate/up --option1=value1 --option2=value2 ... +~~~ + +For example, if we want to migrate for a `forum` module whose migration files +are located within the module's `migrations` directory, we can use the following +command: + +~~~ +yiic migrate/up --migrationPath=ext.forum.migrations +~~~ + + +### Configure Command Globally + +While command line options allow us to configure the migration command +on-the-fly, sometimes we may want to configure the command once for all. +For example, we may want to use a different table to store the migration history, +or we may want to use a customized migration template. We can do so by modifying +the console application's configuration file like the following, + +```php +TBD +``` + +Now if we run the `migrate` command, the above configurations will take effect +without requiring us to enter the command line options every time. From aa3fe610a8c9f1cb53f2442ee7f35eddd1564511 Mon Sep 17 00:00:00 2001 From: Vladimir Vyachin Date: Sun, 5 May 2013 17:03:54 +0400 Subject: [PATCH 59/87] Fix log messages collection --- framework/logging/Target.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/logging/Target.php b/framework/logging/Target.php index e76e8ac..311334d 100644 --- a/framework/logging/Target.php +++ b/framework/logging/Target.php @@ -89,7 +89,7 @@ abstract class Target extends \yii\base\Component */ public function collect($messages, $final) { - $this->_messages = array($this->_messages, $this->filterMessages($messages)); + $this->_messages = array_merge($this->_messages, $this->filterMessages($messages)); $count = count($this->_messages); if ($count > 0 && ($final || $this->exportInterval > 0 && $count >= $this->exportInterval)) { if (($context = $this->getContextMessage()) !== '') { From af72a948f6f965f4a4623e34f347abeb19da4db4 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sun, 5 May 2013 09:07:51 -0400 Subject: [PATCH 60/87] Fixes issue #107: UrlManager::showScriptName default to false. --- framework/web/UrlManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/web/UrlManager.php b/framework/web/UrlManager.php index 318f329..329bf07 100644 --- a/framework/web/UrlManager.php +++ b/framework/web/UrlManager.php @@ -51,7 +51,7 @@ class UrlManager extends Component * @var boolean whether to show entry script name in the constructed URL. Defaults to true. * This property is used only if [[enablePrettyUrl]] is true. */ - public $showScriptName = true; + public $showScriptName = false; /** * @var string the GET variable name for route. This property is used only if [[enablePrettyUrl]] is false. */ From c9895eff82d59695eeba6d9083c56c954a915a51 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sun, 5 May 2013 10:06:40 -0400 Subject: [PATCH 61/87] Fixes issue #110. --- framework/base/View.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/base/View.php b/framework/base/View.php index a72982e..115bfad 100644 --- a/framework/base/View.php +++ b/framework/base/View.php @@ -744,10 +744,10 @@ class View extends Component { $lines = array(); if (!empty($this->metaTags)) { - $lines[] = implode("\n", $this->cssFiles); + $lines[] = implode("\n", $this->metaTags); } if (!empty($this->linkTags)) { - $lines[] = implode("\n", $this->cssFiles); + $lines[] = implode("\n", $this->linkTags); } if (!empty($this->cssFiles)) { $lines[] = implode("\n", $this->cssFiles); From c91a0f4b26ac14d75b98845eec7575a3d3b0eb57 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sun, 5 May 2013 10:14:55 -0400 Subject: [PATCH 62/87] Fixes issue #105: route var appears twice in the created URL --- framework/web/UrlManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/web/UrlManager.php b/framework/web/UrlManager.php index 329bf07..a300033 100644 --- a/framework/web/UrlManager.php +++ b/framework/web/UrlManager.php @@ -174,7 +174,7 @@ class UrlManager extends Component public function createUrl($route, $params = array()) { $anchor = isset($params['#']) ? '#' . $params['#'] : ''; - unset($params['#']); + unset($params['#'], $params[$this->routeVar]); $route = trim($route, '/'); $baseUrl = $this->getBaseUrl(); From b6cee8af881305557a3657893ec7c0db406055d7 Mon Sep 17 00:00:00 2001 From: Vladimir Vyachin Date: Sun, 5 May 2013 18:21:10 +0400 Subject: [PATCH 63/87] fix assetconverter file extensions change only first time --- framework/web/AssetConverter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/web/AssetConverter.php b/framework/web/AssetConverter.php index 8340be5..f2871fe 100644 --- a/framework/web/AssetConverter.php +++ b/framework/web/AssetConverter.php @@ -53,8 +53,8 @@ class AssetConverter extends Component implements IAssetConverter )); exec($command, $output); Yii::info("Converted $asset into $result: " . implode("\n", $output), __METHOD__); - return "$baseUrl/$result"; } + return "$baseUrl/$result"; } } return "$baseUrl/$asset"; From 3c83b8ed7cb0442fc88e66a63d9764d4d31b2bcf Mon Sep 17 00:00:00 2001 From: Rasmus Lerdorf Date: Sun, 5 May 2013 07:31:09 -0700 Subject: [PATCH 64/87] Fix typos A couple of obvious typos here --- framework/validators/FileValidator.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/framework/validators/FileValidator.php b/framework/validators/FileValidator.php index 0fddcf5..ebe6cad 100644 --- a/framework/validators/FileValidator.php +++ b/framework/validators/FileValidator.php @@ -192,11 +192,11 @@ class FileValidator extends Validator break; case UPLOAD_ERR_CANT_WRITE: $this->addError($object, $attribute, $this->message); - Yii::warning('Failed to write the uploaded file to disk: ', $file->getName(), __METHOD__); + Yii::warning('Failed to write the uploaded file to disk: ' . $file->getName(), __METHOD__); break; case UPLOAD_ERR_EXTENSION: $this->addError($object, $attribute, $this->message); - Yii::warning('File upload was stopped by some PHP extension: ', $file->getName(), __METHOD__); + Yii::warning('File upload was stopped by some PHP extension: ' . $file->getName(), __METHOD__); break; default: break; @@ -248,4 +248,4 @@ class FileValidator extends Validator return (int)$sizeStr; } } -} \ No newline at end of file +} From 7f5cbce69cc702633691836a20ecb7f44589e847 Mon Sep 17 00:00:00 2001 From: Vladimir Vyachin Date: Sun, 5 May 2013 18:46:54 +0400 Subject: [PATCH 65/87] fix SecurityHelper description --- framework/helpers/base/SecurityHelper.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/helpers/base/SecurityHelper.php b/framework/helpers/base/SecurityHelper.php index ed5bfd6..d220bf4 100644 --- a/framework/helpers/base/SecurityHelper.php +++ b/framework/helpers/base/SecurityHelper.php @@ -167,11 +167,11 @@ class SecurityHelper * * ~~~ * // generates the hash (usually done during user registration or when the password is changed) - * $hash = SecurityHelper::hashPassword($password); + * $hash = SecurityHelper::generatePasswordHash($password); * // ...save $hash in database... * * // during login, validate if the password entered is correct using $hash fetched from database - * if (PasswordHelper::verifyPassword($password, $hash) { + * if (SecurityHelper::verifyPassword($password, $hash) { * // password is good * } else { * // password is bad From 802c0c94a81d89ea3409dc62ef08a3ec7967fd44 Mon Sep 17 00:00:00 2001 From: Rinat Silnov Date: Sun, 5 May 2013 19:18:04 +0400 Subject: [PATCH 66/87] Check apc.enable_cli for ApcTestCase unit tests --- tests/unit/framework/caching/ApcCacheTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/unit/framework/caching/ApcCacheTest.php b/tests/unit/framework/caching/ApcCacheTest.php index 74ede2a..604efde 100644 --- a/tests/unit/framework/caching/ApcCacheTest.php +++ b/tests/unit/framework/caching/ApcCacheTest.php @@ -17,6 +17,8 @@ class ApcCacheTest extends CacheTest { if(!extension_loaded("apc")) { $this->markTestSkipped("APC not installed. Skipping."); + } else if ('cli' === PHP_SAPI && !ini_get('apc.enable_cli')) { + $this->markTestSkipped("APC cli is not enabled. Skipping."); } if($this->_cacheInstance === null) { From 47c643fbff9ebfc28a5760789c719278a8ccfc2d Mon Sep 17 00:00:00 2001 From: Rinat Silnov Date: Sun, 5 May 2013 19:25:36 +0400 Subject: [PATCH 67/87] Call static::dumpAsString in VarDumper::dump This way we can extend VarDumper::dumpAsString --- framework/helpers/base/VarDumper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/helpers/base/VarDumper.php b/framework/helpers/base/VarDumper.php index 43b0cd8..5268568 100644 --- a/framework/helpers/base/VarDumper.php +++ b/framework/helpers/base/VarDumper.php @@ -39,7 +39,7 @@ class VarDumper */ public static function dump($var, $depth = 10, $highlight = false) { - echo self::dumpAsString($var, $depth, $highlight); + echo static::dumpAsString($var, $depth, $highlight); } /** From 4be9e195c2d572c318a0e68c90765b0ceb823fd0 Mon Sep 17 00:00:00 2001 From: Zander Baldwin Date: Sun, 5 May 2013 17:04:55 +0100 Subject: [PATCH 68/87] Add Newlines Appended newlines to every PHP document that did not have a newline as the last character in the file. --- app/protected/config/assets.php | 2 +- app/protected/config/main.php | 2 +- app/protected/controllers/SiteController.php | 2 +- app/protected/models/ContactForm.php | 2 +- app/protected/models/LoginForm.php | 2 +- app/protected/models/User.php | 2 +- app/protected/views/layouts/main.php | 2 +- app/protected/views/site/contact.php | 2 +- app/protected/views/site/login.php | 2 +- framework/assets.php | 2 +- framework/base/ActionFilter.php | 2 +- framework/base/Exception.php | 2 +- framework/base/View.php | 2 +- framework/base/ViewEvent.php | 2 +- framework/base/Widget.php | 2 +- framework/caching/Cache.php | 2 +- framework/caching/Dependency.php | 2 +- framework/caching/MemCacheServer.php | 2 +- framework/caching/WinCache.php | 2 +- framework/console/Controller.php | 2 +- framework/console/controllers/AppController.php | 2 +- framework/console/controllers/AssetController.php | 2 +- framework/console/controllers/HelpController.php | 2 +- framework/console/webapp/config.php | 2 +- framework/console/webapp/default/index.php | 2 +- framework/console/webapp/default/protected/config/main.php | 2 +- .../console/webapp/default/protected/controllers/SiteController.php | 2 +- framework/console/webapp/default/protected/views/layouts/main.php | 2 +- framework/console/webapp/default/protected/views/site/index.php | 2 +- framework/db/Exception.php | 2 +- framework/db/Expression.php | 2 +- framework/db/Migration.php | 2 +- framework/db/StaleObjectException.php | 2 +- framework/helpers/ArrayHelper.php | 2 +- framework/helpers/FileHelper.php | 2 +- framework/helpers/JsExpression.php | 2 +- framework/helpers/Json.php | 2 +- framework/helpers/SecurityHelper.php | 2 +- framework/helpers/VarDumper.php | 2 +- framework/helpers/base/ArrayHelper.php | 2 +- framework/helpers/base/FileHelper.php | 2 +- framework/helpers/base/Json.php | 2 +- framework/helpers/base/VarDumper.php | 2 +- framework/i18n/PhpMessageSource.php | 2 +- framework/i18n/data/plurals.php | 2 +- framework/logging/EmailTarget.php | 2 +- framework/logging/ProfileTarget.php | 2 +- framework/logging/WebTarget.php | 2 +- framework/renderers/SmartyViewRenderer.php | 2 +- framework/validators/InlineValidator.php | 2 +- framework/validators/NumberValidator.php | 2 +- framework/validators/UniqueValidator.php | 2 +- framework/views/error.php | 2 +- framework/web/AccessControl.php | 2 +- framework/web/AccessRule.php | 2 +- framework/web/AssetBundle.php | 2 +- framework/web/AssetConverter.php | 2 +- framework/web/Controller.php | 2 +- framework/web/HttpCache.php | 2 +- framework/web/IAssetConverter.php | 2 +- framework/web/Identity.php | 2 +- framework/web/PageCache.php | 2 +- framework/web/Pagination.php | 2 +- framework/web/Sort.php | 2 +- framework/web/UserEvent.php | 2 +- framework/widgets/ActiveField.php | 2 +- framework/widgets/Block.php | 2 +- framework/widgets/FragmentCache.php | 2 +- tests/unit/MysqlTestCase.php | 2 +- tests/unit/TestCase.php | 2 +- tests/unit/data/ar/ActiveRecord.php | 2 +- tests/unit/data/ar/Customer.php | 2 +- tests/unit/data/ar/Item.php | 2 +- tests/unit/data/ar/Order.php | 2 +- tests/unit/data/ar/OrderItem.php | 2 +- tests/unit/data/base/Singer.php | 2 +- tests/unit/framework/base/ComponentTest.php | 2 +- tests/unit/framework/base/ObjectTest.php | 2 +- tests/unit/framework/caching/ApcCacheTest.php | 2 +- tests/unit/framework/caching/DbCacheTest.php | 2 +- tests/unit/framework/caching/FileCacheTest.php | 2 +- tests/unit/framework/caching/MemCacheTest.php | 2 +- tests/unit/framework/caching/MemCachedTest.php | 2 +- tests/unit/framework/caching/WinCacheTest.php | 2 +- tests/unit/framework/caching/XCacheTest.php | 2 +- tests/unit/framework/caching/ZendDataCacheTest.php | 2 +- tests/unit/framework/db/ActiveRecordTest.php | 2 +- tests/unit/framework/db/CommandTest.php | 2 +- tests/unit/framework/db/QueryTest.php | 2 +- tests/unit/framework/helpers/JsonTest.php | 2 +- tests/unit/framework/helpers/StringHelperTest.php | 2 +- tests/unit/framework/helpers/VarDumperTest.php | 2 +- tests/unit/framework/validators/EmailValidatorTest.php | 2 +- tests/web/app/protected/config/main.php | 2 +- tests/web/app/protected/controllers/SiteController.php | 2 +- tests/web/app/protected/views/site/index.php | 2 +- 96 files changed, 96 insertions(+), 96 deletions(-) diff --git a/app/protected/config/assets.php b/app/protected/config/assets.php index 6602a6e..a3ba847 100644 --- a/app/protected/config/assets.php +++ b/app/protected/config/assets.php @@ -16,4 +16,4 @@ return array( 'yii', ), ), -); \ No newline at end of file +); diff --git a/app/protected/config/main.php b/app/protected/config/main.php index b982506..96e0986 100644 --- a/app/protected/config/main.php +++ b/app/protected/config/main.php @@ -18,4 +18,4 @@ return array( 'params' => array( 'adminEmail' => 'admin@example.com', ), -); \ No newline at end of file +); diff --git a/app/protected/controllers/SiteController.php b/app/protected/controllers/SiteController.php index 7e6bb15..d1186f6 100644 --- a/app/protected/controllers/SiteController.php +++ b/app/protected/controllers/SiteController.php @@ -46,4 +46,4 @@ class SiteController extends Controller { echo $this->render('about'); } -} \ No newline at end of file +} diff --git a/app/protected/models/ContactForm.php b/app/protected/models/ContactForm.php index 8e8f831..5124b2c 100644 --- a/app/protected/models/ContactForm.php +++ b/app/protected/models/ContactForm.php @@ -60,4 +60,4 @@ class ContactForm extends Model return false; } } -} \ No newline at end of file +} diff --git a/app/protected/models/LoginForm.php b/app/protected/models/LoginForm.php index 23e8c92..5ba1dc6 100644 --- a/app/protected/models/LoginForm.php +++ b/app/protected/models/LoginForm.php @@ -55,4 +55,4 @@ class LoginForm extends Model return false; } } -} \ No newline at end of file +} diff --git a/app/protected/models/User.php b/app/protected/models/User.php index fcbf14a..afbf9f8 100644 --- a/app/protected/models/User.php +++ b/app/protected/models/User.php @@ -58,4 +58,4 @@ class User extends \yii\base\Object implements \yii\web\Identity { return $this->password === $password; } -} \ No newline at end of file +} diff --git a/app/protected/views/layouts/main.php b/app/protected/views/layouts/main.php index a455f20..8fb915a 100644 --- a/app/protected/views/layouts/main.php +++ b/app/protected/views/layouts/main.php @@ -54,4 +54,4 @@ $this->registerAssetBundle('app');
    -endPage(); ?> \ No newline at end of file +endPage(); ?> diff --git a/app/protected/views/site/contact.php b/app/protected/views/site/contact.php index 246570d..4ca40f1 100644 --- a/app/protected/views/site/contact.php +++ b/app/protected/views/site/contact.php @@ -30,4 +30,4 @@ $this->title = 'Contact';
    'btn btn-primary')); ?>
    -endWidget(); ?> \ No newline at end of file +endWidget(); ?> diff --git a/app/protected/views/site/login.php b/app/protected/views/site/login.php index 5608ffb..8672eeb 100644 --- a/app/protected/views/site/login.php +++ b/app/protected/views/site/login.php @@ -18,4 +18,4 @@ $this->title = 'Login';
    'btn btn-primary')); ?>
    -endWidget(); ?> \ No newline at end of file +endWidget(); ?> diff --git a/framework/assets.php b/framework/assets.php index 5cea992..919011b 100644 --- a/framework/assets.php +++ b/framework/assets.php @@ -28,4 +28,4 @@ return array( ), 'depends' => array('yii', 'yii/validation'), ), -); \ No newline at end of file +); diff --git a/framework/base/ActionFilter.php b/framework/base/ActionFilter.php index 1f82e5d..d69c0fe 100644 --- a/framework/base/ActionFilter.php +++ b/framework/base/ActionFilter.php @@ -87,4 +87,4 @@ class ActionFilter extends Behavior { return !in_array($action->id, $this->except, true) && (empty($this->only) || in_array($action->id, $this->only, true)); } -} \ No newline at end of file +} diff --git a/framework/base/Exception.php b/framework/base/Exception.php index 9ee698b..7d26bd0 100644 --- a/framework/base/Exception.php +++ b/framework/base/Exception.php @@ -22,4 +22,4 @@ class Exception extends \Exception { return \Yii::t('yii|Exception'); } -} \ No newline at end of file +} diff --git a/framework/base/View.php b/framework/base/View.php index 115bfad..4718d90 100644 --- a/framework/base/View.php +++ b/framework/base/View.php @@ -797,4 +797,4 @@ class View extends Component } return implode("\n", $lines); } -} \ No newline at end of file +} diff --git a/framework/base/ViewEvent.php b/framework/base/ViewEvent.php index cac7be4..f1ee7b9 100644 --- a/framework/base/ViewEvent.php +++ b/framework/base/ViewEvent.php @@ -41,4 +41,4 @@ class ViewEvent extends Event $this->viewFile = $viewFile; parent::__construct($config); } -} \ No newline at end of file +} diff --git a/framework/base/Widget.php b/framework/base/Widget.php index 1aabd4f..c0c524f 100644 --- a/framework/base/Widget.php +++ b/framework/base/Widget.php @@ -134,4 +134,4 @@ class Widget extends Component return pathinfo($file, PATHINFO_EXTENSION) === '' ? $file . '.php' : $file; } -} \ No newline at end of file +} diff --git a/framework/caching/Cache.php b/framework/caching/Cache.php index fb56d5e..78f2854 100644 --- a/framework/caching/Cache.php +++ b/framework/caching/Cache.php @@ -349,4 +349,4 @@ abstract class Cache extends Component implements \ArrayAccess { $this->delete($key); } -} \ No newline at end of file +} diff --git a/framework/caching/Dependency.php b/framework/caching/Dependency.php index feb8c07..d1428fc 100644 --- a/framework/caching/Dependency.php +++ b/framework/caching/Dependency.php @@ -49,4 +49,4 @@ abstract class Dependency extends \yii\base\Object * @return mixed the data needed to determine if dependency has been changed. */ abstract protected function generateDependencyData(); -} \ No newline at end of file +} diff --git a/framework/caching/MemCacheServer.php b/framework/caching/MemCacheServer.php index 105137e..dc0de08 100644 --- a/framework/caching/MemCacheServer.php +++ b/framework/caching/MemCacheServer.php @@ -46,4 +46,4 @@ class MemCacheServer extends \yii\base\Object * @var boolean if the server should be flagged as online upon a failure. This is used by memcache only. */ public $status = true; -} \ No newline at end of file +} diff --git a/framework/caching/WinCache.php b/framework/caching/WinCache.php index ee6b4a9..4e07c7f 100644 --- a/framework/caching/WinCache.php +++ b/framework/caching/WinCache.php @@ -89,4 +89,4 @@ class WinCache extends Cache { return wincache_ucache_clear(); } -} \ No newline at end of file +} diff --git a/framework/console/Controller.php b/framework/console/Controller.php index c7c5642..2eaf4b8 100644 --- a/framework/console/Controller.php +++ b/framework/console/Controller.php @@ -147,4 +147,4 @@ class Controller extends \yii\base\Controller { return array(); } -} \ No newline at end of file +} diff --git a/framework/console/controllers/AppController.php b/framework/console/controllers/AppController.php index a47acfe..17f7420 100644 --- a/framework/console/controllers/AppController.php +++ b/framework/console/controllers/AppController.php @@ -321,4 +321,4 @@ class AppController extends Controller closedir($handle); return $list; } -} \ No newline at end of file +} diff --git a/framework/console/controllers/AssetController.php b/framework/console/controllers/AssetController.php index 71a2cae..aab489b 100644 --- a/framework/console/controllers/AssetController.php +++ b/framework/console/controllers/AssetController.php @@ -350,4 +350,4 @@ return array( EOD; file_put_contents($configFile, $template); } -} \ No newline at end of file +} diff --git a/framework/console/controllers/HelpController.php b/framework/console/controllers/HelpController.php index 74c354b..82bd6fe 100644 --- a/framework/console/controllers/HelpController.php +++ b/framework/console/controllers/HelpController.php @@ -418,4 +418,4 @@ class HelpController extends Controller $name = $required ? "$name (required)" : $name; return $doc === '' ? $name : "$name: $doc"; } -} \ No newline at end of file +} diff --git a/framework/console/webapp/config.php b/framework/console/webapp/config.php index 112fb18..47ddcc1 100644 --- a/framework/console/webapp/config.php +++ b/framework/console/webapp/config.php @@ -14,4 +14,4 @@ return array( 'permissions' => 0755, ), ), -); \ No newline at end of file +); diff --git a/framework/console/webapp/default/index.php b/framework/console/webapp/default/index.php index b84e257..2aa3580 100644 --- a/framework/console/webapp/default/index.php +++ b/framework/console/webapp/default/index.php @@ -7,4 +7,4 @@ $config = require dirname(__DIR__).'/protected/config/main.php'; $config['basePath'] = dirname(__DIR__).'/protected'; $app = new \yii\web\Application($config); -$app->run(); \ No newline at end of file +$app->run(); diff --git a/framework/console/webapp/default/protected/config/main.php b/framework/console/webapp/default/protected/config/main.php index 795811e..5817783 100644 --- a/framework/console/webapp/default/protected/config/main.php +++ b/framework/console/webapp/default/protected/config/main.php @@ -17,4 +17,4 @@ return array( 'class' => 'yii\caching\DummyCache', ), ), -); \ No newline at end of file +); diff --git a/framework/console/webapp/default/protected/controllers/SiteController.php b/framework/console/webapp/default/protected/controllers/SiteController.php index b47b93c..ac8c1dd 100644 --- a/framework/console/webapp/default/protected/controllers/SiteController.php +++ b/framework/console/webapp/default/protected/controllers/SiteController.php @@ -12,4 +12,4 @@ class SiteController extends Controller 'name' => 'Qiang', )); } -} \ No newline at end of file +} diff --git a/framework/console/webapp/default/protected/views/layouts/main.php b/framework/console/webapp/default/protected/views/layouts/main.php index 5c883e6..9837038 100644 --- a/framework/console/webapp/default/protected/views/layouts/main.php +++ b/framework/console/webapp/default/protected/views/layouts/main.php @@ -14,4 +14,4 @@
    - \ No newline at end of file + diff --git a/framework/console/webapp/default/protected/views/site/index.php b/framework/console/webapp/default/protected/views/site/index.php index 0fb8784..08c5288 100644 --- a/framework/console/webapp/default/protected/views/site/index.php +++ b/framework/console/webapp/default/protected/views/site/index.php @@ -1 +1 @@ -Hello, ! \ No newline at end of file +Hello, ! diff --git a/framework/db/Exception.php b/framework/db/Exception.php index ad97b5a..b7a60b4 100644 --- a/framework/db/Exception.php +++ b/framework/db/Exception.php @@ -41,4 +41,4 @@ class Exception extends \yii\base\Exception { return \Yii::t('yii|Database Exception'); } -} \ No newline at end of file +} diff --git a/framework/db/Expression.php b/framework/db/Expression.php index 4ebcd5f..77e9f60 100644 --- a/framework/db/Expression.php +++ b/framework/db/Expression.php @@ -57,4 +57,4 @@ class Expression extends \yii\base\Object { return $this->expression; } -} \ No newline at end of file +} diff --git a/framework/db/Migration.php b/framework/db/Migration.php index ce2cf97..88abab5 100644 --- a/framework/db/Migration.php +++ b/framework/db/Migration.php @@ -368,4 +368,4 @@ class Migration extends \yii\base\Component $this->db->createCommand()->dropIndex($name, $table)->execute(); echo " done (time: " . sprintf('%.3f', microtime(true) - $time) . "s)\n"; } -} \ No newline at end of file +} diff --git a/framework/db/StaleObjectException.php b/framework/db/StaleObjectException.php index 860c9fc..0a04bd3 100644 --- a/framework/db/StaleObjectException.php +++ b/framework/db/StaleObjectException.php @@ -20,4 +20,4 @@ class StaleObjectException extends Exception { return \Yii::t('yii|Stale Object Exception'); } -} \ No newline at end of file +} diff --git a/framework/helpers/ArrayHelper.php b/framework/helpers/ArrayHelper.php index 3061717..d58341c 100644 --- a/framework/helpers/ArrayHelper.php +++ b/framework/helpers/ArrayHelper.php @@ -16,4 +16,4 @@ namespace yii\helpers; */ class ArrayHelper extends base\ArrayHelper { -} \ No newline at end of file +} diff --git a/framework/helpers/FileHelper.php b/framework/helpers/FileHelper.php index 3fb24e1..04ce4e1 100644 --- a/framework/helpers/FileHelper.php +++ b/framework/helpers/FileHelper.php @@ -18,4 +18,4 @@ namespace yii\helpers; */ class FileHelper extends base\FileHelper { -} \ No newline at end of file +} diff --git a/framework/helpers/JsExpression.php b/framework/helpers/JsExpression.php index 0054b64..5a1f9bd 100644 --- a/framework/helpers/JsExpression.php +++ b/framework/helpers/JsExpression.php @@ -42,4 +42,4 @@ class JsExpression extends Object { return $this->expression; } -} \ No newline at end of file +} diff --git a/framework/helpers/Json.php b/framework/helpers/Json.php index 2a20f3c..5e77c3f 100644 --- a/framework/helpers/Json.php +++ b/framework/helpers/Json.php @@ -15,4 +15,4 @@ namespace yii\helpers; class Json extends base\Json { -} \ No newline at end of file +} diff --git a/framework/helpers/SecurityHelper.php b/framework/helpers/SecurityHelper.php index d3cb2ad..d16e7e6 100644 --- a/framework/helpers/SecurityHelper.php +++ b/framework/helpers/SecurityHelper.php @@ -26,4 +26,4 @@ namespace yii\helpers; */ class SecurityHelper extends base\SecurityHelper { -} \ No newline at end of file +} diff --git a/framework/helpers/VarDumper.php b/framework/helpers/VarDumper.php index 2659188..59a1718 100644 --- a/framework/helpers/VarDumper.php +++ b/framework/helpers/VarDumper.php @@ -25,4 +25,4 @@ namespace yii\helpers; */ class VarDumper extends base\VarDumper { -} \ No newline at end of file +} diff --git a/framework/helpers/base/ArrayHelper.php b/framework/helpers/base/ArrayHelper.php index 5f72fe4..86445d7 100644 --- a/framework/helpers/base/ArrayHelper.php +++ b/framework/helpers/base/ArrayHelper.php @@ -349,4 +349,4 @@ class ArrayHelper } return $d; } -} \ No newline at end of file +} diff --git a/framework/helpers/base/FileHelper.php b/framework/helpers/base/FileHelper.php index 2f62f43..954c86e 100644 --- a/framework/helpers/base/FileHelper.php +++ b/framework/helpers/base/FileHelper.php @@ -169,4 +169,4 @@ class FileHelper } closedir($handle); } -} \ No newline at end of file +} diff --git a/framework/helpers/base/Json.php b/framework/helpers/base/Json.php index 1deb5c2..c92e208 100644 --- a/framework/helpers/base/Json.php +++ b/framework/helpers/base/Json.php @@ -104,4 +104,4 @@ class Json return $data; } } -} \ No newline at end of file +} diff --git a/framework/helpers/base/VarDumper.php b/framework/helpers/base/VarDumper.php index 5268568..730aafe 100644 --- a/framework/helpers/base/VarDumper.php +++ b/framework/helpers/base/VarDumper.php @@ -131,4 +131,4 @@ class VarDumper break; } } -} \ No newline at end of file +} diff --git a/framework/i18n/PhpMessageSource.php b/framework/i18n/PhpMessageSource.php index 1ada44a..f62939f 100644 --- a/framework/i18n/PhpMessageSource.php +++ b/framework/i18n/PhpMessageSource.php @@ -76,4 +76,4 @@ class PhpMessageSource extends MessageSource return array(); } } -} \ No newline at end of file +} diff --git a/framework/i18n/data/plurals.php b/framework/i18n/data/plurals.php index 52c733b..468f7e2 100644 --- a/framework/i18n/data/plurals.php +++ b/framework/i18n/data/plurals.php @@ -624,4 +624,4 @@ return array ( array ( 0 => 'in_array(fmod($n,10),array(1,2))||fmod($n,20)==0', ), -); \ No newline at end of file +); diff --git a/framework/logging/EmailTarget.php b/framework/logging/EmailTarget.php index 4c84739..bb02e34 100644 --- a/framework/logging/EmailTarget.php +++ b/framework/logging/EmailTarget.php @@ -69,4 +69,4 @@ class EmailTarget extends Target } mail($sentTo, $subject, $body, implode("\r\n", $headers)); } -} \ No newline at end of file +} diff --git a/framework/logging/ProfileTarget.php b/framework/logging/ProfileTarget.php index 2b6ffe6..335e172 100644 --- a/framework/logging/ProfileTarget.php +++ b/framework/logging/ProfileTarget.php @@ -189,4 +189,4 @@ class CProfileLogRoute extends CWebLogRoute $total += $delta; return array($token, $calls, $min, $max, $total); } -} \ No newline at end of file +} diff --git a/framework/logging/WebTarget.php b/framework/logging/WebTarget.php index b71e1a2..c98fd9f 100644 --- a/framework/logging/WebTarget.php +++ b/framework/logging/WebTarget.php @@ -58,4 +58,4 @@ class CWebLogRoute extends CLogRoute $viewFile = YII_PATH . DIRECTORY_SEPARATOR . 'views' . DIRECTORY_SEPARATOR . $view . '.php'; include($app->findLocalizedFile($viewFile, 'en')); } -} \ No newline at end of file +} diff --git a/framework/renderers/SmartyViewRenderer.php b/framework/renderers/SmartyViewRenderer.php index 920f3c6..29d7b97 100644 --- a/framework/renderers/SmartyViewRenderer.php +++ b/framework/renderers/SmartyViewRenderer.php @@ -102,4 +102,4 @@ class SmartyViewRenderer extends ViewRenderer return $template->fetch(); } -} \ No newline at end of file +} diff --git a/framework/validators/InlineValidator.php b/framework/validators/InlineValidator.php index 3689a2f..8af5bbc 100644 --- a/framework/validators/InlineValidator.php +++ b/framework/validators/InlineValidator.php @@ -96,4 +96,4 @@ class InlineValidator extends Validator return null; } } -} \ No newline at end of file +} diff --git a/framework/validators/NumberValidator.php b/framework/validators/NumberValidator.php index d0a4002..c0f81cd 100644 --- a/framework/validators/NumberValidator.php +++ b/framework/validators/NumberValidator.php @@ -151,4 +151,4 @@ class NumberValidator extends Validator return 'yii.validation.number(value, messages, ' . Json::encode($options) . ');'; } -} \ No newline at end of file +} diff --git a/framework/validators/UniqueValidator.php b/framework/validators/UniqueValidator.php index 2240e0a..7072ff4 100644 --- a/framework/validators/UniqueValidator.php +++ b/framework/validators/UniqueValidator.php @@ -97,4 +97,4 @@ class UniqueValidator extends Validator $this->addError($object, $attribute, $this->message); } } -} \ No newline at end of file +} diff --git a/framework/views/error.php b/framework/views/error.php index 548d04b..009050a 100644 --- a/framework/views/error.php +++ b/framework/views/error.php @@ -64,4 +64,4 @@ $title = $context->htmlEncode($exception instanceof \yii\base\Exception ? $excep versionInfo : ''?> - \ No newline at end of file + diff --git a/framework/web/AccessControl.php b/framework/web/AccessControl.php index f5983ae..e890510 100644 --- a/framework/web/AccessControl.php +++ b/framework/web/AccessControl.php @@ -103,4 +103,4 @@ class AccessControl extends ActionFilter throw new HttpException(403, Yii::t('yii|You are not allowed to perform this action.')); } } -} \ No newline at end of file +} diff --git a/framework/web/AccessRule.php b/framework/web/AccessRule.php index 3f8c057..b195048 100644 --- a/framework/web/AccessRule.php +++ b/framework/web/AccessRule.php @@ -185,4 +185,4 @@ class AccessRule extends Component { return empty($this->matchCallback) || call_user_func($this->matchCallback, $this, $action); } -} \ No newline at end of file +} diff --git a/framework/web/AssetBundle.php b/framework/web/AssetBundle.php index 4e1eb59..37577dd 100644 --- a/framework/web/AssetBundle.php +++ b/framework/web/AssetBundle.php @@ -173,4 +173,4 @@ class AssetBundle extends Object } } } -} \ No newline at end of file +} diff --git a/framework/web/AssetConverter.php b/framework/web/AssetConverter.php index f2871fe..4fde1fc 100644 --- a/framework/web/AssetConverter.php +++ b/framework/web/AssetConverter.php @@ -59,4 +59,4 @@ class AssetConverter extends Component implements IAssetConverter } return "$baseUrl/$asset"; } -} \ No newline at end of file +} diff --git a/framework/web/Controller.php b/framework/web/Controller.php index 099bf96..517f4b4 100644 --- a/framework/web/Controller.php +++ b/framework/web/Controller.php @@ -40,4 +40,4 @@ class Controller extends \yii\base\Controller } return Yii::$app->getUrlManager()->createUrl($route, $params); } -} \ No newline at end of file +} diff --git a/framework/web/HttpCache.php b/framework/web/HttpCache.php index f64b37f..0a3bb86 100644 --- a/framework/web/HttpCache.php +++ b/framework/web/HttpCache.php @@ -128,4 +128,4 @@ class HttpCache extends ActionFilter { return '"' . base64_encode(sha1($seed, true)) . '"'; } -} \ No newline at end of file +} diff --git a/framework/web/IAssetConverter.php b/framework/web/IAssetConverter.php index 4334d3e..d1d1da0 100644 --- a/framework/web/IAssetConverter.php +++ b/framework/web/IAssetConverter.php @@ -24,4 +24,4 @@ interface IAssetConverter * need conversion, "$baseUrl/$asset" should be returned. */ public function convert($asset, $basePath, $baseUrl); -} \ No newline at end of file +} diff --git a/framework/web/Identity.php b/framework/web/Identity.php index 6d67bc0..101ecdb 100644 --- a/framework/web/Identity.php +++ b/framework/web/Identity.php @@ -78,4 +78,4 @@ interface Identity * @see getAuthKey() */ public function validateAuthKey($authKey); -} \ No newline at end of file +} diff --git a/framework/web/PageCache.php b/framework/web/PageCache.php index 5a50825..2fe36b3 100644 --- a/framework/web/PageCache.php +++ b/framework/web/PageCache.php @@ -101,4 +101,4 @@ class PageCache extends ActionFilter { $this->view->endCache(); } -} \ No newline at end of file +} diff --git a/framework/web/Pagination.php b/framework/web/Pagination.php index 1d41c0c..764dbb4 100644 --- a/framework/web/Pagination.php +++ b/framework/web/Pagination.php @@ -205,4 +205,4 @@ class Pagination extends \yii\base\Object { return $this->pageSize < 1 ? -1 : $this->pageSize; } -} \ No newline at end of file +} diff --git a/framework/web/Sort.php b/framework/web/Sort.php index e5c2451..99084c1 100644 --- a/framework/web/Sort.php +++ b/framework/web/Sort.php @@ -333,4 +333,4 @@ class Sort extends \yii\base\Object return false; } } -} \ No newline at end of file +} diff --git a/framework/web/UserEvent.php b/framework/web/UserEvent.php index 7a5d23d..4e39380 100644 --- a/framework/web/UserEvent.php +++ b/framework/web/UserEvent.php @@ -31,4 +31,4 @@ class UserEvent extends Event * This property is only meaningful for [[User::EVENT_BEFORE_LOGIN]] and [[User::EVENT_BEFORE_LOGOUT]] events. */ public $isValid = true; -} \ No newline at end of file +} diff --git a/framework/widgets/ActiveField.php b/framework/widgets/ActiveField.php index da17012..336966f 100644 --- a/framework/widgets/ActiveField.php +++ b/framework/widgets/ActiveField.php @@ -541,4 +541,4 @@ class ActiveField extends Component . '' ); } -} \ No newline at end of file +} diff --git a/framework/widgets/Block.php b/framework/widgets/Block.php index d6f7317..fdd210f 100644 --- a/framework/widgets/Block.php +++ b/framework/widgets/Block.php @@ -46,4 +46,4 @@ class Block extends Widget } $this->view->blocks[$this->id] = $block; } -} \ No newline at end of file +} diff --git a/framework/widgets/FragmentCache.php b/framework/widgets/FragmentCache.php index 637d115..5b37f6e 100644 --- a/framework/widgets/FragmentCache.php +++ b/framework/widgets/FragmentCache.php @@ -171,4 +171,4 @@ class FragmentCache extends Widget } return $this->cache->buildKey($factors); } -} \ No newline at end of file +} diff --git a/tests/unit/MysqlTestCase.php b/tests/unit/MysqlTestCase.php index e1a1f7e..c7ef970 100644 --- a/tests/unit/MysqlTestCase.php +++ b/tests/unit/MysqlTestCase.php @@ -33,4 +33,4 @@ class MysqlTestCase extends TestCase } return $db; } -} \ No newline at end of file +} diff --git a/tests/unit/TestCase.php b/tests/unit/TestCase.php index 458c6f3..dccd3af 100644 --- a/tests/unit/TestCase.php +++ b/tests/unit/TestCase.php @@ -13,4 +13,4 @@ class TestCase extends \yii\test\TestCase } return isset(self::$params[$name]) ? self::$params[$name] : null; } -} \ No newline at end of file +} diff --git a/tests/unit/data/ar/ActiveRecord.php b/tests/unit/data/ar/ActiveRecord.php index 95346de..f1194ea 100644 --- a/tests/unit/data/ar/ActiveRecord.php +++ b/tests/unit/data/ar/ActiveRecord.php @@ -23,4 +23,4 @@ class ActiveRecord extends \yii\db\ActiveRecord { return self::$db; } -} \ No newline at end of file +} diff --git a/tests/unit/data/ar/Customer.php b/tests/unit/data/ar/Customer.php index a090b7f..9b3eab6 100644 --- a/tests/unit/data/ar/Customer.php +++ b/tests/unit/data/ar/Customer.php @@ -24,4 +24,4 @@ class Customer extends ActiveRecord { return $query->andWhere('status=1'); } -} \ No newline at end of file +} diff --git a/tests/unit/data/ar/Item.php b/tests/unit/data/ar/Item.php index 279893f..5d23378 100644 --- a/tests/unit/data/ar/Item.php +++ b/tests/unit/data/ar/Item.php @@ -8,4 +8,4 @@ class Item extends ActiveRecord { return 'tbl_item'; } -} \ No newline at end of file +} diff --git a/tests/unit/data/ar/Order.php b/tests/unit/data/ar/Order.php index 38257d6..f9dd715 100644 --- a/tests/unit/data/ar/Order.php +++ b/tests/unit/data/ar/Order.php @@ -43,4 +43,4 @@ class Order extends ActiveRecord return false; } } -} \ No newline at end of file +} diff --git a/tests/unit/data/ar/OrderItem.php b/tests/unit/data/ar/OrderItem.php index f879749..607133e 100644 --- a/tests/unit/data/ar/OrderItem.php +++ b/tests/unit/data/ar/OrderItem.php @@ -18,4 +18,4 @@ class OrderItem extends ActiveRecord { return $this->hasOne('Item', array('id' => 'item_id')); } -} \ No newline at end of file +} diff --git a/tests/unit/data/base/Singer.php b/tests/unit/data/base/Singer.php index 3305b98..f1b91e1 100644 --- a/tests/unit/data/base/Singer.php +++ b/tests/unit/data/base/Singer.php @@ -18,4 +18,4 @@ class Singer extends Model array('underscore_style', 'yii\validators\CaptchaValidator'), ); } -} \ No newline at end of file +} diff --git a/tests/unit/framework/base/ComponentTest.php b/tests/unit/framework/base/ComponentTest.php index 74b6e9a..7c860e3 100644 --- a/tests/unit/framework/base/ComponentTest.php +++ b/tests/unit/framework/base/ComponentTest.php @@ -387,4 +387,4 @@ class NewComponent2 extends Component $this->b = $b; $this->c = $c; } -} \ No newline at end of file +} diff --git a/tests/unit/framework/base/ObjectTest.php b/tests/unit/framework/base/ObjectTest.php index b47b178..14856e2 100644 --- a/tests/unit/framework/base/ObjectTest.php +++ b/tests/unit/framework/base/ObjectTest.php @@ -181,4 +181,4 @@ class NewObject extends Object { return $this->_items; } -} \ No newline at end of file +} diff --git a/tests/unit/framework/caching/ApcCacheTest.php b/tests/unit/framework/caching/ApcCacheTest.php index 604efde..859f6a6 100644 --- a/tests/unit/framework/caching/ApcCacheTest.php +++ b/tests/unit/framework/caching/ApcCacheTest.php @@ -26,4 +26,4 @@ class ApcCacheTest extends CacheTest } return $this->_cacheInstance; } -} \ No newline at end of file +} diff --git a/tests/unit/framework/caching/DbCacheTest.php b/tests/unit/framework/caching/DbCacheTest.php index 594e946..a41667c 100644 --- a/tests/unit/framework/caching/DbCacheTest.php +++ b/tests/unit/framework/caching/DbCacheTest.php @@ -67,4 +67,4 @@ class DbCacheTest extends CacheTest } return $this->_cacheInstance; } -} \ No newline at end of file +} diff --git a/tests/unit/framework/caching/FileCacheTest.php b/tests/unit/framework/caching/FileCacheTest.php index 1f6debd..37d3222 100644 --- a/tests/unit/framework/caching/FileCacheTest.php +++ b/tests/unit/framework/caching/FileCacheTest.php @@ -22,4 +22,4 @@ class FileCacheTest extends CacheTest } return $this->_cacheInstance; } -} \ No newline at end of file +} diff --git a/tests/unit/framework/caching/MemCacheTest.php b/tests/unit/framework/caching/MemCacheTest.php index e4804d9..40dba12 100644 --- a/tests/unit/framework/caching/MemCacheTest.php +++ b/tests/unit/framework/caching/MemCacheTest.php @@ -24,4 +24,4 @@ class MemCacheTest extends CacheTest } return $this->_cacheInstance; } -} \ No newline at end of file +} diff --git a/tests/unit/framework/caching/MemCachedTest.php b/tests/unit/framework/caching/MemCachedTest.php index 59396df..c9e437c 100644 --- a/tests/unit/framework/caching/MemCachedTest.php +++ b/tests/unit/framework/caching/MemCachedTest.php @@ -26,4 +26,4 @@ class MemCachedTest extends CacheTest } return $this->_cacheInstance; } -} \ No newline at end of file +} diff --git a/tests/unit/framework/caching/WinCacheTest.php b/tests/unit/framework/caching/WinCacheTest.php index b78d57b..c9470bd 100644 --- a/tests/unit/framework/caching/WinCacheTest.php +++ b/tests/unit/framework/caching/WinCacheTest.php @@ -28,4 +28,4 @@ class WinCacheTest extends CacheTest } return $this->_cacheInstance; } -} \ No newline at end of file +} diff --git a/tests/unit/framework/caching/XCacheTest.php b/tests/unit/framework/caching/XCacheTest.php index e1ed844..b5e41a6 100644 --- a/tests/unit/framework/caching/XCacheTest.php +++ b/tests/unit/framework/caching/XCacheTest.php @@ -24,4 +24,4 @@ class XCacheTest extends CacheTest } return $this->_cacheInstance; } -} \ No newline at end of file +} diff --git a/tests/unit/framework/caching/ZendDataCacheTest.php b/tests/unit/framework/caching/ZendDataCacheTest.php index 91dfbb5..86c06c8 100644 --- a/tests/unit/framework/caching/ZendDataCacheTest.php +++ b/tests/unit/framework/caching/ZendDataCacheTest.php @@ -24,4 +24,4 @@ class ZendDataCacheTest extends CacheTest } return $this->_cacheInstance; } -} \ No newline at end of file +} diff --git a/tests/unit/framework/db/ActiveRecordTest.php b/tests/unit/framework/db/ActiveRecordTest.php index 3b8c2b5..f0ea968 100644 --- a/tests/unit/framework/db/ActiveRecordTest.php +++ b/tests/unit/framework/db/ActiveRecordTest.php @@ -356,4 +356,4 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase $customers = Customer::find()->all(); $this->assertEquals(0, count($customers)); } -} \ No newline at end of file +} diff --git a/tests/unit/framework/db/CommandTest.php b/tests/unit/framework/db/CommandTest.php index d505f6d..2576e78 100644 --- a/tests/unit/framework/db/CommandTest.php +++ b/tests/unit/framework/db/CommandTest.php @@ -289,4 +289,4 @@ class CommandTest extends \yiiunit\MysqlTestCase { } -} \ No newline at end of file +} diff --git a/tests/unit/framework/db/QueryTest.php b/tests/unit/framework/db/QueryTest.php index 2c4359f..1c730cd 100644 --- a/tests/unit/framework/db/QueryTest.php +++ b/tests/unit/framework/db/QueryTest.php @@ -113,4 +113,4 @@ class QueryTest extends \yiiunit\MysqlTestCase { } -} \ No newline at end of file +} diff --git a/tests/unit/framework/helpers/JsonTest.php b/tests/unit/framework/helpers/JsonTest.php index 0e06eb3..6a78cd1 100644 --- a/tests/unit/framework/helpers/JsonTest.php +++ b/tests/unit/framework/helpers/JsonTest.php @@ -57,4 +57,4 @@ class JsonTest extends \yii\test\TestCase $this->setExpectedException('yii\base\InvalidParamException'); Json::decode($json); } -} \ No newline at end of file +} diff --git a/tests/unit/framework/helpers/StringHelperTest.php b/tests/unit/framework/helpers/StringHelperTest.php index 4e1266f..c37aafd 100644 --- a/tests/unit/framework/helpers/StringHelperTest.php +++ b/tests/unit/framework/helpers/StringHelperTest.php @@ -70,4 +70,4 @@ class StringHelperTest extends \yii\test\TestCase $this->assertEquals('PostTag', StringHelper::id2camel('post-tag')); $this->assertEquals('PostTag', StringHelper::id2camel('post_tag', '_')); } -} \ No newline at end of file +} diff --git a/tests/unit/framework/helpers/VarDumperTest.php b/tests/unit/framework/helpers/VarDumperTest.php index 8757588..a797121 100644 --- a/tests/unit/framework/helpers/VarDumperTest.php +++ b/tests/unit/framework/helpers/VarDumperTest.php @@ -9,4 +9,4 @@ class VarDumperTest extends \yii\test\TestCase $obj = new \StdClass(); VarDumper::dump($obj); } -} \ No newline at end of file +} diff --git a/tests/unit/framework/validators/EmailValidatorTest.php b/tests/unit/framework/validators/EmailValidatorTest.php index fbc2f53..512eb5c 100644 --- a/tests/unit/framework/validators/EmailValidatorTest.php +++ b/tests/unit/framework/validators/EmailValidatorTest.php @@ -25,4 +25,4 @@ class EmailValidatorTest extends TestCase $this->assertTrue($validator->validateValue('sam@rmcreative.ru')); $this->assertFalse($validator->validateValue('test@example.com')); } -} \ No newline at end of file +} diff --git a/tests/web/app/protected/config/main.php b/tests/web/app/protected/config/main.php index eed6d54..d5be5de 100644 --- a/tests/web/app/protected/config/main.php +++ b/tests/web/app/protected/config/main.php @@ -1,3 +1,3 @@ Date: Sun, 5 May 2013 15:11:53 -0400 Subject: [PATCH 69/87] Fixes issue #124. --- framework/base/Application.php | 9 +++++++++ framework/web/AccessRule.php | 2 +- framework/web/User.php | 17 +++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/framework/base/Application.php b/framework/base/Application.php index 6dca5cf..5b92f76 100644 --- a/framework/base/Application.php +++ b/framework/base/Application.php @@ -306,6 +306,15 @@ class Application extends Module } /** + * @return null|Component + * @todo + */ + public function getAuthManager() + { + return $this->getComponent('auth'); + } + + /** * Registers the core application components. * @see setComponents */ diff --git a/framework/web/AccessRule.php b/framework/web/AccessRule.php index 3f8c057..1bcb896 100644 --- a/framework/web/AccessRule.php +++ b/framework/web/AccessRule.php @@ -144,7 +144,7 @@ class AccessRule extends Component return true; } elseif ($role === '@' && !$user->getIsGuest()) { return true; - } elseif ($user->hasAccess($role)) { + } elseif ($user->checkAccess($role)) { return true; } } diff --git a/framework/web/User.php b/framework/web/User.php index b8bf7cd..2fbea91 100644 --- a/framework/web/User.php +++ b/framework/web/User.php @@ -447,4 +447,21 @@ class User extends Component } } } + + /** + * Checks whether the user has access to the specified operation. + * @param $operator + * @param array $params + * @return bool + * @todo + */ + public function checkAccess($operation, $params = array()) + { + $auth = Yii::$app->getAuthManager(); + if ($auth !== null) { + return $auth->checkAccess($this->getId(), $operation, $params); + } else { + return true; + } + } } From 0766fbccb5b2b40b4eb414e97faa00a915ccd206 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sun, 5 May 2013 17:16:10 -0400 Subject: [PATCH 70/87] Fixes issue #128. --- framework/helpers/base/SecurityHelper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/helpers/base/SecurityHelper.php b/framework/helpers/base/SecurityHelper.php index d220bf4..3f69fee 100644 --- a/framework/helpers/base/SecurityHelper.php +++ b/framework/helpers/base/SecurityHelper.php @@ -217,7 +217,7 @@ class SecurityHelper throw new InvalidParamException('Password must be a string and cannot be empty.'); } - if (!preg_match('/^\$2[axy]\$(\d\d)\$[\./0-9A-Za-z]{22}/', $hash, $matches) || $matches[1] < 4 || $matches[1] > 30) { + if (!preg_match('/^\$2[axy]\$(\d\d)\$[\.\/0-9A-Za-z]{22}/', $hash, $matches) || $matches[1] < 4 || $matches[1] > 30) { throw new InvalidParamException('Hash is invalid.'); } From 14699b5ec3992a849d1b16d54a9f971dd65cf066 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sun, 5 May 2013 18:32:32 -0400 Subject: [PATCH 71/87] reorganized app code. removed app template from framework folder. --- app/assets/.gitignore | 1 - app/css/bootstrap-responsive.css | 1109 ---- app/css/bootstrap-responsive.min.css | 9 - app/css/bootstrap.css | 6158 -------------------- app/css/bootstrap.min.css | 9 - app/css/site.css | 78 - app/img/glyphicons-halflings-white.png | Bin 8777 -> 0 bytes app/img/glyphicons-halflings.png | Bin 12799 -> 0 bytes app/index.php | 9 - app/js/bootstrap.js | 2276 -------- app/js/bootstrap.min.js | 6 - app/protected/.htaccess | 1 - app/protected/config/assets.php | 19 - app/protected/config/main.php | 21 - app/protected/controllers/SiteController.php | 49 - app/protected/models/ContactForm.php | 63 - app/protected/models/LoginForm.php | 58 - app/protected/models/User.php | 61 - app/protected/runtime/.gitignore | 1 - app/protected/views/layouts/main.php | 57 - app/protected/views/site/about.php | 15 - app/protected/views/site/contact.php | 33 - app/protected/views/site/index.php | 47 - app/protected/views/site/login.php | 21 - apps/bootstrap/assets/.gitignore | 1 + apps/bootstrap/css/bootstrap-responsive.css | 1109 ++++ apps/bootstrap/css/bootstrap-responsive.min.css | 9 + apps/bootstrap/css/bootstrap.css | 6158 ++++++++++++++++++++ apps/bootstrap/css/bootstrap.min.css | 9 + apps/bootstrap/css/site.css | 78 + apps/bootstrap/img/glyphicons-halflings-white.png | Bin 0 -> 8777 bytes apps/bootstrap/img/glyphicons-halflings.png | Bin 0 -> 12799 bytes apps/bootstrap/index.php | 9 + apps/bootstrap/js/bootstrap.js | 2276 ++++++++ apps/bootstrap/js/bootstrap.min.js | 6 + apps/bootstrap/protected/.htaccess | 1 + apps/bootstrap/protected/config/assets.php | 19 + apps/bootstrap/protected/config/main.php | 21 + .../protected/controllers/SiteController.php | 49 + apps/bootstrap/protected/models/ContactForm.php | 63 + apps/bootstrap/protected/models/LoginForm.php | 58 + apps/bootstrap/protected/models/User.php | 61 + apps/bootstrap/protected/runtime/.gitignore | 1 + apps/bootstrap/protected/views/layouts/main.php | 57 + apps/bootstrap/protected/views/site/about.php | 15 + apps/bootstrap/protected/views/site/contact.php | 33 + apps/bootstrap/protected/views/site/index.php | 47 + apps/bootstrap/protected/views/site/login.php | 21 + framework/console/webapp/config.php | 17 - framework/console/webapp/default/index.php | 10 - .../webapp/default/protected/config/main.php | 20 - .../protected/controllers/SiteController.php | 15 - .../default/protected/views/layouts/main.php | 17 - .../webapp/default/protected/views/site/index.php | 1 - readme.md | 3 +- 55 files changed, 10103 insertions(+), 10182 deletions(-) delete mode 100644 app/assets/.gitignore delete mode 100644 app/css/bootstrap-responsive.css delete mode 100644 app/css/bootstrap-responsive.min.css delete mode 100644 app/css/bootstrap.css delete mode 100644 app/css/bootstrap.min.css delete mode 100644 app/css/site.css delete mode 100644 app/img/glyphicons-halflings-white.png delete mode 100644 app/img/glyphicons-halflings.png delete mode 100644 app/index.php delete mode 100644 app/js/bootstrap.js delete mode 100644 app/js/bootstrap.min.js delete mode 100644 app/protected/.htaccess delete mode 100644 app/protected/config/assets.php delete mode 100644 app/protected/config/main.php delete mode 100644 app/protected/controllers/SiteController.php delete mode 100644 app/protected/models/ContactForm.php delete mode 100644 app/protected/models/LoginForm.php delete mode 100644 app/protected/models/User.php delete mode 100644 app/protected/runtime/.gitignore delete mode 100644 app/protected/views/layouts/main.php delete mode 100644 app/protected/views/site/about.php delete mode 100644 app/protected/views/site/contact.php delete mode 100644 app/protected/views/site/index.php delete mode 100644 app/protected/views/site/login.php create mode 100644 apps/bootstrap/assets/.gitignore create mode 100644 apps/bootstrap/css/bootstrap-responsive.css create mode 100644 apps/bootstrap/css/bootstrap-responsive.min.css create mode 100644 apps/bootstrap/css/bootstrap.css create mode 100644 apps/bootstrap/css/bootstrap.min.css create mode 100644 apps/bootstrap/css/site.css create mode 100644 apps/bootstrap/img/glyphicons-halflings-white.png create mode 100644 apps/bootstrap/img/glyphicons-halflings.png create mode 100644 apps/bootstrap/index.php create mode 100644 apps/bootstrap/js/bootstrap.js create mode 100644 apps/bootstrap/js/bootstrap.min.js create mode 100644 apps/bootstrap/protected/.htaccess create mode 100644 apps/bootstrap/protected/config/assets.php create mode 100644 apps/bootstrap/protected/config/main.php create mode 100644 apps/bootstrap/protected/controllers/SiteController.php create mode 100644 apps/bootstrap/protected/models/ContactForm.php create mode 100644 apps/bootstrap/protected/models/LoginForm.php create mode 100644 apps/bootstrap/protected/models/User.php create mode 100644 apps/bootstrap/protected/runtime/.gitignore create mode 100644 apps/bootstrap/protected/views/layouts/main.php create mode 100644 apps/bootstrap/protected/views/site/about.php create mode 100644 apps/bootstrap/protected/views/site/contact.php create mode 100644 apps/bootstrap/protected/views/site/index.php create mode 100644 apps/bootstrap/protected/views/site/login.php delete mode 100644 framework/console/webapp/config.php delete mode 100644 framework/console/webapp/default/index.php delete mode 100644 framework/console/webapp/default/protected/config/main.php delete mode 100644 framework/console/webapp/default/protected/controllers/SiteController.php delete mode 100644 framework/console/webapp/default/protected/views/layouts/main.php delete mode 100644 framework/console/webapp/default/protected/views/site/index.php diff --git a/app/assets/.gitignore b/app/assets/.gitignore deleted file mode 100644 index 72e8ffc..0000000 --- a/app/assets/.gitignore +++ /dev/null @@ -1 +0,0 @@ -* diff --git a/app/css/bootstrap-responsive.css b/app/css/bootstrap-responsive.css deleted file mode 100644 index fcd72f7..0000000 --- a/app/css/bootstrap-responsive.css +++ /dev/null @@ -1,1109 +0,0 @@ -/*! - * Bootstrap Responsive v2.3.1 - * - * 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. - */ - -.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; -} - -@-ms-viewport { - width: device-width; -} - -.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; - } -} - -.visible-print { - display: none !important; -} - -@media print { - .visible-print { - display: inherit !important; - } - .hidden-print { - 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 .nav > li > a:focus, - .nav-collapse .dropdown-menu a:hover, - .nav-collapse .dropdown-menu a:focus { - 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 .nav > li > a:focus, - .navbar-inverse .nav-collapse .dropdown-menu a:hover, - .navbar-inverse .nav-collapse .dropdown-menu a:focus { - 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; - } -} diff --git a/app/css/bootstrap-responsive.min.css b/app/css/bootstrap-responsive.min.css deleted file mode 100644 index d1b7f4b..0000000 --- a/app/css/bootstrap-responsive.min.css +++ /dev/null @@ -1,9 +0,0 @@ -/*! - * Bootstrap Responsive v2.3.1 - * - * 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. - */.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}@-ms-viewport{width:device-width}.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}}.visible-print{display:none!important}@media print{.visible-print{display:inherit!important}.hidden-print{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 .nav>li>a:focus,.nav-collapse .dropdown-menu a:hover,.nav-collapse .dropdown-menu a:focus{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 .nav>li>a:focus,.navbar-inverse .nav-collapse .dropdown-menu a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:focus{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}} diff --git a/app/css/bootstrap.css b/app/css/bootstrap.css deleted file mode 100644 index 2f56af3..0000000 --- a/app/css/bootstrap.css +++ /dev/null @@ -1,6158 +0,0 @@ -/*! - * Bootstrap v2.3.1 - * - * 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. - */ - -.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; -} - -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; - } -} - -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, -a:focus { - 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, -a.muted:focus { - color: #808080; -} - -.text-warning { - color: #c09853; -} - -a.text-warning:hover, -a.text-warning:focus { - color: #a47e3c; -} - -.text-error { - color: #b94a48; -} - -a.text-error:hover, -a.text-error:focus { - color: #953b39; -} - -.text-info { - color: #3a87ad; -} - -a.text-info:hover, -a.text-info:focus { - color: #2d6987; -} - -.text-success { - color: #468847; -} - -a.text-success:hover, -a.text-success:focus { - color: #356635; -} - -.text-left { - text-align: left; -} - -.text-right { - text-align: right; -} - -.text-center { - text-align: center; -} - -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; - *display: inline; - padding-right: 5px; - padding-left: 5px; - *zoom: 1; -} - -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: 17.5px; - font-weight: 300; - line-height: 1.25; -} - -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 { - display: inline-block; - margin-bottom: 10px; - font-size: 0; - white-space: nowrap; - vertical-align: middle; -} - -.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, -.input-append .popover, -.input-prepend .popover { - 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, -.table-bordered tbody:first-child tr:first-child > th: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, -.table-bordered tbody:first-child tr:first-child > th: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 tbody:last-child tr:last-child > th:first-child, -.table-bordered tfoot:last-child tr:last-child > td:first-child, -.table-bordered tfoot:last-child tr:last-child > th: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 tbody:last-child tr:last-child > th:last-child, -.table-bordered tfoot:last-child tr:last-child > td:last-child, -.table-bordered tfoot:last-child tr:last-child > th: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/focus/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:focus > [class^="icon-"], -.dropdown-menu > li > a:hover > [class*=" icon-"], -.dropdown-menu > li > a:focus > [class*=" icon-"], -.dropdown-menu > .active > a > [class^="icon-"], -.dropdown-menu > .active > a > [class*=" icon-"], -.dropdown-submenu:hover > a > [class^="icon-"], -.dropdown-submenu:focus > a > [class^="icon-"], -.dropdown-submenu:hover > a > [class*=" icon-"], -.dropdown-submenu:focus > 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 { - width: 16px; - 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, -.dropdown-submenu:focus > 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, -.dropdown-menu > .active > a:focus { - 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, -.dropdown-menu > .disabled > a:focus { - color: #999999; -} - -.dropdown-menu > .disabled > a:hover, -.dropdown-menu > .disabled > a:focus { - 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, -.close:focus { - 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 #cccccc; - *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: #b3b3b3; - -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:focus, -.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, -.btn:focus { - 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-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:focus, -.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:focus, -.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:focus, -.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:focus, -.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:focus, -.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:focus, -.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, -.btn-link:focus { - color: #005580; - text-decoration: underline; - background-color: transparent; -} - -.btn-link[disabled]:hover, -.btn-link[disabled]:focus { - 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-large .caret { - margin-top: 6px; -} - -.btn-large .caret { - border-top-width: 5px; - border-right-width: 5px; - border-left-width: 5px; -} - -.btn-mini .caret, -.btn-small .caret { - margin-top: 8px; -} - -.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, -.nav > li > a:focus { - 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, -.nav-list > .active > a:focus { - 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, -.nav-tabs > li > a:focus { - border-color: #eeeeee #eeeeee #dddddd; -} - -.nav-tabs > .active > a, -.nav-tabs > .active > a:hover, -.nav-tabs > .active > a:focus { - 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, -.nav-pills > .active > a:focus { - 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, -.nav-tabs.nav-stacked > li > a:focus { - 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, -.nav .dropdown-toggle:focus .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, -.nav > .dropdown.active > a:focus { - cursor: pointer; -} - -.nav-tabs .open .dropdown-toggle, -.nav-pills .open .dropdown-toggle, -.nav > li.dropdown.open.active > a:hover, -.nav > li.dropdown.open.active > a:focus { - 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, -.nav li.dropdown.open a:focus .caret { - border-top-color: #ffffff; - border-bottom-color: #ffffff; - opacity: 1; - filter: alpha(opacity=100); -} - -.tabs-stacked .open > a:hover, -.tabs-stacked .open > a:focus { - 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, -.tabs-below > .nav-tabs > li > a:focus { - border-top-color: #ddd; - border-bottom-color: transparent; -} - -.tabs-below > .nav-tabs > .active > a, -.tabs-below > .nav-tabs > .active > a:hover, -.tabs-below > .nav-tabs > .active > a:focus { - 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, -.tabs-left > .nav-tabs > li > a:focus { - border-color: #eeeeee #dddddd #eeeeee #eeeeee; -} - -.tabs-left > .nav-tabs .active > a, -.tabs-left > .nav-tabs .active > a:hover, -.tabs-left > .nav-tabs .active > a:focus { - 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, -.tabs-right > .nav-tabs > li > a:focus { - border-color: #eeeeee #eeeeee #eeeeee #dddddd; -} - -.tabs-right > .nav-tabs .active > a, -.tabs-right > .nav-tabs .active > a:hover, -.tabs-right > .nav-tabs .active > a:focus { - border-color: #ddd #ddd #ddd transparent; - *border-left-color: #ffffff; -} - -.nav > .disabled > a { - color: #999999; -} - -.nav > .disabled > a:hover, -.nav > .disabled > a:focus { - 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, -.navbar .brand:focus { - text-decoration: none; -} - -.navbar-text { - margin-bottom: 0; - line-height: 40px; - color: #777777; -} - -.navbar-link { - color: #777777; -} - -.navbar-link:hover, -.navbar-link:focus { - 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, -.navbar .input-prepend .btn-group, -.navbar .input-append .btn-group { - 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:focus, -.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, -.navbar .nav li.dropdown > a:focus .caret { - border-top-color: #333333; - border-bottom-color: #333333; -} - -.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, -.navbar-inverse .brand:focus, -.navbar-inverse .nav > li > a:focus { - 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, -.navbar-inverse .navbar-link:focus { - 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, -.navbar-inverse .nav li.dropdown > a:focus .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:focus, -.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 > li > a:focus, -.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, -.pagination ul > .disabled > a:focus { - 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, -.pager li > a:focus { - 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 > a:focus, -.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; - font-size: 11px; - line-height: 1.4; - opacity: 0; - filter: alpha(opacity=0); - visibility: visible; -} - -.tooltip.in { - opacity: 0.8; - filter: alpha(opacity=80); -} - -.tooltip.top { - padding: 5px 0; - margin-top: -3px; -} - -.tooltip.right { - padding: 0 5px; - margin-left: 3px; -} - -.tooltip.bottom { - padding: 5px 0; - margin-top: 3px; -} - -.tooltip.left { - padding: 0 5px; - margin-left: -3px; -} - -.tooltip-inner { - max-width: 200px; - padding: 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; - max-width: 276px; - 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-title:empty { - display: none; -} - -.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, -a.thumbnail:focus { - 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.label:focus, -a.badge:hover, -a.badge:focus { - 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, -.carousel-inner > .item > a > 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, -.carousel-control:focus { - color: #ffffff; - text-decoration: none; - opacity: 0.9; - filter: alpha(opacity=90); -} - -.carousel-indicators { - position: absolute; - top: 15px; - right: 15px; - z-index: 5; - margin: 0; - list-style: none; -} - -.carousel-indicators li { - display: block; - float: left; - width: 10px; - height: 10px; - margin-left: 5px; - text-indent: -999px; - background-color: #ccc; - background-color: rgba(255, 255, 255, 0.25); - border-radius: 5px; -} - -.carousel-indicators .active { - background-color: #fff; -} - -.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; -} diff --git a/app/css/bootstrap.min.css b/app/css/bootstrap.min.css deleted file mode 100644 index c10c7f4..0000000 --- a/app/css/bootstrap.min.css +++ /dev/null @@ -1,9 +0,0 @@ -/*! - * Bootstrap v2.3.1 - * - * 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. - */.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}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}}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,a:focus{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,a.muted:focus{color:#808080}.text-warning{color:#c09853}a.text-warning:hover,a.text-warning:focus{color:#a47e3c}.text-error{color:#b94a48}a.text-error:hover,a.text-error:focus{color:#953b39}.text-info{color:#3a87ad}a.text-info:hover,a.text-info:focus{color:#2d6987}.text-success{color:#468847}a.text-success:hover,a.text-success:focus{color:#356635}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}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;*display:inline;padding-right:5px;padding-left:5px;*zoom:1}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:17.5px;font-weight:300;line-height:1.25}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{display:inline-block;margin-bottom:10px;font-size:0;white-space:nowrap;vertical-align:middle}.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,.input-append .popover,.input-prepend .popover{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,.table-bordered tbody:first-child tr:first-child>th: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,.table-bordered tbody:first-child tr:first-child>th: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 tbody:last-child tr:last-child>th:first-child,.table-bordered tfoot:last-child tr:last-child>td:first-child,.table-bordered tfoot:last-child tr:last-child>th: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 tbody:last-child tr:last-child>th:last-child,.table-bordered tfoot:last-child tr:last-child>td:last-child,.table-bordered tfoot:last-child tr:last-child>th: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:focus>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>li>a:focus>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:focus>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"],.dropdown-submenu:focus>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{width:16px;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,.dropdown-submenu:focus>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,.dropdown-menu>.active>a:focus{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,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{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,.close:focus{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 #ccc;*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:#b3b3b3;-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:focus,.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,.btn:focus{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-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:focus,.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:focus,.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:focus,.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:focus,.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:focus,.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:focus,.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,.btn-link:focus{color:#005580;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,.btn-link[disabled]:focus{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-large .caret{margin-top:6px}.btn-large .caret{border-top-width:5px;border-right-width:5px;border-left-width:5px}.btn-mini .caret,.btn-small .caret{margin-top:8px}.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,.nav>li>a:focus{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,.nav-list>.active>a:focus{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,.nav-tabs>li>a:focus{border-color:#eee #eee #ddd}.nav-tabs>.active>a,.nav-tabs>.active>a:hover,.nav-tabs>.active>a:focus{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,.nav-pills>.active>a:focus{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,.nav-tabs.nav-stacked>li>a:focus{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,.nav .dropdown-toggle:focus .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,.nav>.dropdown.active>a:focus{cursor:pointer}.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover,.nav>li.dropdown.open.active>a:focus{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,.nav li.dropdown.open a:focus .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:1;filter:alpha(opacity=100)}.tabs-stacked .open>a:hover,.tabs-stacked .open>a:focus{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,.tabs-below>.nav-tabs>li>a:focus{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover,.tabs-below>.nav-tabs>.active>a:focus{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,.tabs-left>.nav-tabs>li>a:focus{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover,.tabs-left>.nav-tabs .active>a:focus{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,.tabs-right>.nav-tabs>li>a:focus{border-color:#eee #eee #eee #ddd}.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover,.tabs-right>.nav-tabs .active>a:focus{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}.nav>.disabled>a{color:#999}.nav>.disabled>a:hover,.nav>.disabled>a:focus{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,.navbar .brand:focus{text-decoration:none}.navbar-text{margin-bottom:0;line-height:40px;color:#777}.navbar-link{color:#777}.navbar-link:hover,.navbar-link:focus{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,.navbar .input-prepend .btn-group,.navbar .input-append .btn-group{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:focus,.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,.navbar .nav li.dropdown>a:focus .caret{border-top-color:#333;border-bottom-color:#333}.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,.navbar-inverse .brand:focus,.navbar-inverse .nav>li>a:focus{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,.navbar-inverse .navbar-link:focus{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,.navbar-inverse .nav li.dropdown>a:focus .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:focus,.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>li>a:focus,.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,.pagination ul>.disabled>a:focus{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,.pager li>a:focus{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>a:focus,.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;font-size:11px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.8;filter:alpha(opacity=80)}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding: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;max-width:276px;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-title:empty{display:none}.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,a.thumbnail:focus{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.label:focus,a.badge:hover,a.badge:focus{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,.carousel-inner>.item>a>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,.carousel-control:focus{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-indicators{position:absolute;top:15px;right:15px;z-index:5;margin:0;list-style:none}.carousel-indicators li{display:block;float:left;width:10px;height:10px;margin-left:5px;text-indent:-999px;background-color:#ccc;background-color:rgba(255,255,255,0.25);border-radius:5px}.carousel-indicators .active{background-color:#fff}.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} diff --git a/app/css/site.css b/app/css/site.css deleted file mode 100644 index 890a953..0000000 --- a/app/css/site.css +++ /dev/null @@ -1,78 +0,0 @@ -body { - padding-top: 20px; - padding-bottom: 60px; -} - -/* Custom container */ -.container { - margin: 0 auto; - max-width: 1000px; -} - -.container > hr { - margin: 60px 0; -} - -/* Main marketing message and sign up button */ -.jumbotron { - margin: 80px 0; - text-align: center; -} - -.jumbotron h1 { - font-size: 100px; - line-height: 1; -} - -.jumbotron .lead { - font-size: 24px; - line-height: 1.25; -} - -.jumbotron .btn { - font-size: 21px; - padding: 14px 24px; -} - -/* Supporting marketing content */ -.marketing { - margin: 60px 0; -} - -.marketing p + h4 { - margin-top: 28px; -} - -/* Customize the navbar links to be fill the entire space of the .navbar */ -.navbar .navbar-inner { - padding: 0; -} - -.navbar .nav { - margin: 0; - display: table; - width: 100%; -} - -.navbar .nav li { - display: table-cell; - width: 1%; - float: none; -} - -.navbar .nav li a { - font-weight: bold; - text-align: center; - border-left: 1px solid rgba(255, 255, 255, .75); - border-right: 1px solid rgba(0, 0, 0, .1); -} - -.navbar .nav li:first-child a { - border-left: 0; - border-radius: 3px 0 0 3px; -} - -.navbar .nav li:last-child a { - border-right: 0; - border-radius: 0 3px 3px 0; -} diff --git a/app/img/glyphicons-halflings-white.png b/app/img/glyphicons-halflings-white.png deleted file mode 100644 index 3bf6484a29d8da269f9bc874b25493a45fae3bae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8777 zcmZvC1yGz#v+m*$LXcp=A$ZWB0fL7wNbp_U*$~{_gL`my3oP#L!5tQYy99Ta`+g_q zKlj|KJ2f@c)ARJx{q*bbkhN_!|Wn*Vos8{TEhUT@5e;_WJsIMMcG5%>DiS&dv_N`4@J0cnAQ-#>RjZ z00W5t&tJ^l-QC*ST1-p~00u^9XJ=AUl7oW-;2a+x2k__T=grN{+1c4XK0ZL~^z^i$ zp&>vEhr@4fZWb380S18T&!0cQ3IKpHF)?v=b_NIm0Q>vwY7D0baZ)n z31Fa5sELUQARIVaU0nqf0XzT+fB_63aA;@<$l~wse|mcA;^G1TmX?-)e)jkGPfkuA z92@|!<>h5S_4f8QP-JRq>d&7)^Yin8l7K8gED$&_FaV?gY+wLjpoW%~7NDe=nHfMG z5DO3j{R9kv5GbssrUpO)OyvVrlx>u0UKD0i;Dpm5S5dY16(DL5l{ixz|mhJU@&-OWCTb7_%}8-fE(P~+XIRO zJU|wp1|S>|J3KrLcz^+v1f&BDpd>&MAaibR4#5A_4(MucZwG9E1h4@u0P@C8;oo+g zIVj7kfJi{oV~E(NZ*h(@^-(Q(C`Psb3KZ{N;^GB(a8NE*Vwc715!9 zr-H4Ao|T_c6+VT_JH9H+P3>iXSt!a$F`>s`jn`w9GZ_~B!{0soaiV|O_c^R2aWa%}O3jUE)WO=pa zs~_Wz08z|ieY5A%$@FcBF9^!1a}m5ks@7gjn;67N>}S~Hrm`4sM5Hh`q7&5-N{|31 z6x1{ol7BnskoViZ0GqbLa#kW`Z)VCjt1MysKg|rT zi!?s##Ck>8c zpi|>$lGlw#@yMNi&V4`6OBGJ(H&7lqLlcTQ&1zWriG_fL>BnFcr~?;E93{M-xIozQ zO=EHQ#+?<}%@wbWWv23#!V70h9MOuUVaU>3kpTvYfc|LBw?&b*89~Gc9i&8tlT#kF ztpbZoAzkdB+UTy=tx%L3Z4)I{zY(Kb)eg{InobSJmNwPZt$14aS-uc4eKuY8h$dtfyxu^a%zA)>fYI&)@ZXky?^{5>xSC?;w4r&td6vBdi%vHm4=XJH!3yL3?Ep+T5aU_>i;yr_XGq zxZfCzUU@GvnoIk+_Nd`aky>S&H!b*{A%L>?*XPAgWL(Vf(k7qUS}>Zn=U(ZfcOc{B z3*tOHH@t5Ub5D~#N7!Fxx}P2)sy{vE_l(R7$aW&CX>c|&HY+7};vUIietK%}!phrCuh+;C@1usp;XLU<8Gq8P!rEI3ieg#W$!= zQcZr{hp>8sF?k&Yl0?B84OneiQxef-4TEFrq3O~JAZR}yEJHA|Xkqd49tR&8oq{zP zY@>J^HBV*(gJvJZc_0VFN7Sx?H7#75E3#?N8Z!C+_f53YU}pyggxx1?wQi5Yb-_`I`_V*SMx5+*P^b=ec5RON-k1cIlsBLk}(HiaJyab0`CI zo0{=1_LO$~oE2%Tl_}KURuX<`+mQN_sTdM&* zkFf!Xtl^e^gTy6ON=&gTn6)$JHQq2)33R@_!#9?BLNq-Wi{U|rVX7Vny$l6#+SZ@KvQt@VYb%<9JfapI^b9j=wa+Tqb4ei;8c5 z&1>Uz@lVFv6T4Z*YU$r4G`g=91lSeA<=GRZ!*KTWKDPR}NPUW%peCUj`Ix_LDq!8| zMH-V`Pv!a~QkTL||L@cqiTz)*G-0=ytr1KqTuFPan9y4gYD5>PleK`NZB$ev@W%t= zkp)_=lBUTLZJpAtZg;pjI;7r2y|26-N7&a(hX|`1YNM9N8{>8JAuv}hp1v`3JHT-=5lbXpbMq7X~2J5Kl zh7tyU`_AusMFZ{ej9D;Uyy;SQ!4nwgSnngsYBwdS&EO3NS*o04)*juAYl;57c2Ly0(DEZ8IY?zSph-kyxu+D`tt@oU{32J#I{vmy=#0ySPK zA+i(A3yl)qmTz*$dZi#y9FS;$;h%bY+;StNx{_R56Otq+?pGe^T^{5d7Gs&?`_r`8 zD&dzOA|j8@3A&FR5U3*eQNBf<4^4W_iS_()*8b4aaUzfk2 zzIcMWSEjm;EPZPk{j{1>oXd}pXAj!NaRm8{Sjz!D=~q3WJ@vmt6ND_?HI~|wUS1j5 z9!S1MKr7%nxoJ3k`GB^7yV~*{n~O~n6($~x5Bu{7s|JyXbAyKI4+tO(zZYMslK;Zc zzeHGVl{`iP@jfSKq>R;{+djJ9n%$%EL()Uw+sykjNQdflkJZSjqV_QDWivbZS~S{K zkE@T^Jcv)Dfm93!mf$XYnCT--_A$zo9MOkPB6&diM8MwOfV?+ApNv`moV@nqn>&lv zYbN1-M|jc~sG|yLN^1R2=`+1ih3jCshg`iP&mY$GMTcY^W^T`WOCX!{-KHmZ#GiRH zYl{|+KLn5!PCLtBy~9i}`#d^gCDDx$+GQb~uc;V#K3OgbbOG0j5{BRG-si%Bo{@lB zGIt+Ain8^C`!*S0d0OSWVO+Z89}}O8aFTZ>p&k}2gGCV zh#<$gswePFxWGT$4DC^8@84_e*^KT74?7n8!$8cg=sL$OlKr&HMh@Rr5%*Wr!xoOl zo7jItnj-xYgVTX)H1=A2bD(tleEH57#V{xAeW_ezISg5OC zg=k>hOLA^urTH_e6*vSYRqCm$J{xo}-x3@HH;bsHD1Z`Pzvsn}%cvfw%Q(}h`Dgtb z0_J^niUmoCM5$*f)6}}qi(u;cPgxfyeVaaVmOsG<)5`6tzU4wyhF;k|~|x>7-2hXpVBpc5k{L4M`Wbe6Q?tr^*B z`Y*>6*&R#~%JlBIitlZ^qGe3s21~h3U|&k%%jeMM;6!~UH|+0+<5V-_zDqZQN79?n?!Aj!Nj`YMO9?j>uqI9-Tex+nJD z%e0#Yca6(zqGUR|KITa?9x-#C0!JKJHO(+fy@1!B$%ZwJwncQW7vGYv?~!^`#L~Um zOL++>4qmqW`0Chc0T23G8|vO)tK=Z2`gvS4*qpqhIJCEv9i&&$09VO8YOz|oZ+ubd zNXVdLc&p=KsSgtmIPLN69P7xYkYQ1vJ?u1g)T!6Ru`k2wkdj*wDC)VryGu2=yb0?F z>q~~e>KZ0d_#7f3UgV%9MY1}vMgF{B8yfE{HL*pMyhYF)WDZ^^3vS8F zGlOhs%g_~pS3=WQ#494@jAXwOtr^Y|TnQ5zki>qRG)(oPY*f}U_=ip_{qB0!%w7~G zWE!P4p3khyW-JJnE>eECuYfI?^d366Shq!Wm#x&jAo>=HdCllE$>DPO0N;y#4G)D2y#B@5=N=+F%Xo2n{gKcPcK2!hP*^WSXl+ut; zyLvVoY>VL{H%Kd9^i~lsb8j4>$EllrparEOJNT?Ym>vJa$(P^tOG)5aVb_5w^*&M0 zYOJ`I`}9}UoSnYg#E(&yyK(tqr^@n}qU2H2DhkK-`2He% zgXr_4kpXoQHxAO9S`wEdmqGU4j=1JdG!OixdqB4PPP6RXA}>GM zumruUUH|ZG2$bBj)Qluj&uB=dRb)?^qomw?Z$X%#D+Q*O97eHrgVB2*mR$bFBU`*} zIem?dM)i}raTFDn@5^caxE^XFXVhBePmH9fqcTi`TLaXiueH=@06sl}>F%}h9H_e9 z>^O?LxM1EjX}NVppaO@NNQr=AtHcH-BU{yBT_vejJ#J)l^cl69Z7$sk`82Zyw7Wxt z=~J?hZm{f@W}|96FUJfy65Gk8?^{^yjhOahUMCNNpt5DJw}ZKH7b!bGiFY9y6OY&T z_N)?Jj(MuLTN36ZCJ6I5Xy7uVlrb$o*Z%=-)kPo9s?<^Yqz~!Z* z_mP8(unFq65XSi!$@YtieSQ!<7IEOaA9VkKI?lA`*(nURvfKL8cX}-+~uw9|_5)uC2`ZHcaeX7L8aG6Ghleg@F9aG%X$#g6^yP5apnB>YTz&EfS{q z9UVfSyEIczebC)qlVu5cOoMzS_jrC|)rQlAzK7sfiW0`M8mVIohazPE9Jzn*qPt%6 zZL8RELY@L09B83@Be;x5V-IHnn$}{RAT#<2JA%ttlk#^(%u}CGze|1JY5MPhbfnYG zIw%$XfBmA-<_pKLpGKwbRF$#P;@_)ech#>vj25sv25VM$ouo)?BXdRcO{)*OwTw)G zv43W~T6ekBMtUD%5Bm>`^Ltv!w4~65N!Ut5twl!Agrzyq4O2Fi3pUMtCU~>9gt_=h-f% z;1&OuSu?A_sJvIvQ+dZNo3?m1%b1+s&UAx?8sUHEe_sB7zkm4R%6)<@oYB_i5>3Ip zIA+?jVdX|zL{)?TGpx+=Ta>G80}0}Ax+722$XFNJsC1gcH56{8B)*)eU#r~HrC&}` z|EWW92&;6y;3}!L5zXa385@?-D%>dSvyK;?jqU2t_R3wvBW;$!j45uQ7tyEIQva;Db}r&bR3kqNSh)Q_$MJ#Uj3Gj1F;)sO|%6z#@<+ zi{pbYsYS#u`X$Nf($OS+lhw>xgjos1OnF^$-I$u;qhJswhH~p|ab*nO>zBrtb0ndn zxV0uh!LN`&xckTP+JW}gznSpU492)u+`f{9Yr)js`NmfYH#Wdtradc0TnKNz@Su!e zu$9}G_=ku;%4xk}eXl>)KgpuT>_<`Ud(A^a++K&pm3LbN;gI}ku@YVrA%FJBZ5$;m zobR8}OLtW4-i+qPPLS-(7<>M{)rhiPoi@?&vDeVq5%fmZk=mDdRV>Pb-l7pP1y6|J z8I>sF+TypKV=_^NwBU^>4JJq<*14GLfM2*XQzYdlqqjnE)gZsPW^E@mp&ww* zW9i>XL=uwLVZ9pO*8K>t>vdL~Ek_NUL$?LQi5sc#1Q-f6-ywKcIT8Kw?C(_3pbR`e|)%9S-({if|E+hR2W!&qfQ&UiF^I!|M#xhdWsenv^wpKCBiuxXbnp85`{i|;BM?Ba`lqTA zyRm=UWJl&E{8JzYDHFu>*Z10-?#A8D|5jW9Ho0*CAs0fAy~MqbwYuOq9jjt9*nuHI zbDwKvh)5Ir$r!fS5|;?Dt>V+@F*v8=TJJF)TdnC#Mk>+tGDGCw;A~^PC`gUt*<(|i zB{{g{`uFehu`$fm4)&k7`u{xIV)yvA(%5SxX9MS80p2EKnLtCZ>tlX>*Z6nd&6-Mv$5rHD*db;&IBK3KH&M<+ArlGXDRdX1VVO4)&R$f4NxXI>GBh zSv|h>5GDAI(4E`@F?EnW zS>#c&Gw6~_XL`qQG4bK`W*>hek4LX*efn6|_MY+rXkNyAuu?NxS%L7~9tD3cn7&p( zCtfqe6sjB&Q-Vs7BP5+%;#Gk};4xtwU!KY0XXbmkUy$kR9)!~?*v)qw00!+Yg^#H> zc#8*z6zZo>+(bud?K<*!QO4ehiTCK&PD4G&n)Tr9X_3r-we z?fI+}-G~Yn93gI6F{}Dw_SC*FLZ)5(85zp4%uubtD)J)UELLkvGk4#tw&Tussa)mTD$R2&O~{ zCI3>fr-!-b@EGRI%g0L8UU%%u_<;e9439JNV;4KSxd|78v+I+8^rmMf3f40Jb}wEszROD?xBZu>Ll3;sUIoNxDK3|j3*sam2tC@@e$ z^!;+AK>efeBJB%ALsQ{uFui)oDoq()2USi?n=6C3#eetz?wPswc={I<8x=(8lE4EIsUfyGNZ{|KYn1IR|=E==f z(;!A5(-2y^2xRFCSPqzHAZn5RCN_bp22T(KEtjA(rFZ%>a4@STrHZflxKoqe9Z4@^ zM*scx_y73?Q{vt6?~WEl?2q*;@8 z3M*&@%l)SQmXkcUm)d@GT2#JdzhfSAP9|n#C;$E8X|pwD!r#X?0P>0ZisQ~TNqupW z*lUY~+ikD`vQb?@SAWX#r*Y+;=_|oacL$2CL$^(mV}aKO77pg}O+-=T1oLBT5sL2i z42Qth2+0@C`c+*D0*5!qy26sis<9a7>LN2{z%Qj49t z=L@x`4$ALHb*3COHoT?5S_c(Hs}g!V>W^=6Q0}zaubkDn)(lTax0+!+%B}9Vqw6{H zvL|BRM`O<@;eVi1DzM!tXtBrA20Ce@^Jz|>%X-t`vi-%WweXCh_LhI#bUg2*pcP~R z*RuTUzBKLXO~~uMd&o$v3@d0shHfUjC6c539PE6rF&;Ufa(Rw@K1*m7?f5)t`MjH0 z)_V(cajV5Am>f!kWcI@5rE8t6$S>5M=k=aRZROH6fA^jJp~2NlR4;Q2>L$7F#RT#9 z>4@1RhWG`Khy>P2j1Yx^BBL{S`niMaxlSWV-JBU0-T9zZ%>7mR3l$~QV$({o0;jTI ze5=cN^!Bc2bT|BcojXp~K#2cM>OTe*cM{Kg-j*CkiW)EGQot^}s;cy8_1_@JA0Whq zlrNr+R;Efa+`6N)s5rH*|E)nYZ3uqkk2C(E7@A|3YI`ozP~9Lexx#*1(r8luq+YPk z{J}c$s` zPM35Fx(YWB3Z5IYnN+L_4|jaR(5iWJi2~l&xy}aU7kW?o-V*6Av2wyZTG!E2KSW2* zGRLQkQU;Oz##ie-Z4fI)WSRxn$(ZcD;TL+;^r=a4(G~H3ZhK$lSXZj?cvyY8%d9JM zzc3#pD^W_QnWy#rx#;c&N@sqHhrnHRmj#i;s%zLm6SE(n&BWpd&f7>XnjV}OlZntI70fq%8~9<7 zMYaw`E-rp49-oC1N_uZTo)Cu%RR2QWdHpzQIcNsoDp`3xfP+`gI?tVQZ4X={qU?(n zV>0ASES^Xuc;9JBji{)RnFL(Lez;8XbB1uWaMp@p?7xhXk6V#!6B@aP4Rz7-K%a>i z?fvf}va_DGUXlI#4--`A3qK7J?-HwnG7O~H2;zR~RLW)_^#La!=}+>KW#anZ{|^D3 B7G?kd diff --git a/app/img/glyphicons-halflings.png b/app/img/glyphicons-halflings.png deleted file mode 100644 index a9969993201f9cee63cf9f49217646347297b643..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12799 zcma*OWmH^Ivn@*S;K3nSf_t!#;0f+&pm7Po8`nk}2q8f5;M%x$SdAkd9FAvlc$ zx660V9e3Ox@4WZ^?7jZ%QFGU-T~%||Ug4iK6bbQY@zBuF2$hxOw9wF=A)nUSxR_5@ zEX>HBryGrjyuOFFv$Y4<+|3H@gQfEqD<)+}a~mryD|1U9*I_FOG&F%+Ww{SJ-V2BR zjt<81Ek$}Yb*95D4RS0HCps|uLyovt;P05hchQb-u2bzLtmog&f2}1VlNhxXV);S9 zM2buBg~!q9PtF)&KGRgf3#z7B(hm5WlNClaCWFs!-P!4-u*u5+=+D|ZE9e`KvhTHT zJBnLwGM%!u&vlE%1ytJ=!xt~y_YkFLQb6bS!E+s8l7PiPGSt9xrmg?LV&&SL?J~cI zS(e9TF1?SGyh+M_p@o1dyWu7o7_6p;N6hO!;4~ z2B`I;y`;$ZdtBpvK5%oQ^p4eR2L)BH>B$FQeC*t)c`L71gXHPUa|vyu`Bnz)H$ZcXGve(}XvR!+*8a>BLV;+ryG1kt0=)ytl zNJxFUN{V7P?#|Cp85QTa@(*Q3%K-R(Pkv1N8YU*(d(Y}9?PQ(j;NzWoEVWRD-~H$=f>j9~PN^BM2okI(gY-&_&BCV6RP&I$FnSEM3d=0fCxbxA6~l>54-upTrw zYgX@%m>jsSGi`0cQt6b8cX~+02IghVlNblR7eI;0ps}mpWUcxty1yG56C5rh%ep(X z?)#2d?C<4t-KLc*EAn>>M8%HvC1TyBSoPNg(4id~H8JwO#I)Bf;N*y6ai6K9_bA`4 z_g9(-R;qyH&6I$`b42v|0V3Z8IXN*p*8g$gE98+JpXNY+jXxU0zsR^W$#V=KP z3AEFp@OL}WqwOfsV<)A^UTF4&HF1vQecz?LWE@p^Z2){=KEC_3Iopx_eS42>DeiDG zWMXGbYfG~W7C8s@@m<_?#Gqk;!&)_Key@^0xJxrJahv{B&{^!>TV7TEDZlP|$=ZCz zmX=ZWtt4QZKx**)lQQoW8y-XLiOQy#T`2t}p6l*S`68ojyH@UXJ-b~@tN`WpjF z%7%Yzv807gsO!v=!(2uR)16!&U5~VPrPHtGzUU?2w(b1Xchq}(5Ed^G|SD7IG+kvgyVksU) z(0R)SW1V(>&q2nM%Z!C9=;pTg!(8pPSc%H01urXmQI6Gi^dkYCYfu6b4^tW))b^U+ z$2K&iOgN_OU7n#GC2jgiXU{caO5hZt0(>k+c^(r><#m|#J^s?zA6pi;^#*rp&;aqL zRcZi0Q4HhVX3$ybclxo4FFJW*`IV`)Bj_L3rQe?5{wLJh168Ve1jZv+f1D}f0S$N= zm4i|9cEWz&C9~ZI3q*gwWH^<6sBWuphgy@S3Qy?MJiL>gwd|E<2h9-$3;gT9V~S6r z)cAcmE0KXOwDA5eJ02-75d~f?3;n7a9d_xPBJaO;Z)#@s7gk5$Qn(Fc^w@9c5W0zY z59is0?Mt^@Rolcn{4%)Ioat(kxQH6}hIykSA)zht=9F_W*D#<}N(k&&;k;&gKkWIL z0Of*sP=X(Uyu$Pw;?F@?j{}=>{aSHFcii#78FC^6JGrg-)!)MV4AKz>pXnhVgTgx8 z1&5Y=>|8RGA6++FrSy=__k_imx|z-EI@foKi>tK0Hq2LetjUotCgk2QFXaej!BWYL zJc{fv(&qA7UUJ|AXLc5z*_NW#yWzKtl(c8mEW{A>5Hj^gfZ^HC9lQNQ?RowXjmuCj4!!54Us1=hY z0{@-phvC}yls!PmA~_z>Y&n&IW9FQcj}9(OLO-t^NN$c0o}YksCUWt|DV(MJB%%Sr zdf}8!9ylU2TW!=T{?)g-ojAMKc>3pW;KiZ7f0;&g)k}K^#HBhE5ot)%oxq$*$W@b# zg4p<Ou`ME|Kd1WHK@8 zzLD+0(NHWa`B{em3Ye?@aVsEi>y#0XVZfaFuq#;X5C3{*ikRx7UY4FF{ZtNHNO?A_ z#Q?hwRv~D8fPEc%B5E-ZMI&TAmikl||EERumQCRh7p;)>fdZMxvKq;ky0}7IjhJph zW*uuu*(Y6)S;Od--8uR^R#sb$cmFCnPcj9PPCWhPN;n`i1Q#Qn>ii z{WR|0>8F`vf&#E(c2NsoH=I7Cd-FV|%(7a`i}gZw4N~QFFG2WtS^H%@c?%9UZ+kez z;PwGgg_r6V>Kn5n(nZ40P4qMyrCP3bDkJp@hp6&X3>gzC>=f@Hsen<%I~7W+x@}b> z0}Et*vx_50-q@PIV=(3&Tbm}}QRo*FP2@)A#XX-8jYspIhah`9ukPBr)$8>Tmtg&R z?JBoH17?+1@Y@r>anoKPQ}F8o9?vhcG79Cjv^V6ct709VOQwg{c0Q#rBSsSmK3Q;O zBpNihl3S0_IGVE)^`#94#j~$;7+u870yWiV$@={|GrBmuz4b)*bCOPkaN0{6$MvazOEBxFdKZDlbVvv{8_*kJ zfE6C`4&Kkz<5u%dEdStd85-5UHG5IOWbo8i9azgg#zw-(P1AA049hddAB*UdG3Vn0 zX`OgM+EM|<+KhJ<=k?z~WA5waVj?T9eBdfJGebVifBKS1u<$#vl^BvSg)xsnT5Aw_ZY#}v*LXO#htB>f}x3qDdDHoFeb zAq7;0CW;XJ`d&G*9V)@H&739DpfWYzdQt+Kx_E1K#Cg1EMtFa8eQRk_JuUdHD*2;W zR~XFnl!L2A?48O;_iqCVr1oxEXvOIiN_9CUVTZs3C~P+11}ebyTRLACiJuMIG#`xP zKlC|E(S@QvN+%pBc6vPiQS8KgQAUh75C0a2xcPQDD$}*bM&z~g8+=9ltmkT$;c;s z5_=8%i0H^fEAOQbHXf0;?DN5z-5+1 zDxj50yYkz4ox9p$HbZ|H?8ukAbLE^P$@h}L%i6QVcY>)i!w=hkv2zvrduut%!8>6b zcus3bh1w~L804EZ*s96?GB&F7c5?m?|t$-tp2rKMy>F*=4;w*jW}^;8v`st&8)c; z2Ct2{)?S(Z;@_mjAEjb8x=qAQvx=}S6l9?~H?PmP`-xu;ME*B8sm|!h@BX4>u(xg_ zIHmQzp4Tgf*J}Y=8STR5_s)GKcmgV!$JKTg@LO402{{Wrg>#D4-L%vjmtJ4r?p&$F!o-BOf7ej~ z6)BuK^^g1b#(E>$s`t3i13{6-mmSp7{;QkeG5v}GAN&lM2lQT$@(aQCcFP(%UyZbF z#$HLTqGT^@F#A29b0HqiJsRJAlh8kngU`BDI6 zJUE~&!cQ*&f95Ot$#mxU5+*^$qg_DWNdfu+1irglB7yDglzH()2!@#rpu)^3S8weW z_FE$=j^GTY*|5SH95O8o8W9FluYwB=2PwtbW|JG6kcV^dMVmX(wG+Otj;E$%gfu^K z!t~<3??8=()WQSycsBKy24>NjRtuZ>zxJIED;YXaUz$@0z4rl+TW zWxmvM$%4jYIpO>j5k1t1&}1VKM~s!eLsCVQ`TTjn3JRXZD~>GM z$-IT~(Y)flNqDkC%DfbxaV9?QuWCV&-U1yzrV@0jRhE;)ZO0=r-{s@W?HOFbRHDDV zq;eLo+wOW;nI|#mNf(J?RImB9{YSO2Y`9825Lz#u4(nk3)RGv3X8B(A$TsontJ8L! z9JP^eWxtKC?G8^xAZa1HECx*rp35s!^%;&@Jyk)NexVc)@U4$^X1Dag6`WKs|(HhZ#rzO2KEw3xh~-0<;|zcs0L>OcO#YYX{SN8m6`9pp+ zQG@q$I)T?aoe#AoR@%om_#z=c@ych!bj~lV13Qi-xg$i$hXEAB#l=t7QWENGbma4L zbBf*X*4oNYZUd_;1{Ln_ZeAwQv4z?n9$eoxJeI?lU9^!AB2Y~AwOSq67dT9ADZ)s@ zCRYS7W$Zpkdx$3T>7$I%3EI2ik~m!f7&$Djpt6kZqDWZJ-G{*_eXs*B8$1R4+I}Kf zqniwCI64r;>h2Lu{0c(#Atn)%E8&)=0S4BMhq9$`vu|Ct;^ur~gL`bD>J@l)P$q_A zO7b3HGOUG`vgH{}&&AgrFy%K^>? z>wf**coZ2vdSDcNYSm~dZ(vk6&m6bVKmVgrx-X<>{QzA!)2*L+HLTQz$e8UcB&Djq zl)-%s$ZtUN-R!4ZiG=L0#_P=BbUyH+YPmFl_ogkkQ$=s@T1v}rNnZ^eMaqJ|quc+6 z*ygceDOrldsL30w`H;rNu+IjlS+G~p&0SawXCA1+D zC%cZtjUkLNq%FadtHE?O(yQTP486A{1x<{krq#rpauNQaeyhM3*i0%tBpQHQo-u)x z{0{&KS`>}vf2_}b160XZO2$b)cyrHq7ZSeiSbRvaxnKUH{Q`-P(nL&^fcF2){vhN- zbX&WEjP7?b4A%0y6n_=m%l00uZ+}mCYO(!x?j$+O$*TqoD_Q5EoyDJ?w?^UIa491H zE}87(bR`X;@u#3Qy~9wWdWQIg1`cXrk$x9=ccR|RY1~%{fAJ@uq@J3e872x0v$hmv ze_KcL(wM|n0EOp;t{hKoohYyDmYO;!`7^Lx;0k=PWPGZpI>V5qYlzjSL_(%|mud50 z7#{p97s`U|Sn$WYF>-i{i4`kzlrV6a<}=72q2sAT7Zh{>P%*6B;Zl;~0xWymt10Mo zl5{bmR(wJefJpNGK=fSRP|mpCI-)Nf6?Pv==FcFmpSwF1%CTOucV{yqxSyx4Zws3O z8hr5Uyd%ezIO7?PnEO0T%af#KOiXD$e?V&OX-B|ZX-YsgSs%sv-6U+sLPuz{D4bq| zpd&|o5tNCmpT>(uIbRf?8c}d3IpOb3sn6>_dr*26R#ev<_~vi)wleW$PX|5)$_ z+_|=pi(0D(AB_sjQ;sQQSM&AWqzDO1@NHw;C9cPdXRKRI#@nUW)CgFxzQ1nyd!+h& zcjU!U=&u|>@}R(9D$%lu2TlV>@I2-n@fCr5PrZNVyKWR7hm zWjoy^p7v8m#$qN0K#8jT- zq`mSirDZDa1Jxm;Rg3rAPhC)LcI4@-RvKT+@9&KsR3b0_0zuM!Fg7u>oF>3bzOxZPU&$ab$Z9@ zY)f7pKh22I7ZykL{YsdjcqeN++=0a}elQM-4;Q)(`Ep3|VFHqnXOh14`!Bus& z9w%*EWK6AiAM{s$6~SEQS;A>ey$#`7)khZvamem{P?>k)5&7Sl&&NXKk}o!%vd;-! zpo2p-_h^b$DNBO>{h4JdGB=D>fvGIYN8v&XsfxU~VaefL?q} z3ekM?iOKkCzQHkBkhg=hD!@&(L}FcHKoa zbZ7)H1C|lHjwEb@tu=n^OvdHOo7o+W`0-y3KdP#bb~wM=Vr_gyoEq|#B?$&d$tals ziIs-&7isBpvS|CjC|7C&3I0SE?~`a%g~$PI%;au^cUp@ER3?mn-|vyu!$7MV6(uvt z+CcGuM(Ku2&G0tcRCo7#D$Dirfqef2qPOE5I)oCGzmR5G!o#Q~(k~)c=LpIfrhHQk zeAva6MilEifE7rgP1M7AyWmLOXK}i8?=z2;N=no)`IGm#y%aGE>-FN zyXCp0Sln{IsfOBuCdE*#@CQof%jzuU*jkR*Su3?5t}F(#g0BD0Zzu|1MDes8U7f9; z$JBg|mqTXt`muZ8=Z`3wx$uizZG_7>GI7tcfOHW`C2bKxNOR)XAwRkLOaHS4xwlH4 zDpU29#6wLXI;H?0Se`SRa&I_QmI{zo7p%uveBZ0KZKd9H6@U?YGArbfm)D*^5=&Rp z`k{35?Z5GbZnv>z@NmJ%+sx=1WanWg)8r}C_>EGR8mk(NR$pW<-l8OTU^_u3M@gwS z7}GGa1)`z5G|DZirw;FB@VhH7Dq*0qc=|9lLe{w2#`g+_nt>_%o<~9(VZe=zI*SSz4w43-_o>4E4`M@NPKTWZuQJs)?KXbWp1M zimd5F;?AP(LWcaI-^Sl{`~>tmxsQB9Y$Xi*{Zr#py_+I$vx7@NY`S?HFfS!hUiz$a z{>!&e1(16T!Om)m)&k1W#*d#GslD^4!TwiF2WjFBvi=Ms!ADT)ArEW6zfVuIXcXVk z>AHjPADW+mJzY`_Ieq(s?jbk4iD2Rb8*V3t6?I+E06(K8H!!xnDzO%GB;Z$N-{M|B zeT`jo%9)s%op*XZKDd6*)-^lWO{#RaIGFdBH+;XXjI(8RxpBc~azG1H^2v7c^bkFE zZCVPE+E*Q=FSe8Vm&6|^3ki{9~qafiMAf7i4APZg>b%&5>nT@pHH z%O*pOv(77?ZiT{W zBibx}Q12tRc7Py1NcZTp`Q4ey%T_nj@1WKg5Fz_Rjl4wlJQj)rtp8yL3r!Shy zvZvnmh!tH4T6Js-?vI0<-rzzl{mgT*S0d_7^AU_8gBg^03o-J=p(1o6kww2hx|!%T z-jqp}m^G*W?$!R#M%Ef?&2jYxmx+lXWZszpI4d$pUN`(S)|*c^CgdwY>Fa>> zgGBJhwe8y#Xd*q0=@SLEgPF>+Qe4?%E*v{a`||luZ~&dqMBrRfJ{SDMaJ!s_;cSJp zSqZHXIdc@@XteNySUZs^9SG7xK`8=NBNM)fRVOjw)D^)w%L2OPkTQ$Tel-J)GD3=YXy+F4in(ILy*A3m@3o73uv?JC}Q>f zrY&8SWmesiba0|3X-jmlMT3 z*ST|_U@O=i*sM_*48G)dgXqlwoFp5G6qSM3&%_f_*n!PiT>?cNI)fAUkA{qWnqdMi+aNK_yVQ&lx4UZknAc9FIzVk% zo6JmFH~c{_tK!gt4+o2>)zoP{sR}!!vfRjI=13!z5}ijMFQ4a4?QIg-BE4T6!#%?d&L;`j5=a`4is>U;%@Rd~ zXC~H7eGQhhYWhMPWf9znDbYIgwud(6$W3e>$W4$~d%qoJ z+JE`1g$qJ%>b|z*xCKenmpV$0pM=Gl-Y*LT8K+P)2X#;XYEFF4mRbc~jj?DM@(1e`nL=F4Syv)TKIePQUz)bZ?Bi3@G@HO$Aps1DvDGkYF50O$_welu^cL7;vPiMGho74$;4fDqKbE{U zd1h{;LfM#Fb|Z&uH~Rm_J)R~Vy4b;1?tW_A)Iz#S_=F|~pISaVkCnQ0&u%Yz%o#|! zS-TSg87LUfFSs{tTuM3$!06ZzH&MFtG)X-l7>3)V?Txuj2HyG*5u;EY2_5vU0ujA? zHXh5G%6e3y7v?AjhyX79pnRBVr}RmPmtrxoB7lkxEzChX^(vKd+sLh?SBic=Q)5nA zdz7Mw3_iA>;T^_Kl~?1|5t%GZ;ki_+i>Q~Q1EVdKZ)$Sh3LM@ea&D~{2HOG++7*wF zAC6jW4>fa~!Vp5+$Z{<)Qxb|{unMgCv2)@%3j=7)Zc%U<^i|SAF88s!A^+Xs!OASYT%7;Jx?olg_6NFP1475N z#0s<@E~FI}#LNQ{?B1;t+N$2k*`K$Hxb%#8tRQi*Z#No0J}Pl;HWb){l7{A8(pu#@ zfE-OTvEreoz1+p`9sUI%Y{e5L-oTP_^NkgpYhZjp&ykinnW;(fu1;ttpSsgYM8ABX4dHe_HxU+%M(D=~) zYM}XUJ5guZ;=_ZcOsC`_{CiU$zN3$+x&5C`vX-V3`8&RjlBs^rf00MNYZW+jCd~7N z%{jJuUUwY(M`8$`B>K&_48!Li682ZaRknMgQ3~dnlp8C?__!P2z@=Auv;T^$yrsNy zCARmaA@^Yo2sS%2$`031-+h9KMZsIHfB>s@}>Y(z988e!`%4=EDoAQ0kbk>+lCoK60Mx9P!~I zlq~wf7kcm_NFImt3ZYlE(b3O1K^QWiFb$V^a2Jlwvm(!XYx<`i@ZMS3UwFt{;x+-v zhx{m=m;4dgvkKp5{*lfSN3o^keSpp9{hlXj%=}e_7Ou{Yiw(J@NXuh*;pL6@$HsfB zh?v+r^cp@jQ4EspC#RqpwPY(}_SS$wZ{S959`C25777&sgtNh%XTCo9VHJC-G z;;wi9{-iv+ETiY;K9qvlEc04f;ZnUP>cUL_T*ms``EtGoP^B#Q>n2dSrbAg8a>*Lg zd0EJ^=tdW~7fbcLFsqryFEcy*-8!?;n%;F+8i{eZyCDaiYxghr z$8k>L|2&-!lhvuVdk!r-kpSFl`5F5d4DJr%M4-qOy3gdmQbqF1=aBtRM7)c_Ae?$b8 zQg4c8*KQ{XJmL)1c7#0Yn0#PTMEs4-IHPjkn0!=;JdhMXqzMLeh`yOylXROP- zl#z3+fwM9l3%VN(6R77ua*uI9%hO7l7{+Hcbr(peh;afUK?B4EC09J{-u{mv)+u#? zdKVBCPt`eU@IzL)OXA`Ebu`Xp?u0m%h&X41}FNfnJ*g1!1wcbbpo%F4x!-#R9ft!8{5`Ho}04?FI#Kg zL|k`tF1t_`ywdy8(wnTut>HND(qNnq%Sq=AvvZbXnLx|mJhi!*&lwG2g|edBdVgLy zjvVTKHAx(+&P;P#2Xobo7_RttUi)Nllc}}hX>|N?-u5g7VJ-NNdwYcaOG?NK=5)}` zMtOL;o|i0mSKm(UI_7BL_^6HnVOTkuPI6y@ZLR(H?c1cr-_ouSLp{5!bx^DiKd*Yb z{K78Ci&Twup zTKm)ioN|wcYy%Qnwb)IzbH>W!;Ah5Zdm_jRY`+VRJ2 zhkspZ9hbK3iQD91A$d!0*-1i#%x81|s+SPRmD}d~<1p6!A13(!vABP2kNgqEG z?AMgl^P+iRoIY(9@_I?n1829lGvAsRnHwS~|5vD2+Zi53j<5N4wNn0{q>>jF9*bI) zL$kMXM-awNOElF>{?Jr^tOz1glbwaD-M0OKOlTeW3C!1ZyxRbB>8JDof(O&R1bh%3x#>y2~<>OXO#IIedH0Q`(&&?eo-c~ z>*Ah#3~09unym~UC-UFqqI>{dmUD$Y4@evG#ORLI*{ZM)Jl=e1it!XzY($S3V zLG!Y6fCjE>x6r@5FG1n|8ompSZaJ>9)q6jqU;XxCQk9zV(?C9+i*>w z21+KYt1gXX&0`x3E)hS7I5}snbBzox9C@Xzcr|{B8Hw;SY1$}&BoYKXH^hpjW-RgJ z-Fb}tannKCv>y~^`r|(1Q9;+sZlYf3XPSX|^gR01UFtu$B*R;$sPZdIZShRr>|b@J z;#G{EdoY+O;REEjQ}X7_YzWLO+Ey3>a_KDe1CjSe| z6arqcEZ)CX!8r(si`dqbF$uu&pnf^Np{1f*TdJ`r2;@SaZ z#hb4xlaCA@Pwqj#LlUEe5L{I$k(Zj$d3(~)u(F%&xb8={N9hKxlZIO1ABsM{Mt|)2 zJ^t9Id;?%4PfR4&Ph9B9cFK~@tG3wlFW-0fXZS_L4U*EiAA%+`h%q2^6BCC;t0iO4V=s4Qug{M|iDV@s zC7|ef-dxiR7T&Mpre!%hiUhHM%3Qxi$Lzw6&(Tvlx9QA_7LhYq<(o~=Y>3ka-zrQa zhGpfFK@)#)rtfz61w35^sN1=IFw&Oc!Nah+8@qhJ0UEGr;JplaxOGI82OVqZHsqfX ze1}r{jy;G?&}Da}a7>SCDsFDuzuseeCKof|Dz2BPsP8? zY;a)Tkr2P~0^2BeO?wnzF_Ul-ekY=-w26VnU%U3f19Z-pj&2 z4J_a|o4Dci+MO)mPQIM>kdPG1xydiR9@#8m zh27D7GF{p|a{8({Q-Pr-;#jV{2zHR>lGoFtIfIpoMo?exuQyX_A;;l0AP4!)JEM$EwMInZkj+8*IHP4vKRd zKx_l-i*>A*C@{u%ct`y~s6MWAfO{@FPIX&sg8H{GMDc{4M3%$@c8&RAlw0-R<4DO3 trJqdc$mBpWeznn?E0M$F`|3v=`3%T2A17h;rxP7$%JLd=6(2u;`(N3pt&so# diff --git a/app/index.php b/app/index.php deleted file mode 100644 index 8f98090..0000000 --- a/app/index.php +++ /dev/null @@ -1,9 +0,0 @@ -run(); diff --git a/app/js/bootstrap.js b/app/js/bootstrap.js deleted file mode 100644 index c298ee4..0000000 --- a/app/js/bootstrap.js +++ /dev/null @@ -1,2276 +0,0 @@ -/* =================================================== - * bootstrap-transition.js v2.3.1 - * 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.3.1 - * 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.3.1 - * 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.3.1 - * 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.$indicators = this.$element.find('.carousel-indicators') - 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 - if (this.interval) clearInterval(this.interval); - this.options.interval - && !this.paused - && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) - return this - } - - , getActiveIndex: function () { - this.$active = this.$element.find('.item.active') - this.$items = this.$active.parent().children() - return this.$items.index(this.$active) - } - - , to: function (pos) { - var activeIndex = this.getActiveIndex() - , that = this - - if (pos > (this.$items.length - 1) || pos < 0) return - - if (this.sliding) { - return this.$element.one('slid', function () { - that.to(pos) - }) - } - - if (activeIndex == pos) { - return this.pause().cycle() - } - - return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[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(true) - } - 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] - , direction: direction - }) - - if ($next.hasClass('active')) return - - if (this.$indicators.length) { - this.$indicators.find('.active').removeClass('active') - this.$element.one('slid', function () { - var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()]) - $nextIndicator && $nextIndicator.addClass('active') - }) - } - - 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.pause().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], [data-slide-to]', 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()) - , slideIndex - - $target.carousel(options) - - if (slideIndex = $this.attr('data-slide-to')) { - $target.data('carousel').pause().to(slideIndex).cycle() - } - - e.preventDefault() - }) - -}(window.jQuery);/* ============================================================= - * bootstrap-collapse.js v2.3.1 - * 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 || this.$element.hasClass('in')) 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 || !this.$element.hasClass('in')) 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 = $.extend({}, $.fn.collapse.defaults, $this.data(), 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.3.1 - * 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)) { - if (e.which == 27) $parent.find(toggle).focus() - 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 && $(selector) - - if (!$parent || !$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', clearMenus) - .on('click.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) - .on('click.dropdown-menu', function (e) { e.stopPropagation() }) - .on('click.dropdown.data-api' , toggle, Dropdown.prototype.toggle) - .on('keydown.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown) - -}(window.jQuery); -/* ========================================================= - * bootstrap-modal.js v2.3.1 - * 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 () { - var that = this - this.$element.hide() - this.backdrop(function () { - that.removeBackdrop() - that.$element.trigger('hidden') - }) - } - - , removeBackdrop: function () { - this.$backdrop && 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 = $('