diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 00000000..c2f33e73 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,41 @@ +Contributions to PHPCI are very much encouraged, and we do our best to make it as welcoming and simple as possible. + +### Before You Start +Before you start, please make sure that you are aware of, and agree to, the following conditions of contribution: + +* By making a contribution to PHPCI, you accept that you are granting copyright ownership for that contribution to Block 8 Limited - the company responsible for PHPCI. In countries where copyright reassignment is not permitted, you grant Block 8 Limited a perpetual, non-exclusive licence to use your contribution in any way and for any purpose. + +* By making a contribution to PHPCI, you accept that your code will be released under the open-source [BSD 2-Clause Licence](https://github.com/Block8/PHPCI/blob/master/LICENSE.md). + +Block 8 are committed to PHPCI being a truly free and open source project, providing easy to use continuous integration and testing to as many developers as possible. We may, at our sole discretion, provide paid services based upon PHPCI - but PHPCI will always remain free (as in cost, and freedom) and open source. + +### The Contribution Process + +1. If you are thinking of making a large change or feature addition, [open an issue](/Block8/PHPCI/issues) titled "Intent to implement: ". Describe your idea in detail and discuss it with the community. It might be that someone already has a plan, could help you out, or your idea may simply not be suitable for the project at this time. +2. Fork the PHPCI project on Github +3. Add a feature or fix a bug - We recommend that you do this on a branch within your repository. +4. Create a pull request containing just the one change you want to contribute back to PHPCI. If you have more than one feature or bug fix, please create separate branches within your repository, and then submit a separate pull request for each one. Your pull request should use the template detailed below. +5. We'll then review your pull request and give any necessary feedback, this could be: + * Suggestions to improve your implementation + * Questions + * Issues/bugs related to the change + * Coding standards pointers +6. Once everyone is happy with the submission, we'll merge it back into PHPCI. Your change will then be included in the next project release. + +### Not sure what to start with? +We maintain two labels within our issue tracker that may be of interest to new contributors: + +* [The "Easy Fix" List](https://github.com/Block8/PHPCI/labels/flag:easy-fix) +* [The "Priority" List](https://github.com/Block8/PHPCI/labels/flag:priority) + +### Coding Standards +We require that all contributions meet at least the following guidelines: + +* PSR-1 & PSR-2 compliance for all code +* Doc-blocks for all classes and methods +* All files must contain the standard file-level docblock, including the copyright, license and link tags. + +All pull requests will be checked against these standards. If you're modifying a file as part of your change which does not comply with the above, please make the necessary changes to bring it into compliance prior to submitting the pull request. + +### Other Requirements +When you're adding new features or functionality, or you're updating existing functionality, please ensure that the relevant documentation is also either created or updated on the Wiki. diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 00000000..16692061 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,28 @@ +Before submitting your issue, please make sure that you've checked all of the checkboxes below. + +- [ ] You're running the [latest release](https://github.com/Block8/PHPCI/releases/latest) version of PHPCI. +- [ ] Ensure that you're running at least PHP 5.3.6, you can check this by running `php -v` +- [ ] You've run `composer install --no-dev -o` from the root of your installation. +- [ ] You have set up either the PHPCI [Worker](https://github.com/Block8/PHPCI/wiki/Run-Builds-Using-a-Worker), [Daemon](https://github.com/Block8/PHPCI/wiki/Run-Builds-Using-a-Daemon) or [Cron Job](https://github.com/Block8/PHPCI/wiki/Run-Builds-Using-Cron) to run builds. + +To help us better understand your issue, please answer the following. + +### Expected behaviour + +*Please describe what you're expecting to see happen.* + +### Actual behaviour + +*Please describe what you're actually seeing happen.* + +### Steps to reproduce + +*If your issue requires any specific steps to reproduce, please outline them here.* + +### Environment info +Operating System: +PHP Version: +MySQL Version: + +### Logs or other output that would be helpful +(If logs are large, please upload as attachment). \ No newline at end of file diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..65d060ab --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,23 @@ +Contribution Type: bug fix | new plugin | new feature | refactor | cosmetic +Link to Intent to Implement: +Link to Bug: + +This pull request affects the following areas: + +* [ ] Front-End +* [ ] Builder +* [ ] Build Plugins + +**In raising this pull request, I confirm the following (please check boxes):** + +- [ ] I have read and understood the [contributing guidelines](/.github/CONTRIBUTING.md)? +- [ ] I have checked that another pull request for this purpose does not exist. +- [ ] I have considered, and confirmed that this submission will be valuable to others. +- [ ] I have created or updated the relevant documentation for this change on the PHPCI Wiki. +- [ ] Do the PHPCI tests pass? + + +Detailed description of change: + + + diff --git a/.gitignore b/.gitignore index fbfc1a28..63e81c5b 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,5 @@ PHPCI/Model/Migration.php PHPCI/Model/Base/MigrationBase.php PHPCI/Store/MigrationStore.php PHPCI/Store/Base/MigrationStoreBase.php +local_vars.php +Tests/PHPCI/config.yml diff --git a/phpci.yml b/.phpci.yml similarity index 79% rename from phpci.yml rename to .phpci.yml index 43931360..d6ea0921 100644 --- a/phpci.yml +++ b/.phpci.yml @@ -8,17 +8,23 @@ build_settings: - "PHPCI/Migrations" # Ignore the migrations directory, as both PHPMD and PHPCS can't cope with them. - "PHPCI/Model/Base" # These files are auto-generated, and sometimes hit PHPMD complexity thresholds. - "PHPCI/Languages" # PHPCS fails on character counts for non-Latin languages + - "public/assets" # If there are any PHP files in here, we didn't write them. setup: composer: action: "install" - prefer_dist: false test: + php_parallel_lint: + ignore: + # Only ignore vendor + - vendor/ php_mess_detector: allowed_warnings: 0 + rules: + - phpmd.xml php_code_sniffer: - standard: "PSR2" + standard: phpcs.xml allowed_warnings: 0 allowed_errors: 0 php_loc: @@ -26,7 +32,7 @@ test: php_docblock_checker: allowed_warnings: 0 -failure: +broken: email: committer: true cc: ["php-ci@googlegroups.com"] diff --git a/Dockerfile b/Dockerfile index af646d09..5fb6df83 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,4 +15,7 @@ RUN git config --global user.email "hello@php.ci" ADD ./ /phpci +RUN php -r "readfile('https://getcomposer.org/installer');" | php +RUN mv composer.phar /phpci/composer + CMD /phpci/daemonise phpci:daemonise diff --git a/LICENSE.md b/LICENSE.md index 1df52b9c..4c4f6952 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -6,4 +6,4 @@ Redistribution and use in source and binary forms, with or without modification, - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/PHPCI/Application.php b/PHPCI/Application.php index 88380c87..a6eb646c 100644 --- a/PHPCI/Application.php +++ b/PHPCI/Application.php @@ -14,7 +14,6 @@ use b8\Exception\HttpException; use b8\Http\Response; use b8\Http\Response\RedirectResponse; use b8\View; -use PHPCI\Model\Build; /** * PHPCI Front Controller @@ -22,6 +21,11 @@ use PHPCI\Model\Build; */ class Application extends b8\Application { + /** + * @var \PHPCI\Controller + */ + protected $controller; + /** * Initialise PHPCI - Handles session verification, routing, etc. */ @@ -47,13 +51,13 @@ class Application extends b8\Application return false; }; - $skipAuth = [$this, 'shouldSkipAuth']; + $skipAuth = array($this, 'shouldSkipAuth'); // Handler for the route we're about to register, checks for a valid session where necessary: $routeHandler = function (&$route, Response &$response) use (&$request, $validateSession, $skipAuth) { $skipValidation = in_array($route['controller'], array('session', 'webhook', 'build-status')); - if (!$skipValidation && !$validateSession() && !$skipAuth()) { + if (!$skipValidation && !$validateSession() && (!is_callable($skipAuth) || !$skipAuth())) { if ($request->isAjax()) { $response->setResponseCode(401); $response->setContent(''); @@ -100,7 +104,7 @@ class Application extends b8\Application $this->response->setContent($view->render()); } - if ($this->response->hasLayout()) { + if ($this->response->hasLayout() && $this->controller->layout) { $this->setLayoutVariables($this->controller->layout); $this->controller->layout->content = $this->response->getContent(); @@ -131,9 +135,18 @@ class Application extends b8\Application */ protected function setLayoutVariables(View &$layout) { - /** @var \PHPCI\Store\ProjectStore $projectStore */ - $projectStore = b8\Store\Factory::getStore('Project'); - $layout->projects = $projectStore->getAll(); + $groups = array(); + $groupStore = b8\Store\Factory::getStore('ProjectGroup'); + $groupList = $groupStore->getWhere(array(), 100, 0, array(), array('title' => 'ASC')); + + foreach ($groupList['items'] as $group) { + $thisGroup = array('title' => $group->getTitle()); + $projects = b8\Store\Factory::getStore('Project')->getByGroupId($group->getId()); + $thisGroup['projects'] = $projects['items']; + $groups[] = $thisGroup; + } + + $layout->groups = $groups; } /** diff --git a/PHPCI/BuildFactory.php b/PHPCI/BuildFactory.php index 4825047d..91e618a8 100644 --- a/PHPCI/BuildFactory.php +++ b/PHPCI/BuildFactory.php @@ -36,35 +36,44 @@ class BuildFactory /** * Takes a generic build and returns a type-specific build model. - * @param Build $base The build from which to get a more specific build type. + * @param Build $build The build from which to get a more specific build type. * @return Build */ - public static function getBuild(Build $base) + public static function getBuild(Build $build) { - switch($base->getProject()->getType()) - { - case 'remote': - $type = 'RemoteGitBuild'; - break; - case 'local': - $type = 'LocalBuild'; - break; - case 'github': - $type = 'GithubBuild'; - break; - case 'bitbucket': - $type = 'BitbucketBuild'; - break; - case 'gitlab': - $type = 'GitlabBuild'; - break; - case 'hg': - $type = 'MercurialBuild'; - break; + $project = $build->getProject(); + + if (!empty($project)) { + switch ($project->getType()) { + case 'remote': + $type = 'RemoteGitBuild'; + break; + case 'local': + $type = 'LocalBuild'; + break; + case 'github': + $type = 'GithubBuild'; + break; + case 'bitbucket': + $type = 'BitbucketBuild'; + break; + case 'gitlab': + $type = 'GitlabBuild'; + break; + case 'hg': + $type = 'MercurialBuild'; + break; + case 'svn': + $type = 'SubversionBuild'; + break; + default: + return $build; + } + + $class = '\\PHPCI\\Model\\Build\\' . $type; + $build = new $class($build->getDataArray()); } - $type = '\\PHPCI\\Model\\Build\\' . $type; - - return new $type($base->getDataArray()); + return $build; } } diff --git a/PHPCI/Builder.php b/PHPCI/Builder.php index 904aa506..1aed3d3f 100644 --- a/PHPCI/Builder.php +++ b/PHPCI/Builder.php @@ -188,6 +188,14 @@ class Builder implements LoggerAwareInterface $this->build->sendStatusPostback(); $success = true; + $previous_build = $this->build->getProject()->getPreviousBuild($this->build->getBranch()); + + $previous_state = Build::STATUS_NEW; + + if ($previous_build) { + $previous_state = $previous_build->getStatus(); + } + try { // Set up the build: $this->setupBuild(); @@ -205,34 +213,41 @@ class Builder implements LoggerAwareInterface $this->build->setStatus(Build::STATUS_FAILED); } - // Complete stage plugins are always run - $this->pluginExecutor->executePlugins($this->config, 'complete'); if ($success) { $this->pluginExecutor->executePlugins($this->config, 'success'); + + if ($previous_state == Build::STATUS_FAILED) { + $this->pluginExecutor->executePlugins($this->config, 'fixed'); + } + $this->buildLogger->logSuccess(Lang::get('build_success')); } else { $this->pluginExecutor->executePlugins($this->config, 'failure'); + + if ($previous_state == Build::STATUS_SUCCESS || $previous_state == Build::STATUS_NEW) { + $this->pluginExecutor->executePlugins($this->config, 'broken'); + } + $this->buildLogger->logFailure(Lang::get('build_failed')); } - - // Clean up: - $this->buildLogger->log(Lang::get('removing_build')); - - $cmd = 'rm -Rf "%s"'; - if (IS_WIN) { - $cmd = 'rmdir /S /Q "%s"'; - } - $this->executeCommand($cmd, $this->buildPath); } catch (\Exception $ex) { $this->build->setStatus(Build::STATUS_FAILED); $this->buildLogger->logFailure(Lang::get('exception') . $ex->getMessage()); + }finally{ + // Complete stage plugins are always run + $this->pluginExecutor->executePlugins($this->config, 'complete'); } // Update the build in the database, ping any external services, etc. $this->build->sendStatusPostback(); $this->build->setFinished(new \DateTime()); + + // Clean up: + $this->buildLogger->log(Lang::get('removing_build')); + $this->build->removeBuildDirectory(); + $this->store->save($this->build); } @@ -263,12 +278,14 @@ class Builder implements LoggerAwareInterface /** * Find a binary required by a plugin. - * @param $binary + * @param string $binary + * @param bool $quiet + * * @return null|string */ - public function findBinary($binary) + public function findBinary($binary, $quiet = false) { - return $this->commandExecutor->findBinary($binary, $this->buildPath); + return $this->commandExecutor->findBinary($binary, $quiet = false); } /** @@ -287,8 +304,7 @@ class Builder implements LoggerAwareInterface */ protected function setupBuild() { - $this->buildPath = PHPCI_DIR . 'PHPCI/build/' . $this->build->getId() . '/'; - $this->build->currentBuildPath = $this->buildPath; + $this->buildPath = $this->build->getBuildPath(); $this->interpolator->setupInterpolationVars( $this->build, @@ -296,6 +312,8 @@ class Builder implements LoggerAwareInterface PHPCI_URL ); + $this->commandExecutor->setBuildPath($this->buildPath); + // Create a working copy of the project: if (!$this->build->createWorkingCopy($this, $this->buildPath)) { throw new \Exception(Lang::get('could_not_create_working')); diff --git a/PHPCI/Command/CreateAdminCommand.php b/PHPCI/Command/CreateAdminCommand.php index 81f23c72..265f03b4 100644 --- a/PHPCI/Command/CreateAdminCommand.php +++ b/PHPCI/Command/CreateAdminCommand.php @@ -9,24 +9,36 @@ namespace PHPCI\Command; -use PHPCI\Helper\Lang; use PHPCI\Service\UserService; +use PHPCI\Helper\Lang; +use PHPCI\Store\UserStore; use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; -use b8\Store\Factory; -use PHPCI\Builder; /** -* Create admin command - creates an admin user -* @author Wogan May (@woganmay) -* @package PHPCI -* @subpackage Console -*/ + * Create admin command - creates an admin user + * @author Wogan May (@woganmay) + * @package PHPCI + * @subpackage Console + */ class CreateAdminCommand extends Command { + /** + * @var UserStore + */ + protected $userStore; + + /** + * @param UserStore $userStore + */ + public function __construct(UserStore $userStore) + { + parent::__construct(); + + $this->userStore = $userStore; + } + protected function configure() { $this @@ -35,92 +47,36 @@ class CreateAdminCommand extends Command } /** - * Creates an admin user in the existing PHPCI database - */ + * Creates an admin user in the existing PHPCI database + * + * {@inheritDoc} + */ protected function execute(InputInterface $input, OutputInterface $output) { - $userStore = Factory::getStore('User'); - $userService = new UserService($userStore); + $userService = new UserService($this->userStore); - require(PHPCI_DIR . 'bootstrap.php'); + /** @var $dialog \Symfony\Component\Console\Helper\DialogHelper */ + $dialog = $this->getHelperSet()->get('dialog'); - // Try to create a user account: - $adminEmail = $this->ask(Lang::get('enter_email'), true, FILTER_VALIDATE_EMAIL); + // Function to validate mail address. + $mailValidator = function ($answer) { + if (!filter_var($answer, FILTER_VALIDATE_EMAIL)) { + throw new \InvalidArgumentException(Lang::get('must_be_valid_email')); + } - if (empty($adminEmail)) { - return; - } + return $answer; + }; - $adminPass = $this->ask(Lang::get('enter_pass')); - $adminName = $this->ask(Lang::get('enter_name')); + $adminEmail = $dialog->askAndValidate($output, Lang::get('enter_email'), $mailValidator, false); + $adminName = $dialog->ask($output, Lang::get('enter_name')); + $adminPass = $dialog->askHiddenResponse($output, Lang::get('enter_password')); try { - $userService->createUser($adminName, $adminEmail, $adminPass, 1); - print Lang::get('user_created') . PHP_EOL; - } catch (\Exception $ex) { - print Lang::get('failed_to_create') . PHP_EOL; - print $ex->getMessage(); - print PHP_EOL; + $userService->createUser($adminName, $adminEmail, $adminPass, true); + $output->writeln(Lang::get('user_created')); + } catch (\Exception $e) { + $output->writeln(sprintf('%s', Lang::get('failed_to_create'))); + $output->writeln(sprintf('%s', $e->getMessage())); } } - - protected function ask($question, $emptyOk = false, $validationFilter = null) - { - print $question . ' '; - - $rtn = ''; - $stdin = fopen('php://stdin', 'r'); - $rtn = fgets($stdin); - fclose($stdin); - - $rtn = trim($rtn); - - if (!$emptyOk && empty($rtn)) { - $rtn = $this->ask($question, $emptyOk, $validationFilter); - } elseif ($validationFilter != null && ! empty($rtn)) { - if (! $this -> controlFormat($rtn, $validationFilter, $statusMessage)) { - print $statusMessage; - $rtn = $this->ask($question, $emptyOk, $validationFilter); - } - } - - return $rtn; - } - protected function controlFormat($valueToInspect, $filter, &$statusMessage) - { - $filters = !(is_array($filter))? array($filter) : $filter; - $statusMessage = ''; - $status = true; - $options = array(); - - foreach ($filters as $filter) { - if (! is_int($filter)) { - $regexp = $filter; - $filter = FILTER_VALIDATE_REGEXP; - $options = array( - 'options' => array( - 'regexp' => $regexp, - ) - ); - } - if (! filter_var($valueToInspect, $filter, $options)) { - $status = false; - - switch ($filter) - { - case FILTER_VALIDATE_URL: - $statusMessage = Lang::get('must_be_valid_url') . PHP_EOL; - break; - case FILTER_VALIDATE_EMAIL: - $statusMessage = Lang::get('must_be_valid_email') . PHP_EOL; - break; - case FILTER_VALIDATE_REGEXP: - $statusMessage = Lang::get('incorrect_format') . PHP_EOL; - break; - } - } - } - - return $status; - } } diff --git a/PHPCI/Command/CreateBuildCommand.php b/PHPCI/Command/CreateBuildCommand.php new file mode 100644 index 00000000..01260080 --- /dev/null +++ b/PHPCI/Command/CreateBuildCommand.php @@ -0,0 +1,85 @@ +projectStore = $projectStore; + $this->buildService = $buildService; + } + + /** + * {@inheritDoc} + */ + protected function configure() + { + $this + ->setName('phpci:create-build') + ->setDescription(Lang::get('create_build_project')) + ->addArgument('projectId', InputArgument::REQUIRED, Lang::get('project_id_argument')) + ->addOption('commit', null, InputOption::VALUE_OPTIONAL, Lang::get('commit_id_option')) + ->addOption('branch', null, InputOption::VALUE_OPTIONAL, Lang::get('branch_name_option')); + } + + /** + * {@inheritDoc} + */ + public function execute(InputInterface $input, OutputInterface $output) + { + $projectId = $input->getArgument('projectId'); + $commitId = $input->getOption('commit'); + $branch = $input->getOption('branch'); + + $project = $this->projectStore->getById($projectId); + if (empty($project)) { + throw new \InvalidArgumentException('Project does not exist: ' . $projectId); + } + + try { + $this->buildService->createBuild($project, $commitId, $branch); + $output->writeln(Lang::get('build_created')); + } catch (\Exception $e) { + $output->writeln(sprintf('%s', Lang::get('failed'))); + $output->writeln(sprintf('%s', $e->getMessage())); + } + } +} diff --git a/PHPCI/Command/DaemonCommand.php b/PHPCI/Command/DaemonCommand.php index 79925fbd..cb303eff 100644 --- a/PHPCI/Command/DaemonCommand.php +++ b/PHPCI/Command/DaemonCommand.php @@ -1,4 +1,5 @@ -* @package PHPCI -* @subpackage Console -*/ + * Daemon that loops and call the run-command. + * @author Gabriel Baker + * @package PHPCI + * @subpackage Console + */ class DaemonCommand extends Command { + /** - * @var \Monolog\Logger + * @var Logger */ protected $logger; - public function __construct(Logger $logger, $name = null) + /** + * @var string + */ + protected $pidFilePath; + + /** + * @var string + */ + protected $logFilePath; + + /** + * @var ProcessControlInterface + */ + protected $processControl; + + public function __construct(Logger $logger, ProcessControlInterface $processControl = null, $name = null) { parent::__construct($name); $this->logger = $logger; + $this->processControl = $processControl ?: Factory::getInstance(); } protected function configure() @@ -45,17 +61,30 @@ class DaemonCommand extends Command ->setName('phpci:daemon') ->setDescription('Initiates the daemon to run commands.') ->addArgument( - 'state', - InputArgument::REQUIRED, - 'start|stop|status' - ); + 'state', InputArgument::REQUIRED, 'start|stop|status' + ) + ->addOption( + 'pid-file', 'p', InputOption::VALUE_REQUIRED, + 'Path of the PID file', + implode(DIRECTORY_SEPARATOR, + array(PHPCI_DIR, 'daemon', 'daemon.pid')) + ) + ->addOption( + 'log-file', 'l', InputOption::VALUE_REQUIRED, + 'Path of the log file', + implode(DIRECTORY_SEPARATOR, + array(PHPCI_DIR, 'daemon', 'daemon.log')) + ); } /** - * Loops through running. - */ + * Loops through running. + */ protected function execute(InputInterface $input, OutputInterface $output) { + $this->pidFilePath = $input->getOption('pid-file'); + $this->logFilePath = $input->getOption('log-file'); + $state = $input->getArgument('state'); switch ($state) { @@ -66,64 +95,108 @@ class DaemonCommand extends Command $this->stopDaemon(); break; case 'status': - $this->statusDaemon(); + $this->statusDaemon($output); break; default: - echo "Not a valid choice, please use start stop or status"; + $this->output->writeln("Not a valid choice, please use start, stop or status"); break; } - } protected function startDaemon() { - - if (file_exists(PHPCI_DIR.'/daemon/daemon.pid')) { - echo "Already started\n"; - $this->logger->warning("Daemon already started"); + $pid = $this->getRunningPid(); + if ($pid) { + $this->logger->notice("Daemon already started", array('pid' => $pid)); return "alreadystarted"; } - $logfile = PHPCI_DIR."/daemon/daemon.log"; + $this->logger->info("Trying to start the daemon"); + $cmd = "nohup %s/daemonise phpci:daemonise > %s 2>&1 &"; - $command = sprintf($cmd, PHPCI_DIR, $logfile); - $this->logger->info("Daemon started"); - exec($command); + $command = sprintf($cmd, PHPCI_DIR, $this->logFilePath); + $output = $exitCode = null; + exec($command, $output, $exitCode); + + if ($exitCode !== 0) { + $this->logger->error(sprintf("daemonise exited with status %d", $exitCode)); + return "notstarted"; + } + + for ($i = 0; !($pid = $this->getRunningPid()) && $i < 5; $i++) { + sleep(1); + } + + if (!$pid) { + $this->logger->error("Could not start the daemon"); + return "notstarted"; + } + + $this->logger->notice("Daemon started", array('pid' => $pid)); + return "started"; } protected function stopDaemon() { - - if (!file_exists(PHPCI_DIR.'/daemon/daemon.pid')) { - echo "Not started\n"; - $this->logger->warning("Can't stop daemon as not started"); + $pid = $this->getRunningPid(); + if (!$pid) { + $this->logger->notice("Cannot stop the daemon as it is not started"); return "notstarted"; } - $cmd = "kill $(cat %s/daemon/daemon.pid)"; - $command = sprintf($cmd, PHPCI_DIR); - exec($command); - $this->logger->info("Daemon stopped"); - unlink(PHPCI_DIR.'/daemon/daemon.pid'); - } + $this->logger->info("Trying to terminate the daemon", array('pid' => $pid)); + $this->processControl->kill($pid); - protected function statusDaemon() - { - - if (!file_exists(PHPCI_DIR.'/daemon/daemon.pid')) { - echo "Not running\n"; - return "notrunning"; + for ($i = 0; ($pid = $this->getRunningPid()) && $i < 5; $i++) { + sleep(1); } - $pid = trim(file_get_contents(PHPCI_DIR.'/daemon/daemon.pid')); - $pidcheck = sprintf("/proc/%s", $pid); - if (is_dir($pidcheck)) { - echo "Running\n"; + if ($pid) { + $this->logger->warning("The daemon is resiting, trying to kill it", array('pid' => $pid)); + $this->processControl->kill($pid, true); + + for ($i = 0; ($pid = $this->getRunningPid()) && $i < 5; $i++) { + sleep(1); + } + } + + if (!$pid) { + $this->logger->notice("Daemon stopped"); + return "stopped"; + } + + $this->logger->error("Could not stop the daemon"); + } + + protected function statusDaemon(OutputInterface $output) + { + $pid = $this->getRunningPid(); + if ($pid) { + $output->writeln(sprintf('The daemon is running, PID: %d', $pid)); return "running"; } - unlink(PHPCI_DIR.'/daemon/daemon.pid'); - echo "Not running\n"; + $output->writeln('The daemon is not running'); return "notrunning"; } + + /** Check if there is a running daemon + * + * @return int|null + */ + protected function getRunningPid() + { + if (!file_exists($this->pidFilePath)) { + return; + } + + $pid = intval(trim(file_get_contents($this->pidFilePath))); + + if($this->processControl->isRunning($pid, true)) { + return $pid; + } + + // Not found, remove the stale PID file + unlink($this->pidFilePath); + } } diff --git a/PHPCI/Command/DaemoniseCommand.php b/PHPCI/Command/DaemoniseCommand.php index 915890bd..eadd334e 100644 --- a/PHPCI/Command/DaemoniseCommand.php +++ b/PHPCI/Command/DaemoniseCommand.php @@ -12,9 +12,7 @@ namespace PHPCI\Command; use Monolog\Logger; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\ArgvInput; -use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; /** @@ -76,7 +74,7 @@ class DaemoniseCommand extends Command $this->sleep = 0; $runner = new RunCommand($this->logger); $runner->setMaxBuilds(1); - $runner->setIsDaemon(true); + $runner->setDaemon(true); $emptyInput = new ArgvInput(array()); @@ -87,7 +85,8 @@ class DaemoniseCommand extends Command try { $buildCount = $runner->run($emptyInput, $output); } catch (\Exception $e) { - var_dump($e); + $output->writeln('Exception: ' . $e->getMessage() . ''); + $output->writeln('Line: ' . $e->getLine() . ' - File: ' . $e->getFile() . ''); } if (0 == $buildCount && $this->sleep < 15) { diff --git a/PHPCI/Command/GenerateCommand.php b/PHPCI/Command/GenerateCommand.php index 07307686..ddd227d9 100644 --- a/PHPCI/Command/GenerateCommand.php +++ b/PHPCI/Command/GenerateCommand.php @@ -10,9 +10,7 @@ namespace PHPCI\Command; use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use b8\Database; use b8\Database\CodeGenerator; diff --git a/PHPCI/Command/InstallCommand.php b/PHPCI/Command/InstallCommand.php index 3dab656b..5f5cbd67 100644 --- a/PHPCI/Command/InstallCommand.php +++ b/PHPCI/Command/InstallCommand.php @@ -13,16 +13,15 @@ use Exception; use PDO; use b8\Config; -use b8\Database; use b8\Store\Factory; use PHPCI\Helper\Lang; use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Helper\DialogHelper; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Helper\DialogHelper; use PHPCI\Service\UserService; +use Symfony\Component\Console\Question\ConfirmationQuestion; /** * Install console command - Installs PHPCI. @@ -49,6 +48,9 @@ class InstallCommand extends Command ->addOption('admin-pass', null, InputOption::VALUE_OPTIONAL, Lang::get('admin_pass')) ->addOption('admin-mail', null, InputOption::VALUE_OPTIONAL, Lang::get('admin_email')) ->addOption('config-path', null, InputOption::VALUE_OPTIONAL, Lang::get('config_path'), $defaultPath) + ->addOption('queue-disabled', null, InputOption::VALUE_NONE, 'Don\'t ask for queue details') + ->addOption('queue-server', null, InputOption::VALUE_OPTIONAL, 'Beanstalkd queue server hostname') + ->addOption('queue-name', null, InputOption::VALUE_OPTIONAL, 'Beanstalkd queue name') ->setDescription(Lang::get('install_phpci')); } @@ -59,7 +61,9 @@ class InstallCommand extends Command { $this->configFilePath = $input->getOption('config-path'); - $this->verifyNotInstalled($output); + if (!$this->verifyNotInstalled($output)) { + return; + } $output->writeln(''); $output->writeln('******************'); @@ -96,7 +100,7 @@ class InstallCommand extends Command $this->writeConfigFile($conf); $this->setupDatabase($output); - $admin = $this->getAdminInforamtion($input, $output); + $admin = $this->getAdminInformation($input, $output); $this->createAdminUser($admin, $output); } @@ -161,7 +165,7 @@ class InstallCommand extends Command * @param OutputInterface $output * @return array */ - protected function getAdminInforamtion(InputInterface $input, OutputInterface $output) + protected function getAdminInformation(InputInterface $input, OutputInterface $output) { $admin = array(); @@ -173,7 +177,7 @@ class InstallCommand extends Command // Function to validate mail address. $mailValidator = function ($answer) { if (!filter_var($answer, FILTER_VALIDATE_EMAIL)) { - throw new Exception(Lang::get('must_be_valid_email')); + throw new \InvalidArgumentException(Lang::get('must_be_valid_email')); } return $answer; @@ -230,10 +234,45 @@ class InstallCommand extends Command } $phpci['url'] = $url; + $phpci['worker'] = $this->getQueueInformation($input, $output, $dialog); return $phpci; } + /** + * If the user wants to use a queue, get the necessary details. + * @param InputInterface $input + * @param OutputInterface $output + * @param DialogHelper $dialog + * @return array + */ + protected function getQueueInformation(InputInterface $input, OutputInterface $output, DialogHelper $dialog) + { + if ($input->getOption('queue-disabled')) { + return null; + } + + $rtn = []; + + $helper = $this->getHelper('question'); + $question = new ConfirmationQuestion('Use beanstalkd to manage build queue? ', true); + + if (!$helper->ask($input, $output, $question)) { + $output->writeln('Skipping beanstalkd configuration.'); + return null; + } + + if (!$rtn['host'] = $input->getOption('queue-server')) { + $rtn['host'] = $dialog->ask($output, 'Enter your beanstalkd hostname [localhost]: ', 'localhost'); + } + + if (!$rtn['queue'] = $input->getOption('queue-name')) { + $rtn['queue'] = $dialog->ask($output, 'Enter the queue (tube) name to use [phpci]: ', 'phpci'); + } + + return $rtn; + } + /** * Load configuration for DB form CLI options or ask info to user. * @@ -296,6 +335,8 @@ class InstallCommand extends Command ) ); + unset($pdo); + return true; } catch (Exception $ex) { @@ -322,7 +363,9 @@ class InstallCommand extends Command { $output->write(Lang::get('setting_up_db')); - shell_exec(PHPCI_DIR . 'vendor/bin/phinx migrate -c "' . PHPCI_DIR . 'phinx.php"'); + $phinxBinary = escapeshellarg(PHPCI_DIR . 'vendor/bin/phinx'); + $phinxScript = escapeshellarg(PHPCI_DIR . 'phinx.php'); + shell_exec($phinxBinary . ' migrate -c ' . $phinxScript); $output->writeln(''.Lang::get('ok').''); } @@ -346,7 +389,6 @@ class InstallCommand extends Command } catch (\Exception $ex) { $output->writeln(''.Lang::get('failed_to_create').''); $output->writeln('' . $ex->getMessage() . ''); - die; } } @@ -361,6 +403,7 @@ class InstallCommand extends Command /** * @param OutputInterface $output + * @return bool */ protected function verifyNotInstalled(OutputInterface $output) { @@ -370,8 +413,10 @@ class InstallCommand extends Command if (!empty($content)) { $output->writeln(''.Lang::get('config_exists').''); $output->writeln(''.Lang::get('update_instead').''); - die; + return false; } } + + return true; } } diff --git a/PHPCI/Command/PollCommand.php b/PHPCI/Command/PollCommand.php index 07b628b8..a8729515 100644 --- a/PHPCI/Command/PollCommand.php +++ b/PHPCI/Command/PollCommand.php @@ -14,9 +14,7 @@ use b8\HttpClient; use Monolog\Logger; use PHPCI\Helper\Lang; use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Yaml\Parser; use PHPCI\Model\Build; @@ -60,7 +58,7 @@ class PollCommand extends Command if (!$token) { $this->logger->error(Lang::get('no_token')); - exit(); + return; } $buildStore = Factory::getStore('Build'); diff --git a/PHPCI/Command/RebuildCommand.php b/PHPCI/Command/RebuildCommand.php new file mode 100644 index 00000000..4c24b359 --- /dev/null +++ b/PHPCI/Command/RebuildCommand.php @@ -0,0 +1,93 @@ + +* @package PHPCI +* @subpackage Console +*/ +class RebuildCommand extends Command +{ + /** + * @var Logger + */ + protected $logger; + + /** + * @var OutputInterface + */ + protected $output; + + /** + * @var boolean + */ + protected $run; + + /** + * @var int + */ + protected $sleep; + + /** + * @param \Monolog\Logger $logger + * @param string $name + */ + public function __construct(Logger $logger, $name = null) + { + parent::__construct($name); + $this->logger = $logger; + } + + protected function configure() + { + $this + ->setName('phpci:rebuild') + ->setDescription('Re-runs the last run build.'); + } + + /** + * Loops through running. + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $runner = new RunCommand($this->logger); + $runner->setMaxBuilds(1); + $runner->setDaemon(false); + + /** @var \PHPCI\Store\BuildStore $store */ + $store = Factory::getStore('Build'); + $service = new BuildService($store); + + $builds = $store->getLatestBuilds(null, 1); + $lastBuild = array_shift($builds); + $service->createDuplicateBuild($lastBuild); + + $runner->run(new ArgvInput(array()), $output); + } + + /** + * Called when log entries are made in Builder / the plugins. + * @see \PHPCI\Builder::log() + */ + public function logCallback($log) + { + $this->output->writeln($log); + } +} diff --git a/PHPCI/Command/RebuildQueueCommand.php b/PHPCI/Command/RebuildQueueCommand.php new file mode 100644 index 00000000..4b0af6d8 --- /dev/null +++ b/PHPCI/Command/RebuildQueueCommand.php @@ -0,0 +1,85 @@ + +* @package PHPCI +* @subpackage Console +*/ +class RebuildQueueCommand extends Command +{ + /** + * @var OutputInterface + */ + protected $output; + + /** + * @var Logger + */ + protected $logger; + + /** + * @param \Monolog\Logger $logger + * @param string $name + */ + public function __construct(Logger $logger, $name = null) + { + parent::__construct($name); + $this->logger = $logger; + } + + protected function configure() + { + $this + ->setName('phpci:rebuild-queue') + ->setDescription('Rebuilds the PHPCI worker queue.'); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $this->output = $output; + + // For verbose mode we want to output all informational and above + // messages to the symphony output interface. + if ($input->hasOption('verbose') && $input->getOption('verbose')) { + $this->logger->pushHandler( + new OutputLogHandler($this->output, Logger::INFO) + ); + } + + $store = Factory::getStore('Build'); + $result = $store->getByStatus(0); + + $this->logger->addInfo(Lang::get('found_n_builds', count($result['items']))); + + $buildService = new BuildService($store); + + while (count($result['items'])) { + $build = array_shift($result['items']); + $build = BuildFactory::getBuild($build); + + $this->logger->addInfo('Added build #' . $build->getId() . ' to queue.'); + $buildService->addBuildToQueue($build); + } + } +} diff --git a/PHPCI/Command/RunCommand.php b/PHPCI/Command/RunCommand.php index e0f37b6b..c2c352e6 100644 --- a/PHPCI/Command/RunCommand.php +++ b/PHPCI/Command/RunCommand.php @@ -15,11 +15,8 @@ use PHPCI\Helper\Lang; use PHPCI\Logging\BuildDBLogHandler; use PHPCI\Logging\LoggedBuildContextTidier; use PHPCI\Logging\OutputLogHandler; -use Psr\Log\LoggerAwareInterface; use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use b8\Store\Factory; use PHPCI\Builder; @@ -47,7 +44,7 @@ class RunCommand extends Command /** * @var int */ - protected $maxBuilds = null; + protected $maxBuilds = 100; /** * @var bool @@ -143,7 +140,7 @@ class RunCommand extends Command $this->maxBuilds = (int)$numBuilds; } - public function setIsDaemon($fromDaemon) + public function setDaemon($fromDaemon) { $this->isFromDaemon = (bool)$fromDaemon; } @@ -169,7 +166,7 @@ class RunCommand extends Command $build->setStatus(Build::STATUS_FAILED); $build->setFinished(new \DateTime()); $store->save($build); - $this->removeBuildDirectory($build); + $build->removeBuildDirectory(); continue; } @@ -178,19 +175,4 @@ class RunCommand extends Command return $rtn; } - - protected function removeBuildDirectory($build) - { - $buildPath = PHPCI_DIR . 'PHPCI/build/' . $build->getId() . '/'; - - if (is_dir($buildPath)) { - $cmd = 'rm -Rf "%s"'; - - if (IS_WIN) { - $cmd = 'rmdir /S /Q "%s"'; - } - - shell_exec($cmd); - } - } } diff --git a/PHPCI/Command/UpdateCommand.php b/PHPCI/Command/UpdateCommand.php index 32ce09b2..13e31f79 100644 --- a/PHPCI/Command/UpdateCommand.php +++ b/PHPCI/Command/UpdateCommand.php @@ -9,13 +9,11 @@ namespace PHPCI\Command; +use b8\Config; use Monolog\Logger; use PHPCI\Helper\Lang; use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputDefinition; use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; /** @@ -49,7 +47,9 @@ class UpdateCommand extends Command */ protected function execute(InputInterface $input, OutputInterface $output) { - $this->verifyInstalled($output); + if (!$this->verifyInstalled($output)) { + return; + } $output->write(Lang::get('updating_phpci')); @@ -60,17 +60,9 @@ class UpdateCommand extends Command protected function verifyInstalled(OutputInterface $output) { - if (!file_exists(PHPCI_DIR . 'PHPCI/config.yml')) { - $output->writeln(''.Lang::get('not_installed').''); - $output->writeln(''.Lang::get('install_instead').''); - die; - } + $config = Config::getInstance(); + $phpciUrl = $config->get('phpci.url'); - $content = file_get_contents(PHPCI_DIR . 'PHPCI/config.yml'); - if (empty($content)) { - $output->writeln(''.Lang::get('not_installed').''); - $output->writeln(''.Lang::get('install_instead').''); - die; - } + return !empty($phpciUrl); } } diff --git a/PHPCI/Command/WorkerCommand.php b/PHPCI/Command/WorkerCommand.php new file mode 100644 index 00000000..5ceb6a84 --- /dev/null +++ b/PHPCI/Command/WorkerCommand.php @@ -0,0 +1,87 @@ + +* @package PHPCI +* @subpackage Console +*/ +class WorkerCommand extends Command +{ + /** + * @var OutputInterface + */ + protected $output; + + /** + * @var Logger + */ + protected $logger; + + /** + * @param \Monolog\Logger $logger + * @param string $name + */ + public function __construct(Logger $logger, $name = null) + { + parent::__construct($name); + $this->logger = $logger; + } + + protected function configure() + { + $this + ->setName('phpci:worker') + ->setDescription('Runs the PHPCI build worker.') + ->addOption('debug', null, null, 'Run PHPCI in Debug Mode'); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $this->output = $output; + + // For verbose mode we want to output all informational and above + // messages to the symphony output interface. + if ($input->hasOption('verbose') && $input->getOption('verbose')) { + $this->logger->pushHandler( + new OutputLogHandler($this->output, Logger::INFO) + ); + } + + // Allow PHPCI to run in "debug mode" + if ($input->hasOption('debug') && $input->getOption('debug')) { + $output->writeln('Debug mode enabled.'); + define('PHPCI_DEBUG_MODE', true); + } + + $config = Config::getInstance()->get('phpci.worker', []); + + if (empty($config['host']) || empty($config['queue'])) { + $error = 'The worker is not configured. You must set a host and queue in your config.yml file.'; + throw new \Exception($error); + } + + $worker = new BuildWorker($config['host'], $config['queue']); + $worker->setLogger($this->logger); + $worker->setMaxJobs(Config::getInstance()->get('phpci.worker.max_jobs', -1)); + $worker->startWorker(); + } +} diff --git a/PHPCI/Controller.php b/PHPCI/Controller.php index b065e857..68b1c845 100644 --- a/PHPCI/Controller.php +++ b/PHPCI/Controller.php @@ -10,6 +10,7 @@ namespace PHPCI; use b8\Config; +use b8\Exception\HttpException\ForbiddenException; use b8\Http\Request; use b8\Http\Response; use b8\View; @@ -30,6 +31,11 @@ class Controller extends \b8\Controller */ protected $view; + /** + * @var \b8\View + */ + public $layout; + /** * Initialise the controller. */ @@ -86,6 +92,10 @@ class Controller extends \b8\Controller $this->setView($action); $response = parent::handleAction($action, $actionParams); + if ($response instanceof Response) { + return $response; + } + if (is_string($response)) { $this->controllerView->content = $response; } elseif (isset($this->view)) { diff --git a/PHPCI/Controller/BuildController.php b/PHPCI/Controller/BuildController.php index d552f5b3..55ccbb37 100644 --- a/PHPCI/Controller/BuildController.php +++ b/PHPCI/Controller/BuildController.php @@ -11,7 +11,9 @@ namespace PHPCI\Controller; use b8; use b8\Exception\HttpException\NotFoundException; +use b8\Http\Response\JsonResponse; use PHPCI\BuildFactory; +use PHPCI\Helper\AnsiConverter; use PHPCI\Helper\Lang; use PHPCI\Model\Build; use PHPCI\Model\Project; @@ -66,19 +68,37 @@ class BuildController extends \PHPCI\Controller $this->layout->title = Lang::get('build_n', $buildId); $this->layout->subtitle = $build->getProjectTitle(); - $nav = array( - 'title' => Lang::get('build_n', $buildId), - 'icon' => 'cog', - 'links' => array( - 'build/rebuild/' . $build->getId() => Lang::get('rebuild_now'), - ), - ); + switch ($build->getStatus()) { + case 0: + $this->layout->skin = 'blue'; + break; - if ($this->currentUserIsAdmin()) { - $nav['links']['build/delete/' . $build->getId()] = Lang::get('delete_build'); + case 1: + $this->layout->skin = 'yellow'; + break; + + case 2: + $this->layout->skin = 'green'; + break; + + case 3: + $this->layout->skin = 'red'; + break; } - $this->layout->nav = $nav; + $rebuild = Lang::get('rebuild_now'); + $rebuildLink = PHPCI_URL . 'build/rebuild/' . $build->getId(); + + $delete = Lang::get('delete_build'); + $deleteLink = PHPCI_URL . 'build/delete/' . $build->getId(); + + $actions = "{$rebuild} "; + + if ($this->currentUserIsAdmin()) { + $actions .= " {$delete}"; + } + + $this->layout->actions = $actions; } /** @@ -107,7 +127,17 @@ class BuildController extends \PHPCI\Controller */ public function data($buildId) { - die($this->getBuildData(BuildFactory::getBuildById($buildId))); + $response = new JsonResponse(); + $build = BuildFactory::getBuildById($buildId); + + if (!$build) { + $response->setResponseCode(404); + $response->setContent(array()); + return $response; + } + + $response->setContent($this->getBuildData($build)); + return $response; } /** @@ -124,13 +154,15 @@ class BuildController extends \PHPCI\Controller $data = $this->buildStore->getMeta($key, $build->getProjectId(), $buildId, $build->getBranch(), $numBuilds); } - die(json_encode($data)); + $response = new JsonResponse(); + $response->setContent($data); + return $response; } /** * Get build data from database and json encode it: */ - protected function getBuildData($build) + protected function getBuildData(Build $build) { $data = array(); $data['status'] = (int)$build->getStatus(); @@ -138,8 +170,21 @@ class BuildController extends \PHPCI\Controller $data['created'] = !is_null($build->getCreated()) ? $build->getCreated()->format('Y-m-d H:i:s') : null; $data['started'] = !is_null($build->getStarted()) ? $build->getStarted()->format('Y-m-d H:i:s') : null; $data['finished'] = !is_null($build->getFinished()) ? $build->getFinished()->format('Y-m-d H:i:s') : null; + $data['duration'] = $build->getDuration(); - return json_encode($data); + /** @var \PHPCI\Store\BuildErrorStore $errorStore */ + $errorStore = b8\Store\Factory::getStore('BuildError'); + $errors = $errorStore->getErrorsForBuild($build->getId(), $this->getParam('since', null)); + + $errorView = new b8\View('Build/errors'); + $errorView->build = $build; + $errorView->errors = $errors; + + $data['errors'] = $errorStore->getErrorTotalForBuild($build->getId()); + $data['error_html'] = $errorView->render(); + $data['since'] = (new \DateTime())->format('Y-m-d H:i:s'); + + return $data; } /** @@ -155,8 +200,13 @@ class BuildController extends \PHPCI\Controller $build = $this->buildService->createDuplicateBuild($copy); - header('Location: '.PHPCI_URL.'build/view/' . $build->getId()); - exit; + if ($this->buildService->queueError) { + $_SESSION['global_error'] = Lang::get('add_to_queue_failed'); + } + + $response = new b8\Http\Response\RedirectResponse(); + $response->setHeader('Location', PHPCI_URL.'build/view/' . $build->getId()); + return $response; } /** @@ -174,8 +224,9 @@ class BuildController extends \PHPCI\Controller $this->buildService->deleteBuild($build); - header('Location: '.PHPCI_URL.'project/view/' . $build->getProjectId()); - exit; + $response = new b8\Http\Response\RedirectResponse(); + $response->setHeader('Location', PHPCI_URL.'project/view/' . $build->getProjectId()); + return $response; } /** @@ -183,11 +234,7 @@ class BuildController extends \PHPCI\Controller */ protected function cleanLog($log) { - $log = str_replace('[0;32m', '', $log); - $log = str_replace('[0;31m', '', $log); - $log = str_replace('[0m', '', $log); - - return $log; + return AnsiConverter::convert($log); } /** @@ -200,9 +247,9 @@ class BuildController extends \PHPCI\Controller 'running' => $this->formatBuilds($this->buildStore->getByStatus(Build::STATUS_RUNNING)), ); - if ($this->request->isAjax()) { - die(json_encode($rtn)); - } + $response = new JsonResponse(); + $response->setContent($rtn); + return $response; } /** diff --git a/PHPCI/Controller/BuildStatusController.php b/PHPCI/Controller/BuildStatusController.php index 71ad1e11..62cb9ba7 100644 --- a/PHPCI/Controller/BuildStatusController.php +++ b/PHPCI/Controller/BuildStatusController.php @@ -15,6 +15,7 @@ use b8\Store; use PHPCI\BuildFactory; use PHPCI\Model\Project; use PHPCI\Model\Build; +use PHPCI\Service\BuildStatusService; /** * Build Status Controller - Allows external access to build status information / images. @@ -24,10 +25,9 @@ use PHPCI\Model\Build; */ class BuildStatusController extends \PHPCI\Controller { - /** - * @var \PHPCI\Store\ProjectStore - */ + /* @var \PHPCI\Store\ProjectStore */ protected $projectStore; + /* @var \PHPCI\Store\BuildStore */ protected $buildStore; /** @@ -53,7 +53,7 @@ class BuildStatusController extends \PHPCI\Controller $status = 'passing'; if (!$project->getAllowPublicStatus()) { - die(); + return null; } if (isset($project) && $project instanceof Project) { @@ -70,16 +70,90 @@ class BuildStatusController extends \PHPCI\Controller return $status; } + /** + * Displays projects information in ccmenu format + * + * @param $projectId + * @return bool + * @throws \Exception + * @throws b8\Exception\HttpException + */ + public function ccxml($projectId) + { + /* @var Project $project */ + $project = $this->projectStore->getById($projectId); + $xml = new \SimpleXMLElement(''); + + if (!$project instanceof Project || !$project->getAllowPublicStatus()) { + return $this->renderXml($xml); + } + + try { + $branchList = $this->buildStore->getBuildBranches($projectId); + + if (!$branchList) { + $branchList = array($project->getBranch()); + } + + foreach ($branchList as $branch) { + $buildStatusService = new BuildStatusService($branch, $project, $project->getLatestBuild($branch)); + if ($attributes = $buildStatusService->toArray()) { + $projectXml = $xml->addChild('Project'); + foreach ($attributes as $attributeKey => $attributeValue) { + $projectXml->addAttribute($attributeKey, $attributeValue); + } + } + } + } catch (\Exception $e) { + $xml = new \SimpleXMLElement(''); + } + + return $this->renderXml($xml); + } + + /** + * @param \SimpleXMLElement $xml + * @return bool + */ + protected function renderXml(\SimpleXMLElement $xml = null) + { + $this->response->setHeader('Content-Type', 'text/xml'); + $this->response->setContent($xml->asXML()); + $this->response->flush(); + echo $xml->asXML(); + + return true; + } + /** * Returns the appropriate build status image in SVG format for a given project. */ public function image($projectId) { + $style = $this->getParam('style', 'plastic'); + $label = $this->getParam('label', 'build'); + $status = $this->getStatus($projectId); + + if (is_null($status)) { + $response = new b8\Http\Response\RedirectResponse(); + $response->setHeader('Location', '/'); + return $response; + } + $color = ($status == 'passing') ? 'green' : 'red'; - - header('Content-Type: image/svg+xml'); - die(file_get_contents('http://img.shields.io/badge/build-' . $status . '-' . $color . '.svg')); + $image = file_get_contents(sprintf( + 'http://img.shields.io/badge/%s-%s-%s.svg?style=%s', + $label, + $status, + $color, + $style + )); + + $this->response->disableLayout(); + $this->response->setHeader('Content-Type', 'image/svg+xml'); + $this->response->setContent($image); + return $this->response; } /** diff --git a/PHPCI/Controller/GroupController.php b/PHPCI/Controller/GroupController.php new file mode 100644 index 00000000..898f9e41 --- /dev/null +++ b/PHPCI/Controller/GroupController.php @@ -0,0 +1,120 @@ + + * @package PHPCI + * @subpackage Web + */ +class GroupController extends Controller +{ + /** + * @var \PHPCI\Store\ProjectGroupStore + */ + protected $groupStore; + + /** + * Set up this controller. + */ + public function init() + { + $this->groupStore = b8\Store\Factory::getStore('ProjectGroup'); + } + + /** + * List project groups. + */ + public function index() + { + $this->requireAdmin(); + + $groups = array(); + $groupList = $this->groupStore->getWhere(array(), 100, 0, array(), array('title' => 'ASC')); + + foreach ($groupList['items'] as $group) { + $thisGroup = array( + 'title' => $group->getTitle(), + 'id' => $group->getId(), + ); + $projects = b8\Store\Factory::getStore('Project')->getByGroupId($group->getId()); + $thisGroup['projects'] = $projects['items']; + $groups[] = $thisGroup; + } + + $this->view->groups = $groups; + } + + /** + * Add or edit a project group. + * @param null $groupId + * @return void|b8\Http\Response\RedirectResponse + */ + public function edit($groupId = null) + { + $this->requireAdmin(); + + if (!is_null($groupId)) { + $group = $this->groupStore->getById($groupId); + } else { + $group = new ProjectGroup(); + } + + if ($this->request->getMethod() == 'POST') { + $group->setTitle($this->getParam('title')); + $this->groupStore->save($group); + + $response = new b8\Http\Response\RedirectResponse(); + $response->setHeader('Location', PHPCI_URL.'group'); + return $response; + } + + $form = new Form(); + $form->setMethod('POST'); + $form->setAction(PHPCI_URL . 'group/edit' . (!is_null($groupId) ? '/' . $groupId : '')); + + $title = new Form\Element\Text('title'); + $title->setContainerClass('form-group'); + $title->setClass('form-control'); + $title->setLabel('Group Title'); + $title->setValue($group->getTitle()); + + $submit = new Form\Element\Submit(); + $submit->setValue('Save Group'); + + $form->addField($title); + $form->addField($submit); + + $this->view->form = $form; + } + + /** + * Delete a project group. + * @param $groupId + * @return b8\Http\Response\RedirectResponse + */ + public function delete($groupId) + { + $this->requireAdmin(); + $group = $this->groupStore->getById($groupId); + + $this->groupStore->delete($group); + $response = new b8\Http\Response\RedirectResponse(); + $response->setHeader('Location', PHPCI_URL.'group'); + return $response; + } +} diff --git a/PHPCI/Controller/HomeController.php b/PHPCI/Controller/HomeController.php index 20d4cead..4241d324 100644 --- a/PHPCI/Controller/HomeController.php +++ b/PHPCI/Controller/HomeController.php @@ -23,15 +23,20 @@ use PHPCI\Model\Build; class HomeController extends \PHPCI\Controller { /** - * @var \b8\Store\BuildStore + * @var \PHPCI\Store\BuildStore */ protected $buildStore; /** - * @var \b8\Store\ProjectStore + * @var \PHPCI\Store\ProjectStore */ protected $projectStore; + /** + * @var \PHPCI\Store\ProjectGroupStore + */ + protected $groupStore; + /** * Initialise the controller, set up stores and services. */ @@ -39,6 +44,7 @@ class HomeController extends \PHPCI\Controller { $this->buildStore = b8\Store\Factory::getStore('Build'); $this->projectStore = b8\Store\Factory::getStore('Project'); + $this->groupStore = b8\Store\Factory::getStore('ProjectGroup'); } /** @@ -47,9 +53,6 @@ class HomeController extends \PHPCI\Controller public function index() { $this->layout->title = Lang::get('dashboard'); - - $projects = $this->projectStore->getWhere(array(), 50, 0, array(), array('title' => 'ASC')); - $builds = $this->buildStore->getLatestBuilds(null, 10); foreach ($builds as &$build) { @@ -57,8 +60,7 @@ class HomeController extends \PHPCI\Controller } $this->view->builds = $builds; - $this->view->projects = $projects['items']; - $this->view->summary = $this->getSummaryHtml($projects); + $this->view->groups = $this->getGroupInfo(); return $this->view->render(); } @@ -68,7 +70,9 @@ class HomeController extends \PHPCI\Controller */ public function latest() { - die($this->getLatestBuildsHtml()); + $this->response->disableLayout(); + $this->response->setContent($this->getLatestBuildsHtml()); + return $this->response; } /** @@ -76,8 +80,10 @@ class HomeController extends \PHPCI\Controller */ public function summary() { + $this->response->disableLayout(); $projects = $this->projectStore->getWhere(array(), 50, 0, array(), array('title' => 'ASC')); - die($this->getSummaryHtml($projects)); + $this->response->setContent($this->getSummaryHtml($projects)); + return $this->response; } /** @@ -88,12 +94,22 @@ class HomeController extends \PHPCI\Controller protected function getSummaryHtml($projects) { $summaryBuilds = array(); - $successes = array(); - $failures = array(); + $successes = array(); + $failures = array(); + $counts = array(); - foreach ($projects['items'] as $project) { + foreach ($projects as $project) { $summaryBuilds[$project->getId()] = $this->buildStore->getLatestBuilds($project->getId()); + $count = $this->buildStore->getWhere( + array('project_id' => $project->getId()), + 1, + 0, + array(), + array('id' => 'DESC') + ); + $counts[$project->getId()] = $count['count']; + $success = $this->buildStore->getLastBuildByStatus($project->getId(), Build::STATUS_SUCCESS); $failure = $this->buildStore->getLastBuildByStatus($project->getId(), Build::STATUS_FAILED); @@ -102,10 +118,11 @@ class HomeController extends \PHPCI\Controller } $summaryView = new b8\View('SummaryTable'); - $summaryView->projects = $projects['items']; - $summaryView->builds = $summaryBuilds; + $summaryView->projects = $projects; + $summaryView->builds = $summaryBuilds; $summaryView->successful = $successes; - $summaryView->failed = $failures; + $summaryView->failed = $failures; + $summaryView->counts = $counts; return $summaryView->render(); } @@ -126,4 +143,24 @@ class HomeController extends \PHPCI\Controller return $view->render(); } + + /** + * Get a summary of the project groups we have, and what projects they have in them. + * @return array + */ + protected function getGroupInfo() + { + $rtn = array(); + $groups = $this->groupStore->getWhere(array(), 100, 0, array(), array('title' => 'ASC')); + + foreach ($groups['items'] as $group) { + $thisGroup = array('title' => $group->getTitle()); + $projects = $this->projectStore->getByGroupId($group->getId()); + $thisGroup['projects'] = $projects['items']; + $thisGroup['summary'] = $this->getSummaryHtml($thisGroup['projects']); + $rtn[] = $thisGroup; + } + + return $rtn; + } } diff --git a/PHPCI/Controller/PluginController.php b/PHPCI/Controller/PluginController.php index ac829f7f..64cb1463 100644 --- a/PHPCI/Controller/PluginController.php +++ b/PHPCI/Controller/PluginController.php @@ -11,7 +11,6 @@ namespace PHPCI\Controller; use b8; use PHPCI\Helper\Lang; -use PHPCI\Model\Build; use PHPCI\Plugin\Util\ComposerPluginInformation; use PHPCI\Plugin\Util\FilesPluginInformation; use PHPCI\Plugin\Util\PluginInformationCollection; @@ -24,24 +23,6 @@ use PHPCI\Plugin\Util\PluginInformationCollection; */ class PluginController extends \PHPCI\Controller { - protected $required = array( - 'php', - 'ext-pdo', - 'ext-pdo_mysql', - 'block8/b8framework', - 'ircmaxell/password-compat', - 'swiftmailer/swiftmailer', - 'symfony/yaml', - 'symfony/console', - 'psr/log', - 'monolog/monolog', - 'pimple/pimple', - 'robmorgan/phinx', - ); - - protected $canInstall; - protected $composerPath; - /** * List all enabled plugins, installed and recommend packages. * @return string @@ -50,12 +31,8 @@ class PluginController extends \PHPCI\Controller { $this->requireAdmin(); - $this->view->canWrite = is_writable(APPLICATION_PATH . 'composer.json'); - $this->view->required = $this->required; - $json = $this->getComposerJson(); $this->view->installedPackages = $json['require']; - $this->view->suggestedPackages = $json['suggest']; $pluginInfo = new PluginInformationCollection(); $pluginInfo->add(FilesPluginInformation::newFromDir( @@ -72,46 +49,6 @@ class PluginController extends \PHPCI\Controller return $this->view->render(); } - /** - * Remove a given package. - */ - public function remove() - { - $this->requireAdmin(); - - $package = $this->getParam('package', null); - $json = $this->getComposerJson(); - - if (!in_array($package, $this->required)) { - unset($json['require'][$package]); - $this->setComposerJson($json); - - header('Location: ' . PHPCI_URL . 'plugin?r=' . $package); - die; - } - - header('Location: ' . PHPCI_URL); - die; - } - - /** - * Install a given package. - */ - public function install() - { - $this->requireAdmin(); - - $package = $this->getParam('package', null); - $version = $this->getParam('version', '*'); - - $json = $this->getComposerJson(); - $json['require'][$package] = $version; - $this->setComposerJson($json); - - header('Location: ' . PHPCI_URL . 'plugin?w=' . $package); - die; - } - /** * Get the json-decoded contents of the composer.json file. * @return mixed @@ -121,79 +58,4 @@ class PluginController extends \PHPCI\Controller $json = file_get_contents(APPLICATION_PATH . 'composer.json'); return json_decode($json, true); } - - /** - * Convert array to json and save composer.json - * - * @param $array - */ - protected function setComposerJson($array) - { - if (defined('JSON_PRETTY_PRINT')) { - $json = json_encode($array, JSON_PRETTY_PRINT); - } else { - $json = json_encode($array); - } - - file_put_contents(APPLICATION_PATH . 'composer.json', $json); - } - - /** - * Find a system binary. - * @param $binary - * @return null|string - */ - protected function findBinary($binary) - { - if (is_string($binary)) { - $binary = array($binary); - } - - foreach ($binary as $bin) { - // Check project root directory: - if (is_file(APPLICATION_PATH . $bin)) { - return APPLICATION_PATH . $bin; - } - - // Check Composer bin dir: - if (is_file(APPLICATION_PATH . 'vendor/bin/' . $bin)) { - return APPLICATION_PATH . 'vendor/bin/' . $bin; - } - - // Use "which" - $which = trim(shell_exec('which ' . $bin)); - - if (!empty($which)) { - return $which; - } - } - - return null; - } - - /** - * Perform a search on packagist.org. - */ - public function packagistSearch() - { - $searchQuery = $this->getParam('q', ''); - $http = new \b8\HttpClient(); - $http->setHeaders(array('User-Agent: PHPCI/1.0 (+https://www.phptesting.org)')); - $res = $http->get('https://packagist.org/search.json', array('q' => $searchQuery)); - - die(json_encode($res['body'])); - } - - /** - * Look up available versions of a given package on packagist.org - */ - public function packagistVersions() - { - $name = $this->getParam('p', ''); - $http = new \b8\HttpClient(); - $http->setHeaders(array('User-Agent: PHPCI/1.0 (+https://www.phptesting.org)')); - $res = $http->get('https://packagist.org/packages/'.$name.'.json'); - - die(json_encode($res['body'])); - } } diff --git a/PHPCI/Controller/ProjectController.php b/PHPCI/Controller/ProjectController.php index 01900aa0..72be46e5 100644 --- a/PHPCI/Controller/ProjectController.php +++ b/PHPCI/Controller/ProjectController.php @@ -10,17 +10,14 @@ namespace PHPCI\Controller; use b8; -use b8\Controller; use b8\Form; -use b8\Exception\HttpException\ForbiddenException; use b8\Exception\HttpException\NotFoundException; use b8\Store; +use PHPCI; use PHPCI\BuildFactory; use PHPCI\Helper\Github; use PHPCI\Helper\Lang; use PHPCI\Helper\SshKey; -use PHPCI\Model\Build; -use PHPCI\Model\Project; use PHPCI\Service\BuildService; use PHPCI\Service\ProjectService; @@ -30,7 +27,7 @@ use PHPCI\Service\ProjectService; * @package PHPCI * @subpackage Web */ -class ProjectController extends \PHPCI\Controller +class ProjectController extends PHPCI\Controller { /** * @var \PHPCI\Store\ProjectStore @@ -81,14 +78,15 @@ class ProjectController extends \PHPCI\Controller $pages = $builds[1] == 0 ? 1 : ceil($builds[1] / $per_page); if ($page > $pages) { - header('Location: '.PHPCI_URL.'project/view/'.$projectId); - die; + $response = new b8\Http\Response\RedirectResponse(); + $response->setHeader('Location', PHPCI_URL.'project/view/'.$projectId); + return $response; } $this->view->builds = $builds[0]; $this->view->total = $builds[1]; $this->view->project = $project; - $this->view->branch = urldecode($branch); + $this->view->branch = urldecode($branch); $this->view->branches = $this->projectStore->getKnownBranches($projectId); $this->view->page = $page; $this->view->pages = $pages; @@ -118,8 +116,13 @@ class ProjectController extends \PHPCI\Controller $email = $_SESSION['phpci_user']->getEmail(); $build = $this->buildService->createBuild($project, null, urldecode($branch), $email); - header('Location: '.PHPCI_URL.'build/view/' . $build->getId()); - exit; + if ($this->buildService->queueError) { + $_SESSION['global_error'] = Lang::get('add_to_queue_failed'); + } + + $response = new b8\Http\Response\RedirectResponse(); + $response->setHeader('Location', PHPCI_URL.'build/view/' . $build->getId()); + return $response; } /** @@ -132,8 +135,9 @@ class ProjectController extends \PHPCI\Controller $project = $this->projectStore->getById($projectId); $this->projectService->deleteProject($project); - header('Location: '.PHPCI_URL); - exit; + $response = new b8\Http\Response\RedirectResponse(); + $response->setHeader('Location', PHPCI_URL); + return $response; } /** @@ -143,7 +147,10 @@ class ProjectController extends \PHPCI\Controller { $branch = $this->getParam('branch', ''); $builds = $this->getLatestBuildsHtml($projectId, urldecode($branch)); - die($builds[0]); + + $this->response->disableLayout(); + $this->response->setContent($builds[0]); + return $this->response; } /** @@ -217,11 +224,14 @@ class ProjectController extends \PHPCI\Controller 'build_config' => $this->getParam('build_config', null), 'allow_public_status' => $this->getParam('allow_public_status', 0), 'branch' => $this->getParam('branch', null), + 'group' => $this->getParam('group_id', null), ); $project = $this->projectService->createProject($title, $type, $reference, $options); - header('Location: '.PHPCI_URL.'project/view/' . $project->getId()); - die; + + $response = new b8\Http\Response\RedirectResponse(); + $response->setHeader('Location', PHPCI_URL.'project/view/' . $project->getId()); + return $response; } } @@ -263,7 +273,7 @@ class ProjectController extends \PHPCI\Controller $view->type = 'edit'; $view->project = $project; $view->form = $form; - $view->key = null; + $view->key = $values['pubkey']; return $view->render(); } @@ -277,13 +287,16 @@ class ProjectController extends \PHPCI\Controller 'ssh_public_key' => $this->getParam('pubkey', null), 'build_config' => $this->getParam('build_config', null), 'allow_public_status' => $this->getParam('allow_public_status', 0), + 'archived' => $this->getParam('archived', 0), 'branch' => $this->getParam('branch', null), + 'group' => $this->getParam('group_id', null), ); $project = $this->projectService->updateProject($project, $title, $type, $reference, $options); - header('Location: '.PHPCI_URL.'project/view/' . $project->getId()); - die; + $response = new b8\Http\Response\RedirectResponse(); + $response->setHeader('Location', PHPCI_URL.'project/view/' . $project->getId()); + return $response; } /** @@ -305,10 +318,11 @@ class ProjectController extends \PHPCI\Controller 'remote' => Lang::get('remote'), 'local' => Lang::get('local'), 'hg' => Lang::get('hg'), + 'svn' => Lang::get('svn'), ); $field = Form\Element\Select::create('type', Lang::get('where_hosted'), true); - $field->setPattern('^(github|bitbucket|gitlab|remote|local|hg)'); + $field->setPattern('^(github|bitbucket|gitlab|remote|local|hg|svn)'); $field->setOptions($options); $field->setClass('form-control')->setContainerClass('form-group'); $form->addField($field); @@ -344,12 +358,32 @@ class ProjectController extends \PHPCI\Controller $field->setClass('form-control')->setContainerClass('form-group')->setValue('master'); $form->addField($field); + $field = Form\Element\Select::create('group_id', 'Project Group', true); + $field->setClass('form-control')->setContainerClass('form-group')->setValue(1); + + $groups = array(); + $groupStore = b8\Store\Factory::getStore('ProjectGroup'); + $groupList = $groupStore->getWhere(array(), 100, 0, array(), array('title' => 'ASC')); + + foreach ($groupList['items'] as $group) { + $groups[$group->getId()] = $group->getTitle(); + } + + $field->setOptions($groups); + $form->addField($field); + $field = Form\Element\Checkbox::create('allow_public_status', Lang::get('allow_public_status'), false); $field->setContainerClass('form-group'); $field->setCheckedValue(1); $field->setValue(0); $form->addField($field); + $field = Form\Element\Checkbox::create('archived', Lang::get('archived'), false); + $field->setContainerClass('form-group'); + $field->setCheckedValue(1); + $field->setValue(0); + $form->addField($field); + $field = new Form\Element\Submit(); $field->setValue(Lang::get('save_project')); $field->setContainerClass('form-group'); @@ -366,7 +400,10 @@ class ProjectController extends \PHPCI\Controller protected function githubRepositories() { $github = new Github(); - die(json_encode($github->getRepositories())); + + $response = new b8\Http\Response\JsonResponse(); + $response->setContent($github->getRepositories()); + return $response; } /** diff --git a/PHPCI/Controller/SessionController.php b/PHPCI/Controller/SessionController.php index c5f8b962..b68d61f7 100644 --- a/PHPCI/Controller/SessionController.php +++ b/PHPCI/Controller/SessionController.php @@ -43,14 +43,23 @@ class SessionController extends \PHPCI\Controller $isLoginFailure = false; if ($this->request->getMethod() == 'POST') { - $user = $this->userStore->getByEmail($this->getParam('email')); - - if ($user && password_verify($this->getParam('password', ''), $user->getHash())) { - $_SESSION['phpci_user_id'] = $user->getId(); - header('Location: ' . $this->getLoginRedirect()); - die; - } else { + $token = $this->getParam('token'); + if (!isset($token, $_SESSION['login_token']) || $token !== $_SESSION['login_token']) { $isLoginFailure = true; + } else { + unset($_SESSION['login_token']); + + $user = $this->userStore->getByEmail($this->getParam('email')); + + if ($user && password_verify($this->getParam('password', ''), $user->getHash())) { + session_regenerate_id(true); + $_SESSION['phpci_user_id'] = $user->getId(); + $response = new b8\Http\Response\RedirectResponse(); + $response->setHeader('Location', $this->getLoginRedirect()); + return $response; + } else { + $isLoginFailure = true; + } } } @@ -77,9 +86,15 @@ class SessionController extends \PHPCI\Controller $pwd->setClass('btn-success'); $form->addField($pwd); + $tokenValue = $this->generateToken(); + $_SESSION['login_token'] = $tokenValue; + $token = new b8\Form\Element\Hidden('token'); + $token->setValue($tokenValue); + $form->addField($token); + $this->view->form = $form->render(); $this->view->failed = $isLoginFailure; - + return $this->view->render(); } @@ -92,8 +107,10 @@ class SessionController extends \PHPCI\Controller unset($_SESSION['phpci_user_id']); session_destroy(); - header('Location: ' . PHPCI_URL); - die; + + $response = new b8\Http\Response\RedirectResponse(); + $response->setHeader('Location', PHPCI_URL); + return $response; } /** @@ -151,8 +168,9 @@ class SessionController extends \PHPCI\Controller $_SESSION['phpci_user'] = $this->userStore->save($user); $_SESSION['phpci_user_id'] = $user->getId(); - header('Location: ' . PHPCI_URL); - die; + $response = new b8\Http\Response\RedirectResponse(); + $response->setHeader('Location', PHPCI_URL); + return $response; } $this->view->id = $userId; @@ -176,4 +194,20 @@ class SessionController extends \PHPCI\Controller return $rtn; } + + /** Generate a random token. + * + * @return string + */ + protected function generateToken() + { + if (function_exists('openssl_random_pseudo_bytes')) { + return bin2hex(openssl_random_pseudo_bytes(16)); + } + + return sprintf("%04x", mt_rand(0, 0xFFFF)) + . sprintf("%04x", mt_rand(0, 0xFFFF)) + . sprintf("%04x", mt_rand(0, 0xFFFF)) + . sprintf("%04x", mt_rand(0, 0xFFFF)); + } } diff --git a/PHPCI/Controller/SettingsController.php b/PHPCI/Controller/SettingsController.php index 72df7c95..645e19a4 100644 --- a/PHPCI/Controller/SettingsController.php +++ b/PHPCI/Controller/SettingsController.php @@ -14,7 +14,6 @@ use b8\Form; use b8\HttpClient; use PHPCI\Controller; use PHPCI\Helper\Lang; -use PHPCI\Model\Build; use Symfony\Component\Yaml\Dumper; use Symfony\Component\Yaml\Parser; @@ -41,7 +40,7 @@ class SettingsController extends Controller parent::init(); $parser = new Parser(); - $yaml = file_get_contents(APPLICATION_PATH . 'PHPCI/config.yml'); + $yaml = file_get_contents(PHPCI_CONFIG_FILE); $this->settings = $parser->parse($yaml); } @@ -77,6 +76,7 @@ class SettingsController extends Controller $authSettings = $this->settings['phpci']['authentication_settings']; } + $this->view->configFile = PHPCI_CONFIG_FILE; $this->view->basicSettings = $this->getBasicForm($basicSettings); $this->view->buildSettings = $this->getBuildForm($buildSettings); $this->view->github = $this->getGithubForm(); @@ -102,13 +102,15 @@ class SettingsController extends Controller $this->settings['phpci']['github']['secret'] = $this->getParam('githubsecret', ''); $error = $this->storeSettings(); + $response = new b8\Http\Response\RedirectResponse(); + if ($error) { - header('Location: ' . PHPCI_URL . 'settings?saved=2'); + $response->setHeader('Location', PHPCI_URL . 'settings?saved=2'); } else { - header('Location: ' . PHPCI_URL . 'settings?saved=1'); + $response->setHeader('Location', PHPCI_URL . 'settings?saved=1'); } - die; + return $response; } /** @@ -123,13 +125,15 @@ class SettingsController extends Controller $error = $this->storeSettings(); + $response = new b8\Http\Response\RedirectResponse(); + if ($error) { - header('Location: ' . PHPCI_URL . 'settings?saved=2'); + $response->setHeader('Location', PHPCI_URL . 'settings?saved=2'); } else { - header('Location: ' . PHPCI_URL . 'settings?saved=1'); + $response->setHeader('Location', PHPCI_URL . 'settings?saved=1'); } - die; + return $response; } /** @@ -143,13 +147,15 @@ class SettingsController extends Controller $error = $this->storeSettings(); + $response = new b8\Http\Response\RedirectResponse(); + if ($error) { - header('Location: ' . PHPCI_URL . 'settings?saved=2'); + $response->setHeader('Location', PHPCI_URL . 'settings?saved=2'); } else { - header('Location: ' . PHPCI_URL . 'settings?saved=1'); + $response->setHeader('Location', PHPCI_URL . 'settings?saved=1'); } - die; + return $response; } /** @@ -162,13 +168,15 @@ class SettingsController extends Controller $this->settings['phpci']['basic'] = $this->getParams(); $error = $this->storeSettings(); + $response = new b8\Http\Response\RedirectResponse(); + if ($error) { - header('Location: ' . PHPCI_URL . 'settings?saved=2'); + $response->setHeader('Location', PHPCI_URL . 'settings?saved=2'); } else { - header('Location: ' . PHPCI_URL . 'settings?saved=1'); + $response->setHeader('Location', PHPCI_URL . 'settings?saved=1'); } - die; + return $response; } /** @@ -183,13 +191,15 @@ class SettingsController extends Controller $error = $this->storeSettings(); + $response = new b8\Http\Response\RedirectResponse(); + if ($error) { - header('Location: ' . PHPCI_URL . 'settings?saved=2'); + $response->setHeader('Location', PHPCI_URL . 'settings?saved=2'); } else { - header('Location: ' . PHPCI_URL . 'settings?saved=1'); + $response->setHeader('Location', PHPCI_URL . 'settings?saved=1'); } - die; + return $response; } /** @@ -212,14 +222,15 @@ class SettingsController extends Controller $this->settings['phpci']['github']['token'] = $resp['access_token']; $this->storeSettings(); - header('Location: ' . PHPCI_URL . 'settings?linked=1'); - die; + $response = new b8\Http\Response\RedirectResponse(); + $response->setHeader('Location', PHPCI_URL . 'settings?linked=1'); + return $response; } } - - header('Location: ' . PHPCI_URL . 'settings?linked=2'); - die; + $response = new b8\Http\Response\RedirectResponse(); + $response->setHeader('Location', PHPCI_URL . 'settings?linked=2'); + return $response; } /** @@ -231,7 +242,7 @@ class SettingsController extends Controller { $dumper = new Dumper(); $yaml = $dumper->dump($this->settings, 4); - file_put_contents(APPLICATION_PATH . 'PHPCI/config.yml', $yaml); + file_put_contents(PHPCI_CONFIG_FILE, $yaml); if (error_get_last()) { $error_get_last = error_get_last(); @@ -318,7 +329,7 @@ class SettingsController extends Controller $field->setContainerClass('form-group'); $form->addField($field); - $field = new Form\Element\Text('smtp_password'); + $field = new Form\Element\Password('smtp_password'); $field->setRequired(false); $field->setLabel(Lang::get('smtp_password')); $field->setClass('form-control'); @@ -340,7 +351,7 @@ class SettingsController extends Controller $form->addField($field); $field = new Form\Element\Select('smtp_encryption'); - $field->setOptions(['' => Lang::get('none'), 'tls' => Lang::get('tls'), 'ssl' => Lang::get('ssl')]); + $field->setOptions(array('' => Lang::get('none'), 'tls' => Lang::get('tls'), 'ssl' => Lang::get('ssl'))); $field->setRequired(false); $field->setLabel(Lang::get('use_smtp_encryption')); $field->setContainerClass('form-group'); @@ -376,7 +387,7 @@ class SettingsController extends Controller */ protected function canWriteConfig() { - return is_writeable(APPLICATION_PATH . 'PHPCI/config.yml'); + return is_writeable(PHPCI_CONFIG_FILE); } /** @@ -395,13 +406,13 @@ class SettingsController extends Controller $field->setLabel(Lang::get('failed_after')); $field->setClass('form-control'); $field->setContainerClass('form-group'); - $field->setOptions([ + $field->setOptions(array( 300 => Lang::get('5_mins'), 900 => Lang::get('15_mins'), 1800 => Lang::get('30_mins'), 3600 => Lang::get('1_hour'), 10800 => Lang::get('3_hours'), - ]); + )); $field->setValue(1800); $form->addField($field); @@ -433,7 +444,7 @@ class SettingsController extends Controller $field->setClass('form-control'); $field->setContainerClass('form-group'); $field->setOptions(Lang::getLanguageOptions()); - $field->setValue('en'); + $field->setValue(Lang::getLanguage()); $form->addField($field); diff --git a/PHPCI/Controller/UserController.php b/PHPCI/Controller/UserController.php index 7710c503..19a7313f 100644 --- a/PHPCI/Controller/UserController.php +++ b/PHPCI/Controller/UserController.php @@ -10,12 +10,10 @@ namespace PHPCI\Controller; use b8; -use b8\Exception\HttpException\ForbiddenException; use b8\Exception\HttpException\NotFoundException; use b8\Form; use PHPCI\Controller; use PHPCI\Helper\Lang; -use PHPCI\Model\User; use PHPCI\Service\UserService; /** @@ -125,6 +123,7 @@ class UserController extends Controller $lang->setLabel(Lang::get('language')); $lang->setRequired(true); $lang->setOptions(Lang::getLanguageOptions()); + $lang->setValue(Lang::getLanguage()); $form->addField($lang); $submit = new Form\Element\Submit(); @@ -175,8 +174,9 @@ class UserController extends Controller $this->userService->createUser($name, $email, $password, $isAdmin); - header('Location: '.PHPCI_URL.'user'); - die; + $response = new b8\Http\Response\RedirectResponse(); + $response->setHeader('Location', PHPCI_URL . 'user'); + return $response; } /** @@ -215,8 +215,9 @@ class UserController extends Controller $this->userService->updateUser($user, $name, $email, $password, $isAdmin); - header('Location: '.PHPCI_URL.'user'); - die; + $response = new b8\Http\Response\RedirectResponse(); + $response->setHeader('Location', PHPCI_URL . 'user'); + return $response; } /** @@ -288,7 +289,8 @@ class UserController extends Controller $this->userService->deleteUser($user); - header('Location: '.PHPCI_URL.'user'); - die; + $response = new b8\Http\Response\RedirectResponse(); + $response->setHeader('Location', PHPCI_URL . 'user'); + return $response; } } diff --git a/PHPCI/Controller/WebhookController.php b/PHPCI/Controller/WebhookController.php index a7652971..4b444d03 100644 --- a/PHPCI/Controller/WebhookController.php +++ b/PHPCI/Controller/WebhookController.php @@ -2,7 +2,7 @@ /** * PHPCI - Continuous Integration for PHP * - * @copyright Copyright 2014, Block 8 Limited. + * @copyright Copyright 2014-2015, Block 8 Limited. * @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md * @link https://www.phptesting.org/ */ @@ -11,32 +11,39 @@ namespace PHPCI\Controller; use b8; use b8\Store; +use Exception; use PHPCI\BuildFactory; -use PHPCI\Model\Build; +use PHPCI\Model\Project; use PHPCI\Service\BuildService; +use PHPCI\Store\BuildStore; +use PHPCI\Store\ProjectStore; /** * Webhook Controller - Processes webhook pings from BitBucket, Github, Gitlab, etc. + * * @author Dan Cryer * @author Sami Tikka * @author Alex Russell + * @author Guillaume Perréal * @package PHPCI * @subpackage Web + * + * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) */ -class WebhookController extends \PHPCI\Controller +class WebhookController extends \b8\Controller { /** - * @var \PHPCI\Store\BuildStore + * @var BuildStore */ protected $buildStore; /** - * @var \PHPCI\Store\ProjectStore + * @var ProjectStore */ protected $projectStore; /** - * @var \PHPCI\Service\BuildService + * @var BuildService */ protected $buildService; @@ -50,86 +57,147 @@ class WebhookController extends \PHPCI\Controller $this->buildService = new BuildService($this->buildStore); } - /** - * Called by Bitbucket POST service. + /** Handle the action, Ensuring to return a JsonResponse. + * + * @param string $action + * @param mixed $actionParams + * + * @return \b8\Http\Response */ - public function bitbucket($project) + public function handleAction($action, $actionParams) + { + $response = new b8\Http\Response\JsonResponse(); + try { + $data = parent::handleAction($action, $actionParams); + if (isset($data['responseCode'])) { + $response->setResponseCode($data['responseCode']); + unset($data['responseCode']); + } + $response->setContent($data); + } catch (Exception $ex) { + $response->setResponseCode(500); + $response->setContent(array('status' => 'failed', 'error' => $ex->getMessage())); + } + return $response; + } + + /** + * Called by Bitbucket. + */ + public function bitbucket($projectId) + { + $project = $this->fetchProject($projectId, 'bitbucket'); + + // Support both old services and new webhooks + if ($payload = $this->getParam('payload')) { + return $this->bitbucketService(json_decode($payload, true), $project); + } + + $payload = json_decode(file_get_contents("php://input"), true); + + if (empty($payload['push']['changes'])) { + // Invalid event from bitbucket + return [ + 'status' => 'failed', + 'commits' => [] + ]; + } + + return $this->bitbucketWebhook($payload, $project); + } + + /** + * Bitbucket webhooks. + */ + protected function bitbucketWebhook($payload, $project) + { + $results = array(); + $status = 'failed'; + foreach ($payload['push']['changes'] as $commit) { + try { + $email = $commit['new']['target']['author']['raw']; + $email = substr($email, 0, strpos($email, '>')); + $email = substr($email, strpos($email, '<') + 1); + + $results[$commit['new']['target']['hash']] = $this->createBuild( + $project, + $commit['new']['target']['hash'], + $commit['new']['name'], + $email, + $commit['new']['target']['message'] + ); + $status = 'ok'; + } catch (Exception $ex) { + $results[$commit['new']['target']['hash']] = array('status' => 'failed', 'error' => $ex->getMessage()); + } + } + + return array('status' => $status, 'commits' => $results); + } + + /** + * Bitbucket POST service. + */ + protected function bitbucketService($payload, $project) { $payload = json_decode($this->getParam('payload'), true); + $results = array(); + $status = 'failed'; foreach ($payload['commits'] as $commit) { try { $email = $commit['raw_author']; $email = substr($email, 0, strpos($email, '>')); $email = substr($email, strpos($email, '<') + 1); - $this->createBuild($project, $commit['raw_node'], $commit['branch'], $email, $commit['message']); - } catch (\Exception $ex) { - header('HTTP/1.1 500 Internal Server Error'); - header('Ex: ' . $ex->getMessage()); - die('FAIL'); + $results[$commit['raw_node']] = $this->createBuild( + $project, + $commit['raw_node'], + $commit['branch'], + $email, + $commit['message'] + ); + $status = 'ok'; + } catch (Exception $ex) { + $results[$commit['raw_node']] = array('status' => 'failed', 'error' => $ex->getMessage()); } } - die('OK'); + return array('status' => $status, 'commits' => $results); } /** * Called by POSTing to /webhook/git/?branch=&commit= * - * @param string $project + * @param string $projectId */ - public function git($project) + public function git($projectId) { - $branch = $this->getParam('branch'); + $project = $this->fetchProject($projectId, array('local', 'remote')); + $branch = $this->getParam('branch', $project->getBranch()); $commit = $this->getParam('commit'); $commitMessage = $this->getParam('message'); $committer = $this->getParam('committer'); - try { - if (empty($branch)) { - $branch = 'master'; - } - - if (empty($commit)) { - $commit = null; - } - - if (empty($commitMessage)) { - $commitMessage = null; - } - - if (empty($committer)) { - $committer = null; - } - - $this->createBuild($project, $commit, $branch, $committer, $commitMessage); - } catch (\Exception $ex) { - header('HTTP/1.1 400 Bad Request'); - header('Ex: ' . $ex->getMessage()); - die('FAIL'); - } - - die('OK'); + return $this->createBuild($project, $commit, $branch, $committer, $commitMessage); } /** * Called by Github Webhooks: */ - public function github($project) + public function github($projectId) { + $project = $this->fetchProject($projectId, 'github'); + switch ($_SERVER['CONTENT_TYPE']) { case 'application/json': $payload = json_decode(file_get_contents('php://input'), true); break; - case 'application/x-www-form-urlencoded': $payload = json_decode($this->getParam('payload'), true); break; - default: - header('HTTP/1.1 400 Bad Request'); - die('Request content type not supported'); + return array('status' => 'failed', 'error' => 'Content type not supported.', 'responseCode' => 401); } // Handle Pull Request web hooks: @@ -142,187 +210,244 @@ class WebhookController extends \PHPCI\Controller return $this->githubCommitRequest($project, $payload); } - header('HTTP/1.1 200 OK'); - die('This request type is not supported, this is not an error.'); + return array('status' => 'ignored', 'message' => 'Unusable payload.'); } /** * Handle the payload when Github sends a commit webhook. - * @param $project + * + * @param Project $project * @param array $payload + * @param b8\Http\Response\JsonResponse $response + * + * @return b8\Http\Response\JsonResponse */ - protected function githubCommitRequest($project, array $payload) + protected function githubCommitRequest(Project $project, array $payload) { // Github sends a payload when you close a pull request with a - // non-existant commit. We don't want this. + // non-existent commit. We don't want this. if (array_key_exists('after', $payload) && $payload['after'] === '0000000000000000000000000000000000000000') { - die('OK'); + return array('status' => 'ignored'); } - try { + if (isset($payload['commits']) && is_array($payload['commits'])) { + // If we have a list of commits, then add them all as builds to be tested: - if (isset($payload['commits']) && is_array($payload['commits'])) { - // If we have a list of commits, then add them all as builds to be tested: - - foreach ($payload['commits'] as $commit) { - if (!$commit['distinct']) { - continue; - } + $results = array(); + $status = 'failed'; + foreach ($payload['commits'] as $commit) { + if (!$commit['distinct']) { + $results[$commit['id']] = array('status' => 'ignored'); + continue; + } + try { $branch = str_replace('refs/heads/', '', $payload['ref']); $committer = $commit['committer']['email']; - $this->createBuild($project, $commit['id'], $branch, $committer, $commit['message']); + $results[$commit['id']] = $this->createBuild( + $project, + $commit['id'], + $branch, + $committer, + $commit['message'] + ); + $status = 'ok'; + } catch (Exception $ex) { + $results[$commit['id']] = array('status' => 'failed', 'error' => $ex->getMessage()); } - } elseif (substr($payload['ref'], 0, 10) == 'refs/tags/') { - // If we don't, but we're dealing with a tag, add that instead: - $branch = str_replace('refs/tags/', 'Tag: ', $payload['ref']); - $committer = $payload['pusher']['email']; - $message = $payload['head_commit']['message']; - $this->createBuild($project, $payload['after'], $branch, $committer, $message); } - - } catch (\Exception $ex) { - header('HTTP/1.1 500 Internal Server Error'); - header('Ex: ' . $ex->getMessage()); - die('FAIL'); + return array('status' => $status, 'commits' => $results); } - die('OK'); + if (substr($payload['ref'], 0, 10) == 'refs/tags/') { + // If we don't, but we're dealing with a tag, add that instead: + $branch = str_replace('refs/tags/', 'Tag: ', $payload['ref']); + $committer = $payload['pusher']['email']; + $message = $payload['head_commit']['message']; + return $this->createBuild($project, $payload['after'], $branch, $committer, $message); + } + + return array('status' => 'ignored', 'message' => 'Unusable payload.'); } /** * Handle the payload when Github sends a Pull Request webhook. - * @param $projectId + * + * @param Project $project * @param array $payload */ - protected function githubPullRequest($projectId, array $payload) + protected function githubPullRequest(Project $project, array $payload) { // We only want to know about open pull requests: if (!in_array($payload['action'], array('opened', 'synchronize', 'reopened'))) { - die('OK'); + return array('status' => 'ok'); } - try { - $headers = array(); - $token = \b8\Config::getInstance()->get('phpci.github.token'); + $headers = array(); + $token = \b8\Config::getInstance()->get('phpci.github.token'); - if (!empty($token)) { - $headers[] = 'Authorization: token ' . $token; + if (!empty($token)) { + $headers[] = 'Authorization: token ' . $token; + } + + $url = $payload['pull_request']['commits_url']; + $http = new \b8\HttpClient(); + $http->setHeaders($headers); + $response = $http->get($url); + + // Check we got a success response: + if (!$response['success']) { + throw new Exception('Could not get commits, failed API request.'); + } + + $results = array(); + $status = 'failed'; + foreach ($response['body'] as $commit) { + // Skip all but the current HEAD commit ID: + $id = $commit['sha']; + if ($id != $payload['pull_request']['head']['sha']) { + $results[$id] = array('status' => 'ignored', 'message' => 'not branch head'); + continue; } - $url = $payload['pull_request']['commits_url']; - $http = new \b8\HttpClient(); - $http->setHeaders($headers); - $response = $http->get($url); - - // Check we got a success response: - if (!$response['success']) { - header('HTTP/1.1 500 Internal Server Error'); - header('Ex: Could not get commits, failed API request.'); - die('FAIL'); - } - - foreach ($response['body'] as $commit) { + try { $branch = str_replace('refs/heads/', '', $payload['pull_request']['base']['ref']); $committer = $commit['commit']['author']['email']; $message = $commit['commit']['message']; + $remoteUrlKey = $payload['pull_request']['head']['repo']['private'] ? 'ssh_url' : 'clone_url'; + $extra = array( 'build_type' => 'pull_request', 'pull_request_id' => $payload['pull_request']['id'], 'pull_request_number' => $payload['number'], 'remote_branch' => $payload['pull_request']['head']['ref'], - 'remote_url' => $payload['pull_request']['head']['repo']['clone_url'], + 'remote_url' => $payload['pull_request']['head']['repo'][$remoteUrlKey], ); - $this->createBuild($projectId, $commit['sha'], $branch, $committer, $message, $extra); + $results[$id] = $this->createBuild($project, $id, $branch, $committer, $message, $extra); + $status = 'ok'; + } catch (Exception $ex) { + $results[$id] = array('status' => 'failed', 'error' => $ex->getMessage()); } - } catch (\Exception $ex) { - header('HTTP/1.1 500 Internal Server Error'); - header('Ex: ' . $ex->getMessage()); - die('FAIL'); } - die('OK'); + return array('status' => $status, 'commits' => $results); } /** * Called by Gitlab Webhooks: */ - public function gitlab($project) + public function gitlab($projectId) { + $project = $this->fetchProject($projectId, 'gitlab'); + $payloadString = file_get_contents("php://input"); $payload = json_decode($payloadString, true); - try { + // build on merge request events + if (isset($payload['object_kind']) && $payload['object_kind'] == 'merge_request') { + $attributes = $payload['object_attributes']; + if ($attributes['state'] == 'opened' || $attributes['state'] == 'reopened') { + $branch = $attributes['source_branch']; + $commit = $attributes['last_commit']; + $committer = $commit['author']['email']; - - // build on merge request events - if (isset($payload['object_kind']) && $payload['object_kind'] == 'merge_request') { - $attributes = $payload['object_attributes']; - if ($attributes['state'] == 'opened' || $attributes['state'] == 'reopened') { - - $branch = $attributes['source_branch']; - $commit = $attributes['last_commit']; - $committer = $commit['author']['email']; - - $this->createBuild($project, $commit['id'], $branch, $committer, $commit['message']); - } + return $this->createBuild($project, $commit['id'], $branch, $committer, $commit['message']); } - - // build on push events - if (isset($payload['commits']) && is_array($payload['commits'])) { - // If we have a list of commits, then add them all as builds to be tested: - - foreach ($payload['commits'] as $commit) { - $branch = str_replace('refs/heads/', '', $payload['ref']); - $committer = $commit['author']['email']; - $this->createBuild($project, $commit['id'], $branch, $committer, $commit['message']); - } - } - - } catch (\Exception $ex) { - header('HTTP/1.1 500 Internal Server Error'); - header('Ex: ' . $ex->getMessage()); - die('FAIL'); } - die('OK'); + // build on push events + if (isset($payload['commits']) && is_array($payload['commits'])) { + // If we have a list of commits, then add them all as builds to be tested: + + $results = array(); + $status = 'failed'; + foreach ($payload['commits'] as $commit) { + try { + $branch = str_replace('refs/heads/', '', $payload['ref']); + $committer = $commit['author']['email']; + $results[$commit['id']] = $this->createBuild( + $project, + $commit['id'], + $branch, + $committer, + $commit['message'] + ); + $status = 'ok'; + } catch (Exception $ex) { + $results[$commit['id']] = array('status' => 'failed', 'error' => $ex->getMessage()); + } + } + return array('status' => $status, 'commits' => $results); + } + + return array('status' => 'ignored', 'message' => 'Unusable payload.'); } /** * Wrapper for creating a new build. - * @param $projectId - * @param $commitId - * @param $branch - * @param $committer - * @param $commitMessage - * @param null $extra - * @return bool - * @throws \Exception + * + * @param Project $project + * @param string $commitId + * @param string $branch + * @param string $committer + * @param string $commitMessage + * @param array $extra + * + * @return array + * + * @throws Exception */ - protected function createBuild($projectId, $commitId, $branch, $committer, $commitMessage, $extra = null) - { + protected function createBuild( + Project $project, + $commitId, + $branch, + $committer, + $commitMessage, + array $extra = null + ) { // Check if a build already exists for this commit ID: - $builds = $this->buildStore->getByProjectAndCommit($projectId, $commitId); + $builds = $this->buildStore->getByProjectAndCommit($project->getId(), $commitId); if ($builds['count']) { - return true; - } - - $project = $this->projectStore->getById($projectId); - - if (empty($project)) { - throw new \Exception('Project does not exist:' . $projectId); + return array( + 'status' => 'ignored', + 'message' => sprintf('Duplicate of build #%d', $builds['items'][0]->getId()) + ); } // If not, create a new build job for it: $build = $this->buildService->createBuild($project, $commitId, $branch, $committer, $commitMessage, $extra); - $build = BuildFactory::getBuild($build); - // Send a status postback if the build type provides one: - $build->sendStatusPostback(); + return array('status' => 'ok', 'buildID' => $build->getID()); + } - return true; + /** + * Fetch a project and check its type. + * + * @param int $projectId + * @param array|string $expectedType + * + * @return Project + * + * @throws Exception If the project does not exist or is not of the expected type. + */ + protected function fetchProject($projectId, $expectedType) + { + $project = $this->projectStore->getById($projectId); + + if (empty($projectId)) { + throw new Exception('Project does not exist: ' . $projectId); + } + + if (is_array($expectedType) + ? !in_array($project->getType(), $expectedType) + : $project->getType() !== $expectedType + ) { + throw new Exception('Wrong project type: ' . $project->getType()); + } + + return $project; } } diff --git a/PHPCI/ErrorHandler.php b/PHPCI/ErrorHandler.php new file mode 100644 index 00000000..d268965d --- /dev/null +++ b/PHPCI/ErrorHandler.php @@ -0,0 +1,68 @@ + 'Warning', + E_NOTICE => 'Notice', + E_USER_ERROR => 'User Error', + E_USER_WARNING => 'User Warning', + E_USER_NOTICE => 'User Notice', + E_STRICT => 'Runtime Notice', + E_RECOVERABLE_ERROR => 'Catchable Fatal Error', + E_DEPRECATED => 'Deprecated', + E_USER_DEPRECATED => 'User Deprecated', + ); + + /** + * Registers an instance of the error handler to throw ErrorException. + */ + public static function register() + { + $handler = new static(); + set_error_handler(array($handler, 'handleError')); + } + + /** + * @param integer $level + * @param string $message + * @param string $file + * @param integer $line + * + * @throws \ErrorException + * + * @internal + */ + public function handleError($level, $message, $file, $line) + { + if (error_reporting() & $level === 0) { + return; + } + + $exceptionLevel = isset($this->levels[$level]) ? $this->levels[$level] : $level; + throw new \ErrorException( + sprintf('%s: %s in %s line %d', $exceptionLevel, $message, $file, $line), + 0, + $level, + $file, + $line + ); + } +} diff --git a/PHPCI/Helper/AnsiConverter.php b/PHPCI/Helper/AnsiConverter.php new file mode 100644 index 00000000..7df6663c --- /dev/null +++ b/PHPCI/Helper/AnsiConverter.php @@ -0,0 +1,55 @@ +convert($text); + } + + /** + * Do not instantiate this class. + */ + private function __construct() + { + } +} diff --git a/PHPCI/Helper/BaseCommandExecutor.php b/PHPCI/Helper/BaseCommandExecutor.php index 28247ebc..b3b47f7b 100644 --- a/PHPCI/Helper/BaseCommandExecutor.php +++ b/PHPCI/Helper/BaseCommandExecutor.php @@ -9,9 +9,9 @@ namespace PHPCI\Helper; -use \PHPCI\Logging\BuildLogger; +use Exception; +use PHPCI\Logging\BuildLogger; use Psr\Log\LogLevel; -use PHPCI\Helper\Lang; /** * Handles running system commands with variables. @@ -20,7 +20,7 @@ use PHPCI\Helper\Lang; abstract class BaseCommandExecutor implements CommandExecutor { /** - * @var \PHPCI\Logging\BuildLogger + * @var BuildLogger */ protected $logger; @@ -62,9 +62,7 @@ abstract class BaseCommandExecutor implements CommandExecutor $this->logger = $logger; $this->quiet = $quiet; $this->verbose = $verbose; - $this->lastOutput = array(); - $this->rootDir = $rootDir; } @@ -78,6 +76,7 @@ abstract class BaseCommandExecutor implements CommandExecutor $this->lastOutput = array(); $command = call_user_func_array('sprintf', $args); + $this->logger->logDebug($command); if ($this->quiet) { $this->logger->log('Executing: ' . $command); @@ -91,8 +90,7 @@ abstract class BaseCommandExecutor implements CommandExecutor ); $pipes = array(); - - $process = proc_open($command, $descriptorSpec, $pipes, dirname($this->buildPath), null); + $process = proc_open($command, $descriptorSpec, $pipes, $this->buildPath, null); if (is_resource($process)) { fclose($pipes[0]); @@ -146,13 +144,12 @@ abstract class BaseCommandExecutor implements CommandExecutor /** * Find a binary required by a plugin. * @param string $binary - * @param null $buildPath + * @param bool $quiet * @return null|string */ - public function findBinary($binary, $buildPath = null) + public function findBinary($binary, $quiet = false) { - $binaryPath = null; - $composerBin = $this->getComposerBinDir(realpath($buildPath)); + $composerBin = $this->getComposerBinDir(realpath($this->buildPath)); if (is_string($binary)) { $binary = array($binary); @@ -162,32 +159,31 @@ abstract class BaseCommandExecutor implements CommandExecutor $this->logger->log(Lang::get('looking_for_binary', $bin), LogLevel::DEBUG); if (is_dir($composerBin) && is_file($composerBin.'/'.$bin)) { - $this->logger->log(Lang::get('found_in_path', $composerBin, $bin), LogLevel::DEBUG); - $binaryPath = $composerBin . '/' . $bin; - break; + return $composerBin . '/' . $bin; } if (is_file($this->rootDir . $bin)) { $this->logger->log(Lang::get('found_in_path', 'root', $bin), LogLevel::DEBUG); - $binaryPath = $this->rootDir . $bin; - break; + return $this->rootDir . $bin; } if (is_file($this->rootDir . 'vendor/bin/' . $bin)) { $this->logger->log(Lang::get('found_in_path', 'vendor/bin', $bin), LogLevel::DEBUG); - $binaryPath = $this->rootDir . 'vendor/bin/' . $bin; - break; + return $this->rootDir . 'vendor/bin/' . $bin; } $findCmdResult = $this->findGlobalBinary($bin); if (is_file($findCmdResult)) { $this->logger->log(Lang::get('found_in_path', '', $bin), LogLevel::DEBUG); - $binaryPath = $findCmdResult; - break; + return $findCmdResult; } } - return $binaryPath; + + if ($quiet) { + return; + } + throw new Exception(Lang::get('could_not_find', implode('/', $binary))); } /** @@ -219,4 +215,13 @@ abstract class BaseCommandExecutor implements CommandExecutor } return null; } + + /** + * Set the buildPath property. + * @param string $path + */ + public function setBuildPath($path) + { + $this->buildPath = $path; + } } diff --git a/PHPCI/Helper/BuildInterpolator.php b/PHPCI/Helper/BuildInterpolator.php index fbadbc30..1e7222bb 100644 --- a/PHPCI/Helper/BuildInterpolator.php +++ b/PHPCI/Helper/BuildInterpolator.php @@ -38,6 +38,7 @@ class BuildInterpolator $this->interpolation_vars['%COMMIT%'] = $build->getCommitId(); $this->interpolation_vars['%SHORT_COMMIT%'] = substr($build->getCommitId(), 0, 7); $this->interpolation_vars['%COMMIT_EMAIL%'] = $build->getCommitterEmail(); + $this->interpolation_vars['%COMMIT_MESSAGE%'] = $build->getCommitMessage(); $this->interpolation_vars['%COMMIT_URI%'] = $build->getCommitLink(); $this->interpolation_vars['%BRANCH%'] = $build->getBranch(); $this->interpolation_vars['%BRANCH_URI%'] = $build->getBranchLink(); @@ -49,6 +50,7 @@ class BuildInterpolator $this->interpolation_vars['%BUILD_URI%'] = $phpCiUrl . "build/view/" . $build->getId(); $this->interpolation_vars['%PHPCI_COMMIT%'] = $this->interpolation_vars['%COMMIT%']; $this->interpolation_vars['%PHPCI_SHORT_COMMIT%'] = $this->interpolation_vars['%SHORT_COMMIT%']; + $this->interpolation_vars['%PHPCI_COMMIT_MESSAGE%'] = $this->interpolation_vars['%COMMIT_MESSAGE%']; $this->interpolation_vars['%PHPCI_COMMIT_EMAIL%'] = $this->interpolation_vars['%COMMIT_EMAIL%']; $this->interpolation_vars['%PHPCI_COMMIT_URI%'] = $this->interpolation_vars['%COMMIT_URI%']; $this->interpolation_vars['%PHPCI_PROJECT%'] = $this->interpolation_vars['%PROJECT%']; @@ -61,6 +63,7 @@ class BuildInterpolator putenv('PHPCI=1'); putenv('PHPCI_COMMIT=' . $this->interpolation_vars['%COMMIT%']); putenv('PHPCI_SHORT_COMMIT=' . $this->interpolation_vars['%SHORT_COMMIT%']); + putenv('PHPCI_COMMIT_MESSAGE=' . $this->interpolation_vars['%COMMIT_MESSAGE%']); putenv('PHPCI_COMMIT_EMAIL=' . $this->interpolation_vars['%COMMIT_EMAIL%']); putenv('PHPCI_COMMIT_URI=' . $this->interpolation_vars['%COMMIT_URI%']); putenv('PHPCI_PROJECT=' . $this->interpolation_vars['%PROJECT%']); diff --git a/PHPCI/Helper/CommandExecutor.php b/PHPCI/Helper/CommandExecutor.php index d83f0c6b..4f0028eb 100644 --- a/PHPCI/Helper/CommandExecutor.php +++ b/PHPCI/Helper/CommandExecutor.php @@ -26,8 +26,17 @@ interface CommandExecutor /** * Find a binary required by a plugin. * @param string $binary - * @param string $buildPath the current build path + * @param bool $quiet Returns null instead of throwing an execption. + * * @return null|string + * + * @throws \Exception when no binary has been found and $quiet is false. */ - public function findBinary($binary, $buildPath = null); + public function findBinary($binary, $quiet = false); + + /** + * Set the buildPath property. + * @param string $path + */ + public function setBuildPath($path); } diff --git a/PHPCI/Helper/Diff.php b/PHPCI/Helper/Diff.php new file mode 100644 index 00000000..5dcb5388 --- /dev/null +++ b/PHPCI/Helper/Diff.php @@ -0,0 +1,62 @@ +isHtml = $isHtml; diff --git a/PHPCI/Helper/Github.php b/PHPCI/Helper/Github.php index b83b06c3..67173eb4 100644 --- a/PHPCI/Helper/Github.php +++ b/PHPCI/Helper/Github.php @@ -48,24 +48,18 @@ class Github $res = $http->get($url, $params); foreach ($res['body'] as $item) { - $results[] = $item; - } foreach ($res['headers'] as $header) { - if (preg_match('/^Link: <([^>]+)>; rel="next"/', $header, $r)) { - $host = parse_url($r[1]); parse_str($host['query'], $params); $results = $this->makeRecursiveRequest($host['path'], $params, $results); break; - } - } return $results; @@ -79,7 +73,7 @@ class Github $token = Config::getInstance()->get('phpci.github.token'); if (!$token) { - die(json_encode(null)); + return null; } $cache = Cache::getCache(Cache::TYPE_APC); @@ -108,4 +102,74 @@ class Github return $rtn; } + + /** + * Create a comment on a specific file (and commit) in a Github Pull Request. + * @param $repo + * @param $pullId + * @param $commitId + * @param $file + * @param $line + * @param $comment + * @return null + */ + public function createPullRequestComment($repo, $pullId, $commitId, $file, $line, $comment) + { + $token = Config::getInstance()->get('phpci.github.token'); + + if (!$token) { + return null; + } + + $url = '/repos/' . strtolower($repo) . '/pulls/' . $pullId . '/comments'; + + $params = array( + 'body' => $comment, + 'commit_id' => $commitId, + 'path' => $file, + 'position' => $line, + ); + + $http = new HttpClient('https://api.github.com'); + $http->setHeaders(array( + 'Content-Type: application/x-www-form-urlencoded', + 'Authorization: Basic ' . base64_encode($token . ':x-oauth-basic'), + )); + + $http->post($url, json_encode($params)); + } + + /** + * Create a comment on a Github commit. + * @param $repo + * @param $commitId + * @param $file + * @param $line + * @param $comment + * @return null + */ + public function createCommitComment($repo, $commitId, $file, $line, $comment) + { + $token = Config::getInstance()->get('phpci.github.token'); + + if (!$token) { + return null; + } + + $url = '/repos/' . strtolower($repo) . '/commits/' . $commitId . '/comments'; + + $params = array( + 'body' => $comment, + 'path' => $file, + 'position' => $line, + ); + + $http = new HttpClient('https://api.github.com'); + $http->setHeaders(array( + 'Content-Type: application/x-www-form-urlencoded', + 'Authorization: Basic ' . base64_encode($token . ':x-oauth-basic'), + )); + + $http->post($url, json_encode($params)); + } } diff --git a/PHPCI/Helper/Lang.php b/PHPCI/Helper/Lang.php index 1877426c..42027cee 100644 --- a/PHPCI/Helper/Lang.php +++ b/PHPCI/Helper/Lang.php @@ -13,6 +13,7 @@ use b8\Config; /** * Languages Helper Class - Handles loading strings files and the strings within them. + * * @package PHPCI\Helper */ class Lang @@ -23,6 +24,7 @@ class Lang /** * Get a specific string from the language file. + * * @param $string * @return mixed|string */ @@ -48,6 +50,7 @@ class Lang /** * Get the currently active language. + * * @return string|null */ public static function getLanguage() @@ -57,7 +60,9 @@ class Lang /** * Try and load a language, and if successful, set it for use throughout the system. + * * @param $language + * * @return bool */ public static function setLanguage($language) @@ -73,6 +78,7 @@ class Lang /** * Return a list of available languages and their names. + * * @return array */ public static function getLanguageOptions() @@ -90,6 +96,7 @@ class Lang /** * Get the strings for the currently active language. + * * @return string[] */ public static function getStrings() @@ -99,6 +106,7 @@ class Lang /** * Initialise the Language helper, try load the language file for the user's browser or the configured default. + * * @param Config $config */ public static function init(Config $config) @@ -137,6 +145,7 @@ class Lang /** * Load a specific language file. + * * @return string[]|null */ protected static function loadLanguage() @@ -147,7 +156,7 @@ class Lang return null; } - require_once($langFile); + require($langFile); if (is_null($strings) || !is_array($strings) || !count($strings)) { return null; @@ -168,4 +177,24 @@ class Lang } } } + + /** + * Create a time tag for localization. + * + * See http://momentjs.com/docs/#/displaying/format/ for a list of supported formats. + * + * @param \DateTime $dateTime The dateTime to represent. + * @param string $format The moment.js format to use. + * + * @return string The formatted tag. + */ + public static function formatDateTime(\DateTime $dateTime, $format = 'lll') + { + return sprintf( + '', + $dateTime->format(\DateTime::ISO8601), + $format, + $dateTime->format(\DateTime::RFC2822) + ); + } } diff --git a/PHPCI/Helper/LoginIsDisabled.php b/PHPCI/Helper/LoginIsDisabled.php index 208aac23..ec23858c 100644 --- a/PHPCI/Helper/LoginIsDisabled.php +++ b/PHPCI/Helper/LoginIsDisabled.php @@ -9,8 +9,10 @@ namespace PHPCI\Helper; +use b8\Config; + /** -* Login Is Disabled Helper - Checks if login is disalbed in the view +* Login Is Disabled Helper - Checks if login is disabled in the view * @author Stephen Ball * @package PHPCI * @subpackage Web @@ -18,7 +20,7 @@ namespace PHPCI\Helper; class LoginIsDisabled { /** - * Checks if + * Checks if * @param $method * @param array $params * @return mixed|null @@ -27,7 +29,7 @@ class LoginIsDisabled { unset($method, $params); - $config = b8\Config::getInstance(); + $config = Config::getInstance(); $state = (bool) $config->get('phpci.authentication_settings.state', false); return (false !== $state); diff --git a/PHPCI/Helper/MailerFactory.php b/PHPCI/Helper/MailerFactory.php index 641c06b9..c84c068d 100644 --- a/PHPCI/Helper/MailerFactory.php +++ b/PHPCI/Helper/MailerFactory.php @@ -71,7 +71,7 @@ class MailerFactory } else { // Check defaults - switch($configName) { + switch ($configName) { case 'smtp_address': return "localhost"; case 'default_mailto_address': diff --git a/PHPCI/Helper/SshKey.php b/PHPCI/Helper/SshKey.php index ca12a815..932686f2 100644 --- a/PHPCI/Helper/SshKey.php +++ b/PHPCI/Helper/SshKey.php @@ -39,9 +39,9 @@ class SshKey $return = array('private_key' => '', 'public_key' => ''); - if ($this->canGenerateKeys()) { - shell_exec('ssh-keygen -q -t rsa -b 2048 -f '.$keyFile.' -N "" -C "deploy@phpci"'); + $output = @shell_exec('ssh-keygen -t rsa -b 2048 -f '.$keyFile.' -N "" -C "deploy@phpci"'); + if (!empty($output)) { $pub = file_get_contents($keyFile . '.pub'); $prv = file_get_contents($keyFile); @@ -56,16 +56,4 @@ class SshKey return $return; } - - /** - * Checks whether or not we can generate keys, by quietly test running ssh-keygen. - * @return bool - */ - public function canGenerateKeys() - { - $keygen = @shell_exec('ssh-keygen -h'); - $canGenerateKeys = !empty($keygen); - - return $canGenerateKeys; - } } diff --git a/PHPCI/Helper/WindowsCommandExecutor.php b/PHPCI/Helper/WindowsCommandExecutor.php index aa01fea4..a1d0889f 100644 --- a/PHPCI/Helper/WindowsCommandExecutor.php +++ b/PHPCI/Helper/WindowsCommandExecutor.php @@ -22,6 +22,9 @@ class WindowsCommandExecutor extends BaseCommandExecutor */ protected function findGlobalBinary($binary) { - return trim(shell_exec('where ' . $binary)); + $command = sprintf('where %s', $binary); + $result = shell_exec($command); + + return trim($result); } } diff --git a/PHPCI/Languages/lang.da.php b/PHPCI/Languages/lang.da.php index 12ed31e2..d7a0df59 100644 --- a/PHPCI/Languages/lang.da.php +++ b/PHPCI/Languages/lang.da.php @@ -39,6 +39,7 @@ PHPCI', 'reset_email_title' => 'PHPCI Adgangskode-nulstilling for %s', 'reset_invalid' => 'Ugyldig anmodning om adgangskode-nulstilling.', 'email_address' => 'Email-addresse', + 'login' => 'Login / Email Address', 'password' => 'Adgangskode', 'log_in' => 'Log ind', @@ -112,6 +113,8 @@ i din foretrukne hosting-platform.', (hvis du ikke har mulighed for at tilføje en phpci.yml fil i projektets repository)', 'default_branch' => 'Default branch navn', 'allow_public_status' => 'Tillad offentlig status-side og -billede for dette projekt?', + 'archived' => 'Archived', + 'archived_menu' => 'Archived', 'save_project' => 'Gem Projekt', 'error_mercurial' => 'Mercurial repository-URL skal starte med http:// eller https://', @@ -125,6 +128,7 @@ i din foretrukne hosting-platform.', 'all_branches' => 'Alle branches', 'builds' => 'Builds', 'id' => 'ID', + 'date' => 'Date', 'project' => 'Projekt', 'commit' => 'Commit', 'branch' => 'Branch', @@ -166,6 +170,7 @@ Services sektionen under dit Bitbucket-repository.', 'lines_of_code' => 'Kode-linjer', 'build_log' => 'Build-log', 'quality_trend' => 'Kvalitets-trend', + 'codeception_errors' => 'Codeception-fejl', 'phpmd_warnings' => 'PHPMD-advarsler', 'phpcs_warnings' => 'PHPCS-advarsler', 'phpcs_errors' => 'PHPCS-fejl', @@ -174,6 +179,7 @@ Services sektionen under dit Bitbucket-repository.', 'phpdoccheck_warnings' => 'Manglende Docblocks', 'issues' => 'Sager', + 'codeception' => 'Codeception', 'phpcpd' => 'PHP Copy/Paste Detector', 'phpcs' => 'PHP Code Sniffer', 'phpdoccheck' => 'Manglende Docblocks', @@ -190,14 +196,20 @@ Services sektionen under dit Bitbucket-repository.', 'end' => 'Slut', 'from' => 'Fra', 'to' => 'Til', - 'suite' => 'Suite', - 'test' => 'Test', 'result' => 'Resultat', 'ok' => 'OK', 'took_n_seconds' => 'Tog %d sekunder', 'build_created' => 'Build Oprettet', 'build_started' => 'Build Startet', 'build_finished' => 'Build Afsluttet', + 'test_message' => 'Message', + 'test_no_message' => 'No message', + 'test_success' => 'Successful: %d', + 'test_fail' => 'Failures: %d', + 'test_skipped' => 'Skipped: %d', + 'test_error' => 'Errors: %d', + 'test_todo' => 'Todos: %d', + 'test_total' => '%d test(s)', // Users 'name' => 'Navn', @@ -293,15 +305,15 @@ du kører composer update.', Kontrollér venligst nedenstående fejl før du fortsætter.', 'must_be_valid_email' => 'Skal være en gyldig email-adresse.', 'must_be_valid_url' => 'Skal være en gyldig URL.', - 'enter_name' => 'Administrator-navn:', - 'enter_email' => 'Administrators email-adresse:', - 'enter_password' => 'Administrator-adgangskode:', - 'enter_phpci_url' => 'Din PHPCI URL (eksempelvis "http://phpci.local"):', + 'enter_name' => 'Administrator-navn: ', + 'enter_email' => 'Administrators email-adresse: ', + 'enter_password' => 'Administrator-adgangskode: ', + 'enter_phpci_url' => 'Din PHPCI URL (eksempelvis "http://phpci.local"): ', - 'enter_db_host' => 'Indtast dit MySQL-hostnavn [localhost]:', - 'enter_db_name' => 'Indtast dit MySQL database-navn [phpci]:', - 'enter_db_user' => 'Indtast dit MySQL-brugernavn [phpci]:', - 'enter_db_pass' => 'Indtast dit MySQL-password:', + 'enter_db_host' => 'Indtast dit MySQL-hostnavn [localhost]: ', + 'enter_db_name' => 'Indtast dit MySQL database-navn [phpci]: ', + 'enter_db_user' => 'Indtast dit MySQL-brugernavn [phpci]: ', + 'enter_db_pass' => 'Indtast dit MySQL-password: ', 'could_not_connect' => 'PHPCI kunne ikke forbinde til MySQL med de angivning oplysninger. Forsøg igen.', 'setting_up_db' => 'Indlæser database...', 'user_created' => 'Brugerkonto oprettet!', @@ -328,6 +340,12 @@ Kontrollér venligst nedenstående fejl før du fortsætter.', 'create_admin_user' => 'Tilføj en administrator', 'incorrect_format' => 'Forkert format', + // Create Build Command + 'create_build_project' => 'Create a build for a project', + 'project_id_argument' => 'A project ID', + 'commit_id_option' => 'Commit ID to build', + 'branch_name_option' => 'Branch to build', + // Run Command 'run_all_pending' => 'Kør alle PHPCI builds i køen.', 'finding_builds' => 'Finder builds der skal køres', diff --git a/PHPCI/Languages/lang.de.php b/PHPCI/Languages/lang.de.php index 36346b74..8e5bb3b2 100644 --- a/PHPCI/Languages/lang.de.php +++ b/PHPCI/Languages/lang.de.php @@ -13,7 +13,7 @@ $strings = array( // Log in: 'log_in_to_phpci' => 'In PHPCI einloggen', - 'login_error' => 'Fehlerhafte Emailadresse oder fehlerhaftes Passowrt', + 'login_error' => 'Fehlerhafte Emailadresse oder fehlerhaftes Passwort', 'forgotten_password_link' => 'Passwort vergessen?', 'reset_emailed' => 'Wir haben Ihnen einen Link geschickt, um Ihr Passwort zurückzusetzen', 'reset_header' => 'Keine Panik!
Geben Sie einfach unten Ihre Emailadresse an @@ -39,6 +39,7 @@ PHPCI', 'reset_email_title' => 'PHPCI Passwort zurücksetzen für %s', 'reset_invalid' => 'Fehlerhafte Anfrage für das Zurücksetzen eines Passwortes', 'email_address' => 'Emailadresse', + 'login' => 'Login / Emailadresse', 'password' => 'Passwort', 'log_in' => 'Einloggen', @@ -56,13 +57,13 @@ PHPCI', // Sidebar 'hello_name' => 'Hallo, %s', 'dashboard' => 'Dashboard', - 'admin_options' => 'Administraion', + 'admin_options' => 'Administration', 'add_project' => 'Projekt hinzufügen', 'settings' => 'Einstellungen', 'manage_users' => 'Benutzereinstellungen', 'plugins' => 'Plugins', 'view' => 'Ansehen', - 'build_now' => 'Aktueller Build', + 'build_now' => 'Jetzt bauen', 'edit_project' => 'Projekt bearbeiten', 'delete_project' => 'Projekt löschen', @@ -101,6 +102,7 @@ generiert. Um es zu verwenden, fügen Sie einfach den folgenden Public Key im Ab 'remote' => 'Externe URL', 'local' => 'Lokaler Pfad', 'hg' => 'Mercurial', + 'svn' => 'Subversion', 'where_hosted' => 'Wo wird Ihr Projekt gehostet?', 'choose_github' => 'Wählen Sie ein GitHub Repository:', @@ -113,6 +115,8 @@ generiert. Um es zu verwenden, fügen Sie einfach den folgenden Public Key im Ab (falls Sie Ihrem Projektrepository kein phpci.yml hinzufügen können)', 'default_branch' => 'Name des Standardbranches', 'allow_public_status' => 'Öffentliche Statusseite und -bild für dieses Projekt einschalten?', + 'archived' => 'Archiviert', + 'archived_menu' => 'Archiviert', 'save_project' => 'Projekt speichern', 'error_mercurial' => 'Mercurial Repository-URL muss mit http://, oder https:// beginnen', @@ -126,6 +130,7 @@ generiert. Um es zu verwenden, fügen Sie einfach den folgenden Public Key im Ab 'all_branches' => 'Alle Branches', 'builds' => 'Builds', 'id' => 'ID', + 'date' => 'Datum', 'project' => 'Projekt', 'commit' => 'Commit', 'branch' => 'Branch', @@ -146,6 +151,9 @@ generiert. Um es zu verwenden, fügen Sie einfach den folgenden Public Key im Ab 'webhooks_help_bitbucket' => 'Um für dieses Projekt automatisch einen Build zu starten, wenn neue Commits gepushed werden, fügen Sie die untenstehende URL als "POST" Service in der Services-Sektion Ihres Bitbucket Repositories hinzu.', // View Build + 'errors' => 'Fehler', + 'information' => 'Information', + 'build_x_not_found' => 'Build mit ID %d existiert nicht.', 'build_n' => 'Build %d', 'rebuild_now' => 'Build neu starten', @@ -164,6 +172,7 @@ generiert. Um es zu verwenden, fügen Sie einfach den folgenden Public Key im Ab 'lines_of_code' => 'Anzahl Codezeilen', 'build_log' => 'Buildprotokoll', 'quality_trend' => 'Qualitätstrend', + 'codeception_errors' => 'Codeception Errors', 'phpmd_warnings' => 'PHPMD Warnings', 'phpcs_warnings' => 'PHPCS Warnings', 'phpcs_errors' => 'PHPCS Errors', @@ -172,12 +181,21 @@ generiert. Um es zu verwenden, fügen Sie einfach den folgenden Public Key im Ab 'phpdoccheck_warnings' => 'Fehlende Docblocks', 'issues' => 'Probleme', + 'codeception' => 'Codeception', 'phpcpd' => 'PHP Copy/Paste Detector', 'phpcs' => 'PHP Code Sniffer', 'phpdoccheck' => 'Fehlende Docblocks', 'phpmd' => 'PHP Mess Detector', 'phpspec' => 'PHP Spec', 'phpunit' => 'PHP Unit', + 'technical_debt' => 'Technische Schulden', + 'behat' => 'Behat', + + 'codeception_feature' => 'Feature', + 'codeception_suite' => 'Suite', + 'codeception_time' => 'Zeit', + 'codeception_synopsis' => '%1$d Tests in %2$f Sekunden ausgeführt. + %3$d Fehler.', 'file' => 'Datei', 'line' => 'Zeile', @@ -188,14 +206,20 @@ generiert. Um es zu verwenden, fügen Sie einfach den folgenden Public Key im Ab 'end' => 'Ende', 'from' => 'Von', 'to' => 'Bis', - 'suite' => 'Suite', - 'test' => 'Test', 'result' => 'Resultat', 'ok' => 'OK', 'took_n_seconds' => 'Benötigte %d Sekunden', 'build_created' => 'Build erstellt', 'build_started' => 'Build gestartet', 'build_finished' => 'Build abgeschlossen', + 'test_message' => 'Nachricht', + 'test_no_message' => 'Keine Nachricht', + 'test_success' => 'Erfolgreich: %d', + 'test_fail' => 'Fehlschläge: %d', + 'test_skipped' => 'Übersprungen: %d', + 'test_error' => 'Fehler: %d', + 'test_todo' => 'Todos: %d', + 'test_total' => '%d Test(s)', // Users 'name' => 'Name', @@ -271,6 +295,19 @@ generiert. Um es zu verwenden, fügen Sie einfach den folgenden Public Key im Ab 'search_packagist_for_more' => 'Packagist nach mehr Packages durchsuchen', 'search' => 'Suchen »', + // Summary plugin + 'build-summary' => 'Zusammenfassung', + 'stage' => 'Abschnitt', + 'duration' => 'Dauer', + 'plugin' => 'Plugin', + 'stage_setup' => 'Vorbereitung', + 'stage_test' => 'Test', + 'stage_complete' => 'Vollständig', + 'stage_success' => 'Erfolg', + 'stage_failure' => 'Fehlschlag', + 'stage_broken' => 'Defekt', + 'stage_fixed' => 'Behoben', + // Installer 'installation_url' => 'PHPCI Installations-URL', 'db_host' => 'Datenbankserver', @@ -291,9 +328,9 @@ generiert. Um es zu verwenden, fügen Sie einfach den folgenden Public Key im Ab Bitte überprüfen Sie die Fehler, bevor Sie fortfahren,', 'must_be_valid_email' => 'Muss eine gültige Emailadresse sein.', 'must_be_valid_url' => 'Muss eine valide URL sein.', - 'enter_name' => 'Name des Administrators:', - 'enter_email' => 'Emailadresse des Administrators:', - 'enter_password' => 'Passwort des Administrators:', + 'enter_name' => 'Name des Administrators: ', + 'enter_email' => 'Emailadresse des Administrators: ', + 'enter_password' => 'Passwort des Administrators: ', 'enter_phpci_url' => 'Ihre PHPCI-URL (z.B. "http://phpci.local"): ', 'enter_db_host' => 'Bitte geben Sie Ihren MySQL-Host ein [localhost]: ', @@ -326,6 +363,12 @@ generiert. Um es zu verwenden, fügen Sie einfach den folgenden Public Key im Ab 'create_admin_user' => 'Administratorenbenutzer erstellen', 'incorrect_format' => 'Falsches Format', + // Create Build Command + 'create_build_project' => 'Create a build for a project', + 'project_id_argument' => 'A project ID', + 'commit_id_option' => 'Commit ID to build', + 'branch_name_option' => 'Branch to build', + // Run Command 'run_all_pending' => 'Führe alle ausstehenden PHPCI Builds aus.', 'finding_builds' => 'Suche verarbeitbare Builds', @@ -373,5 +416,18 @@ generiert. Um es zu verwenden, fügen Sie einfach den folgenden Public Key im Ab 'build_file_missing' => 'Angegebene Builddatei existiert nicht.', 'property_file_missing' => 'Angegebene Eigenschaftsdatei existiert nicht.', 'could_not_process_report' => 'Konnte den von diesem Tool erstellten Bericht nicht verarbeiten.', - 'shell_not_enabled' => 'Das Shell-Plugin ist nicht aktiviert. Bitte aktivieren Sie es via config.yml.' + 'shell_not_enabled' => 'Das Shell-Plugin ist nicht aktiviert. Bitte aktivieren Sie es via config.yml.', + + // Error Levels: + 'critical' => 'Kritisch', + 'high' => 'Hoch', + 'normal' => 'Normal', + 'low' => 'Niedrig', + + // Plugins that generate errors: + 'php_mess_detector' => 'PHP Mess Detector', + 'php_code_sniffer' => 'PHP Code Sniffer', + 'php_unit' => 'PHP Unit', + 'php_cpd' => 'PHP Copy/Paste Detector', + 'php_docblock_checker' => 'PHP Docblock Checker', ); diff --git a/PHPCI/Languages/lang.el.php b/PHPCI/Languages/lang.el.php index 2089cd04..45ee4bee 100644 --- a/PHPCI/Languages/lang.el.php +++ b/PHPCI/Languages/lang.el.php @@ -39,6 +39,7 @@ PHPCI', 'reset_email_title' => 'PHPCI Επαναφορά Κωδικού για %s', 'reset_invalid' => 'Μη έγκυρο αίτημα επαναφοράς κωδικού πρόσβασης.', 'email_address' => 'Διεύθυνση email', + 'login' => 'Login / Email Address', 'password' => 'Κωδικός πρόσβασης', 'log_in' => 'Είσοδος', @@ -113,6 +114,8 @@ PHPCI', (αν δεν μπορείτε να προσθέσετε ένα αρχείο phpci.yml στο αποθετήριο έργων)', 'default_branch' => 'Προκαθορισμένο όνομα διακλάδωσης', 'allow_public_status' => 'Ενεργοποίηση της σελίδας δημόσιας κατάστασης και την εικόνα για το έργο αυτό;', + 'archived' => 'Archived', + 'archived_menu' => 'Archived', 'save_project' => 'Αποθήκευση έργου', 'error_mercurial' => 'Ο σύνδεσμος URL του ευμετάβλητου αποθετηρίου πρέπει να ξεκινάει με http:// ή https://', @@ -126,6 +129,7 @@ PHPCI', 'all_branches' => 'Όλες οι διακλαδώσεις', 'builds' => 'Κατασκευές', 'id' => 'Αριθμός αναγνώρισης', + 'date' => 'Date', 'project' => 'Έργο', 'commit' => 'Συνεισφορά', 'branch' => 'Διακλάδωση', @@ -166,14 +170,17 @@ Services του Bitbucket αποθετηρίου σας.', 'lines_of_code' => 'Γραμμές Κώδικα', 'build_log' => 'Αρχείο καταγραφής κατασκευών', 'quality_trend' => 'Ποιότητα τρέντ', + 'codeception_errors' => 'Λάθη Codeception', 'phpmd_warnings' => 'Προειδοποιήσεις PHPMD', 'phpcs_warnings' => 'Προειδοποιήσεις PHPCS ', + 'codeception_errors' => 'Λάθη Codeception', 'phpcs_errors' => 'Λάθη PHPCS', 'phplint_errors' => 'Λάθη Lint', 'phpunit_errors' => 'Λάθη PHPUnit ', 'phpdoccheck_warnings' => 'Χαμένα Docblocks', 'issues' => 'Θέματα', + 'codeception' => 'Codeception', 'phpcpd' => 'PHP Ανιχνευτής Αντιγραφής/Επικόλλησης', 'phpcs' => 'Sniffer Κώδικα PHP', 'phpdoccheck' => 'Χαμένα Docblocks', @@ -190,14 +197,20 @@ Services του Bitbucket αποθετηρίου σας.', 'end' => 'Τέλος', 'from' => 'Από', 'to' => 'Προς', - 'suite' => 'Σουίτα', - 'test' => 'Τέστ', 'result' => 'Αποτέλεσμα', 'ok' => 'ΟΚ', 'took_n_seconds' => 'Χρειάστηκαν %d δευτερόλεπτα', 'build_created' => 'Η κατασκευή δημιουργήθηκε', 'build_started' => 'Η κατασκευή άρχισε', 'build_finished' => 'Η κατασκευή ολοκληρώθηκε', + 'test_message' => 'Message', + 'test_no_message' => 'No message', + 'test_success' => 'Successful: %d', + 'test_fail' => 'Failures: %d', + 'test_skipped' => 'Skipped: %d', + 'test_error' => 'Errors: %d', + 'test_todo' => 'Todos: %d', + 'test_total' => '%d test(s)', // Users 'name' => 'Όνομα', @@ -294,15 +307,15 @@ Services του Bitbucket αποθετηρίου σας.', Παρακαλούμε διαβάστε τα παραπάνω λάθη πριν συνεχίσετε.', 'must_be_valid_email' => 'Πρέπει να είναι μια έγκυρη διεύθυνση ηλεκτρονικού ταχυδρομείου.', 'must_be_valid_url' => 'Πρέπει να είναι μια έγκυρη διεύθυνση URL.', - 'enter_name' => 'Όνομα διαχειριστή:', - 'enter_email' => 'Ηλ. Διεύθυνση διαχειριστή:', - 'enter_password' => 'Κωδικός πρόσβασης διαχειριστή:', + 'enter_name' => 'Όνομα διαχειριστή: ', + 'enter_email' => 'Ηλ. Διεύθυνση διαχειριστή: ', + 'enter_password' => 'Κωδικός πρόσβασης διαχειριστή: ', 'enter_phpci_url' => 'Ο URL σύνδεσμος σας για το PHPCI ("http://phpci.local" για παράδειγμα): ', - 'enter_db_host' => 'Παρακαλώ εισάγετε τον MySQL οικοδεσπότη σας [localhost]:', + 'enter_db_host' => 'Παρακαλώ εισάγετε τον MySQL οικοδεσπότη σας [localhost]: ', 'enter_db_name' => 'Παρακαλώ εισάγετε το όνομα της MySQL βάσης δεδομένων σας [phpci]: ', - 'enter_db_user' => 'Παρακαλώ εισάγετε το όνομα χρήστη της MySQL σας [phpci]:', - 'enter_db_pass' => 'Παρακαλώ εισάγετε τον κωδικό χρήστη της MySQL σας:', + 'enter_db_user' => 'Παρακαλώ εισάγετε το όνομα χρήστη της MySQL σας [phpci]: ', + 'enter_db_pass' => 'Παρακαλώ εισάγετε τον κωδικό χρήστη της MySQL σας: ', 'could_not_connect' => 'Το PHPCI δεν μπόρεσε να συνδεθεί με την MySQL με τα στοχεία που δώσατε. Παρακαλώ δοκιμάστε ξανά.', 'setting_up_db' => 'Γίνεται ρύθμιση της βάσης δεδομένων σας ...', 'user_created' => 'Λογαριασμός χρήστη δημιουργήθηκε!', @@ -329,6 +342,12 @@ Services του Bitbucket αποθετηρίου σας.', 'create_admin_user' => 'Δημιουργήστε ένα χρήστη διαχειριστή', 'incorrect_format' => 'Λανθασμένη μορφοποίηση', + // Create Build Command + 'create_build_project' => 'Create a build for a project', + 'project_id_argument' => 'A project ID', + 'commit_id_option' => 'Commit ID to build', + 'branch_name_option' => 'Branch to build', + // Run Command 'run_all_pending' => 'Εκτελέστε όλες τις εκκρεμείς PHPCI κατασκευές.', 'finding_builds' => 'Αναζήτηση κατασκευών για επεξεργασία', diff --git a/PHPCI/Languages/lang.en.php b/PHPCI/Languages/lang.en.php index 41526624..63df75d2 100644 --- a/PHPCI/Languages/lang.en.php +++ b/PHPCI/Languages/lang.en.php @@ -39,6 +39,7 @@ PHPCI', 'reset_email_title' => 'PHPCI Password Reset for %s', 'reset_invalid' => 'Invalid password reset request.', 'email_address' => 'Email Address', + 'login' => 'Login / Email Address', 'password' => 'Password', 'log_in' => 'Log in', @@ -101,6 +102,7 @@ PHPCI', 'remote' => 'Remote URL', 'local' => 'Local Path', 'hg' => 'Mercurial', + 'svn' => 'Subversion', 'where_hosted' => 'Where is your project hosted?', 'choose_github' => 'Choose a GitHub repository:', @@ -113,6 +115,8 @@ PHPCI', (if you cannot add a phpci.yml file in the project repository)', 'default_branch' => 'Default branch name', 'allow_public_status' => 'Enable public status page and image for this project?', + 'archived' => 'Archived', + 'archived_menu' => 'Archived', 'save_project' => 'Save Project', 'error_mercurial' => 'Mercurial repository URL must be start with http:// or https://', @@ -126,6 +130,7 @@ PHPCI', 'all_branches' => 'All Branches', 'builds' => 'Builds', 'id' => 'ID', + 'date' => 'Date', 'project' => 'Project', 'commit' => 'Commit', 'branch' => 'Branch', @@ -149,6 +154,9 @@ PHPCI', Services section of your Bitbucket repository.', // View Build + 'errors' => 'Errors', + 'information' => 'Information', + 'build_x_not_found' => 'Build with ID %d does not exist.', 'build_n' => 'Build %d', 'rebuild_now' => 'Rebuild Now', @@ -167,6 +175,7 @@ PHPCI', 'lines_of_code' => 'Lines of Code', 'build_log' => 'Build Log', 'quality_trend' => 'Quality Trend', + 'codeception_errors' => 'Codeception Errors', 'phpmd_warnings' => 'PHPMD Warnings', 'phpcs_warnings' => 'PHPCS Warnings', 'phpcs_errors' => 'PHPCS Errors', @@ -175,12 +184,21 @@ PHPCI', 'phpdoccheck_warnings' => 'Missing Docblocks', 'issues' => 'Issues', + 'codeception' => 'Codeception', 'phpcpd' => 'PHP Copy/Paste Detector', 'phpcs' => 'PHP Code Sniffer', 'phpdoccheck' => 'Missing Docblocks', 'phpmd' => 'PHP Mess Detector', 'phpspec' => 'PHP Spec', 'phpunit' => 'PHP Unit', + 'technical_debt' => 'Technical Debt', + 'behat' => 'Behat', + + 'codeception_feature' => 'Feature', + 'codeception_suite' => 'Suite', + 'codeception_time' => 'Time', + 'codeception_synopsis' => '%1$d tests carried out in %2$f seconds. + %3$d failures.', 'file' => 'File', 'line' => 'Line', @@ -191,14 +209,20 @@ PHPCI', 'end' => 'End', 'from' => 'From', 'to' => 'To', - 'suite' => 'Suite', - 'test' => 'Test', 'result' => 'Result', 'ok' => 'OK', 'took_n_seconds' => 'Took %d seconds', 'build_created' => 'Build Created', 'build_started' => 'Build Started', 'build_finished' => 'Build Finished', + 'test_message' => 'Message', + 'test_no_message' => 'No message', + 'test_success' => 'Successful: %d', + 'test_fail' => 'Failures: %d', + 'test_skipped' => 'Skipped: %d', + 'test_error' => 'Errors: %d', + 'test_todo' => 'Todos: %d', + 'test_total' => '%d test(s)', // Users 'name' => 'Name', @@ -275,6 +299,19 @@ PHPCI', 'search_packagist_for_more' => 'Search Packagist for more packages', 'search' => 'Search »', + // Summary plugin + 'build-summary' => 'Summary', + 'stage' => 'Stage', + 'duration' => 'Duration', + 'plugin' => 'Plugin', + 'stage_setup' => 'Setup', + 'stage_test' => 'Test', + 'stage_complete' => 'Complete', + 'stage_success' => 'Success', + 'stage_failure' => 'Failure', + 'stage_broken' => 'Broken', + 'stage_fixed' => 'Fixed', + // Installer 'installation_url' => 'PHPCI Installation URL', 'db_host' => 'Database Host', @@ -295,9 +332,9 @@ PHPCI', Please review the errors above before continuing.', 'must_be_valid_email' => 'Must be a valid email address.', 'must_be_valid_url' => 'Must be a valid URL.', - 'enter_name' => 'Admin Name:', - 'enter_email' => 'Admin Email:', - 'enter_password' => 'Admin Password:', + 'enter_name' => 'Admin Name: ', + 'enter_email' => 'Admin Email: ', + 'enter_password' => 'Admin Password: ', 'enter_phpci_url' => 'Your PHPCI URL ("http://phpci.local" for example): ', 'enter_db_host' => 'Please enter your MySQL host [localhost]: ', @@ -330,6 +367,15 @@ PHPCI', 'create_admin_user' => 'Create an admin user', 'incorrect_format' => 'Incorrect format', + // Create Build Command + 'create_build_project' => 'Create a build for a project', + 'project_id_argument' => 'A project ID', + 'commit_id_option' => 'Commit ID to build', + 'branch_name_option' => 'Branch to build', + 'add_to_queue_failed' => 'Build created successfully, but failed to add to build queue. This usually happens + when PHPCI is set to use a beanstalkd server that does not exist, + or your beanstalkd server has stopped.', + // Run Command 'run_all_pending' => 'Run all pending PHPCI builds.', 'finding_builds' => 'Finding builds to process', @@ -377,5 +423,22 @@ PHPCI', 'build_file_missing' => 'Specified build file does not exist.', 'property_file_missing' => 'Specified property file does not exist.', 'could_not_process_report' => 'Could not process the report generated by this tool.', - 'shell_not_enabled' => 'The shell plugin is not enabled. Please enable it via config.yml.' + 'shell_not_enabled' => 'The shell plugin is not enabled. Please enable it via config.yml.', + + + // Error Levels: + 'critical' => 'Critical', + 'high' => 'High', + 'normal' => 'Normal', + 'low' => 'Low', + + // Plugins that generate errors: + 'php_mess_detector' => 'PHP Mess Detector', + 'php_code_sniffer' => 'PHP Code Sniffer', + 'php_unit' => 'PHP Unit', + 'php_cpd' => 'PHP Copy/Paste Detector', + 'php_docblock_checker' => 'PHP Docblock Checker', + 'behat' => 'Behat', + 'technical_debt' => 'Technical Debt', + ); diff --git a/PHPCI/Languages/lang.es.php b/PHPCI/Languages/lang.es.php new file mode 100644 index 00000000..1b7b33f7 --- /dev/null +++ b/PHPCI/Languages/lang.es.php @@ -0,0 +1,387 @@ + 'Español', + 'language' => 'Lenguaje', + + // Log in: + 'log_in_to_phpci' => 'Ingresar a PHPCI', + 'login_error' => 'Email o contraseña incorrectos', + 'forgotten_password_link' => '¿Olvidaste tu contraseña?', + 'reset_emailed' => 'Te hemos enviado un email para reiniciar tu contraseña.', + 'reset_header' => '¡No te preocupes!
Solo tienes que ingresar tu dirección de email + y te enviaremos por email un enlace para reiniciar tu contraseña.', + 'reset_email_address' => 'Ingresa tu dirección de email:', + 'reset_send_email' => 'Enviar enlace', + 'reset_enter_password' => 'Ingresa una nueva contraseña', + 'reset_new_password' => 'Nueva contraseña:', + 'reset_change_password' => 'Cambiar contraseña', + 'reset_no_user_exists' => 'No existe ningún usuario con ese email, por favor intenta nuevamente.', + 'reset_email_body' => 'Hola %s, + +Has recibido este correo porque tú, o alguien más, ha solicitado reiniciar la contraseña de PHPCI + +Si fuiste tú, por favor haz click en el siguiente enlace para reiniciar tu contraseña: %ssession/reset-password/%d/%s + +De lo contrario, por favor ignora este correo y ninguna acción será realizada. + +Gracias, + +PHPCI', + + 'reset_email_title' => 'Reiniciar contraseña de PHPCI para %s', + 'reset_invalid' => 'Pedido inválido.', + 'email_address' => 'Dirección de email', + 'password' => 'Contraseña', + 'log_in' => 'Ingresar', + + + // Top Nav + 'toggle_navigation' => 'Activar navegación', + 'n_builds_pending' => '%d builds pendientes', + 'n_builds_running' => '%d builds ejecutándose', + 'edit_profile' => 'Editar Perfil', + 'sign_out' => 'Cerrar Sesión', + 'branch_x' => 'Rama: %s', + 'created_x' => 'Creada el: %s', + 'started_x' => 'Comenzó: %s', + + // Sidebar + 'hello_name' => 'Hola, %s', + 'dashboard' => 'Escritorio', + 'admin_options' => 'Opciones de Admin.', + 'add_project' => 'Agregar Proyecto', + 'settings' => 'Configuración', + 'manage_users' => 'Administrar Usuarios', + 'plugins' => 'Plugins', + 'view' => 'Vista', + 'build_now' => 'Ejecutar Build', + 'edit_project' => 'Editar Proyecto', + 'delete_project' => 'Eliminar Proyecto', + + // Project Summary: + 'no_builds_yet' => '¡No existen builds aún!', + 'x_of_x_failed' => '%d de los últimos %d builds fallaron.', + 'x_of_x_failed_short' => '%d / %d fallaron.', + 'last_successful_build' => ' El último build exitoso fue %s.', + 'never_built_successfully' => ' Este proyecto nunca tuvo un build exitoso.', + 'all_builds_passed' => 'Todos los últimos %d builds pasaron.', + 'all_builds_passed_short' => '%d / %d pasaron.', + 'last_failed_build' => ' El último build en fallar fue %s.', + 'never_failed_build' => ' Este proyecto no tiene ningún build fallido.', + 'view_project' => 'Ver Proyecto', + + // Timeline: + 'latest_builds' => 'Últimos builds', + 'pending' => 'Pediente', + 'running' => 'Ejecutando', + 'success' => 'Éxito', + 'successful' => 'Exitoso', + 'failed' => 'Falló', + 'manual_build' => 'Build Manual', + + // Add/Edit Project: + 'new_project' => 'Nuevo Proyecto', + 'project_x_not_found' => 'El Proyecto con ID %d no existe.', + 'project_details' => 'Detalles del Proyecto', + 'public_key_help' => 'Para facilitarte, hemos generado un par de llaves SSH para que uses en este proyecto. + Para usarlo, sólo agrega la siguiente llave pública a la sección de "deploy keys" + de tu plataforma de hosting de versionado de código.', + 'select_repository_type' => 'Selecciona tipo de repositorio...', + 'github' => 'GitHub', + 'bitbucket' => 'Bitbucket', + 'gitlab' => 'GitLab', + 'remote' => 'URL Remota', + 'local' => 'Path local', + 'hg' => 'Mercurial', + 'svn' => 'Subversion', + + 'where_hosted' => '¿Dónde está alojado tu proyecto?', + 'choose_github' => 'Selecciona un repositorio de GitHub:', + + 'repo_name' => 'Nombre del repositorio / URL (Remoto) o Ruta (Local)', + 'project_title' => 'Titulo del proyecto', + 'project_private_key' => 'Clave privada a usar para acceder al repositorio + (dejar en blanco para remotos locales o anónimos)', + 'build_config' => 'Configuración PHPCI para builds del proyecto + (en caso que no puedas agregar el archivo phpci.yml al repositorio)', + 'default_branch' => 'Nombre de la rama por defecto', + 'allow_public_status' => '¿Activar página pública con el estado del proyecto?', + 'archived' => 'Archivado', + 'archived_menu' => 'Archivado', + 'save_project' => 'Guardar Proyecto', + + 'error_mercurial' => 'La URL del repositorio de Mercurial debe comenzar con http:// or https://', + 'error_remote' => 'La URL del repositorio debe comenzar con git://, http:// or https://', + 'error_gitlab' => 'El nombre del repositorio de GitLab debe tener el formato "user@domain.tld:owner/repo.git"', + 'error_github' => 'El nombre del repositorio debe tener el formato "owner/repo"', + 'error_bitbucket' => 'El nombre del repo debe tener el formato "owner/repo"', + 'error_path' => 'La ruta especificada no existe.', + + // View Project: + 'all_branches' => 'Todas las ramas', + 'builds' => 'Builds', + 'id' => 'ID', + 'project' => 'Proyecto', + 'commit' => 'Commit', + 'branch' => 'Rama', + 'status' => 'Estado', + 'prev_link' => '« Anterior', + 'next_link' => 'Siguiente »', + 'public_key' => 'Llave pública', + 'delete_build' => 'Eliminar Build', + + 'webhooks' => 'Webhooks', + 'webhooks_help_github' => 'Para compilar automáticamente este proyecto cada vez que se realiza un commit, agreagar la siguiente URL + como un nuevo "webhook" en la sección Webhooks + and Services de tu repositorio en GitHub.', + + 'webhooks_help_gitlab' => 'Para compilar automáticamente este proyecto, cada vez que se realiza un commit, agreagar la siguiente URL + como una "WebHook URL" en la sección "web hooks" de tu repositorio en GitLab.', + + 'webhooks_help_bitbucket' => 'Para compilar automáticamente este proyecto, cada vez que se realiza un commit, agreagar la siguiente URL + como un servicio "POST" en la sección + + Services de tu repositorio en Bitbucket.', + + // View Build + 'build_x_not_found' => 'El build con ID %d no existe.', + 'build_n' => 'Build %d', + 'rebuild_now' => 'Rebuild Ahora', + + + 'committed_by_x' => 'Commit hecho por %s', + 'commit_id_x' => 'Commit: %s', + + 'chart_display' => 'Este gráfico será mostrado una vez que el build se haya completado.', + + 'build' => 'Build', + 'lines' => 'Líneas', + 'comment_lines' => 'Líneas de comentario', + 'noncomment_lines' => 'Líneas no comentario', + 'logical_lines' => 'Líneas lógicas', + 'lines_of_code' => 'Líneas de código', + 'build_log' => 'Log', + 'quality_trend' => 'Tendencia de calidad', + 'codeception_errors' => 'Errores de Codeception', + 'phpmd_warnings' => 'PHPMD Warnings', + 'phpcs_warnings' => 'PHPCS Warnings', + 'phpcs_errors' => 'PHPCS Errors', + 'phplint_errors' => 'Lint Errors', + 'phpunit_errors' => 'PHPUnit Errors', + 'phpdoccheck_warnings' => 'Docblocks faltantes', + 'issues' => 'Incidencias', + + 'codeception' => 'Codeception', + 'phpcpd' => 'PHP Copy/Paste Detector', + 'phpcs' => 'PHP Code Sniffer', + 'phpdoccheck' => 'Missing Docblocks', + 'phpmd' => 'PHP Mess Detector', + 'phpspec' => 'PHP Spec', + 'phpunit' => 'PHP Unit', + 'technical_debt' => 'Deuda Técnica', + 'behat' => 'Behat', + + 'file' => 'Archivo', + 'line' => 'Línea', + 'class' => 'Clase', + 'method' => 'Método', + 'message' => 'Mensaje', + 'start' => 'Inicio', + 'end' => 'Fin', + 'from' => 'De', + 'to' => 'Para', + 'suite' => 'Suite', + 'test' => 'Test', + 'result' => 'Resultado', + 'ok' => 'OK', + 'took_n_seconds' => 'Tomó %d segundos', + 'build_created' => 'Build Creado', + 'build_started' => 'Build Comenzado', + 'build_finished' => 'Build Terminado', + + // Users + 'name' => 'Nombre', + 'password_change' => 'Contraseña (dejar en blanco si no quiere cambiarla)', + 'save' => 'Guardar »', + 'update_your_details' => 'Actualizar los detalles', + 'your_details_updated' => 'Tus detalles han sido actualizados.', + 'add_user' => 'Agregar Usuario', + 'is_admin' => '¿Es Admin?', + 'yes' => 'Si', + 'no' => 'No', + 'edit' => 'Editar', + 'edit_user' => 'Editar Usuario', + 'delete_user' => 'Delete Usuario', + 'user_n_not_found' => 'Usuario con ID %d no existe.', + 'is_user_admin' => '¿Es un usuario administrador?', + 'save_user' => 'Guardar Usuario', + + // Settings: + 'settings_saved' => 'Tu configuración ha sido guardada.', + 'settings_check_perms' => 'Tu configuración no fue guardada, verificar los permisos del archivo config.yml.', + 'settings_cannot_write' => 'PHPCI no puede escribir en el archivo config.yml file, la configuración no será guardada correctamente + hasta no corregir esto.', + 'settings_github_linked' => 'Tu cuenta GitHub ha sido conectada.', + 'settings_github_not_linked' => 'No se pudo conectar a tu cuenta GitHub.', + 'build_settings' => 'Configuración del Build ', + 'github_application' => 'Aplicación GitHub', + 'github_sign_in' => 'Antes de comenzar a utilizar GitHub, tienes que ingresar y permitir + el acceso a tu cuenta a PHPCI.', + 'github_phpci_linked' => 'PHPCI ha sido conectado a tu cuenta GitHub.', + 'github_where_to_find' => 'Donde encontrar estos...', + 'github_where_help' => 'Si eres priopietario de la aplicaión que quieres usar, puedes encontrar esta información en + el área de configuración de aplicaciones.', + + 'email_settings' => 'Configuraciones de Email', + 'email_settings_help' => 'Para que PHPCI pueda enviar email con el status de los builds, + debes configurar las siguientes propiedades SMTP.', + + 'application_id' => 'ID de aplicación', + 'application_secret' => 'Application Secret', + + 'smtp_server' => 'Servidor SMTP', + 'smtp_port' => 'Puerto SMTP', + 'smtp_username' => 'Usuario SMTP', + 'smtp_password' => 'Contraseña SMTP', + 'from_email_address' => 'Dirección de email DE', + 'default_notification_address' => 'Dirección de correo de notificación por defecto', + 'use_smtp_encryption' => 'Usar encriptación SMTP?', + 'none' => 'None', + 'ssl' => 'SSL', + 'tls' => 'TLS', + + 'failed_after' => 'Considerar el build como fallido luego de ', + '5_mins' => '5 Minutos', + '15_mins' => '15 Minutos', + '30_mins' => '30 Minutos', + '1_hour' => '1 Hora', + '3_hours' => '3 Horas', + + // Plugins + 'cannot_update_composer' => 'PHPCI no puede actualizar composer.json porque no tiene permisos de escritura.', + 'x_has_been_removed' => '%s ha sido elimiando.', + 'x_has_been_added' => '%s ha sido agregado a composer.json y será instalado la próxima vez que ejecutes composer update.', + 'enabled_plugins' => 'Activar Plugins', + 'provided_by_package' => 'Provisto por Paquete', + 'installed_packages' => 'Paquetes Instalados', + 'suggested_packages' => 'Paquetes Sugeridos', + 'title' => 'Título', + 'description' => 'Descripción', + 'version' => 'Versión', + 'install' => 'Instalar »', + 'remove' => 'Eliminar »', + 'search_packagist_for_more' => 'Buscar más paquetes en Packagist', + 'search' => 'Buscar »', + + // Installer + 'installation_url' => 'URL de la instalación PHPCI', + 'db_host' => 'Host', + 'db_name' => 'Nombre de la base de datos', + 'db_user' => 'Usuario de la base de datos', + 'db_pass' => 'Clave de la base de datos', + 'admin_name' => 'Nombre del Admin', + 'admin_pass' => 'Clave del Admin', + 'admin_email' => 'Email de Admin', + 'config_path' => 'Ruta al archivo config', + 'install_phpci' => 'Instalar PHPCI', + 'welcome_to_phpci' => 'Bienvenido a PHPCI', + 'please_answer' => 'Por favor, responde las siguientes preguntas:', + 'phpci_php_req' => 'PHPCI requiere al menos PHP 5.3.8 para funcionar.', + 'extension_required' => 'Extensión requerida: %s', + 'function_required' => 'PHPCI debe poder invocar la función %s(). Está deshabilitada en php.ini?', + 'requirements_not_met' => 'PHPCI no pudo ser instalado, ya que no se cumplen todos los requerimientos. + Por favor, corrige los errores antes de continuar.', + 'must_be_valid_email' => 'Debe ser una dirección de correos válida.', + 'must_be_valid_url' => 'Debe ser una URL válida.', + 'enter_name' => 'Nombre del Admin:', + 'enter_email' => 'Email del Admin:', + 'enter_password' => 'Contraseña de Admin:', + 'enter_phpci_url' => 'La URL de PHPCI ("Por ejemplo: http://phpci.local"): ', + + 'enter_db_host' => 'Por favor, ingresa el servidor MySQL [localhost]: ', + 'enter_db_name' => 'Por favor, ingresa el nombre de la base de datos MySQL [phpci]: ', + 'enter_db_user' => 'Por favor, ingresa el usuario MySQL [phpci]: ', + 'enter_db_pass' => 'Por favor, ingresa la contraseña MySQL: ', + 'could_not_connect' => 'PHPCI no pudo conectarse a MySQL con los datos dados. Por favor, intenta nuevamente.', + 'setting_up_db' => 'Configurando base de datos... ', + 'user_created' => '¡Cuenta de usuario creada!', + 'failed_to_create' => 'PHPCI no pudo crear la cuenta de admin.', + 'config_exists' => 'El archivo config de PHPCI ya existe y no es vacío.', + 'update_instead' => 'Si está intentando actualizar PHPCI, por favor, utiliza phpci:update.', + + // Update + 'update_phpci' => 'Actuliza la base de datos para reflejar los modelos actualizados.', + 'updating_phpci' => 'Actualizando base de datos PHPCI: ', + 'not_installed' => 'PHPCI no está instalado.', + 'install_instead' => 'Por favor, instala PHPCI via phpci:install.', + + // Poll Command + 'poll_github' => 'Chequear en GitHub si se necesita comenzar un Build.', + 'no_token' => 'No se encontró ningún token GitHub', + 'finding_projects' => 'Buscando proyectos para chequear', + 'found_n_projects' => 'Se encontraron %d proyectos', + 'last_commit_is' => 'El último commit en GitHub para %s es %s', + 'adding_new_build' => 'Último commit es diferente a la base de datos, agregando nuevo build.', + 'finished_processing_builds' => 'Fin de procesamiento de builds.', + + // Create Admin + 'create_admin_user' => 'Crear un usuario Admin', + 'incorrect_format' => 'Formato incorrecto', + + // Run Command + 'run_all_pending' => 'Ejecutar todos los builds PHPCI pendientes.', + 'finding_builds' => 'Buscando builds a procesar', + 'found_n_builds' => 'Se encontraron %d builds', + 'skipping_build' => 'Saltando Build %d - Build del proyecto ya en ejecución.', + 'marked_as_failed' => 'Build %d falló debido a timeout.', + + // Builder + 'missing_phpci_yml' => 'Este proyecto no contiene el archivo phpci.yml o está vacío.', + 'build_success' => 'BUILD EXITOSO', + 'build_failed' => 'BUILD FALLIDO', + 'removing_build' => 'Eliminando Build.', + 'exception' => 'Excepción: ', + 'could_not_create_working' => 'Imposible crear copia de trabajo.', + 'working_copy_created' => 'Copia de trabajo creada: %s', + 'looking_for_binary' => 'Buscando binario: %s', + 'found_in_path' => 'Encontrado en %s: %s', + 'running_plugin' => 'EJECUTANDO PLUGIN: %s', + 'plugin_success' => 'PLUGIN: EXITO', + 'plugin_failed' => 'PLUGIN: FALLÓ', + 'plugin_missing' => 'No existe el plugin: %s', + 'tap_version' => 'TapParser únicamente soporta la verisón 13 de TAP', + 'tap_error' => 'Cadena de caracteres TAP inválida, el número de tests no coincide con la cuenta de tests declarada.', + + // Build Plugins: + 'no_tests_performed' => 'No se ejecutaron tests.', + 'could_not_find' => 'No se encontró %s', + 'no_campfire_settings' => 'No se especificaron parámetros de conexión para el plugin Campfire', + 'failed_to_wipe' => 'Imposible eliminar directorio existente %s antes de copiarlo', + 'passing_build' => 'Build Exitoso', + 'failing_build' => 'Build Fallido', + 'log_output' => 'Log de Salida: ', + 'n_emails_sent' => '%d emails enviados.', + 'n_emails_failed' => '%d emails no pudieron ser enviados.', + 'unable_to_set_env' => 'Imposible setear variable de entorno', + 'tag_created' => 'Tag creado por PHPCI: %s', + 'x_built_at_x' => 'Build de %PROJECT_TITLE% en %BUILD_URI%', + 'hipchat_settings' => 'Por favor, definir room y authToken para el plugin hipchat_notify', + 'irc_settings' => 'Debes configurar un servidor, room y apodo.', + 'invalid_command' => 'Comando inválido', + 'import_file_key' => 'Sentencia de importación debe contener una llave \'file\'', + 'cannot_open_import' => 'Imposible abrir archivo de importación SQL: %s', + 'unable_to_execute' => 'Imposible ejecutar archivo SQL', + 'phar_internal_error' => 'Error interno en plugin Phar', + 'build_file_missing' => 'El archivo de build especificado no existe.', + 'property_file_missing' => 'El archivo de propiedades especificado no existe.', + 'could_not_process_report' => 'Imposible procesar el reporte generado por la herramienta.', + 'shell_not_enabled' => 'El plugin shell no está habilitado. Por favor, habilitalo desde config.yml.' +); diff --git a/PHPCI/Languages/lang.fr.php b/PHPCI/Languages/lang.fr.php index bd85bccd..a0f2cab8 100644 --- a/PHPCI/Languages/lang.fr.php +++ b/PHPCI/Languages/lang.fr.php @@ -14,21 +14,21 @@ $strings = array( // Log in: 'log_in_to_phpci' => 'Connectez-vous à PHPCI', 'login_error' => 'Adresse email ou mot de passe invalide', - 'forgotten_password_link' => 'Mot de passe oublié ?', + 'forgotten_password_link' => 'Mot de passe oublié ?', 'reset_emailed' => 'Nous vous avons envoyé un email avec un lien pour réinitialiser votre mot de passe.', 'reset_header' => 'Pas d\'inquiétude
Entrez simplement votre adresse email ci-dessous et nous vous enverrons un message avec un lien pour réinitialiser votre mot de passe.', 'reset_email_address' => 'Entrez votre adresse email:', 'reset_send_email' => 'Envoyer le mail', 'reset_enter_password' => 'Veuillez entrer un nouveau mot de passe', - 'reset_new_password' => 'Nouveau mot de passe :', + 'reset_new_password' => 'Nouveau mot de passe :', 'reset_change_password' => 'Modifier le mot de passe', 'reset_no_user_exists' => 'Il n\'existe aucun utilisateur avec cette adresse email, merci de réessayer.', 'reset_email_body' => 'Bonjour %s, Vous avez reçu cet email parce qu\'une demande de réinitialisation de mot de passe a été faite pour votre compte PHPCI. -Si c\'est bien vous, merci de cliquer sur le lien suivant pour réinitialiser votre mot de passe : %ssession/reset-password/%d/%s +Si c\'est bien vous, merci de cliquer sur le lien suivant pour réinitialiser votre mot de passe : %ssession/reset-password/%d/%s Sinon, merci d\'ignorer ce message. @@ -39,6 +39,7 @@ PHPCI', 'reset_email_title' => 'Réinitialisation du mot de passe PHPCI pour %s', 'reset_invalid' => 'Requête de réinitialisation de mot de passe invalide.', 'email_address' => 'Adresse email', + 'login' => 'Login / Email Address', 'password' => 'Mot de passe', 'log_in' => 'Connexion', @@ -49,9 +50,9 @@ PHPCI', 'n_builds_running' => '%d builds en cours d\'exécution', 'edit_profile' => 'Éditer le profil', 'sign_out' => 'Déconnexion', - 'branch_x' => 'Branche : %s', - 'created_x' => 'Créé à : %s', - 'started_x' => 'Démarré à : %s', + 'branch_x' => 'Branche : %s', + 'created_x' => 'Créé à : %s', + 'started_x' => 'Démarré à : %s', // Sidebar 'hello_name' => 'Salut %s', @@ -67,19 +68,19 @@ PHPCI', 'delete_project' => 'Supprimer le projet', // Project Summary: - 'no_builds_yet' => 'Aucun build pour le moment!', - 'x_of_x_failed' => '%d parmis les derniers %d builds ont échoué.', - 'x_of_x_failed_short' => '%d / %d ont échoué.', - 'last_successful_build' => ' Le dernier build qui a réussi est %s.', - 'never_built_successfully' => ' Aucun build n\'a été exécuté avec succès sur ce projet.', - 'all_builds_passed' => 'Les derniers %d builds ont réussis.', - 'all_builds_passed_short' => '%d / %d ont réussis.', - 'last_failed_build' => ' Le dernier build en échec est %s.', - 'never_failed_build' => ' Ce projet n\'a jamais eu un build en échec.', + 'no_builds_yet' => 'Aucun build pour le moment !', + 'x_of_x_failed' => '%d des %d derniers builds ont échoué.', + 'x_of_x_failed_short' => '%d échecs / %d.', + 'last_successful_build' => ' Le dernier build réussi date du %s.', + 'never_built_successfully' => ' Aucun build de ce projet n\'a réussi.', + 'all_builds_passed' => 'Les %d derniers builds ont réussi.', + 'all_builds_passed_short' => '%d réussites / %d.', + 'last_failed_build' => ' Le dernier build en échec date du %s.', + 'never_failed_build' => ' Aucun build de ce projet n\'a échoué.', 'view_project' => 'Voir le projet', // Timeline: - 'latest_builds' => 'Les derniers Builds', + 'latest_builds' => 'Derniers builds', 'pending' => 'En attente', 'running' => 'En cours', 'success' => 'Terminé', @@ -102,8 +103,8 @@ PHPCI', 'local' => 'Chemin local', 'hg' => 'Mercurial', - 'where_hosted' => 'Où est hébergé votre projet ?', - 'choose_github' => 'Choisissez un dépôt GitHub :', + 'where_hosted' => 'Où est hébergé votre projet ?', + 'choose_github' => 'Choisissez un dépôt GitHub :', 'repo_name' => 'Nom du dépôt / URL (distance) ou chemin (local)', 'project_title' => 'Titre du projet', @@ -112,7 +113,9 @@ PHPCI', 'build_config' => 'Configuration PHPCI spécifique pour ce projet (si vous ne pouvez pas ajouter de fichier phpci.yml à la racine du dépôt)', 'default_branch' => 'Nom de la branche par défaut', - 'allow_public_status' => 'Activer la page de statut publique et l\'image pour ce projet ?', + 'allow_public_status' => 'Activer la page de statut publique et l\'image pour ce projet ?', + 'archived' => 'Archived', + 'archived_menu' => 'Archived', 'save_project' => 'Enregistrer le projet', 'error_mercurial' => 'Les URLs de dépôt Mercurial doivent commencer par http:// ou https://', @@ -126,6 +129,7 @@ PHPCI', 'all_branches' => 'Toutes les branches', 'builds' => 'Builds', 'id' => 'ID', + 'date' => 'Date', 'project' => 'Projet', 'commit' => 'Commit', 'branch' => 'Branche', @@ -155,7 +159,7 @@ PHPCI', 'committed_by_x' => 'Committé par %s', - 'commit_id_x' => 'Commit: %s', + 'commit_id_x' => 'Commit : %s', 'chart_display' => 'Ce graphique s\'affichera une fois que le build sera terminé.', @@ -167,6 +171,7 @@ PHPCI', 'lines_of_code' => 'Lignes de code', 'build_log' => 'Log du build', 'quality_trend' => 'Tendance de la qualité', + 'codeception_errors' => 'Erreurs Codeception', 'phpmd_warnings' => 'Alertes PHPMD', 'phpcs_warnings' => 'Alertes PHPCS', 'phpcs_errors' => 'Erreurs PHPCS', @@ -175,6 +180,7 @@ PHPCI', 'phpdoccheck_warnings' => 'Blocs de documentation manquants', 'issues' => 'Tickets', + 'codeception' => 'Codeception', 'phpcpd' => 'PHP Copy/Paste Detector', 'phpcs' => 'PHP Code Sniffer', 'phpdoccheck' => 'Missing Docblocks', @@ -191,14 +197,20 @@ PHPCI', 'end' => 'Fin', 'from' => 'À partir de', 'to' => 'jusque', - 'suite' => 'Suite', - 'test' => 'Test', 'result' => 'Resultat', 'ok' => 'OK', 'took_n_seconds' => 'Exécuté en %d secondes', 'build_created' => 'Build créé', 'build_started' => 'Build démarré', 'build_finished' => 'Build terminé', + 'test_message' => 'Message', + 'test_no_message' => 'Pas de message', + 'test_success' => 'Réussi(s): %d', + 'test_fail' => 'Echec(s): %d', + 'test_skipped' => 'Passé(s): %d', + 'test_error' => 'Erreurs: %d', + 'test_todo' => 'Todos: %d', + 'test_total' => '%d test(s)', // Users 'name' => 'Nom', @@ -207,7 +219,7 @@ PHPCI', 'update_your_details' => 'Mettre à jour vos préférences', 'your_details_updated' => 'Vos préférences ont été bien mises à jour.', 'add_user' => 'Ajouter un utilisateur', - 'is_admin' => 'Est-il administrateur ?', + 'is_admin' => 'Est-il administrateur ?', 'yes' => 'Oui', 'no' => 'Non', 'edit' => 'Éditer', @@ -261,7 +273,7 @@ PHPCI', // Plugins 'cannot_update_composer' => 'PHPCI ne peut pas mettre à jour le fichier composer.json pour vous, il n\'est pas modifiable.', 'x_has_been_removed' => '%s a été supprimé.', - 'x_has_been_added' => '%s a été ajouté au fichier composer.json poru vous et il sera installé la prochaine fois + 'x_has_been_added' => '%s a été ajouté au fichier composer.json pour vous et il sera installé la prochaine fois que vous lancerez "composer update".', 'enabled_plugins' => 'Plugins activés', 'provided_by_package' => 'Fournis par le paquet', @@ -275,6 +287,17 @@ PHPCI', 'search_packagist_for_more' => 'Rechercher sur Packagist pour trouver plus de paquets', 'search' => 'Rechercher »', + // Summary plugin + 'build-summary' => 'Résumé', + 'stage' => 'Étape', + 'duration' => 'Durée', + 'plugin' => 'Plugin', + 'stage_setup' => 'Préparation', + 'stage_test' => 'Test', + 'stage_complete' => 'Terminé', + 'stage_success' => 'Succes', + 'stage_failure' => 'Échec', + // Installer 'installation_url' => 'URL d\'installation de PHPCI', 'db_host' => 'Hôte de la BDD', @@ -287,17 +310,17 @@ PHPCI', 'config_path' => 'Chemin vers le fichier de configuration', 'install_phpci' => 'Installer PHPCI', 'welcome_to_phpci' => 'Bienvenue sur PHPCI', - 'please_answer' => 'Merci de répondre aux questions suivantes:', + 'please_answer' => 'Merci de répondre aux questions suivantes :', 'phpci_php_req' => 'PHPCI requiert au moins PHP 5.3.8 pour fonctionner.', - 'extension_required' => 'Extensions requises: %s', + 'extension_required' => 'Extensions requises : %s', 'function_required' => 'PHPCI doit être capable d\'appeler la fonction %s(). Est-ce qu\'elle est désactivée dans votre php.ini?', 'requirements_not_met' => 'PHPCI ne peut pas être installé parce que toutes les conditions requises ne sont pas respectées. Merci de corriger les erreurs ci-dessus avant de continuer.', 'must_be_valid_email' => 'Doit être une adresse email valide.', 'must_be_valid_url' => 'Doit être une URL valide.', - 'enter_name' => 'Nom de l\'admin:', - 'enter_email' => 'Email de l\'admin:', - 'enter_password' => 'Mot de passe de l\'admin:', + 'enter_name' => 'Nom de l\'admin: ', + 'enter_email' => 'Email de l\'admin: ', + 'enter_password' => 'Mot de passe de l\'admin: ', 'enter_phpci_url' => 'Votre URL vers PHPCI (par exemple "http://phpci.local"): ', 'enter_db_host' => 'Merci d\'entrer le nom d\'hôte MySQL [localhost]: ', @@ -306,7 +329,7 @@ PHPCI', 'enter_db_pass' => 'Merci d\'entrer le mot de passe MySQL: ', 'could_not_connect' => 'PHPCI ne peut pas se connecter à MySQL à partir des informations fournies. Veuillez réessayer..', 'setting_up_db' => 'Paramétrage de la base de données... ', - 'user_created' => 'Le compte utilisateur a été créé!', + 'user_created' => 'Le compte utilisateur a été créé !', 'failed_to_create' => 'PHPCI n\'a pas réussi à créer votre compte admin.', 'config_exists' => 'Le fichier de configuration PHPCI existe et n\'est pas vide.', 'update_instead' => 'Si vous essayez de mettre à jour PHPCI, merci d\'utiliser la commande phpci:update.', @@ -330,6 +353,12 @@ PHPCI', 'create_admin_user' => 'Créer un utilisateur admin', 'incorrect_format' => 'Format incorrect', + // Create Build Command + 'create_build_project' => 'Créer un build projet', + 'project_id_argument' => 'ID du projet', + 'commit_id_option' => 'ID du commit', + 'branch_name_option' => 'Branche', + // Run Command 'run_all_pending' => 'Démarrage de tout les builds PHPCI en attente.', 'finding_builds' => 'Découverte des builds à traiter', @@ -365,7 +394,7 @@ PHPCI', 'n_emails_sent' => '%d emails envoyés.', 'n_emails_failed' => '%d emails dont l\'envoi a échoué.', 'unable_to_set_env' => 'Impossible d\'initialiser la variable d\'environnement', - 'tag_created' => 'Tag créé par PHPCI: %s', + 'tag_created' => 'Tag créé par PHPCI : %s', 'x_built_at_x' => '%PROJECT_TITLE% construit à %BUILD_URI%', 'hipchat_settings' => 'Merci de définir une "room" et un "authToken" pour le plugin hipchat_notify', 'irc_settings' => 'Vous devez configurer un serveur, une "room" et un "nick".', diff --git a/PHPCI/Languages/lang.it.php b/PHPCI/Languages/lang.it.php index 7134c488..d254fbcd 100644 --- a/PHPCI/Languages/lang.it.php +++ b/PHPCI/Languages/lang.it.php @@ -11,25 +11,24 @@ $strings = array( 'language_name' => 'Italiano', 'language' => 'Lingua', - + // Log in: 'log_in_to_phpci' => 'Accedi a PHPCI', 'login_error' => 'Indirizzo email o password errati', 'forgotten_password_link' => 'Hai dimenticato la tua password?', - 'reset_emailed' => 'Ti abbiamo inviato un link per ripristinare la tua password via email.', + 'reset_emailed' => 'Ti abbiamo inviato un link via email per ripristinare la tua password.', 'reset_header' => 'Non preoccuparti!
E\' sufficiente inserire il tuo indirizzo email di seguito e ti invieremo una email con il link per il ripristino della tua password.', 'reset_email_address' => 'Inserisci il tuo indirizzo email:', 'reset_send_email' => 'Invia il link di reset della password', 'reset_enter_password' => 'Per favore inserisci la nuova password', 'reset_new_password' => 'Nuova password:', 'reset_change_password' => 'Cambia password', - 'reset_no_user_exists' => 'No user exists with that email address, please try again.', 'reset_no_user_exists' => 'Non esiste nessun utente con questo indirizzo email, per favore prova ancora.', 'reset_email_body' => 'Ciao %s, hai ricevuto questa email perché tu, o qualcun\'altro, ha richiesto un reset della password per PHPCI. -Se questa mail è tua, per favore apri il seguente link per resettare la tua password: %ssession/reset-password/%d/%s +Se questa mail è tua, per favore apri il seguente link per ripristinare la tua password: %ssession/reset-password/%d/%s altrimenti, per favore, ignora questa email e nessuna azione verrà intrapresa. @@ -40,6 +39,7 @@ PHPCI', 'reset_email_title' => 'Ripristino della password di PHPCI per %s', 'reset_invalid' => 'Richeista di ripristino password non valida.', 'email_address' => 'Indirizzo Email', + 'login' => 'Login / Email Address', 'password' => 'Password', 'log_in' => 'Accedi', @@ -113,7 +113,9 @@ PHPCI', (se non puoi aggiungere il file phpci.yml nel repository di questo progetto)', 'default_branch' => 'Nome del branch di default', 'allow_public_status' => 'Vuoi rendere pubblica la pagina dello stato e l\'immagine per questo progetto?', - 'save_project' => 'Salca il Progetto', + 'archived' => 'Archived', + 'archived_menu' => 'Archived', + 'save_project' => 'Salva il Progetto', 'error_mercurial' => 'L\'URL del repository Mercurial URL deve iniziare con http:// o https://', 'error_remote' => 'L\'URL del repository deve iniziare con git://, http:// o https://', @@ -127,6 +129,7 @@ PHPCI', 'all_branches' => 'Tutti i Branche', 'builds' => 'Builds', 'id' => 'ID', + 'date' => 'Data', 'project' => 'Progetto', 'commit' => 'Commit', 'branch' => 'Branch', @@ -137,16 +140,16 @@ PHPCI', 'delete_build' => 'Rimuovi build', 'webhooks' => 'Webhooks', - 'webhooks_help_github' => 'Per efettuare la build automatica di questo progetto quando vengono pushati nuovi commit, + 'webhooks_help_github' => 'Per effettuare la build automatica di questo progetto quando vengono inseriti nuovi commit, aggiungi l\'URL seguente come "Webhook" nella sezione Webhooks and Services del tuo repository su GitHub.', - 'webhooks_help_gitlab' => 'Per efettuare la build automatica di questo progetto quando vengono pushati nuovi commit, + 'webhooks_help_gitlab' => 'Per effettuare la build automatica di questo progetto quando vengono inseriti nuovi commit, aggiungi l\'URL seguente come "Webhook URL" nella sezione "WebHook URL" del tuo repository GitLab.', - 'webhooks_help_bitbucket' => 'Per efettuare la build automatica di questo progetto quando vengono pushati nuovi + 'webhooks_help_bitbucket' => 'Per effettuare la build automatica di questo progetto quando vengono inseriti nuovi commit, aggiungi l\'URL seguente come serizio "POST" nella sezione Services del tuo repository su BITBUCKET.', @@ -157,7 +160,7 @@ PHPCI', 'rebuild_now' => 'Esegui nuovamente la build ora', - 'committed_by_x' => 'Committato da %s', + 'committed_by_x' => 'Inviato da %s', 'commit_id_x' => 'Commit: %s', 'chart_display' => 'Questo grafico verrà mostrato una volta terminata la build.', @@ -169,15 +172,17 @@ PHPCI', 'logical_lines' => 'Linee di logica', 'lines_of_code' => 'Linee di codice', 'build_log' => 'Log della build', - 'quality_trend' => 'Trand della qualità', - 'phpmd_warnings' => 'Warning di PHPMD', - 'phpcs_warnings' => 'Warning di PHPCS', + 'quality_trend' => 'Trend della qualità', + 'codeception_errors' => 'Errori di Codeception', + 'phpmd_warnings' => 'Avvisi di PHPMD', + 'phpcs_warnings' => 'Avvisi di PHPCS', 'phpcs_errors' => 'Errori di PHPCS', 'phplint_errors' => 'Errori di Lint', 'phpunit_errors' => 'Errori di PHPUnit', 'phpdoccheck_warnings' => 'Docblocks mancanti', 'issues' => 'Segnalazioni', + 'codeception' => 'Codeception', 'phpcpd' => 'PHP Copy/Paste Detector', 'phpcs' => 'PHP Code Sniffer', 'phpdoccheck' => 'Docblocks mancanti', @@ -194,14 +199,20 @@ PHPCI', 'end' => 'Finisci', 'from' => 'Da', 'to' => 'A', - 'suite' => 'Suite', - 'test' => 'Test', 'result' => 'Risultati', 'ok' => 'OK', 'took_n_seconds' => 'Sono stati impiegati %d seconds', 'build_created' => 'Build Creata', 'build_started' => 'Build Avviata', 'build_finished' => 'Build Terminata', + 'test_message' => 'Message', + 'test_no_message' => 'No message', + 'test_success' => 'Successful: %d', + 'test_fail' => 'Failures: %d', + 'test_skipped' => 'Skipped: %d', + 'test_error' => 'Errors: %d', + 'test_todo' => 'Todos: %d', + 'test_total' => '%d test(s)', // Users 'name' => 'Nome', @@ -228,16 +239,16 @@ PHPCI', 'settings_github_linked' => 'Il tuo account GitHub è stato collegato.', 'settings_github_not_linked' => 'Il tuo account GitHub non può essere collegato.', 'build_settings' => 'Configurazioni della build', - 'github_application' => 'Applicatzione GitHub', + 'github_application' => 'Applicazione GitHub', 'github_sign_in' => 'Prima di poter iniziare ad usare GitHub, è necessario collegarsi e garantire a PHPCI l\'accesso al tuo account.', 'github_phpci_linked' => 'PHPCI è stato collegato correttamente al tuo account GitHub.', 'github_where_to_find' => 'Dove trovare queste...', - 'github_where_help' => 'Se sei il proprietario dell\'applicazione, puoi trovare queste informazioni nell\'are delle + 'github_where_help' => 'Se sei il proprietario dell\'applicazione, puoi trovare queste informazioni nell\'area delle configurazioni dell\'applicazione.', 'email_settings' => 'Impostazioni Email', - 'email_settings_help' => 'Prima che possa inviare le email con lo status PHPCI, devi configurare l\'SMTP qio sotto.', + 'email_settings_help' => 'Prima che possa inviare le email con lo status PHPCI, devi configurare l\'SMTP qui sotto.', 'application_id' => 'ID dell\'Applicazione', 'application_secret' => 'Secret dell\'Applicazione', @@ -263,7 +274,7 @@ PHPCI', // Plugins 'cannot_update_composer' => 'PHPCI non può aggiornare composer.json per te non essendo scrivibile.', 'x_has_been_removed' => '%s è stato rimosso.', - 'x_has_been_added' => '%s è stato aggiunto al composer.json per te verrà installato la prossima volta che eseguirai + 'x_has_been_added' => '%s è stato aggiunto al file composer.json per te, verrà installato la prossima volta che eseguirai composer update.', 'enabled_plugins' => 'Plugins attivati', 'provided_by_package' => 'Fornito dal pacchetto', @@ -298,9 +309,9 @@ PHPCI', Per favore controlla gli errori riportati prima di proseguire.', 'must_be_valid_email' => 'Deve essere un indirizzo email valido.', 'must_be_valid_url' => 'Deve essere un URL valido.', - 'enter_name' => 'Nome dell\'amministratore:', - 'enter_email' => 'Email dell\'amministratore:', - 'enter_password' => 'Password dell\'amministratore:', + 'enter_name' => 'Nome dell\'amministratore: ', + 'enter_email' => 'Email dell\'amministratore: ', + 'enter_password' => 'Password dell\'amministratore: ', 'enter_phpci_url' => 'L\'URL di PHPCI ("http://phpci.locale" ad esempio): ', 'enter_db_host' => 'Per favore inserisci l\'host MySQL [localhost]: ', @@ -333,12 +344,18 @@ PHPCI', 'create_admin_user' => 'Crea un nuovo utente amministrarore', 'incorrect_format' => 'Formato errato', + // Create Build Command + 'create_build_project' => 'Create a build for a project', + 'project_id_argument' => 'A project ID', + 'commit_id_option' => 'Commit ID to build', + 'branch_name_option' => 'Branch to build', + // Run Command 'run_all_pending' => 'Esegui tutte le build in attesa su PHPCI.', 'finding_builds' => 'Ricerca delel build da processare', 'found_n_builds' => 'Trovate %d build', 'skipping_build' => 'Saltata la build %d - La build del progetto è già in corso.', - 'marked_as_failed' => 'Build %d è satata contrassegnata come come fallita per un timeout.', + 'marked_as_failed' => 'Build %d è stata contrassegnata come fallita per un timeout.', // Builder 'missing_phpci_yml' => 'Questo progetto non contiene il file phpci.yml, o il file è vuoto.', diff --git a/PHPCI/Languages/lang.nl.php b/PHPCI/Languages/lang.nl.php index e03e709f..96d9f5d5 100644 --- a/PHPCI/Languages/lang.nl.php +++ b/PHPCI/Languages/lang.nl.php @@ -39,6 +39,7 @@ PHPCI', 'reset_email_title' => 'PHPCI wachtwoord reset voor %s', 'reset_invalid' => 'Ongeldig wachtwoord reset verzoek', 'email_address' => 'E-mailadres', + 'login' => 'Login / Email Address', 'password' => 'Wachtwoord', 'log_in' => 'Log in', @@ -113,6 +114,8 @@ van je gekozen source code hosting platform', (indien je geen phpci.yml bestand aan de project repository kan toevoegen)', 'default_branch' => 'Standaard branch naam', 'allow_public_status' => 'Publieke statuspagina en afbeelding beschikbaar maken voor dit project?', + 'archived' => 'Archived', + 'archived_menu' => 'Archived', 'save_project' => 'Project opslaan', 'error_mercurial' => 'Mercurial repository URL dient te starten met http:// of https://', @@ -126,6 +129,7 @@ van je gekozen source code hosting platform', 'all_branches' => 'Alle brances', 'builds' => 'Builds', 'id' => 'ID', + 'date' => 'Datum', 'project' => 'Project', 'commit' => 'Commit', 'branch' => 'Branch', @@ -167,6 +171,7 @@ Services sectie van je Bitbucket repository toegevoegd worden.', 'lines_of_code' => 'Lijnen code', 'build_log' => 'Build Log', 'quality_trend' => 'Kwaliteitstrend', + 'codeception_errors' => 'Codeception Fouten', 'phpmd_warnings' => 'PHPMD Waarschuwingen', 'phpcs_warnings' => 'PHPCS Waarschuwingen', 'phpcs_errors' => 'PHPCS Fouten', @@ -175,6 +180,7 @@ Services sectie van je Bitbucket repository toegevoegd worden.', 'phpdoccheck_warnings' => 'Ontbrekende Docblocks', 'issues' => 'Problemen', + 'codeception' => 'Codeception', 'phpcpd' => 'PHP Copy/Paste Detector', 'phpcs' => 'PHP Code Sniffer', 'phpdoccheck' => 'Ontbrekende Docblocks', @@ -191,14 +197,20 @@ Services sectie van je Bitbucket repository toegevoegd worden.', 'end' => 'Einde', 'from' => 'Van', 'to' => 'Tot', - 'suite' => 'Suite', - 'test' => 'Test', 'result' => 'Resultaat', 'ok' => 'OK', 'took_n_seconds' => 'Duurde %d seconden', 'build_created' => 'Build aangemaakt', 'build_started' => 'Build gestart', 'build_finished' => 'Build beëindigd', + 'test_message' => 'Message', + 'test_no_message' => 'No message', + 'test_success' => 'Successful: %d', + 'test_fail' => 'Failures: %d', + 'test_skipped' => 'Skipped: %d', + 'test_error' => 'Errors: %d', + 'test_todo' => 'Todos: %d', + 'test_total' => '%d test(s)', // Users 'name' => 'Naam', @@ -295,15 +307,15 @@ keer je composer update uitvoert.', Gelieve de fouten na te kijken vooraleer verder te gaan.', 'must_be_valid_email' => 'Moet een geldig e-mailadres zijn.', 'must_be_valid_url' => 'Moet een geldige URL zijn.', - 'enter_name' => 'Administrator naam:', - 'enter_email' => 'Administrator e-mailadres:', - 'enter_password' => 'Administrator wachtwoord:', - 'enter_phpci_url' => 'Je PHPCI URL (bijvoorbeeld "http://phpci.local")', + 'enter_name' => 'Administrator naam: ', + 'enter_email' => 'Administrator e-mailadres: ', + 'enter_password' => 'Administrator wachtwoord: ', + 'enter_phpci_url' => 'Je PHPCI URL (bijvoorbeeld "http://phpci.local"): ', - 'enter_db_host' => 'Vul je MySQL host in [localhost]:', - 'enter_db_name' => 'Vul je MySQL databasenaam in [phpci]:', - 'enter_db_user' => 'Vul je MySQL gebruikersnaam in [phpci]:', - 'enter_db_pass' => 'Vul je MySQL watchtwoord in:', + 'enter_db_host' => 'Vul je MySQL host in [localhost]: ', + 'enter_db_name' => 'Vul je MySQL databasenaam in [phpci]: ', + 'enter_db_user' => 'Vul je MySQL gebruikersnaam in [phpci]: ', + 'enter_db_pass' => 'Vul je MySQL watchtwoord in: ', 'could_not_connect' => 'PHPCI kon met deze gegevens geen verbinding maken met MySQL. Gelieve opnieuw te proberen.', 'setting_up_db' => 'Database wordt aangemaakt...', 'user_created' => 'Gebruikersprofiel aangemaakt!', @@ -330,6 +342,12 @@ Gelieve de fouten na te kijken vooraleer verder te gaan.', 'create_admin_user' => 'Administrator-gebruiker aanmaken', 'incorrect_format' => 'Incorrect formaat', + // Create Build Command + 'create_build_project' => 'Create a build for a project', + 'project_id_argument' => 'A project ID', + 'commit_id_option' => 'Commit ID to build', + 'branch_name_option' => 'Branch to build', + // Run Command 'run_all_pending' => 'Voer alle wachtende PHPCI builds uit.', 'finding_builds' => 'Zoekt builds om te verwerken', diff --git a/PHPCI/Languages/lang.pl.php b/PHPCI/Languages/lang.pl.php index a614d29d..e1d3c3bf 100644 --- a/PHPCI/Languages/lang.pl.php +++ b/PHPCI/Languages/lang.pl.php @@ -39,6 +39,7 @@ PHPCI', 'reset_email_title' => 'Reset Hasła PHPCI dla %s', 'reset_invalid' => 'Prośba o zmianę hasła jest nieważna.', 'email_address' => 'Adres email', + 'login' => 'Login / Email Address', 'password' => 'Hasło', 'log_in' => 'Zaloguj się', @@ -101,6 +102,7 @@ od wybranego kodu źródłowego platformy hostingowej.', 'remote' => 'Zdalny URL ', 'local' => 'Lokalna Ścieżka ', 'hg' => 'Mercurial', + 'svn' => 'Subversion', 'where_hosted' => 'Gdzie hostowany jest Twój projekt?', 'choose_github' => 'Wybierz repozytorium GitHub:', @@ -113,6 +115,8 @@ od wybranego kodu źródłowego platformy hostingowej.', (jeśli nie możesz dodać pliku phpci.yml do repozytorium projektu)', 'default_branch' => 'Domyślna nazwa gałęzi', 'allow_public_status' => 'Włączyć status publiczny dla tego projektu?', + 'archived' => 'W archiwum', + 'archived_menu' => 'W archiwum', 'save_project' => 'Zachowaj Projekt', 'error_mercurial' => 'URL repozytorium Mercurialnego powinno zaczynać się od http:// and https://', @@ -126,6 +130,7 @@ od wybranego kodu źródłowego platformy hostingowej.', 'all_branches' => 'Wszystkie Gałęzie', 'builds' => 'Budowania', 'id' => 'ID', + 'date' => 'Data', 'project' => 'Projekt', 'commit' => 'Commit', 'branch' => 'Gałąź', @@ -167,6 +172,7 @@ Services repozytoria Bitbucket.', 'lines_of_code' => 'Linie Kodu', 'build_log' => 'Log Budowania', 'quality_trend' => 'Trend Jakości', + 'codeception_errors' => 'Błędy Codeception', 'phpmd_warnings' => 'Alerty PHPMD', 'phpcs_warnings' => 'Alerty PHPCS', 'phpcs_errors' => 'Błędy PHPCS', @@ -175,12 +181,15 @@ Services repozytoria Bitbucket.', 'phpdoccheck_warnings' => 'Brakuje sekcji DocBlock', 'issues' => 'Problemy', + 'codeception' => 'Codeception', 'phpcpd' => 'PHP Copy/Paste Detector', 'phpcs' => 'PHP Code Sniffer', 'phpdoccheck' => 'Brakuje sekcji DocBlock', 'phpmd' => 'PHP Mess Detector', - 'phpspec' => 'Speck PHP', - 'phpunit' => 'Jednostka PHP', + 'phpspec' => 'PHPSpec', + 'phpunit' => 'PHPUnit', + 'technical_debt' => 'Dług technologiczny', + 'behat' => 'Behat', 'file' => 'Plik', 'line' => 'Linia', @@ -191,14 +200,20 @@ Services repozytoria Bitbucket.', 'end' => 'Koniec', 'from' => 'Od', 'to' => 'Do', - 'suite' => 'Zestaw ', - 'test' => 'Test', 'result' => 'Wynik', 'ok' => 'OK', 'took_n_seconds' => 'Zajęło %d sekund', 'build_created' => 'Budowanie Stworzone', 'build_started' => 'Budowanie Rozpoczęte', 'build_finished' => 'Budowanie Zakończone', + 'test_message' => 'Wiadomość', + 'test_no_message' => 'Brak wiadomości', + 'test_success' => 'Powodzenie: %d', + 'test_fail' => 'Niepowodzenia: %d', + 'test_skipped' => 'Pominęte: %d', + 'test_error' => 'Błędy: %d', + 'test_todo' => 'Do zrobienia: %d', + 'test_total' => '%d test(ów)', // Users 'name' => 'Nazwa', @@ -293,15 +308,15 @@ wywołaniu polecenia composer update.', Przejrzyj powyższą listę błędów przed kontynuowaniem.', 'must_be_valid_email' => 'Poprawny adres email jest wymagany.', 'must_be_valid_url' => 'Poprawny URL jest wymagany.', - 'enter_name' => 'Imię Admina:', - 'enter_email' => 'Email Admina:', - 'enter_password' => 'Hasło Admina:', - 'enter_phpci_url' => 'URL PHPCI (na przykład "http://phpci.local"):', + 'enter_name' => 'Imię Admina: ', + 'enter_email' => 'Email Admina: ', + 'enter_password' => 'Hasło Admina: ', + 'enter_phpci_url' => 'URL PHPCI (na przykład "http://phpci.local"): ', - 'enter_db_host' => 'Wpisz hosta MySQL [host lokalny]:', - 'enter_db_name' => 'Wpisz nazwę bazy danych MySQL [phpci]:', - 'enter_db_user' => 'Wpisz nazwę użytkownika MySQL [phpci]:', - 'enter_db_pass' => 'Wpisz hasło MySQL:', + 'enter_db_host' => 'Wpisz hosta MySQL [host lokalny]: ', + 'enter_db_name' => 'Wpisz nazwę bazy danych MySQL [phpci]: ', + 'enter_db_user' => 'Wpisz nazwę użytkownika MySQL [phpci]: ', + 'enter_db_pass' => 'Wpisz hasło MySQL: ', 'could_not_connect' => 'Z podanymi ustawieniami PHPCI nie udało się połączyć z MySQL. Spróbuj ponownie.', 'setting_up_db' => 'Ustawianie Twojej bazy danych...', 'user_created' => 'Utworzono konto użytkownika!', @@ -328,6 +343,12 @@ Przejrzyj powyższą listę błędów przed kontynuowaniem.', 'create_admin_user' => 'Utwórz admina', 'incorrect_format' => 'Niepoprawny format', + // Create Build Command + 'create_build_project' => 'Utwórz budowanie dla projektu', + 'project_id_argument' => 'ID projektu', + 'commit_id_option' => 'ID Commita do budowania', + 'branch_name_option' => 'Gałąź do budowania', + // Run Command 'run_all_pending' => 'Uruchom wszystkie oczekujące budowy w PHPCI', 'finding_builds' => 'Szukam budów do przetwarzania.', diff --git a/PHPCI/Languages/lang.ru.php b/PHPCI/Languages/lang.ru.php index 4abc9721..0a7acff2 100644 --- a/PHPCI/Languages/lang.ru.php +++ b/PHPCI/Languages/lang.ru.php @@ -38,10 +38,10 @@ PHPCI', 'reset_email_title' => 'Сброс пароля PHPCI для %s', 'reset_invalid' => 'Некорректный запрос на сброс пароля.', 'email_address' => 'Email', + 'login' => 'Логин / Email', 'password' => 'Пароль', 'log_in' => 'Войти', - // Top Nav 'toggle_navigation' => 'Скрыть/показать панель навигации', 'n_builds_pending' => '%d сборок ожидает', @@ -84,7 +84,7 @@ PHPCI', 'success' => 'Успешно', 'successful' => 'Успешна', 'failed' => 'Провалена', - 'manual_build' => 'Ручной сборки', + 'manual_build' => 'Запущена вручную', // Add/Edit Project: 'new_project' => 'Новый проект', @@ -99,6 +99,7 @@ PHPCI', 'remote' => 'Внешний URL', 'local' => 'Локальный путь', 'hg' => 'Mercurial', + 'svn' => 'Subversion', 'where_hosted' => 'Расположение проекта', 'choose_github' => 'Выберите GitHub репозиторий:', @@ -106,11 +107,13 @@ PHPCI', 'repo_name' => 'Репозиторий / Внешний URL / Локальный путь', 'project_title' => 'Название проекта', 'project_private_key' => 'Приватный ключ для доступа к репозиторию - (оставьте поле пустым для локального использования и/или анонимного доступа)', + (оставьте поле пустым для локального использования и/или анонимного доступа)', 'build_config' => 'Конфигурация сборки проекта для PHPCI - (если вы не добавили файл phpci.yml в репозиторий вашего проекта)', + (если вы не добавили файл phpci.yml в репозиторий вашего проекта)', 'default_branch' => 'Ветка по умолчанию', 'allow_public_status' => 'Разрешить публичный статус и изображение (статуса) для проекта', + 'archived' => 'Архивный', + 'archived_menu' => 'Архив', 'save_project' => 'Сохранить проект', 'error_mercurial' => 'URL репозитория Mercurial должен начинаться с http:// или https://', @@ -124,6 +127,7 @@ PHPCI', 'all_branches' => 'Все ветки', 'builds' => 'Сборки', 'id' => 'ID', + 'date' => 'Дата', 'project' => 'Проект', 'commit' => 'Коммит', 'branch' => 'Ветка', @@ -135,13 +139,13 @@ PHPCI', 'webhooks' => 'Webhooks', 'webhooks_help_github' => 'Чтобы Автоматически собирать этот проект при публикации новых коммитов, добавьте URL ниже в качестве нового хука в разделе настроек Webhooks - and Services вашего GitHub репозитория.', + and Services вашего GitHub репозитория.', 'webhooks_help_gitlab' => 'Чтобы Автоматически собирать этот проект при публикации новых коммитов, добавьте URL ниже в качестве "WebHook URL" в разделе "Web Hooks" вашего GitLab репозитория.', 'webhooks_help_bitbucket' => 'Чтобы Автоматически собирать этот проект при публикации новых коммитов, добавьте URL ниже как "POST" сервис в разделе - Services вашего Bitbucket репозитория.', + Services вашего Bitbucket репозитория.', // View Build 'build_x_not_found' => 'Сборки с ID %d не существует.', @@ -162,6 +166,7 @@ PHPCI', 'lines_of_code' => 'Строк кода', 'build_log' => 'Лог сборки', 'quality_trend' => 'Тенденция качества', + 'codeception_errors' => 'Ошибки Codeception', 'phpmd_warnings' => 'Предупреждения PHPMD', 'phpcs_warnings' => 'Предупреждения PHPCS', 'phpcs_errors' => 'Ошибки PHPCS', @@ -170,30 +175,44 @@ PHPCI', 'phpdoccheck_warnings' => 'Пропущенные Docblocks', 'issues' => 'Проблемы', + 'codeception' => 'Codeception', 'phpcpd' => 'PHP Copy/Paste Detector', 'phpcs' => 'PHP Code Sniffer', 'phpdoccheck' => 'Missing Docblocks', 'phpmd' => 'PHP Mess Detector', 'phpspec' => 'PHP Spec', 'phpunit' => 'PHP Unit', + 'technical_debt' => 'Технические долги', + 'behat' => 'Behat', + + 'codeception_feature' => 'Свойство', + 'codeception_suite' => 'Набор', + 'codeception_time' => 'Время', + 'codeception_synopsis' => 'Тестов выполнено: %1$d (за %2$f сек.). Провалов: %3$d.', 'file' => 'Файл', 'line' => 'Строка', 'class' => 'Класс', 'method' => 'Метод', 'message' => 'Сообщение', - 'start' => 'Запуск', + 'start' => 'Начало', 'end' => 'Конец', - 'from' => 'От', - 'to' => 'До', - 'suite' => 'Комплект', - 'test' => 'Тест', + 'from' => 'Из', + 'to' => 'В', 'result' => 'Результат', 'ok' => 'OK', 'took_n_seconds' => 'Заняло секунд: %d', 'build_created' => 'Сборка создана', 'build_started' => 'Сборка запущена', 'build_finished' => 'Сборка окончена', + 'test_message' => 'Message', + 'test_no_message' => 'No message', + 'test_success' => 'Успешно: %d', + 'test_fail' => 'Провалено: %d', + 'test_skipped' => 'Пропущено: %d', + 'test_error' => 'Ошибок: %d', + 'test_todo' => 'Todo: %d', + 'test_total' => 'Тестов: %d', // Users 'name' => 'Имя', @@ -268,6 +287,19 @@ PHPCI', 'search_packagist_for_more' => 'Искать на Packagist', 'search' => 'Искать »', + // Summary plugin + 'build-summary' => 'Сводка', + 'stage' => 'Этап', + 'duration' => 'Продолжительность', + 'plugin' => 'Плагин', + 'stage_setup' => 'Установка', + 'stage_test' => 'тестирование', + 'stage_complete' => 'Завершение', + 'stage_success' => 'Успешное завершение', + 'stage_failure' => 'Провал', + 'stage_broken' => 'Поломка', + 'stage_fixed' => 'Исправление', + // Installer 'installation_url' => 'URL-адрес PHPCI для установки', 'db_host' => 'Хост базы данных', @@ -288,9 +320,9 @@ PHPCI', Пожалуйста, просмотрите возникшие ошибки перед тем, как продолжить.', 'must_be_valid_email' => 'Должен быть корректным email-адресом.', 'must_be_valid_url' => 'Должен быть корректным URL-адресом.', - 'enter_name' => 'Имя администратора:', - 'enter_email' => 'Email администратора:', - 'enter_password' => 'Пароль администратора:', + 'enter_name' => 'Имя администратора: ', + 'enter_email' => 'Email администратора: ', + 'enter_password' => 'Пароль администратора: ', 'enter_phpci_url' => 'URL-адрес вашего PHPCI (например: "http://phpci.local"): ', 'enter_db_host' => 'Пожалуйста, введите хост MySQL [localhost]: ', @@ -323,6 +355,12 @@ PHPCI', 'create_admin_user' => 'Добавить аккаунт администратора', 'incorrect_format' => 'Неверный формат', + // Create Build Command + 'create_build_project' => 'Создать сборку проекта', + 'project_id_argument' => 'ID проекта', + 'commit_id_option' => 'ID коммита для сборки', + 'branch_name_option' => 'Ветка для сборки', + // Run Command 'run_all_pending' => 'Запустить все ожидающие PHPCI сборки.', 'finding_builds' => 'Поиск сборок для запуска', diff --git a/PHPCI/Languages/lang.uk.php b/PHPCI/Languages/lang.uk.php index 24f9cbb2..54ced220 100644 --- a/PHPCI/Languages/lang.uk.php +++ b/PHPCI/Languages/lang.uk.php @@ -8,7 +8,7 @@ */ $strings = array( - 'language_name' => 'Український', + 'language_name' => 'Українська', 'language' => 'Мова', // Log in: @@ -20,10 +20,10 @@ $strings = array( і вам буде надіслано листа із посиланням на скидання паролю.', 'reset_email_address' => 'Введіть свою email адресу:', 'reset_send_email' => 'Скидання пароля', - 'reset_enter_password' => 'Введіть будь-ласка новий пароль', + 'reset_enter_password' => 'Введіть, будь ласка, новий пароль', 'reset_new_password' => 'Новий пароль:', 'reset_change_password' => 'Змінити пароль', - 'reset_no_user_exists' => 'Не існує користувача з такою email адресою, будь-ласка повторіть знову.', + 'reset_no_user_exists' => 'Не існує користувача з такою email адресою, будь ласка, повторіть знову.', 'reset_email_body' => 'Привіт, %s, Ви отримали цей лист, тому що ви або хтось інший запросили скидання пароля в PHPCI. @@ -39,6 +39,7 @@ PHPCI', 'reset_email_title' => 'Скидання пароль PHPCI для %s', 'reset_invalid' => 'Невірний запит скидання паролю.', 'email_address' => 'Email адреса', + 'login' => 'Логин / Email адреса', 'password' => 'Пароль', 'log_in' => 'Увійти', @@ -62,7 +63,7 @@ PHPCI', 'manage_users' => 'Управління користувачами', 'plugins' => 'Плагіни', 'view' => 'Переглянути', - 'build_now' => 'Збірати', + 'build_now' => 'Зібрати', 'edit_project' => 'Редагувати проект', 'delete_project' => 'Видалити проект', @@ -112,6 +113,8 @@ PHPCI', (якщо ви не додали файл phpci.yml до репозиторію вашого проекту)', 'default_branch' => 'Назва гілки за замовчуванням', 'allow_public_status' => 'Увімкнути публічну сторінку статусу та зображення для цього проекта?', + 'archived' => 'Архівний', + 'archived_menu' => 'Архів', 'save_project' => 'Зберегти проект', 'error_mercurial' => 'URL репозиторію Mercurial повинен починатись із http:// або https://', @@ -125,6 +128,7 @@ PHPCI', 'all_branches' => 'Усі гілки', 'builds' => 'Збірки', 'id' => 'ID', + 'date' => 'Дата', 'project' => 'Проект', 'commit' => 'Комміт', 'branch' => 'Гілка', @@ -167,14 +171,16 @@ PHPCI', 'lines_of_code' => 'Рядки коду', 'build_log' => 'Лог збірки', 'quality_trend' => 'Тенденція якості', + 'codeception_errors' => 'Помилки Codeception', 'phpmd_warnings' => 'Попередження PHPMD', 'phpcs_warnings' => 'Попередження PHPCS', 'phpcs_errors' => 'Помилки PHPCS', 'phplint_errors' => 'Помилки Lint', - 'phpunit_errors' => 'Помилки PHPCS', + 'phpunit_errors' => 'Помилки PHPUnit', 'phpdoccheck_warnings' => 'Відсутні Docblocks', 'issues' => 'Проблеми', + 'codeception' => 'Codeception', 'phpcpd' => 'PHP Copy/Paste Detector', 'phpcs' => 'PHP Code Sniffer', 'phpdoccheck' => 'Відсутні Docblocks', @@ -183,7 +189,7 @@ PHPCI', 'phpunit' => 'PHP Unit', 'file' => 'Файл', - 'line' => 'Строка', + 'line' => 'Рядок', 'class' => 'Клас', 'method' => 'Метод', 'message' => 'Повідомлення', @@ -191,14 +197,20 @@ PHPCI', 'end' => 'Кінець', 'from' => 'Від', 'to' => 'До', - 'suite' => 'Комплект', - 'test' => 'Тест', 'result' => 'Результат', 'ok' => 'OK', 'took_n_seconds' => 'Зайняло %d секунд', 'build_created' => 'Збірка створена', 'build_started' => 'Збірка розпочата', 'build_finished' => 'Збірка завершена', + 'test_message' => 'Message', + 'test_no_message' => 'No message', + 'test_success' => 'Successful: %d', + 'test_fail' => 'Failures: %d', + 'test_skipped' => 'Skipped: %d', + 'test_error' => 'Errors: %d', + 'test_todo' => 'Todos: %d', + 'test_total' => '%d test(s)', // Users 'name' => 'Ім’я', @@ -295,15 +307,15 @@ PHPCI', Будь ласка, продивіться наявні помилки перед тим, як продовжити.', 'must_be_valid_email' => 'Повинно бути коректною email адресою.', 'must_be_valid_url' => 'Повинно бути коректним URL.', - 'enter_name' => 'Ім’я адміністратора:', - 'enter_email' => 'Email адміністратора:', - 'enter_password' => 'Пароль адміністратора:', - 'enter_phpci_url' => 'URL адреса вашого PHPCI (наприклад, "http://phpci.local"):', + 'enter_name' => 'Ім’я адміністратора: ', + 'enter_email' => 'Email адміністратора: ', + 'enter_password' => 'Пароль адміністратора: ', + 'enter_phpci_url' => 'URL адреса вашого PHPCI (наприклад, "http://phpci.local"): ', - 'enter_db_host' => 'Будь ласка, введіть хост MySQL [localhost]:', - 'enter_db_name' => 'Будь ласка, введить ім’я бази даних MySQL [phpci]:', - 'enter_db_user' => 'Будь ласка, введить ім’я користувача MySQL [phpci]:', - 'enter_db_pass' => 'Будь ласка, введить ваш пароль MySQL:', + 'enter_db_host' => 'Будь ласка, введіть хост MySQL [localhost]: ', + 'enter_db_name' => 'Будь ласка, введить ім’я бази даних MySQL [phpci]: ', + 'enter_db_user' => 'Будь ласка, введить ім’я користувача MySQL [phpci]: ', + 'enter_db_pass' => 'Будь ласка, введить ваш пароль MySQL: ', 'could_not_connect' => 'PHPCI не може підключитися до MySQL із наданими параметрами. Будь ласка, спробуйте ще раз.', 'setting_up_db' => 'Налаштування вашої бази даних...', 'user_created' => 'Аккаунт користувача створено!', @@ -330,6 +342,12 @@ PHPCI', 'create_admin_user' => 'Створити аккаунт адміністратора', 'incorrect_format' => 'Невірний формат', + // Create Build Command + 'create_build_project' => 'Create a build for a project', + 'project_id_argument' => 'A project ID', + 'commit_id_option' => 'Commit ID to build', + 'branch_name_option' => 'Branch to build', + // Run Command 'run_all_pending' => 'Запустити всі PHPCI збірки, які очікують.', 'finding_builds' => 'Пошук збірок для обробки', diff --git a/PHPCI/Logging/BuildDBLogHandler.php b/PHPCI/Logging/BuildDBLogHandler.php index bda8cfce..91664b25 100644 --- a/PHPCI/Logging/BuildDBLogHandler.php +++ b/PHPCI/Logging/BuildDBLogHandler.php @@ -12,6 +12,7 @@ namespace PHPCI\Logging; use b8\Store\Factory; use Monolog\Handler\AbstractProcessingHandler; use PHPCI\Model\Build; +use Psr\Log\LogLevel; /** * Class BuildDBLogHandler writes the build log to the database. diff --git a/PHPCI/Logging/BuildLogger.php b/PHPCI/Logging/BuildLogger.php index 73f3b464..a68e9e6d 100644 --- a/PHPCI/Logging/BuildLogger.php +++ b/PHPCI/Logging/BuildLogger.php @@ -67,7 +67,7 @@ class BuildLogger implements LoggerAwareInterface } } - /** + /** * Add a success-coloured message to the log. * @param string */ @@ -98,6 +98,17 @@ class BuildLogger implements LoggerAwareInterface ); } + /** + * Add a debug message to the log. + * @param string + */ + public function logDebug($message) + { + if (defined('PHPCI_DEBUG_MODE') && PHPCI_DEBUG_MODE) { + $this->log("\033[0;33m" . $message . "\033[0m"); + } + } + /** * Sets a logger instance on the object * diff --git a/PHPCI/Logging/Handler.php b/PHPCI/Logging/Handler.php index ebfa2620..e22351da 100644 --- a/PHPCI/Logging/Handler.php +++ b/PHPCI/Logging/Handler.php @@ -70,7 +70,6 @@ class Handler public function handleError($level, $message, $file, $line) { if (error_reporting() & $level) { - $exception_level = isset($this->levels[$level]) ? $this->levels[$level] : $level; throw new \ErrorException( @@ -140,7 +139,6 @@ class Handler protected function log(\Exception $exception) { if (null !== $this->logger) { - $message = sprintf( '%s: %s (uncaught exception) at %s line %s', get_class($exception), diff --git a/PHPCI/Logging/LoggerConfig.php b/PHPCI/Logging/LoggerConfig.php index 69617ee6..fd929aeb 100644 --- a/PHPCI/Logging/LoggerConfig.php +++ b/PHPCI/Logging/LoggerConfig.php @@ -9,6 +9,7 @@ namespace PHPCI\Logging; +use Monolog\ErrorHandler; use Monolog\Logger; /** @@ -19,6 +20,7 @@ class LoggerConfig { const KEY_ALWAYS_LOADED = "_"; private $config; + private $cache = array(); /** * The filepath is expected to return an array which will be @@ -56,9 +58,20 @@ class LoggerConfig */ public function getFor($name) { + if (isset($this->cache[$name])) { + return $this->cache[$name]; + } + $handlers = $this->getHandlers(self::KEY_ALWAYS_LOADED); - $handlers = array_merge($handlers, $this->getHandlers($name)); - return new Logger($name, $handlers); + if ($name !== self::KEY_ALWAYS_LOADED) { + $handlers = array_merge($handlers, $this->getHandlers($name)); + } + + $logger = new Logger($name, $handlers); + ErrorHandler::register($logger); + $this->cache[$name] = $logger; + + return $logger; } /** diff --git a/PHPCI/Migrations/20140513153133_change_build_keys_migration.php b/PHPCI/Migrations/20140513153133_change_build_keys_migration.php index b26a9388..7fd253cc 100644 --- a/PHPCI/Migrations/20140513153133_change_build_keys_migration.php +++ b/PHPCI/Migrations/20140513153133_change_build_keys_migration.php @@ -23,4 +23,4 @@ class ChangeBuildKeysMigration extends AbstractMigration $project->renameColumn('ssh_private_key', 'git_key'); $project->renameColumn('ssh_public_key', 'public_key'); } -} \ No newline at end of file +} diff --git a/PHPCI/Migrations/20140611170618_choose_branch.php b/PHPCI/Migrations/20140611170618_choose_branch.php index 5945c241..26b4ed4c 100644 --- a/PHPCI/Migrations/20140611170618_choose_branch.php +++ b/PHPCI/Migrations/20140611170618_choose_branch.php @@ -37,4 +37,4 @@ class ChooseBranch extends AbstractMigration $project = $this->table('project'); $project->removeColumn('branch')->save(); } -} \ No newline at end of file +} diff --git a/PHPCI/Migrations/20140730143702_fix_database_columns.php b/PHPCI/Migrations/20140730143702_fix_database_columns.php index 809fc878..a1ac2493 100644 --- a/PHPCI/Migrations/20140730143702_fix_database_columns.php +++ b/PHPCI/Migrations/20140730143702_fix_database_columns.php @@ -20,7 +20,7 @@ class FixDatabaseColumns extends AbstractMigration $build->changeColumn('project_id', 'integer', array('null' => false)); $build->changeColumn('commit_id', 'string', array('limit' => 50, 'null' => false)); $build->changeColumn('status', 'integer', array('null' => false)); - $build->changeColumn('log', 'text', array('null' => true, 'default' => '')); + $build->changeColumn('log', 'text', array('null' => true)); $build->changeColumn('branch', 'string', array('limit' => 50, 'null' => false, 'default' => 'master')); $build->changeColumn('created', 'datetime', array('null' => true)); $build->changeColumn('started', 'datetime', array('null' => true)); diff --git a/PHPCI/Migrations/20150131075425_archive_project.php b/PHPCI/Migrations/20150131075425_archive_project.php new file mode 100644 index 00000000..796fd48b --- /dev/null +++ b/PHPCI/Migrations/20150131075425_archive_project.php @@ -0,0 +1,26 @@ +table('project'); + $project->addColumn('archived', 'boolean'); + $project->save(); + } + + /** + * Migrate Down. + */ + public function down() + { + $project = $this->table('project'); + $project->removeColumn('archived'); + $project->save(); + } +} \ No newline at end of file diff --git a/PHPCI/Migrations/20150203105015_fix_column_types.php b/PHPCI/Migrations/20150203105015_fix_column_types.php new file mode 100644 index 00000000..53db2ad6 --- /dev/null +++ b/PHPCI/Migrations/20150203105015_fix_column_types.php @@ -0,0 +1,27 @@ +table('build'); + $build->changeColumn('log', 'text', array( + 'null' => true, + 'limit' => MysqlAdapter::TEXT_MEDIUM, + )); + + // Update the build meta value column to MEDIUMTEXT: + $buildMeta = $this->table('build_meta'); + $buildMeta->changeColumn('meta_value', 'text', array( + 'null' => false, + 'limit' => MysqlAdapter::TEXT_MEDIUM, + )); + } +} diff --git a/PHPCI/Migrations/20150324174958_unique_email_and_name_user_fields.php b/PHPCI/Migrations/20150324174958_unique_email_and_name_user_fields.php new file mode 100644 index 00000000..f8d24ba0 --- /dev/null +++ b/PHPCI/Migrations/20150324174958_unique_email_and_name_user_fields.php @@ -0,0 +1,30 @@ +table('user'); + $user_table + ->addIndex('email', array('unique' => true)) + ->addIndex('name', array('unique' => true)) + ->save(); + } + + /** + * Migrate Down. + */ + public function down() + { + $user_table = $this->table('user'); + $user_table + ->removeIndex('email', array('unique' => true)) + ->removeIndex('name', array('unique' => true)) + ->save(); + } +} diff --git a/PHPCI/Migrations/20151008140800_add_project_groups.php b/PHPCI/Migrations/20151008140800_add_project_groups.php new file mode 100644 index 00000000..f6035014 --- /dev/null +++ b/PHPCI/Migrations/20151008140800_add_project_groups.php @@ -0,0 +1,29 @@ +table('project_group'); + $table->addColumn('title', 'string', array('limit' => 100, 'null' => false)); + $table->save(); + + $group = new \PHPCI\Model\ProjectGroup(); + $group->setTitle('Projects'); + + /** @var \PHPCI\Model\ProjectGroup $group */ + $group = \b8\Store\Factory::getStore('ProjectGroup')->save($group); + + $table = $this->table('project'); + $table->addColumn('group_id', 'integer', array( + 'signed' => true, + 'null' => false, + 'default' => $group->getId(), + )); + + $table->addForeignKey('group_id', 'project_group', 'id', array('delete'=> 'RESTRICT', 'update' => 'CASCADE')); + $table->save(); + } +} diff --git a/PHPCI/Migrations/20151009100610_remove_unique_name_index.php b/PHPCI/Migrations/20151009100610_remove_unique_name_index.php new file mode 100644 index 00000000..283dfbc0 --- /dev/null +++ b/PHPCI/Migrations/20151009100610_remove_unique_name_index.php @@ -0,0 +1,40 @@ +table('user'); + + if ($user->hasIndex('name', array('unique' => true))) { + $user->removeIndex('name', array('unique' => true)); + $user->save(); + } + + $user->addIndex('name', array('unique' => false)); + $user->save(); + } +} diff --git a/PHPCI/Migrations/20151014091859_errors_table.php b/PHPCI/Migrations/20151014091859_errors_table.php new file mode 100644 index 00000000..a064f6e5 --- /dev/null +++ b/PHPCI/Migrations/20151014091859_errors_table.php @@ -0,0 +1,24 @@ +table('build_error'); + $table->addColumn('build_id', 'integer', array('signed' => true)); + $table->addColumn('plugin', 'string', array('limit' => 100)); + $table->addColumn('file', 'string', array('limit' => 250, 'null' => true)); + $table->addColumn('line_start', 'integer', array('signed' => false, 'null' => true)); + $table->addColumn('line_end', 'integer', array('signed' => false, 'null' => true)); + $table->addColumn('severity', 'integer', array('signed' => false, 'limit' => MysqlAdapter::INT_TINY)); + $table->addColumn('message', 'string', array('limit' => 250)); + $table->addColumn('created_date', 'datetime'); + $table->addIndex(array('build_id', 'created_date'), array('unique' => false)); + $table->addForeignKey('build_id', 'build', 'id', array('delete'=> 'CASCADE', 'update' => 'CASCADE')); + $table->save(); + + } +} diff --git a/PHPCI/Migrations/20151015124825_convert_errors.php b/PHPCI/Migrations/20151015124825_convert_errors.php new file mode 100644 index 00000000..3622bf14 --- /dev/null +++ b/PHPCI/Migrations/20151015124825_convert_errors.php @@ -0,0 +1,183 @@ +metaStore = \b8\Store\Factory::getStore('BuildMeta'); + $this->errorStore = \b8\Store\Factory::getStore('BuildError'); + + while ($count == 100) { + $data = $this->metaStore->getErrorsForUpgrade(100); + $count = count($data); + + /** @var \PHPCI\Model\BuildMeta $meta */ + foreach ($data as $meta) { + try { + switch ($meta->getMetaKey()) { + case 'phpmd-data': + $this->processPhpMdMeta($meta); + break; + + case 'phpcs-data': + $this->processPhpCsMeta($meta); + break; + + case 'phpdoccheck-data': + $this->processPhpDocCheckMeta($meta); + break; + + case 'phpcpd-data': + $this->processPhpCpdMeta($meta); + break; + + case 'technicaldebt-data': + $this->processTechnicalDebtMeta($meta); + break; + } + } catch (\Exception $ex) {} + + $this->metaStore->delete($meta); + } + } + } + + protected function processPhpMdMeta(BuildMeta $meta) + { + $data = json_decode($meta->getMetaValue(), true); + + if (is_array($data) && count($data)) { + foreach ($data as $error) { + $buildError = new BuildError(); + $buildError->setBuildId($meta->getBuildId()); + $buildError->setPlugin('php_mess_detector'); + $buildError->setCreatedDate(new \DateTime()); + $buildError->setFile($error['file']); + $buildError->setLineStart($error['line_start']); + $buildError->setLineEnd($error['line_end']); + $buildError->setSeverity(BuildError::SEVERITY_HIGH); + $buildError->setMessage($error['message']); + + $this->errorStore->save($buildError); + } + } + } + + protected function processPhpCsMeta(BuildMeta $meta) + { + $data = json_decode($meta->getMetaValue(), true); + + if (is_array($data) && count($data)) { + foreach ($data as $error) { + $buildError = new BuildError(); + $buildError->setBuildId($meta->getBuildId()); + $buildError->setPlugin('php_code_sniffer'); + $buildError->setCreatedDate(new \DateTime()); + $buildError->setFile($error['file']); + $buildError->setLineStart($error['line']); + $buildError->setLineEnd($error['line']); + $buildError->setMessage($error['message']); + + switch ($error['type']) { + case 'ERROR': + $buildError->setSeverity(BuildError::SEVERITY_HIGH); + break; + + case 'WARNING': + $buildError->setSeverity(BuildError::SEVERITY_LOW); + break; + } + + $this->errorStore->save($buildError); + } + } + } + + protected function processPhpDocCheckMeta(BuildMeta $meta) + { + $data = json_decode($meta->getMetaValue(), true); + + if (is_array($data) && count($data)) { + foreach ($data as $error) { + $buildError = new BuildError(); + $buildError->setBuildId($meta->getBuildId()); + $buildError->setPlugin('php_docblock_checker'); + $buildError->setCreatedDate(new \DateTime()); + $buildError->setFile($error['file']); + $buildError->setLineStart($error['line']); + $buildError->setLineEnd($error['line']); + + switch ($error['type']) { + case 'method': + $buildError->setMessage($error['class'] . '::' . $error['method'] . ' is missing a docblock.'); + $buildError->setSeverity(BuildError::SEVERITY_NORMAL); + break; + + case 'class': + $buildError->setMessage('Class ' . $error['class'] . ' is missing a docblock.'); + $buildError->setSeverity(BuildError::SEVERITY_LOW); + break; + } + + $this->errorStore->save($buildError); + } + } + } + + protected function processPhpCpdMeta(BuildMeta $meta) + { + $data = json_decode($meta->getMetaValue(), true); + + if (is_array($data) && count($data)) { + foreach ($data as $error) { + $buildError = new BuildError(); + $buildError->setBuildId($meta->getBuildId()); + $buildError->setPlugin('php_cpd'); + $buildError->setCreatedDate(new \DateTime()); + $buildError->setFile($error['file']); + $buildError->setLineStart($error['line_start']); + $buildError->setLineEnd($error['line_end']); + $buildError->setSeverity(BuildError::SEVERITY_NORMAL); + $buildError->setMessage('Copy and paste detected.'); + + $this->errorStore->save($buildError); + } + } + } + + protected function processTechnicalDebtMeta(BuildMeta $meta) + { + $data = json_decode($meta->getMetaValue(), true); + + if (is_array($data) && count($data)) { + foreach ($data as $error) { + $buildError = new BuildError(); + $buildError->setBuildId($meta->getBuildId()); + $buildError->setPlugin('technical_debt'); + $buildError->setCreatedDate(new \DateTime()); + $buildError->setFile($error['file']); + $buildError->setLineStart($error['line']); + $buildError->setSeverity(BuildError::SEVERITY_NORMAL); + $buildError->setMessage($error['message']); + + $this->errorStore->save($buildError); + } + } + } +} diff --git a/PHPCI/Migrations/20160623100223_project_table_defaults.php b/PHPCI/Migrations/20160623100223_project_table_defaults.php new file mode 100644 index 00000000..079db327 --- /dev/null +++ b/PHPCI/Migrations/20160623100223_project_table_defaults.php @@ -0,0 +1,18 @@ +table('project') + ->changeColumn('build_config', MysqlAdapter::PHINX_TYPE_TEXT, array('null' => true)) + ->changeColumn('archived', MysqlAdapter::PHINX_TYPE_INTEGER, array( + 'length' => MysqlAdapter::INT_TINY, + 'default' => 0, + )) + ->save(); + } +} diff --git a/PHPCI/Model/Base/BuildBase.php b/PHPCI/Model/Base/BuildBase.php index 119290e2..7c0fcdd3 100644 --- a/PHPCI/Model/Base/BuildBase.php +++ b/PHPCI/Model/Base/BuildBase.php @@ -118,7 +118,7 @@ class BuildBase extends Model 'default' => null, ), 'log' => array( - 'type' => 'text', + 'type' => 'mediumtext', 'nullable' => true, 'default' => null, ), @@ -621,6 +621,18 @@ class BuildBase extends Model return $this->setProjectId($value->getId()); } + /** + * Get BuildError models by BuildId for this Build. + * + * @uses \PHPCI\Store\BuildErrorStore::getByBuildId() + * @uses \PHPCI\Model\BuildError + * @return \PHPCI\Model\BuildError[] + */ + public function getBuildBuildErrors() + { + return Factory::getStore('BuildError', 'PHPCI')->getByBuildId($this->getId()); + } + /** * Get BuildMeta models by BuildId for this Build. * diff --git a/PHPCI/Model/Base/BuildErrorBase.php b/PHPCI/Model/Base/BuildErrorBase.php new file mode 100644 index 00000000..6364bb29 --- /dev/null +++ b/PHPCI/Model/Base/BuildErrorBase.php @@ -0,0 +1,503 @@ + null, + 'build_id' => null, + 'plugin' => null, + 'file' => null, + 'line_start' => null, + 'line_end' => null, + 'severity' => null, + 'message' => null, + 'created_date' => null, + ); + + /** + * @var array + */ + protected $getters = array( + // Direct property getters: + 'id' => 'getId', + 'build_id' => 'getBuildId', + 'plugin' => 'getPlugin', + 'file' => 'getFile', + 'line_start' => 'getLineStart', + 'line_end' => 'getLineEnd', + 'severity' => 'getSeverity', + 'message' => 'getMessage', + 'created_date' => 'getCreatedDate', + + // Foreign key getters: + 'Build' => 'getBuild', + ); + + /** + * @var array + */ + protected $setters = array( + // Direct property setters: + 'id' => 'setId', + 'build_id' => 'setBuildId', + 'plugin' => 'setPlugin', + 'file' => 'setFile', + 'line_start' => 'setLineStart', + 'line_end' => 'setLineEnd', + 'severity' => 'setSeverity', + 'message' => 'setMessage', + 'created_date' => 'setCreatedDate', + + // Foreign key setters: + 'Build' => 'setBuild', + ); + + /** + * @var array + */ + public $columns = array( + 'id' => array( + 'type' => 'int', + 'length' => 11, + 'primary_key' => true, + 'auto_increment' => true, + 'default' => null, + ), + 'build_id' => array( + 'type' => 'int', + 'length' => 11, + 'default' => null, + ), + 'plugin' => array( + 'type' => 'varchar', + 'length' => 100, + 'default' => null, + ), + 'file' => array( + 'type' => 'varchar', + 'length' => 250, + 'nullable' => true, + 'default' => null, + ), + 'line_start' => array( + 'type' => 'int', + 'length' => 11, + 'nullable' => true, + 'default' => null, + ), + 'line_end' => array( + 'type' => 'int', + 'length' => 11, + 'nullable' => true, + 'default' => null, + ), + 'severity' => array( + 'type' => 'tinyint', + 'length' => 3, + 'default' => null, + ), + 'message' => array( + 'type' => 'varchar', + 'length' => 250, + 'default' => null, + ), + 'created_date' => array( + 'type' => 'datetime', + 'default' => null, + ), + ); + + /** + * @var array + */ + public $indexes = array( + 'PRIMARY' => array('unique' => true, 'columns' => 'id'), + 'build_id' => array('columns' => 'build_id, created_date'), + ); + + /** + * @var array + */ + public $foreignKeys = array( + 'build_error_ibfk_1' => array( + 'local_col' => 'build_id', + 'update' => 'CASCADE', + 'delete' => 'CASCADE', + 'table' => 'build', + 'col' => 'id' + ), + ); + + /** + * Get the value of Id / id. + * + * @return int + */ + public function getId() + { + $rtn = $this->data['id']; + + return $rtn; + } + + /** + * Get the value of BuildId / build_id. + * + * @return int + */ + public function getBuildId() + { + $rtn = $this->data['build_id']; + + return $rtn; + } + + /** + * Get the value of Plugin / plugin. + * + * @return string + */ + public function getPlugin() + { + $rtn = $this->data['plugin']; + + return $rtn; + } + + /** + * Get the value of File / file. + * + * @return string + */ + public function getFile() + { + $rtn = $this->data['file']; + + return $rtn; + } + + /** + * Get the value of LineStart / line_start. + * + * @return int + */ + public function getLineStart() + { + $rtn = $this->data['line_start']; + + return $rtn; + } + + /** + * Get the value of LineEnd / line_end. + * + * @return int + */ + public function getLineEnd() + { + $rtn = $this->data['line_end']; + + return $rtn; + } + + /** + * Get the value of Severity / severity. + * + * @return int + */ + public function getSeverity() + { + $rtn = $this->data['severity']; + + return $rtn; + } + + /** + * Get the value of Message / message. + * + * @return string + */ + public function getMessage() + { + $rtn = $this->data['message']; + + return $rtn; + } + + /** + * Get the value of CreatedDate / created_date. + * + * @return \DateTime + */ + public function getCreatedDate() + { + $rtn = $this->data['created_date']; + + if (!empty($rtn)) { + $rtn = new \DateTime($rtn); + } + + return $rtn; + } + + /** + * Set the value of Id / id. + * + * Must not be null. + * @param $value int + */ + public function setId($value) + { + $this->_validateNotNull('Id', $value); + $this->_validateInt('Id', $value); + + if ($this->data['id'] === $value) { + return; + } + + $this->data['id'] = $value; + + $this->_setModified('id'); + } + + /** + * Set the value of BuildId / build_id. + * + * Must not be null. + * @param $value int + */ + public function setBuildId($value) + { + $this->_validateNotNull('BuildId', $value); + $this->_validateInt('BuildId', $value); + + if ($this->data['build_id'] === $value) { + return; + } + + $this->data['build_id'] = $value; + + $this->_setModified('build_id'); + } + + /** + * Set the value of Plugin / plugin. + * + * Must not be null. + * @param $value string + */ + public function setPlugin($value) + { + $this->_validateNotNull('Plugin', $value); + $this->_validateString('Plugin', $value); + + if ($this->data['plugin'] === $value) { + return; + } + + $this->data['plugin'] = $value; + + $this->_setModified('plugin'); + } + + /** + * Set the value of File / file. + * + * @param $value string + */ + public function setFile($value) + { + $this->_validateString('File', $value); + + if ($this->data['file'] === $value) { + return; + } + + $this->data['file'] = $value; + + $this->_setModified('file'); + } + + /** + * Set the value of LineStart / line_start. + * + * @param $value int + */ + public function setLineStart($value) + { + $this->_validateInt('LineStart', $value); + + if ($this->data['line_start'] === $value) { + return; + } + + $this->data['line_start'] = $value; + + $this->_setModified('line_start'); + } + + /** + * Set the value of LineEnd / line_end. + * + * @param $value int + */ + public function setLineEnd($value) + { + $this->_validateInt('LineEnd', $value); + + if ($this->data['line_end'] === $value) { + return; + } + + $this->data['line_end'] = $value; + + $this->_setModified('line_end'); + } + + /** + * Set the value of Severity / severity. + * + * Must not be null. + * @param $value int + */ + public function setSeverity($value) + { + $this->_validateNotNull('Severity', $value); + $this->_validateInt('Severity', $value); + + if ($this->data['severity'] === $value) { + return; + } + + $this->data['severity'] = $value; + + $this->_setModified('severity'); + } + + /** + * Set the value of Message / message. + * + * Must not be null. + * @param $value string + */ + public function setMessage($value) + { + $this->_validateNotNull('Message', $value); + $this->_validateString('Message', $value); + + if ($this->data['message'] === $value) { + return; + } + + $this->data['message'] = $value; + + $this->_setModified('message'); + } + + /** + * Set the value of CreatedDate / created_date. + * + * Must not be null. + * @param $value \DateTime + */ + public function setCreatedDate($value) + { + $this->_validateNotNull('CreatedDate', $value); + $this->_validateDate('CreatedDate', $value); + + if ($this->data['created_date'] === $value) { + return; + } + + $this->data['created_date'] = $value; + + $this->_setModified('created_date'); + } + + /** + * Get the Build model for this BuildError by Id. + * + * @uses \PHPCI\Store\BuildStore::getById() + * @uses \PHPCI\Model\Build + * @return \PHPCI\Model\Build + */ + public function getBuild() + { + $key = $this->getBuildId(); + + if (empty($key)) { + return null; + } + + $cacheKey = 'Cache.Build.' . $key; + $rtn = $this->cache->get($cacheKey, null); + + if (empty($rtn)) { + $rtn = Factory::getStore('Build', 'PHPCI')->getById($key); + $this->cache->set($cacheKey, $rtn); + } + + return $rtn; + } + + /** + * Set Build - Accepts an ID, an array representing a Build or a Build model. + * + * @param $value mixed + */ + public function setBuild($value) + { + // Is this an instance of Build? + if ($value instanceof \PHPCI\Model\Build) { + return $this->setBuildObject($value); + } + + // Is this an array representing a Build item? + if (is_array($value) && !empty($value['id'])) { + return $this->setBuildId($value['id']); + } + + // Is this a scalar value representing the ID of this foreign key? + return $this->setBuildId($value); + } + + /** + * Set Build - Accepts a Build model. + * + * @param $value \PHPCI\Model\Build + */ + public function setBuildObject(\PHPCI\Model\Build $value) + { + return $this->setBuildId($value->getId()); + } +} diff --git a/PHPCI/Model/Base/BuildMetaBase.php b/PHPCI/Model/Base/BuildMetaBase.php index 0ac8fa93..dc018819 100644 --- a/PHPCI/Model/Base/BuildMetaBase.php +++ b/PHPCI/Model/Base/BuildMetaBase.php @@ -99,7 +99,7 @@ class BuildMetaBase extends Model 'default' => null, ), 'meta_value' => array( - 'type' => 'text', + 'type' => 'mediumtext', 'default' => null, ), ); diff --git a/PHPCI/Model/Base/ProjectBase.php b/PHPCI/Model/Base/ProjectBase.php index bcf793ab..0dc0c0eb 100644 --- a/PHPCI/Model/Base/ProjectBase.php +++ b/PHPCI/Model/Base/ProjectBase.php @@ -38,12 +38,14 @@ class ProjectBase extends Model 'reference' => null, 'branch' => null, 'ssh_private_key' => null, - 'ssh_public_key' => null, 'type' => null, 'access_information' => null, 'last_commit' => null, 'build_config' => null, + 'ssh_public_key' => null, 'allow_public_status' => null, + 'archived' => null, + 'group_id' => null, ); /** @@ -56,14 +58,17 @@ class ProjectBase extends Model 'reference' => 'getReference', 'branch' => 'getBranch', 'ssh_private_key' => 'getSshPrivateKey', - 'ssh_public_key' => 'getSshPublicKey', 'type' => 'getType', 'access_information' => 'getAccessInformation', 'last_commit' => 'getLastCommit', 'build_config' => 'getBuildConfig', + 'ssh_public_key' => 'getSshPublicKey', 'allow_public_status' => 'getAllowPublicStatus', + 'archived' => 'getArchived', + 'group_id' => 'getGroupId', // Foreign key getters: + 'Group' => 'getGroup', ); /** @@ -76,14 +81,17 @@ class ProjectBase extends Model 'reference' => 'setReference', 'branch' => 'setBranch', 'ssh_private_key' => 'setSshPrivateKey', - 'ssh_public_key' => 'setSshPublicKey', 'type' => 'setType', 'access_information' => 'setAccessInformation', 'last_commit' => 'setLastCommit', 'build_config' => 'setBuildConfig', + 'ssh_public_key' => 'setSshPublicKey', 'allow_public_status' => 'setAllowPublicStatus', + 'archived' => 'setArchived', + 'group_id' => 'setGroupId', // Foreign key setters: + 'Group' => 'setGroup', ); /** @@ -117,11 +125,6 @@ class ProjectBase extends Model 'nullable' => true, 'default' => null, ), - 'ssh_public_key' => array( - 'type' => 'text', - 'nullable' => true, - 'default' => null, - ), 'type' => array( 'type' => 'varchar', 'length' => 50, @@ -144,10 +147,25 @@ class ProjectBase extends Model 'nullable' => true, 'default' => null, ), + 'ssh_public_key' => array( + 'type' => 'text', + 'nullable' => true, + 'default' => null, + ), 'allow_public_status' => array( 'type' => 'int', 'length' => 11, ), + 'archived' => array( + 'type' => 'tinyint', + 'length' => 1, + 'default' => null, + ), + 'group_id' => array( + 'type' => 'int', + 'length' => 11, + 'default' => 1, + ), ); /** @@ -156,12 +174,20 @@ class ProjectBase extends Model public $indexes = array( 'PRIMARY' => array('unique' => true, 'columns' => 'id'), 'idx_project_title' => array('columns' => 'title'), + 'group_id' => array('columns' => 'group_id'), ); /** * @var array */ public $foreignKeys = array( + 'project_ibfk_1' => array( + 'local_col' => 'group_id', + 'update' => 'CASCADE', + 'delete' => '', + 'table' => 'project_group', + 'col' => 'id' + ), ); /** @@ -224,18 +250,6 @@ class ProjectBase extends Model return $rtn; } - /** - * Get the value of SshPublicKey / ssh_public_key. - * - * @return string - */ - public function getSshPublicKey() - { - $rtn = $this->data['ssh_public_key']; - - return $rtn; - } - /** * Get the value of Type / type. * @@ -284,6 +298,18 @@ class ProjectBase extends Model return $rtn; } + /** + * Get the value of SshPublicKey / ssh_public_key. + * + * @return string + */ + public function getSshPublicKey() + { + $rtn = $this->data['ssh_public_key']; + + return $rtn; + } + /** * Get the value of AllowPublicStatus / allow_public_status. * @@ -296,6 +322,30 @@ class ProjectBase extends Model return $rtn; } + /** + * Get the value of Archived / archived. + * + * @return int + */ + public function getArchived() + { + $rtn = $this->data['archived']; + + return $rtn; + } + + /** + * Get the value of GroupId / group_id. + * + * @return int + */ + public function getGroupId() + { + $rtn = $this->data['group_id']; + + return $rtn; + } + /** * Set the value of Id / id. * @@ -394,24 +444,6 @@ class ProjectBase extends Model $this->_setModified('ssh_private_key'); } - /** - * Set the value of SshPublicKey / ssh_public_key. - * - * @param $value string - */ - public function setSshPublicKey($value) - { - $this->_validateString('SshPublicKey', $value); - - if ($this->data['ssh_public_key'] === $value) { - return; - } - - $this->data['ssh_public_key'] = $value; - - $this->_setModified('ssh_public_key'); - } - /** * Set the value of Type / type. * @@ -486,6 +518,24 @@ class ProjectBase extends Model $this->_setModified('build_config'); } + /** + * Set the value of SshPublicKey / ssh_public_key. + * + * @param $value string + */ + public function setSshPublicKey($value) + { + $this->_validateString('SshPublicKey', $value); + + if ($this->data['ssh_public_key'] === $value) { + return; + } + + $this->data['ssh_public_key'] = $value; + + $this->_setModified('ssh_public_key'); + } + /** * Set the value of AllowPublicStatus / allow_public_status. * @@ -506,6 +556,103 @@ class ProjectBase extends Model $this->_setModified('allow_public_status'); } + /** + * Set the value of Archived / archived. + * + * Must not be null. + * @param $value int + */ + public function setArchived($value) + { + $this->_validateNotNull('Archived', $value); + $this->_validateInt('Archived', $value); + + if ($this->data['archived'] === $value) { + return; + } + + $this->data['archived'] = $value; + + $this->_setModified('archived'); + } + + /** + * Set the value of GroupId / group_id. + * + * Must not be null. + * @param $value int + */ + public function setGroupId($value) + { + $this->_validateNotNull('GroupId', $value); + $this->_validateInt('GroupId', $value); + + if ($this->data['group_id'] === $value) { + return; + } + + $this->data['group_id'] = $value; + + $this->_setModified('group_id'); + } + + /** + * Get the ProjectGroup model for this Project by Id. + * + * @uses \PHPCI\Store\ProjectGroupStore::getById() + * @uses \PHPCI\Model\ProjectGroup + * @return \PHPCI\Model\ProjectGroup + */ + public function getGroup() + { + $key = $this->getGroupId(); + + if (empty($key)) { + return null; + } + + $cacheKey = 'Cache.ProjectGroup.' . $key; + $rtn = $this->cache->get($cacheKey, null); + + if (empty($rtn)) { + $rtn = Factory::getStore('ProjectGroup', 'PHPCI')->getById($key); + $this->cache->set($cacheKey, $rtn); + } + + return $rtn; + } + + /** + * Set Group - Accepts an ID, an array representing a ProjectGroup or a ProjectGroup model. + * + * @param $value mixed + */ + public function setGroup($value) + { + // Is this an instance of ProjectGroup? + if ($value instanceof \PHPCI\Model\ProjectGroup) { + return $this->setGroupObject($value); + } + + // Is this an array representing a ProjectGroup item? + if (is_array($value) && !empty($value['id'])) { + return $this->setGroupId($value['id']); + } + + // Is this a scalar value representing the ID of this foreign key? + return $this->setGroupId($value); + } + + /** + * Set Group - Accepts a ProjectGroup model. + * + * @param $value \PHPCI\Model\ProjectGroup + */ + public function setGroupObject(\PHPCI\Model\ProjectGroup $value) + { + return $this->setGroupId($value->getId()); + } + /** * Get Build models by ProjectId for this Project. * diff --git a/PHPCI/Model/Base/ProjectGroupBase.php b/PHPCI/Model/Base/ProjectGroupBase.php new file mode 100644 index 00000000..3b5eed69 --- /dev/null +++ b/PHPCI/Model/Base/ProjectGroupBase.php @@ -0,0 +1,168 @@ + null, + 'title' => null, + ); + + /** + * @var array + */ + protected $getters = array( + // Direct property getters: + 'id' => 'getId', + 'title' => 'getTitle', + + // Foreign key getters: + ); + + /** + * @var array + */ + protected $setters = array( + // Direct property setters: + 'id' => 'setId', + 'title' => 'setTitle', + + // Foreign key setters: + ); + + /** + * @var array + */ + public $columns = array( + 'id' => array( + 'type' => 'int', + 'length' => 11, + 'primary_key' => true, + 'auto_increment' => true, + 'default' => null, + ), + 'title' => array( + 'type' => 'varchar', + 'length' => 100, + 'default' => null, + ), + ); + + /** + * @var array + */ + public $indexes = array( + 'PRIMARY' => array('unique' => true, 'columns' => 'id'), + ); + + /** + * @var array + */ + public $foreignKeys = array( + ); + + /** + * Get the value of Id / id. + * + * @return int + */ + public function getId() + { + $rtn = $this->data['id']; + + return $rtn; + } + + /** + * Get the value of Title / title. + * + * @return string + */ + public function getTitle() + { + $rtn = $this->data['title']; + + return $rtn; + } + + /** + * Set the value of Id / id. + * + * Must not be null. + * @param $value int + */ + public function setId($value) + { + $this->_validateNotNull('Id', $value); + $this->_validateInt('Id', $value); + + if ($this->data['id'] === $value) { + return; + } + + $this->data['id'] = $value; + + $this->_setModified('id'); + } + + /** + * Set the value of Title / title. + * + * Must not be null. + * @param $value string + */ + public function setTitle($value) + { + $this->_validateNotNull('Title', $value); + $this->_validateString('Title', $value); + + if ($this->data['title'] === $value) { + return; + } + + $this->data['title'] = $value; + + $this->_setModified('title'); + } + + /** + * Get Project models by GroupId for this ProjectGroup. + * + * @uses \PHPCI\Store\ProjectStore::getByGroupId() + * @uses \PHPCI\Model\Project + * @return \PHPCI\Model\Project[] + */ + public function getGroupProjects() + { + return Factory::getStore('Project', 'PHPCI')->getByGroupId($this->getId()); + } +} diff --git a/PHPCI/Model/Base/UserBase.php b/PHPCI/Model/Base/UserBase.php index e9be15a0..4de48537 100644 --- a/PHPCI/Model/Base/UserBase.php +++ b/PHPCI/Model/Base/UserBase.php @@ -106,6 +106,8 @@ class UserBase extends Model public $indexes = array( 'PRIMARY' => array('unique' => true, 'columns' => 'id'), 'idx_email' => array('unique' => true, 'columns' => 'email'), + 'email' => array('unique' => true, 'columns' => 'email'), + 'name' => array('columns' => 'name'), ); /** diff --git a/PHPCI/Model/Build.php b/PHPCI/Model/Build.php index 6dfef060..a8bfd683 100644 --- a/PHPCI/Model/Build.php +++ b/PHPCI/Model/Build.php @@ -28,7 +28,7 @@ class Build extends BuildBase const STATUS_SUCCESS = 2; const STATUS_FAILED = 3; - public $currentBuildPath = null; + public $currentBuildPath; /** * Get link to commit from another source (i.e. Github) @@ -99,16 +99,21 @@ class Build extends BuildBase { $build_config = null; - // Try phpci.yml first: - if (is_file($buildPath . '/phpci.yml')) { - $build_config = file_get_contents($buildPath . '/phpci.yml'); - } - // Try getting the project build config from the database: if (empty($build_config)) { $build_config = $this->getProject()->getBuildConfig(); } + // Try .phpci.yml + if (is_file($buildPath . '/.phpci.yml')) { + $build_config = file_get_contents($buildPath . '/.phpci.yml'); + } + + // Try phpci.yml first: + if (empty($build_config) && is_file($buildPath . '/phpci.yml')) { + $build_config = file_get_contents($buildPath . '/phpci.yml'); + } + // Fall back to zero config plugins: if (empty($build_config)) { $build_config = $this->getZeroConfigPlugins($builder); @@ -193,4 +198,104 @@ class Build extends BuildBase return $rtn; } + + /** + * Returns the commit message for this build. + * @return string + */ + public function getCommitMessage() + { + $rtn = htmlspecialchars($this->data['commit_message']); + + return $rtn; + } + + /** + * Allows specific build types (e.g. Github) to report violations back to their respective services. + * @param Builder $builder + * @param $plugin + * @param $message + * @param int $severity + * @param null $file + * @param null $lineStart + * @param null $lineEnd + * @return BuildError + */ + public function reportError( + Builder $builder, + $plugin, + $message, + $severity = BuildError::SEVERITY_NORMAL, + $file = null, + $lineStart = null, + $lineEnd = null + ) { + unset($builder); + + $error = new BuildError(); + $error->setBuild($this); + $error->setCreatedDate(new \DateTime()); + $error->setPlugin($plugin); + $error->setMessage($message); + $error->setSeverity($severity); + $error->setFile($file); + $error->setLineStart($lineStart); + $error->setLineEnd($lineEnd); + + return Factory::getStore('BuildError')->save($error); + } + + /** + * Return the path to run this build into. + * + * @return string|null + */ + public function getBuildPath() + { + if (!$this->getId()) { + return null; + } + + if (empty($this->currentBuildPath)) { + $buildDirectory = $this->getId() . '_' . substr(md5(microtime(true)), 0, 5); + $this->currentBuildPath = PHPCI_BUILD_ROOT_DIR . $buildDirectory . DIRECTORY_SEPARATOR; + } + + return $this->currentBuildPath; + } + + /** + * Removes the build directory. + */ + public function removeBuildDirectory() + { + $buildPath = $this->getBuildPath(); + + if (!$buildPath || !is_dir($buildPath)) { + return; + } + + exec(sprintf(IS_WIN ? 'rmdir /S /Q "%s"' : 'rm -Rf "%s"', $buildPath)); + } + + /** + * Get the number of seconds a build has been running for. + * @return int + */ + public function getDuration() + { + $start = $this->getStarted(); + + if (empty($start)) { + return 0; + } + + $end = $this->getFinished(); + + if (empty($end)) { + $end = new \DateTime(); + } + + return $end->getTimestamp() - $start->getTimestamp(); + } } diff --git a/PHPCI/Model/Build/GithubBuild.php b/PHPCI/Model/Build/GithubBuild.php index feef147a..a9a18913 100644 --- a/PHPCI/Model/Build/GithubBuild.php +++ b/PHPCI/Model/Build/GithubBuild.php @@ -10,6 +10,8 @@ namespace PHPCI\Model\Build; use PHPCI\Builder; +use PHPCI\Helper\Diff; +use PHPCI\Helper\Github; use PHPCI\Model\Build\RemoteGitBuild; /** @@ -43,39 +45,52 @@ class GithubBuild extends RemoteGitBuild { $token = \b8\Config::getInstance()->get('phpci.github.token'); - if (empty($token)) { + if (empty($token) || empty($this->data['id'])) { return; } $project = $this->getProject(); + if (empty($project)) { + return; + } + $url = 'https://api.github.com/repos/'.$project->getReference().'/statuses/'.$this->getCommitId(); $http = new \b8\HttpClient(); - switch($this->getStatus()) - { + switch ($this->getStatus()) { case 0: case 1: $status = 'pending'; + $description = 'PHPCI build running.'; break; case 2: $status = 'success'; + $description = 'PHPCI build passed.'; break; case 3: $status = 'failure'; + $description = 'PHPCI build failed.'; break; default: $status = 'error'; + $description = 'PHPCI build failed to complete.'; break; } $phpciUrl = \b8\Config::getInstance()->get('phpci.url'); - $params = array( 'state' => $status, - 'target_url' => $phpciUrl . '/build/view/' . $this->getId()); + + $params = array( + 'state' => $status, + 'target_url' => $phpciUrl . '/build/view/' . $this->getId(), + 'description' => $description, + 'context' => 'PHPCI', + ); + $headers = array( 'Authorization: token ' . $token, 'Content-Type: application/x-www-form-urlencoded' - ); + ); $http->setHeaders($headers); $http->request('POST', $url, json_encode($params)); @@ -101,12 +116,16 @@ class GithubBuild extends RemoteGitBuild */ public function getCommitMessage() { - $rtn = $this->data['commit_message']; + $rtn = parent::getCommitMessage($this->data['commit_message']); - $reference = $this->getProject()->getReference(); - $commitLink = '#$1'; - $rtn = preg_replace('/\#([0-9]+)/', $commitLink, $rtn); - $rtn = preg_replace('/\@([a-zA-Z0-9_]+)/', '@$1', $rtn); + $project = $this->getProject(); + + if (!is_null($project)) { + $reference = $project->getReference(); + $commitLink = '#$1'; + $rtn = preg_replace('/\#([0-9]+)/', $commitLink, $rtn); + $rtn = preg_replace('/\@([a-zA-Z0-9_]+)/', '@$1', $rtn); + } return $rtn; } @@ -123,7 +142,7 @@ class GithubBuild extends RemoteGitBuild if ($this->getExtra('build_type') == 'pull_request') { $matches = array(); - preg_match('/\/([a-zA-Z0-9_\-]+\/[a-zA-Z0-9_\-]+)/', $this->getExtra('remote_url'), $matches); + preg_match('/[\/:]([a-zA-Z0-9_\-]+\/[a-zA-Z0-9_\-]+)/', $this->getExtra('remote_url'), $matches); $reference = $matches[1]; $branch = $this->getExtra('remote_branch'); @@ -132,7 +151,7 @@ class GithubBuild extends RemoteGitBuild $link = 'https://github.com/' . $reference . '/'; $link .= 'blob/' . $branch . '/'; $link .= '{FILE}'; - $link .= '#L{LINE}'; + $link .= '#L{LINE}-L{LINE_END}'; return $link; } @@ -167,4 +186,69 @@ class GithubBuild extends RemoteGitBuild return $success; } + + /** + * @inheritDoc + */ + public function reportError( + Builder $builder, + $plugin, + $message, + $severity = BuildError::SEVERITY_NORMAL, + $file = null, + $lineStart = null, + $lineEnd = null + ) { + $diffLineNumber = $this->getDiffLineNumber($builder, $file, $lineStart); + + if (!is_null($diffLineNumber)) { + $helper = new Github(); + + $repo = $this->getProject()->getReference(); + $prNumber = $this->getExtra('pull_request_number'); + $commit = $this->getCommitId(); + + if (!empty($prNumber)) { + $helper->createPullRequestComment($repo, $prNumber, $commit, $file, $diffLineNumber, $message); + } else { + $helper->createCommitComment($repo, $commit, $file, $diffLineNumber, $message); + } + } + + return parent::reportError($builder, $plugin, $message, $severity, $file, $lineStart, $lineEnd); + } + + /** + * Uses git diff to figure out what the diff line position is, based on the error line number. + * @param Builder $builder + * @param $file + * @param $line + * @return int|null + */ + protected function getDiffLineNumber(Builder $builder, $file, $line) + { + $line = (integer)$line; + + $builder->logExecOutput(false); + + $prNumber = $this->getExtra('pull_request_number'); + $path = $builder->buildPath; + + if (!empty($prNumber)) { + $builder->executeCommand('cd %s && git diff origin/%s "%s"', $path, $this->getBranch(), $file); + } else { + $commitId = $this->getCommitId(); + $compare = $commitId == 'Manual' ? 'HEAD' : $commitId; + $builder->executeCommand('cd %s && git diff %s^^ "%s"', $path, $compare, $file); + } + + $builder->logExecOutput(true); + + $diff = $builder->getLastOutput(); + + $helper = new Diff(); + $lines = $helper->getLinePositions($diff); + + return isset($lines[$line]) ? $lines[$line] : null; + } } diff --git a/PHPCI/Model/Build/GitlabBuild.php b/PHPCI/Model/Build/GitlabBuild.php index 086bc046..a1e0562c 100644 --- a/PHPCI/Model/Build/GitlabBuild.php +++ b/PHPCI/Model/Build/GitlabBuild.php @@ -47,7 +47,7 @@ class GitlabBuild extends RemoteGitBuild 'http://%s/%s/blob/%s/{FILE}#L{LINE}', $this->getProject()->getAccessInformation("domain"), $this->getProject()->getReference(), - $this->getBranch() + $this->getCommitId() ); } diff --git a/PHPCI/Model/Build/LocalBuild.php b/PHPCI/Model/Build/LocalBuild.php index b94ede4e..5131abe1 100644 --- a/PHPCI/Model/Build/LocalBuild.php +++ b/PHPCI/Model/Build/LocalBuild.php @@ -35,12 +35,14 @@ class LocalBuild extends Build return $this->handleConfig($builder, $buildPath) !== false; } - $buildSettings = $this->handleConfig($builder, $reference); + $configHandled = $this->handleConfig($builder, $reference); - if ($buildSettings === false) { + if ($configHandled === false) { return false; } + $buildSettings = $builder->getConfig('build_settings'); + if (isset($buildSettings['prefer_symlink']) && $buildSettings['prefer_symlink'] === true) { return $this->handleSymlink($builder, $reference, $buildPath); } else { diff --git a/PHPCI/Model/Build/MercurialBuild.php b/PHPCI/Model/Build/MercurialBuild.php index 500b5372..0f38940b 100644 --- a/PHPCI/Model/Build/MercurialBuild.php +++ b/PHPCI/Model/Build/MercurialBuild.php @@ -13,36 +13,87 @@ use PHPCI\Model\Build; use PHPCI\Builder; /** -* Mercurial Build Model -* @author Pavel Gopanenko -* @package PHPCI -* @subpackage Core -*/ + * Mercurial Build Model + * @author Pavel Gopanenko + * @package PHPCI + * @subpackage Core + */ class MercurialBuild extends Build { /** - * Get the URL to be used to clone this remote repository. - */ + * Get the URL to be used to clone this remote repository. + */ protected function getCloneUrl() { return $this->getProject()->getReference(); } /** - * Create a working copy by cloning, copying, or similar. - */ + * Create a working copy by cloning, copying, or similar. + */ public function createWorkingCopy(Builder $builder, $buildPath) { - $this->cloneByHttp($builder, $buildPath); + $key = trim($this->getProject()->getSshPublicKey()); + + if (!empty($key) && strpos($this->getProject()->getReference(), 'ssh') > -1) { + $success = $this->cloneBySsh($builder, $buildPath); + } else { + $success = $this->cloneByHttp($builder, $buildPath); + } + + if (!$success) { + $builder->logFailure('Failed to clone remote git repository.'); + return false; + } return $this->handleConfig($builder, $buildPath); } /** - * Use an mercurial clone. - */ + * Use a HTTP-based Mercurial clone. + */ protected function cloneByHttp(Builder $builder, $cloneTo) { return $builder->executeCommand('hg clone %s "%s" -r %s', $this->getCloneUrl(), $cloneTo, $this->getBranch()); } + + /** + * Use an SSH-based Mercurial clone. + */ + protected function cloneBySsh(Builder $builder, $cloneTo) + { + $keyFile = $this->writeSshKey(); + + // Do the git clone: + $cmd = 'hg clone --ssh "ssh -i '.$keyFile.'" %s "%s"'; + $success = $builder->executeCommand($cmd, $this->getCloneUrl(), $cloneTo); + + if ($success) { + $success = $this->postCloneSetup($builder, $cloneTo); + } + + // Remove the key file: + unlink($keyFile); + return $success; + } + + /** + * Handle post-clone tasks (switching branch, etc.) + * @param Builder $builder + * @param $cloneTo + * @return bool + */ + protected function postCloneSetup(Builder $builder, $cloneTo) + { + $success = true; + $commit = $this->getCommitId(); + + // Allow switching to a specific branch: + if (!empty($commit) && $commit != 'Manual') { + $cmd = 'cd "%s" && hg checkout %s'; + $success = $builder->executeCommand($cmd, $cloneTo, $this->getBranch()); + } + + return $success; + } } diff --git a/PHPCI/Model/Build/RemoteGitBuild.php b/PHPCI/Model/Build/RemoteGitBuild.php index 80718011..faaccfb5 100644 --- a/PHPCI/Model/Build/RemoteGitBuild.php +++ b/PHPCI/Model/Build/RemoteGitBuild.php @@ -54,7 +54,7 @@ class RemoteGitBuild extends Build */ protected function cloneByHttp(Builder $builder, $cloneTo) { - $cmd = 'git clone '; + $cmd = 'git clone --recursive '; $depth = $builder->getConfig('clone_depth'); @@ -84,7 +84,7 @@ class RemoteGitBuild extends Build } // Do the git clone: - $cmd = 'git clone '; + $cmd = 'git clone --recursive '; $depth = $builder->getConfig('clone_depth'); @@ -124,16 +124,16 @@ class RemoteGitBuild extends Build $success = true; $commit = $this->getCommitId(); + $chdir = IS_WIN ? 'cd /d "%s"' : 'cd "%s"'; + if (!empty($commit) && $commit != 'Manual') { - $cmd = 'cd "%s"'; + $cmd = $chdir . ' && git checkout %s --quiet'; + $success = $builder->executeCommand($cmd, $cloneTo, $commit); + } - if (IS_WIN) { - $cmd = 'cd /d "%s"'; - } - - $cmd .= ' && git checkout %s --quiet'; - - $success = $builder->executeCommand($cmd, $cloneTo, $this->getCommitId()); + // Always update the commit hash with the actual HEAD hash + if ($builder->executeCommand($chdir . ' && git rev-parse HEAD', $cloneTo)) { + $this->setCommitId(trim($builder->getLastOutput())); } return $success; diff --git a/PHPCI/Model/Build/SubversionBuild.php b/PHPCI/Model/Build/SubversionBuild.php new file mode 100644 index 00000000..af884933 --- /dev/null +++ b/PHPCI/Model/Build/SubversionBuild.php @@ -0,0 +1,182 @@ + + * @package PHPCI + * @subpackage Core + */ +class SubversionBuild extends Build +{ + protected $svnCommand = 'svn export -q --non-interactive '; + + /** + * Get the URL to be used to clone this remote repository. + */ + protected function getCloneUrl() + { + $url = $this->getProject()->getReference(); + + if (substr($url, -1) != '/') { + $url .= '/'; + } + + $branch = $this->getBranch(); + + if (empty($branch) || $branch == 'trunk') { + $url .= 'trunk'; + } else { + $url .= 'branches/' . $branch; + } + + return $url; + } + + /** + * @param Builder $builder + * + * @return void + */ + protected function extendSvnCommandFromConfig(Builder $builder) + { + $cmd = $this->svnCommand; + + $svn = $builder->getConfig('svn'); + if ($svn) { + foreach ($svn as $key => $value) { + $cmd .= " --$key $value "; + } + } + + $depth = $builder->getConfig('clone_depth'); + + if (!is_null($depth)) { + $cmd .= ' --depth ' . intval($depth) . ' '; + } + + $this->svnCommand = $cmd; + } + + /** + * Create a working copy by cloning, copying, or similar. + */ + public function createWorkingCopy(Builder $builder, $buildPath) + { + $this->handleConfig($builder, $buildPath); + + $this->extendSvnCommandFromConfig($builder); + + $key = trim($this->getProject()->getSshPrivateKey()); + + if (!empty($key)) { + $success = $this->cloneBySsh($builder, $buildPath); + } else { + $success = $this->cloneByHttp($builder, $buildPath); + } + + if (!$success) { + $builder->logFailure('Failed to export remote subversion repository.'); + return false; + } + + return $this->handleConfig($builder, $buildPath); + } + + /** + * Use an HTTP-based svn export. + */ + protected function cloneByHttp(Builder $builder, $cloneTo) + { + $cmd = $this->svnCommand; + + if ($this->getCommitId() != 'Manual') { + $cmd .= ' -r %s %s "%s"'; + $success = $builder->executeCommand($cmd, $this->getCommitId(), $this->getCloneUrl(), $cloneTo); + } else { + $cmd .= ' %s "%s"'; + $success = $builder->executeCommand($cmd, $this->getCloneUrl(), $cloneTo); + } + + return $success; + } + + /** + * Use an SSH-based svn export. + */ + protected function cloneBySsh(Builder $builder, $cloneTo) + { + $cmd = $this->svnCommand . ' %s "%s"'; + + if (!IS_WIN) { + $keyFile = $this->writeSshKey($cloneTo); + $sshWrapper = $this->writeSshWrapper($cloneTo, $keyFile); + $cmd = 'export SVN_SSH="' . $sshWrapper . '" && ' . $cmd; + } + + $success = $builder->executeCommand($cmd, $this->getCloneUrl(), $cloneTo); + + if (!IS_WIN) { + // Remove the key file and svn wrapper: + unlink($keyFile); + unlink($sshWrapper); + } + + return $success; + } + + /** + * Create an SSH key file on disk for this build. + * @param $cloneTo + * @return string + */ + protected function writeSshKey($cloneTo) + { + $keyPath = dirname($cloneTo . '/temp'); + $keyFile = $keyPath . '.key'; + + // Write the contents of this project's svn key to the file: + file_put_contents($keyFile, $this->getProject()->getSshPrivateKey()); + chmod($keyFile, 0600); + + // Return the filename: + return $keyFile; + } + + /** + * Create an SSH wrapper script for Svn to use, to disable host key checking, etc. + * @param $cloneTo + * @param $keyFile + * @return string + */ + protected function writeSshWrapper($cloneTo, $keyFile) + { + $path = dirname($cloneTo . '/temp'); + $wrapperFile = $path . '.sh'; + + $sshFlags = '-o CheckHostIP=no -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -o PasswordAuthentication=no'; + + // Write out the wrapper script for this build: + $script = <<getSeverity()) { + case self::SEVERITY_CRITICAL: + return 'critical'; + + case self::SEVERITY_HIGH: + return 'high'; + + case self::SEVERITY_NORMAL: + return 'normal'; + + case self::SEVERITY_LOW: + return 'low'; + } + } + + /** + * Get the class to apply to HTML elements representing this error. + * @return string + */ + public function getSeverityClass() + { + switch ($this->getSeverity()) { + case self::SEVERITY_CRITICAL: + return 'danger'; + + case self::SEVERITY_HIGH: + return 'warning'; + + case self::SEVERITY_NORMAL: + return 'info'; + + case self::SEVERITY_LOW: + return 'default'; + } + } +} diff --git a/PHPCI/Model/Project.php b/PHPCI/Model/Project.php index 4a8b3c69..4b5268b2 100644 --- a/PHPCI/Model/Project.php +++ b/PHPCI/Model/Project.php @@ -50,6 +50,29 @@ class Project extends ProjectBase return null; } + /** + * Return the previous build from a specific branch, for this project. + * @param string $branch + * @return mixed|null + */ + public function getPreviousBuild($branch = 'master') + { + $criteria = array('branch' => $branch, 'project_id' => $this->getId()); + + $order = array('id' => 'DESC'); + $builds = Store\Factory::getStore('Build')->getWhere($criteria, 1, 1, array(), $order); + + if (is_array($builds['items']) && count($builds['items'])) { + $previous = array_shift($builds['items']); + + if (isset($previous) && $previous instanceof Build) { + return $previous; + } + } + + return null; + } + /** * Store this project's access_information data * @param string|array $value @@ -73,7 +96,7 @@ class Project extends ProjectBase $info = $this->data['access_information']; // Handle old-format (serialized) access information first: - if (!empty($info) && substr($info, 0, 1) != '{') { + if (!empty($info) && !in_array(substr($info, 0, 1), array('{', '['))) { $data = unserialize($info); } else { $data = json_decode($info, true); diff --git a/PHPCI/Model/ProjectGroup.php b/PHPCI/Model/ProjectGroup.php new file mode 100644 index 00000000..f85e6339 --- /dev/null +++ b/PHPCI/Model/ProjectGroup.php @@ -0,0 +1,18 @@ + diff --git a/PHPCI/Plugin/Atoum.php b/PHPCI/Plugin/Atoum.php index 8abc871e..877f009b 100644 --- a/PHPCI/Plugin/Atoum.php +++ b/PHPCI/Plugin/Atoum.php @@ -10,6 +10,7 @@ namespace PHPCI\Plugin; use PHPCI\Builder; +use PHPCI\Helper\Lang; use PHPCI\Model\Build; /** diff --git a/PHPCI/Plugin/Behat.php b/PHPCI/Plugin/Behat.php index 0e2fe69b..d63016dc 100644 --- a/PHPCI/Plugin/Behat.php +++ b/PHPCI/Plugin/Behat.php @@ -12,6 +12,7 @@ namespace PHPCI\Plugin; use PHPCI\Builder; use PHPCI\Helper\Lang; use PHPCI\Model\Build; +use PHPCI\Model\BuildError; /** * Behat BDD Plugin @@ -66,12 +67,72 @@ class Behat implements \PHPCI\Plugin if (!$behat) { $this->phpci->logFailure(Lang::get('could_not_find', 'behat')); + return false; } $success = $this->phpci->executeCommand($behat . ' %s', $this->features); chdir($curdir); + list($errorCount, $data) = $this->parseBehatOutput(); + + $this->build->storeMeta('behat-warnings', $errorCount); + $this->build->storeMeta('behat-data', $data); + return $success; } + + /** + * Parse the behat output and return details on failures + * + * @return array + */ + public function parseBehatOutput() + { + $output = $this->phpci->getLastOutput(); + + $parts = explode('---', $output); + + if (count($parts) <= 1) { + return array(0, array()); + } + + $lines = explode(PHP_EOL, $parts[1]); + + $storeFailures = false; + $data = array(); + + foreach ($lines as $line) { + $line = trim($line); + if ($line == 'Failed scenarios:') { + $storeFailures = true; + continue; + } + + if (strpos($line, ':') === false) { + $storeFailures = false; + } + + if ($storeFailures) { + $lineParts = explode(':', $line); + $data[] = array( + 'file' => $lineParts[0], + 'line' => $lineParts[1] + ); + + $this->build->reportError( + $this->phpci, + 'behat', + 'Behat scenario failed.', + BuildError::SEVERITY_HIGH, + $lineParts[0], + $lineParts[1] + ); + } + } + + $errorCount = count($data); + + return array($errorCount, $data); + } } diff --git a/PHPCI/Plugin/Campfire.php b/PHPCI/Plugin/Campfire.php index b111786e..59ab9128 100644 --- a/PHPCI/Plugin/Campfire.php +++ b/PHPCI/Plugin/Campfire.php @@ -38,19 +38,19 @@ class Campfire implements \PHPCI\Plugin */ public function __construct(Builder $phpci, Build $build, array $options = array()) { - $this->phpci = $phpci; - $this->build = $build; - - $this->message = $options['message']; + $this->phpci = $phpci; + $this->build = $build; + $this->message = $options['message']; $this->userAgent = "PHPCI/1.0 (+http://www.phptesting.org/)"; - $this->cookie = "phpcicookie"; + $this->cookie = "phpcicookie"; $buildSettings = $phpci->getConfig('build_settings'); + if (isset($buildSettings['campfire'])) { - $campfire = $buildSettings['campfire']; - $this->url = $campfire['url']; + $campfire = $buildSettings['campfire']; + $this->url = $campfire['url']; $this->authToken = $campfire['authToken']; - $this->roomId = $campfire['roomId']; + $this->roomId = $campfire['roomId']; } else { throw new \Exception(Lang::get('no_campfire_settings')); } @@ -63,7 +63,7 @@ class Campfire implements \PHPCI\Plugin */ public function execute() { - $url = PHPCI_URL."build/view/".$this->build->getId(); + $url = PHPCI_URL . "build/view/" . $this->build->getId(); $message = str_replace("%buildurl%", $url, $this->message); $this->joinRoom($this->roomId); $status = $this->speak($message, $this->roomId); @@ -101,6 +101,7 @@ class Campfire implements \PHPCI\Plugin public function speak($message, $roomId, $isPaste = false) { $page = '/room/'.$roomId.'/speak.json'; + if ($isPaste) { $type = 'PasteMessage'; } else { @@ -143,12 +144,13 @@ class Campfire implements \PHPCI\Plugin // We tend to get one space with an otherwise blank response $output = trim($output); + if (strlen($output)) { /* Responses are JSON. Decode it to a data structure */ return json_decode($output); } + // Simple 200 OK response (such as for joining a room) - // TODO: check for other result codes here return true; } } diff --git a/PHPCI/Plugin/CleanBuild.php b/PHPCI/Plugin/CleanBuild.php index 2d33aee4..684e8e7a 100644 --- a/PHPCI/Plugin/CleanBuild.php +++ b/PHPCI/Plugin/CleanBuild.php @@ -39,9 +39,9 @@ class CleanBuild implements \PHPCI\Plugin */ public function __construct(Builder $phpci, Build $build, array $options = array()) { - $this->phpci = $phpci; - $this->build = $build; - $this->remove = isset($options['remove']) && is_array($options['remove']) ? $options['remove'] : array(); + $this->phpci = $phpci; + $this->build = $build; + $this->remove = isset($options['remove']) && is_array($options['remove']) ? $options['remove'] : array(); } /** @@ -57,7 +57,7 @@ class CleanBuild implements \PHPCI\Plugin $this->phpci->executeCommand($cmd, $this->phpci->buildPath . 'composer.lock'); $success = true; - + foreach ($this->remove as $file) { $ok = $this->phpci->executeCommand($cmd, $this->phpci->buildPath . $file); diff --git a/PHPCI/Plugin/Codeception.php b/PHPCI/Plugin/Codeception.php index 2f9e66fd..c28e3a48 100644 --- a/PHPCI/Plugin/Codeception.php +++ b/PHPCI/Plugin/Codeception.php @@ -12,31 +12,66 @@ namespace PHPCI\Plugin; use PHPCI\Builder; use PHPCI\Helper\Lang; use PHPCI\Model\Build; +use PHPCI\Plugin\Util\TestResultParsers\Codeception as Parser; +use Psr\Log\LogLevel; /** * Codeception Plugin - Enables full acceptance, unit, and functional testing. * @author Don Gilbert + * @author Igor Timoshenko + * @author Adam Cooper * @package PHPCI * @subpackage Plugins */ -class Codeception implements \PHPCI\Plugin +class Codeception implements \PHPCI\Plugin, \PHPCI\ZeroConfigPlugin { - /** - * @var string - */ + /** @var string */ protected $args = ''; - /** - * @var Builder - */ + /** @var Builder */ protected $phpci; + /** @var Build */ protected $build; /** - * @var string|string[] $xmlConfigFile The path (or array of paths) of an xml config for PHPUnit + * @var string $ymlConfigFile The path of a yml config for Codeception */ - protected $xmlConfigFile; + protected $ymlConfigFile; + + /** + * @var string $path The path to the codeception tests folder. + */ + protected $path; + + /** + * @param $stage + * @param Builder $builder + * @param Build $build + * @return bool + */ + public static function canExecute($stage, Builder $builder, Build $build) + { + return $stage == 'test' && !is_null(self::findConfigFile($builder->buildPath)); + } + + /** + * Try and find the codeception YML config file. + * @param $buildPath + * @return null|string + */ + public static function findConfigFile($buildPath) + { + if (file_exists($buildPath . 'codeception.yml')) { + return 'codeception.yml'; + } + + if (file_exists($buildPath . 'codeception.dist.yml')) { + return 'codeception.dist.yml'; + } + + return null; + } /** * Set up the plugin, configure options, etc. @@ -48,71 +83,81 @@ class Codeception implements \PHPCI\Plugin { $this->phpci = $phpci; $this->build = $build; + $this->path = 'tests' . DIRECTORY_SEPARATOR . '_output' . DIRECTORY_SEPARATOR; - if (isset($options['config'])) { - $this->xmlConfigFile = $options['config']; + if (empty($options['config'])) { + $this->ymlConfigFile = self::findConfigFile($this->phpci->buildPath); + } else { + $this->ymlConfigFile = $options['config']; } if (isset($options['args'])) { $this->args = (string) $options['args']; } + if (isset($options['path'])) { + $this->path = $options['path']; + } } /** - * Runs Codeception tests, optionally using specified config file(s). + * Runs Codeception tests */ public function execute() { - $success = true; - - // Run any config files first. This can be either a single value or an array. - if ($this->xmlConfigFile !== null) { - $success &= $this->runConfigFile($this->xmlConfigFile); + if (empty($this->ymlConfigFile)) { + throw new \Exception("No configuration file found"); } - return $success; + // Run any config files first. This can be either a single value or an array. + return $this->runConfigFile($this->ymlConfigFile); } /** * Run tests from a Codeception config file. * @param $configPath * @return bool|mixed + * @throws \Exception */ protected function runConfigFile($configPath) { - if (is_array($configPath)) { - return $this->recurseArg($configPath, array($this, "runConfigFile")); - } else { + $this->phpci->logExecOutput(false); - $codecept = $this->phpci->findBinary('codecept'); + $codecept = $this->phpci->findBinary('codecept'); - if (!$codecept) { - $this->phpci->logFailure(Lang::get('could_not_find', 'codecept')); - return false; - } + if (!$codecept) { + $this->phpci->logFailure(Lang::get('could_not_find', 'codecept')); - $cmd = 'cd "%s" && ' . $codecept . ' run -c "%s" '. $this->args; - if (IS_WIN) { - $cmd = 'cd /d "%s" && ' . $codecept . ' run -c "%s" '. $this->args; - } - - $configPath = $this->phpci->buildPath . $configPath; - $success = $this->phpci->executeCommand($cmd, $this->phpci->buildPath, $configPath); - - return $success; + return false; } - } - /** - * @param $array - * @param $callable - * @return bool|mixed - */ - protected function recurseArg($array, $callable) - { - $success = true; - foreach ($array as $subItem) { - $success &= call_user_func($callable, $subItem); + $cmd = 'cd "%s" && ' . $codecept . ' run -c "%s" --xml ' . $this->args; + + if (IS_WIN) { + $cmd = 'cd /d "%s" && ' . $codecept . ' run -c "%s" --xml ' . $this->args; } + + $configPath = $this->phpci->buildPath . $configPath; + $success = $this->phpci->executeCommand($cmd, $this->phpci->buildPath, $configPath); + + $this->phpci->log( + 'Codeception XML path: '. $this->phpci->buildPath . $this->path . 'report.xml', + Loglevel::DEBUG + ); + + $xml = file_get_contents($this->phpci->buildPath . $this->path . 'report.xml', false); + $parser = new Parser($this->phpci, $xml); + $output = $parser->parse(); + + $meta = array( + 'tests' => $parser->getTotalTests(), + 'timetaken' => $parser->getTotalTimeTaken(), + 'failures' => $parser->getTotalFailures() + ); + + $this->build->storeMeta('codeception-meta', $meta); + $this->build->storeMeta('codeception-data', $output); + $this->build->storeMeta('codeception-errors', $parser->getTotalFailures()); + $this->phpci->logExecOutput(true); + return $success; } } diff --git a/PHPCI/Plugin/Composer.php b/PHPCI/Plugin/Composer.php index 3930f3d6..7bd86ac3 100644 --- a/PHPCI/Plugin/Composer.php +++ b/PHPCI/Plugin/Composer.php @@ -27,6 +27,7 @@ class Composer implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin protected $preferDist; protected $phpci; protected $build; + protected $nodev; /** * Check if this plugin can be executed. @@ -37,7 +38,7 @@ class Composer implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin */ public static function canExecute($stage, Builder $builder, Build $build) { - $path = $builder->buildPath . '/composer.json'; + $path = $builder->buildPath . DIRECTORY_SEPARATOR . 'composer.json'; if (file_exists($path) && $stage == 'setup') { return true; @@ -54,15 +55,17 @@ class Composer implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin */ public function __construct(Builder $phpci, Build $build, array $options = array()) { - $path = $phpci->buildPath; - $this->phpci = $phpci; - $this->build = $build; - $this->directory = $path; - $this->action = 'install'; + $path = $phpci->buildPath; + $this->phpci = $phpci; + $this->build = $build; + $this->directory = $path; + $this->action = 'install'; $this->preferDist = false; + $this->preferSource = false; + $this->nodev = false; if (array_key_exists('directory', $options)) { - $this->directory = $path . '/' . $options['directory']; + $this->directory = $path . DIRECTORY_SEPARATOR . $options['directory']; } if (array_key_exists('action', $options)) { @@ -72,6 +75,15 @@ class Composer implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin if (array_key_exists('prefer_dist', $options)) { $this->preferDist = (bool)$options['prefer_dist']; } + + if (array_key_exists('prefer_source', $options)) { + $this->preferDist = false; + $this->preferSource = (bool)$options['prefer_source']; + } + + if (array_key_exists('no_dev', $options)) { + $this->nodev = (bool)$options['no_dev']; + } } /** @@ -81,11 +93,6 @@ class Composer implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin { $composerLocation = $this->phpci->findBinary(array('composer', 'composer.phar')); - if (!$composerLocation) { - $this->phpci->logFailure(Lang::get('could_not_find', 'composer')); - return false; - } - $cmd = ''; if (IS_WIN) { @@ -96,10 +103,17 @@ class Composer implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin if ($this->preferDist) { $this->phpci->log('Using --prefer-dist flag'); - $cmd .= '--prefer-dist'; - } else { + $cmd .= ' --prefer-dist'; + } + + if ($this->preferSource) { $this->phpci->log('Using --prefer-source flag'); - $cmd .= '--prefer-source'; + $cmd .= ' --prefer-source'; + } + + if ($this->nodev) { + $this->phpci->log('Using --no-dev flag'); + $cmd .= ' --no-dev'; } $cmd .= ' --working-dir="%s" %s'; diff --git a/PHPCI/Plugin/CopyBuild.php b/PHPCI/Plugin/CopyBuild.php index a80819fb..f9646cac 100644 --- a/PHPCI/Plugin/CopyBuild.php +++ b/PHPCI/Plugin/CopyBuild.php @@ -35,12 +35,12 @@ class CopyBuild implements \PHPCI\Plugin */ public function __construct(Builder $phpci, Build $build, array $options = array()) { - $path = $phpci->buildPath; - $this->phpci = $phpci; - $this->build = $build; - $this->directory = isset($options['directory']) ? $options['directory'] : $path; - $this->wipe = isset($options['wipe']) ? (bool)$options['wipe'] : false; - $this->ignore = isset($options['respect_ignore']) ? (bool)$options['respect_ignore'] : false; + $path = $phpci->buildPath; + $this->phpci = $phpci; + $this->build = $build; + $this->directory = isset($options['directory']) ? $options['directory'] : $path; + $this->wipe = isset($options['wipe']) ? (bool)$options['wipe'] : false; + $this->ignore = isset($options['respect_ignore']) ? (bool)$options['respect_ignore'] : false; } /** @@ -74,7 +74,7 @@ class CopyBuild implements \PHPCI\Plugin */ protected function wipeExistingDirectory() { - if ($this->wipe == true && $this->directory != '/' && is_dir($this->directory)) { + if ($this->wipe === true && $this->directory != '/' && is_dir($this->directory)) { $cmd = 'rm -Rf "%s*"'; $success = $this->phpci->executeCommand($cmd, $this->directory); diff --git a/PHPCI/Plugin/Deployer.php b/PHPCI/Plugin/Deployer.php new file mode 100644 index 00000000..9c56a340 --- /dev/null +++ b/PHPCI/Plugin/Deployer.php @@ -0,0 +1,73 @@ + +* @package PHPCI +* @subpackage Plugins +*/ +class Deployer implements \PHPCI\Plugin +{ + protected $webhookUrl; + protected $reason; + protected $updateOnly; + + /** + * Set up the plugin, configure options, etc. + * @param Builder $phpci + * @param Build $build + * @param array $options + */ + public function __construct(Builder $phpci, Build $build, array $options = array()) + { + $this->phpci = $phpci; + $this->build = $build; + $this->reason = 'PHPCI Build #%BUILD% - %COMMIT_MESSAGE%'; + + if (isset($options['webhook_url'])) { + $this->webhookUrl = $options['webhook_url']; + } + + if (isset($options['reason'])) { + $this->reason = $options['reason']; + } + + $this->updateOnly = isset($options['update_only']) ? (bool) $options['update_only'] : true; + } + + /** + * Copies files from the root of the build directory into the target folder + */ + public function execute() + { + if (empty($this->webhookUrl)) { + $this->phpci->logFailure('You must specify a webhook URL.'); + return false; + } + + $http = new HttpClient(); + + $response = $http->post($this->webhookUrl, array( + 'reason' => $this->phpci->interpolate($this->reason), + 'source' => 'PHPCI', + 'url' => $this->phpci->interpolate('%BUILD_URI%'), + 'branch' => $this->phpci->interpolate('%BRANCH%'), + 'update_only' => $this->updateOnly + )); + + return $response['success']; + } +} diff --git a/PHPCI/Plugin/Email.php b/PHPCI/Plugin/Email.php index 98b226e3..17e235e2 100644 --- a/PHPCI/Plugin/Email.php +++ b/PHPCI/Plugin/Email.php @@ -9,10 +9,13 @@ namespace PHPCI\Plugin; +use Exception; use b8\View; use PHPCI\Builder; use PHPCI\Helper\Lang; use PHPCI\Model\Build; +use PHPCI\Helper\Email as EmailHelper; +use Psr\Log\LogLevel; /** * Email Plugin - Provides simple email capability to PHPCI. @@ -27,21 +30,16 @@ class Email implements \PHPCI\Plugin */ protected $phpci; + /** + * @var \PHPCI\Model\Build + */ + protected $build; + /** * @var array */ protected $options; - /** - * @var \Swift_Mailer - */ - protected $mailer; - - /** - * @var string - */ - protected $fromAddress; - /** * Set up the plugin, configure options, etc. * @param Builder $phpci @@ -52,25 +50,16 @@ class Email implements \PHPCI\Plugin public function __construct( Builder $phpci, Build $build, - \Swift_Mailer $mailer, array $options = array() ) { - $this->phpci = $phpci; - $this->build = $build; - $this->options = $options; - - $phpCiSettings = $phpci->getSystemConfig('phpci'); - - $this->fromAddress = isset($phpCiSettings['email_settings']['from_address']) - ? $phpCiSettings['email_settings']['from_address'] - : "notifications-ci@phptesting.org"; - - $this->mailer = $mailer; + $this->phpci = $phpci; + $this->build = $build; + $this->options = $options; } /** - * Connects to MySQL and runs a specified set of queries. - */ + * Send a notification mail. + */ public function execute() { $addresses = $this->getEmailAddresses(); @@ -81,79 +70,86 @@ class Email implements \PHPCI\Plugin return false; } - $subjectTemplate = "PHPCI - %s - %s"; - $projectName = $this->phpci->getBuildProjectTitle(); - $logText = $this->build->getLog(); + $buildStatus = $this->build->isSuccessful() ? "Passing Build" : "Failing Build"; + $projectName = $this->build->getProject()->getTitle(); - if ($this->build->isSuccessful()) { - $sendFailures = $this->sendSeparateEmails( - $addresses, - sprintf($subjectTemplate, $projectName, Lang::get('passing_build')), - sprintf(Lang::get('log_output')."
%s
", $logText) - ); - } else { - $view = new View('Email/failed'); - $view->build = $this->build; - $view->project = $this->build->getProject(); - - $emailHtml = $view->render(); - - $sendFailures = $this->sendSeparateEmails( - $addresses, - sprintf($subjectTemplate, $projectName, Lang::get('failing_build')), - $emailHtml + try { + $view = $this->getMailTemplate(); + } catch (Exception $e) { + $this->phpci->log( + sprintf('Unknown mail template "%s", falling back to default.', $this->options['template']), + LogLevel::WARNING ); + $view = $this->getDefaultMailTemplate(); } + $view->build = $this->build; + $view->project = $this->build->getProject(); + + $layout = new View('Email/layout'); + $layout->build = $this->build; + $layout->project = $this->build->getProject(); + $layout->content = $view->render(); + $body = $layout->render(); + + $sendFailures = $this->sendSeparateEmails( + $addresses, + sprintf("PHPCI - %s - %s", $projectName, $buildStatus), + $body + ); + // This is a success if we've not failed to send anything. + $this->phpci->log(sprintf("%d emails sent", (count($addresses) - $sendFailures))); + $this->phpci->log(sprintf("%d emails failed to send", $sendFailures)); - $this->phpci->log(Lang::get('n_emails_sent', (count($addresses) - count($sendFailures)))); - $this->phpci->log(Lang::get('n_emails_failed', count($sendFailures))); - - return (count($sendFailures) == 0); + return ($sendFailures === 0); } /** - * @param string[]|string $toAddresses Array or single address to send to + * @param string $toAddress Single address to send to * @param string[] $ccList * @param string $subject Email subject * @param string $body Email body * @return array Array of failed addresses */ - public function sendEmail($toAddresses, $ccList, $subject, $body) + protected function sendEmail($toAddress, $ccList, $subject, $body) { - $message = \Swift_Message::newInstance($subject) - ->setFrom($this->fromAddress) - ->setTo($toAddresses) - ->setBody($body) - ->setContentType("text/html"); + $email = new EmailHelper(); + + $email->setEmailTo($toAddress, $toAddress); + $email->setSubject($subject); + $email->setBody($body); + $email->setHtml(true); if (is_array($ccList) && count($ccList)) { - $message->setCc($ccList); + foreach ($ccList as $address) { + $email->addCc($address, $address); + } } - $failedAddresses = array(); - $this->mailer->send($message, $failedAddresses); - - return $failedAddresses; + return $email->send(); } /** - * Send out build status emails. + * Send an email to a list of specified subjects. + * * @param array $toAddresses - * @param $subject - * @param $body - * @return array + * List of destination addresses for message. + * @param string $subject + * Mail subject + * @param string $body + * Mail body + * + * @return int number of failed messages */ public function sendSeparateEmails(array $toAddresses, $subject, $body) { - $failures = array(); + $failures = 0; $ccList = $this->getCcAddresses(); foreach ($toAddresses as $address) { - $newFailures = $this->sendEmail($address, $ccList, $subject, $body); - foreach ($newFailures as $failure) { - $failures[] = $failure; + if (!$this->sendEmail($address, $ccList, $subject, $body)) { + $failures++; } } return $failures; @@ -178,15 +174,16 @@ class Email implements \PHPCI\Plugin } } - if (isset($this->options['default_mailto_address'])) { + if (empty($addresses) && isset($this->options['default_mailto_address'])) { $addresses[] = $this->options['default_mailto_address']; - return $addresses; } - return $addresses; + + return array_unique($addresses); } /** * Get the list of email addresses to CC. + * * @return array */ protected function getCcAddresses() @@ -201,4 +198,30 @@ class Email implements \PHPCI\Plugin return $ccAddresses; } + + /** + * Get the mail template used to sent the mail. + * + * @return View + */ + protected function getMailTemplate() + { + if (isset($this->options['template'])) { + return new View('Email/' . $this->options['template']); + } + + return $this->getDefaultMailTemplate(); + } + + /** + * Get the default mail template. + * + * @return View + */ + protected function getDefaultMailTemplate() + { + $template = $this->build->isSuccessful() ? 'short' : 'long'; + + return new View('Email/' . $template); + } } diff --git a/PHPCI/Plugin/Env.php b/PHPCI/Plugin/Env.php index 4e4b6563..b89bf67d 100644 --- a/PHPCI/Plugin/Env.php +++ b/PHPCI/Plugin/Env.php @@ -52,7 +52,7 @@ class Env implements \PHPCI\Plugin // This allows the standard syntax: "FOO: bar" $env_var = "$key=$value"; } - + if (!putenv($this->phpci->interpolate($env_var))) { $success = false; $this->phpci->logFailure(Lang::get('unable_to_set_env')); diff --git a/PHPCI/Plugin/FlowdockNotify.php b/PHPCI/Plugin/FlowdockNotify.php new file mode 100644 index 00000000..8ac9f2ab --- /dev/null +++ b/PHPCI/Plugin/FlowdockNotify.php @@ -0,0 +1,73 @@ + + * @package PHPCI + * @subpackage Plugins + */ +class FlowdockNotify implements \PHPCI\Plugin +{ + private $api_key; + private $email; + const MESSAGE_DEFAULT = 'Build %BUILD% has finished for commit %SHORT_COMMIT% + (%COMMIT_EMAIL%)> on branch %BRANCH%'; + + /** + * Set up the plugin, configure options, etc. + * @param Builder $phpci + * @param Build $build + * @param array $options + * @throws \Exception + */ + public function __construct(Builder $phpci, Build $build, array $options = array()) + { + $this->phpci = $phpci; + $this->build = $build; + if (!is_array($options) || !isset($options['api_key'])) { + throw new \Exception('Please define the api_key for Flowdock Notify plugin!'); + } + $this->api_key = trim($options['api_key']); + $this->message = isset($options['message']) ? $options['message'] : self::MESSAGE_DEFAULT; + $this->email = isset($options['email']) ? $options['email'] : 'PHPCI'; + } + + /** + * Run the Flowdock plugin. + * @return bool + * @throws \Exception + */ + public function execute() + { + + $message = $this->phpci->interpolate($this->message); + $successfulBuild = $this->build->isSuccessful() ? 'Success' : 'Failed'; + $push = new Push($this->api_key); + $flowMessage = TeamInboxMessage::create() + ->setSource("PHPCI") + ->setFromAddress($this->email) + ->setFromName($this->build->getProject()->getTitle()) + ->setSubject($successfulBuild) + ->setTags(['#ci']) + ->setLink($this->build->getBranchLink()) + ->setContent($message); + + if (!$push->sendTeamInboxMessage($flowMessage, array('connect_timeout' => 5000, 'timeout' => 5000))) { + throw new \Exception(sprintf('Flowdock Failed: %s', $flowMessage->getResponseErrors())); + } + return true; + } +} diff --git a/PHPCI/Plugin/Grunt.php b/PHPCI/Plugin/Grunt.php index 1ad0ceec..4d62ffd8 100644 --- a/PHPCI/Plugin/Grunt.php +++ b/PHPCI/Plugin/Grunt.php @@ -52,7 +52,7 @@ class Grunt implements \PHPCI\Plugin // Handle options: if (isset($options['directory'])) { - $this->directory = $path . '/' . $options['directory']; + $this->directory = $path . DIRECTORY_SEPARATOR . $options['directory']; } if (isset($options['task'])) { diff --git a/PHPCI/Plugin/Gulp.php b/PHPCI/Plugin/Gulp.php index 97ad9246..b6c6cab4 100644 --- a/PHPCI/Plugin/Gulp.php +++ b/PHPCI/Plugin/Gulp.php @@ -52,7 +52,7 @@ class Gulp implements \PHPCI\Plugin // Handle options: if (isset($options['directory'])) { - $this->directory = $path . '/' . $options['directory']; + $this->directory = $path . DIRECTORY_SEPARATOR . $options['directory']; } if (isset($options['task'])) { diff --git a/PHPCI/Plugin/HipchatNotify.php b/PHPCI/Plugin/HipchatNotify.php index 0cc1bf70..a39b94fe 100644 --- a/PHPCI/Plugin/HipchatNotify.php +++ b/PHPCI/Plugin/HipchatNotify.php @@ -21,11 +21,9 @@ use PHPCI\Model\Build; */ class HipchatNotify implements \PHPCI\Plugin { - private $authToken; - private $userAgent; - private $cookie; - private $color; - private $notify; + protected $authToken; + protected $color; + protected $notify; /** * Set up the plugin, configure options, etc. diff --git a/PHPCI/Plugin/Irc.php b/PHPCI/Plugin/Irc.php index 7fe06753..a7610a8c 100644 --- a/PHPCI/Plugin/Irc.php +++ b/PHPCI/Plugin/Irc.php @@ -77,19 +77,56 @@ class Irc implements \PHPCI\Plugin } $sock = fsockopen($this->server, $this->port); - fputs($sock, 'USER ' . $this->nick . ' phptesting.org ' . $this->nick . ' :' . $this->nick . "\r\n"); - fputs($sock, 'NICK ' . $this->nick . "\r\n"); - fputs($sock, 'JOIN ' . $this->room . "\r\n"); - fputs($sock, 'PRIVMSG ' . $this->room . ' :' . $msg . "\r\n"); + stream_set_timeout($sock, 1); - while (fgets($sock)) { - // We don't need to do anything, - // but the IRC server doesn't appear to post the message - // unless we wait for responses. - } + $connectCommands = array( + 'USER ' . $this->nick . ' 0 * :' . $this->nick, + 'NICK ' . $this->nick, + ); + $this->executeIrcCommands($sock, $connectCommands); + $this->executeIrcCommand($sock, 'JOIN ' . $this->room); + $this->executeIrcCommand($sock, 'PRIVMSG ' . $this->room . ' :' . $msg); fclose($sock); return true; } + + /** + * @param resource $socket + * @param array $commands + * @return bool + */ + private function executeIrcCommands($socket, array $commands) + { + foreach ($commands as $command) { + fputs($socket, $command . "\n"); + } + + $pingBack = false; + + // almost all servers expect pingback! + while ($response = fgets($socket)) { + $matches = array(); + if (preg_match('/^PING \\:([A-Z0-9]+)/', $response, $matches)) { + $pingBack = $matches[1]; + } + } + + if ($pingBack) { + $command = 'PONG :' . $pingBack . "\n"; + fputs($socket, $command); + } + } + + /** + * + * @param resource $socket + * @param string $command + * @return bool + */ + private function executeIrcCommand($socket, $command) + { + return $this->executeIrcCommands($socket, array($command)); + } } diff --git a/PHPCI/Plugin/Lint.php b/PHPCI/Plugin/Lint.php index 90436d70..a7ddc55c 100644 --- a/PHPCI/Plugin/Lint.php +++ b/PHPCI/Plugin/Lint.php @@ -41,9 +41,9 @@ class Lint implements PHPCI\Plugin */ public function __construct(Builder $phpci, Build $build, array $options = array()) { - $this->phpci = $phpci; + $this->phpci = $phpci; $this->build = $build; - $this->directories = array(''); + $this->directories = array(''); $this->ignore = $phpci->ignore; if (!empty($options['directory'])) { @@ -93,7 +93,7 @@ class Lint implements PHPCI\Plugin if ($item->isFile() && $item->getExtension() == 'php' && !$this->lintFile($php, $itemPath)) { $success = false; - } elseif ($item->isDir() && $this->recursive && !$this->lintDirectory($php, $itemPath . '/')) { + } elseif ($item->isDir() && $this->recursive && !$this->lintDirectory($php, $itemPath . DIRECTORY_SEPARATOR)) { $success = false; } diff --git a/PHPCI/Plugin/Mysql.php b/PHPCI/Plugin/Mysql.php old mode 100755 new mode 100644 index 5c36a09f..fdb521ef --- a/PHPCI/Plugin/Mysql.php +++ b/PHPCI/Plugin/Mysql.php @@ -166,10 +166,11 @@ class Mysql implements \PHPCI\Plugin $args = array( ':import_file' => escapeshellarg($import_file), ':decomp_cmd' => $decomp_cmd, + ':host' => escapeshellarg($this->host), ':user' => escapeshellarg($this->user), ':pass' => escapeshellarg($this->pass), ':database' => ($database === null)? '': escapeshellarg($database), ); - return strtr('cat :import_file :decomp_cmd | mysql -u:user -p:pass :database', $args); + return strtr('cat :import_file :decomp_cmd | mysql -h:host -u:user -p:pass :database', $args); } } diff --git a/PHPCI/Plugin/PackageBuild.php b/PHPCI/Plugin/PackageBuild.php index 8e40c71f..fb116640 100644 --- a/PHPCI/Plugin/PackageBuild.php +++ b/PHPCI/Plugin/PackageBuild.php @@ -33,12 +33,12 @@ class PackageBuild implements \PHPCI\Plugin */ public function __construct(Builder $phpci, Build $build, array $options = array()) { - $path = $phpci->buildPath; - $this->build = $build; - $this->phpci = $phpci; - $this->directory = isset($options['directory']) ? $options['directory'] : $path; - $this->filename = isset($options['filename']) ? $options['filename'] : 'build'; - $this->format = isset($options['format']) ? $options['format'] : 'zip'; + $path = $phpci->buildPath; + $this->build = $build; + $this->phpci = $phpci; + $this->directory = isset($options['directory']) ? $options['directory'] : $path; + $this->filename = isset($options['filename']) ? $options['filename'] : 'build'; + $this->format = isset($options['format']) ? $options['format'] : 'zip'; } /** @@ -46,7 +46,7 @@ class PackageBuild implements \PHPCI\Plugin */ public function execute() { - $path = $this->phpci->buildPath; + $path = $this->phpci->buildPath; $build = $this->build; if ($this->directory == $path) { @@ -69,8 +69,7 @@ class PackageBuild implements \PHPCI\Plugin } foreach ($this->format as $format) { - switch($format) - { + switch ($format) { case 'tar': $cmd = 'tar cfz "%s/%s.tar.gz" ./*'; break; diff --git a/PHPCI/Plugin/Pdepend.php b/PHPCI/Plugin/Pdepend.php index d1039554..faef406d 100644 --- a/PHPCI/Plugin/Pdepend.php +++ b/PHPCI/Plugin/Pdepend.php @@ -73,21 +73,19 @@ class Pdepend implements \PHPCI\Plugin */ public function execute() { + if (!file_exists($this->location)) { + mkdir($this->location); + } if (!is_writable($this->location)) { - throw new \Exception(sprintf('The location %s is not writable.', $this->location)); + throw new \Exception(sprintf('The location %s is not writable or does not exist.', $this->location)); } $pdepend = $this->phpci->findBinary('pdepend'); - if (!$pdepend) { - $this->phpci->logFailure(Lang::get('could_not_find', 'pdepend')); - return false; - } - $cmd = $pdepend . ' --summary-xml="%s" --jdepend-chart="%s" --overview-pyramid="%s" %s "%s"'; $this->removeBuildArtifacts(); - + // If we need to ignore directories if (count($this->phpci->ignore)) { $ignore = ' --ignore=' . implode(',', $this->phpci->ignore); diff --git a/PHPCI/Plugin/Pgsql.php b/PHPCI/Plugin/Pgsql.php index 9a5f630c..60057464 100644 --- a/PHPCI/Plugin/Pgsql.php +++ b/PHPCI/Plugin/Pgsql.php @@ -73,9 +73,9 @@ class Pgsql implements \PHPCI\Plugin } /** - * Connects to PgSQL and runs a specified set of queries. - * @return boolean - */ + * Connects to PgSQL and runs a specified set of queries. + * @return boolean + */ public function execute() { try { @@ -83,7 +83,7 @@ class Pgsql implements \PHPCI\Plugin $pdo = new PDO('pgsql:host=' . $this->host, $this->user, $this->pass, $opts); foreach ($this->queries as $query) { - $pdo->query($query); + $pdo->query($this->phpci->interpolate($query)); } } catch (\Exception $ex) { $this->phpci->logFailure($ex->getMessage()); diff --git a/PHPCI/Plugin/Phar.php b/PHPCI/Plugin/Phar.php index f04580e7..c734bb6c 100644 --- a/PHPCI/Plugin/Phar.php +++ b/PHPCI/Plugin/Phar.php @@ -213,7 +213,7 @@ class Phar implements \PHPCI\Plugin $content = ''; $filename = $this->getStub(); if ($filename) { - $content = file_get_contents($this->getPHPCI()->buildPath . '/' . $this->getStub()); + $content = file_get_contents($this->getPHPCI()->buildPath . DIRECTORY_SEPARATOR . $this->getStub()); } return $content; } @@ -227,8 +227,8 @@ class Phar implements \PHPCI\Plugin $success = false; try { - - $phar = new PHPPhar($this->getDirectory() . '/' . $this->getFilename(), 0, $this->getFilename()); + $file = $this->getDirectory() . DIRECTORY_SEPARATOR . $this->getFilename(); + $phar = new PHPPhar($file, 0, $this->getFilename()); $phar->buildFromDirectory($this->getPHPCI()->buildPath, $this->getRegExp()); $stub = $this->getStubContent(); @@ -237,7 +237,6 @@ class Phar implements \PHPCI\Plugin } $success = true; - } catch (Exception $e) { $this->getPHPCI()->log(Lang::get('phar_internal_error')); $this->getPHPCI()->log($e->getMessage()); diff --git a/PHPCI/Plugin/Phing.php b/PHPCI/Plugin/Phing.php index ae86968b..e322b72e 100644 --- a/PHPCI/Plugin/Phing.php +++ b/PHPCI/Plugin/Phing.php @@ -47,7 +47,7 @@ class Phing implements \PHPCI\Plugin * Set working directory */ if (isset($options['directory'])) { - $directory = $phpci->buildPath . '/' . $options['directory']; + $directory = $phpci->buildPath . DIRECTORY_SEPARATOR . $options['directory']; } else { $directory = $phpci->buildPath; } @@ -81,11 +81,6 @@ class Phing implements \PHPCI\Plugin { $phingExecutable = $this->phpci->findBinary('phing'); - if (!$phingExecutable) { - $this->phpci->logFailure(Lang::get('could_not_find', 'phing')); - return false; - } - $cmd[] = $phingExecutable . ' -f ' . $this->getBuildFilePath(); if ($this->getPropertyFile()) { @@ -213,8 +208,12 @@ class Phing implements \PHPCI\Plugin */ public function propertiesToString() { - if (empty($this->properties)) { - return ''; + /** + * fix the problem when execute phing out of the build dir + * @ticket 748 + */ + if (!isset($this->properties['project.basedir'])) { + $this->properties['project.basedir'] = $this->getDirectory(); } $propertiesString = array(); @@ -256,7 +255,7 @@ class Phing implements \PHPCI\Plugin */ public function setPropertyFile($propertyFile) { - if (!file_exists($this->getDirectory() . '/' . $propertyFile)) { + if (!file_exists($this->getDirectory() . DIRECTORY_SEPARATOR . $propertyFile)) { throw new \Exception(Lang::get('property_file_missing')); } diff --git a/PHPCI/Plugin/PhpCodeSniffer.php b/PHPCI/Plugin/PhpCodeSniffer.php old mode 100755 new mode 100644 index 3ee232b7..6f4ed4e0 --- a/PHPCI/Plugin/PhpCodeSniffer.php +++ b/PHPCI/Plugin/PhpCodeSniffer.php @@ -12,6 +12,7 @@ namespace PHPCI\Plugin; use PHPCI; use PHPCI\Builder; use PHPCI\Model\Build; +use PHPCI\Model\BuildError; /** * PHP Code Sniffer Plugin - Allows PHP Code Sniffer testing. @@ -149,11 +150,6 @@ class PhpCodeSniffer implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin $phpcs = $this->phpci->findBinary('phpcs'); - if (!$phpcs) { - $this->phpci->logFailure(PHPCI\Helper\Lang::get('could_not_find', 'phpcs')); - return false; - } - $this->phpci->logExecOutput(false); $cmd = $phpcs . ' --report=json %s %s %s %s %s "%s"'; @@ -168,14 +164,13 @@ class PhpCodeSniffer implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin ); $output = $this->phpci->getLastOutput(); - list($errors, $warnings, $data) = $this->processReport($output); + list($errors, $warnings) = $this->processReport($output); $this->phpci->logExecOutput(true); $success = true; $this->build->storeMeta('phpcs-warnings', $warnings); $this->build->storeMeta('phpcs-errors', $errors); - $this->build->storeMeta('phpcs-data', $data); if ($this->allowed_warnings != -1 && $warnings > $this->allowed_warnings) { $success = false; @@ -231,21 +226,21 @@ class PhpCodeSniffer implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin $errors = $data['totals']['errors']; $warnings = $data['totals']['warnings']; - $rtn = array(); - foreach ($data['files'] as $fileName => $file) { $fileName = str_replace($this->phpci->buildPath, '', $fileName); foreach ($file['messages'] as $message) { - $rtn[] = array( - 'file' => $fileName, - 'line' => $message['line'], - 'type' => $message['type'], - 'message' => $message['message'], + $this->build->reportError( + $this->phpci, + 'php_code_sniffer', + 'PHPCS: ' . $message['message'], + $message['type'] == 'ERROR' ? BuildError::SEVERITY_HIGH : BuildError::SEVERITY_LOW, + $fileName, + $message['line'] ); } } - return array($errors, $warnings, $rtn); + return array($errors, $warnings); } } diff --git a/PHPCI/Plugin/PhpCpd.php b/PHPCI/Plugin/PhpCpd.php old mode 100644 new mode 100755 index 9bbcfc09..aa076d2d --- a/PHPCI/Plugin/PhpCpd.php +++ b/PHPCI/Plugin/PhpCpd.php @@ -12,6 +12,7 @@ namespace PHPCI\Plugin; use PHPCI\Builder; use PHPCI\Helper\Lang; use PHPCI\Model\Build; +use PHPCI\Model\BuildError; /** * PHP Copy / Paste Detector - Allows PHP Copy / Paste Detector testing. @@ -28,7 +29,7 @@ class PhpCpd implements \PHPCI\Plugin /** * @var string, based on the assumption the root may not hold the code to be - * tested, exteds the base path + * tested, extends the base path */ protected $path; @@ -49,17 +50,12 @@ class PhpCpd implements \PHPCI\Plugin $this->build = $build; $this->path = $phpci->buildPath; - $this->standard = 'PSR1'; $this->ignore = $phpci->ignore; if (!empty($options['path'])) { $this->path = $phpci->buildPath . $options['path']; } - if (!empty($options['standard'])) { - $this->standard = $options['standard']; - } - if (!empty($options['ignore'])) { $this->ignore = $options['ignore']; } @@ -74,9 +70,9 @@ class PhpCpd implements \PHPCI\Plugin if (count($this->ignore)) { $map = function ($item) { // remove the trailing slash - $item = (substr($item, -1) == '/' ? substr($item, 0, -1) : $item); + $item = rtrim($item, DIRECTORY_SEPARATOR); - if (is_file($this->path . '/' . $item)) { + if (is_file(rtrim($this->path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $item)) { return ' --names-exclude ' . $item; } else { return ' --exclude ' . $item; @@ -90,21 +86,15 @@ class PhpCpd implements \PHPCI\Plugin $phpcpd = $this->phpci->findBinary('phpcpd'); - if (!$phpcpd) { - $this->phpci->logFailure(Lang::get('could_not_find', 'phpcpd')); - return false; - } - $tmpfilename = tempnam('/tmp', 'phpcpd'); $cmd = $phpcpd . ' --log-pmd "%s" %s "%s"'; $success = $this->phpci->executeCommand($cmd, $tmpfilename, $ignore, $this->path); print $this->phpci->getLastOutput(); - - list($errorCount, $data) = $this->processReport(file_get_contents($tmpfilename)); + + $errorCount = $this->processReport(file_get_contents($tmpfilename)); $this->build->storeMeta('phpcpd-warnings', $errorCount); - $this->build->storeMeta('phpcpd-data', $data); unlink($tmpfilename); @@ -127,24 +117,33 @@ class PhpCpd implements \PHPCI\Plugin } $warnings = 0; - $data = array(); - foreach ($xml->duplication as $duplication) { foreach ($duplication->file as $file) { $fileName = (string)$file['path']; $fileName = str_replace($this->phpci->buildPath, '', $fileName); - $data[] = array( - 'file' => $fileName, - 'line_start' => (int) $file['line'], - 'line_end' => (int) $file['line'] + (int) $duplication['lines'], - 'code' => (string) $duplication->codefragment + $message = <<codefragment} +``` +CPD; + + $this->build->reportError( + $this->phpci, + 'php_cpd', + $message, + BuildError::SEVERITY_NORMAL, + $fileName, + $file['line'], + (int) $file['line'] + (int) $duplication['lines'] ); } $warnings++; } - return array($warnings, $data); + return $warnings; } } diff --git a/PHPCI/Plugin/PhpCsFixer.php b/PHPCI/Plugin/PhpCsFixer.php index 1374bc71..9aa0d33f 100644 --- a/PHPCI/Plugin/PhpCsFixer.php +++ b/PHPCI/Plugin/PhpCsFixer.php @@ -14,7 +14,7 @@ use PHPCI\Helper\Lang; use PHPCI\Model\Build; /** -* PHP CS Fixer - Works with the PHP CS Fixer for testing coding standards. +* PHP CS Fixer - Works with the PHP Coding Standards Fixer for testing coding standards. * @author Gabriel Baker * @package PHPCI * @subpackage Plugins @@ -32,10 +32,10 @@ class PhpCsFixer implements \PHPCI\Plugin protected $build; protected $workingDir = ''; - protected $level = ' --level=all'; - protected $verbose = ''; - protected $diff = ''; - protected $levels = array('psr0', 'psr1', 'psr2', 'all'); + protected $level = ' --level=psr2'; + protected $verbose = ''; + protected $diff = ''; + protected $levels = array('psr0', 'psr1', 'psr2', 'symfony'); /** * Standard Constructor @@ -69,11 +69,6 @@ class PhpCsFixer implements \PHPCI\Plugin $phpcsfixer = $this->phpci->findBinary('php-cs-fixer'); - if (!$phpcsfixer) { - $this->phpci->logFailure(Lang::get('could_not_find', 'php-cs-fixer')); - return false; - } - $cmd = $phpcsfixer . ' fix . %s %s %s'; $success = $this->phpci->executeCommand($cmd, $this->verbose, $this->diff, $this->level); diff --git a/PHPCI/Plugin/PhpDocblockChecker.php b/PHPCI/Plugin/PhpDocblockChecker.php old mode 100755 new mode 100644 index 9650127f..2396497c --- a/PHPCI/Plugin/PhpDocblockChecker.php +++ b/PHPCI/Plugin/PhpDocblockChecker.php @@ -104,11 +104,6 @@ class PhpDocblockChecker implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin // Check that the binary exists: $checker = $this->phpci->findBinary('phpdoccheck'); - if (!$checker) { - $this->phpci->logFailure(PHPCI\Helper\Lang::get('could_not_find', 'phpdoccheck')); - return false; - } - // Build ignore string: $ignore = ''; if (count($this->ignore)) { @@ -143,12 +138,12 @@ class PhpDocblockChecker implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin // Re-enable exec output logging: $this->phpci->logExecOutput(true); - $output = json_decode($this->phpci->getLastOutput()); + $output = json_decode($this->phpci->getLastOutput(), true); $errors = count($output); $success = true; $this->build->storeMeta('phpdoccheck-warnings', $errors); - $this->build->storeMeta('phpdoccheck-data', $output); + $this->reportErrors($output); if ($this->allowed_warnings != -1 && $errors > $this->allowed_warnings) { $success = false; @@ -156,4 +151,30 @@ class PhpDocblockChecker implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin return $success; } + + /** + * Report all of the errors we've encountered line-by-line. + * @param $output + */ + protected function reportErrors($output) + { + foreach ($output as $error) { + $message = 'Class ' . $error['class'] . ' is missing a docblock.'; + $severity = PHPCI\Model\BuildError::SEVERITY_LOW; + + if ($error['type'] == 'method') { + $message = $error['class'] . '::' . $error['method'] . ' is missing a docblock.'; + $severity = PHPCI\Model\BuildError::SEVERITY_NORMAL; + } + + $this->build->reportError( + $this->phpci, + 'php_docblock_checker', + $message, + $severity, + $error['file'], + $error['line'] + ); + } + } } diff --git a/PHPCI/Plugin/PhpLoc.php b/PHPCI/Plugin/PhpLoc.php index 65398e05..c8dedb91 100644 --- a/PHPCI/Plugin/PhpLoc.php +++ b/PHPCI/Plugin/PhpLoc.php @@ -69,24 +69,20 @@ class PhpLoc implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin public function execute() { $ignore = ''; - if (count($this->phpci->ignore)) { - $map = function ($item) { - return ' --exclude ' . (substr($item, -1) == '/' ? substr($item, 0, -1) : $item); - }; - $ignore = array_map($map, $this->phpci->ignore); + if (count($this->phpci->ignore)) { + $map = function ($item) { + return ' --exclude ' . rtrim($item, DIRECTORY_SEPARATOR); + }; + + $ignore = array_map($map, $this->phpci->ignore); $ignore = implode('', $ignore); } $phploc = $this->phpci->findBinary('phploc'); - if (!$phploc) { - $this->phpci->logFailure(PHPCI\Helper\Lang::get('could_not_find', 'phploc')); - return false; - } - $success = $this->phpci->executeCommand($phploc . ' %s "%s"', $ignore, $this->directory); - $output = $this->phpci->getLastOutput(); + $output = $this->phpci->getLastOutput(); if (preg_match_all('/\((LOC|CLOC|NCLOC|LLOC)\)\s+([0-9]+)/', $output, $matches)) { $data = array(); diff --git a/PHPCI/Plugin/PhpMessDetector.php b/PHPCI/Plugin/PhpMessDetector.php old mode 100755 new mode 100644 index 4603d534..ec92bc61 --- a/PHPCI/Plugin/PhpMessDetector.php +++ b/PHPCI/Plugin/PhpMessDetector.php @@ -38,7 +38,7 @@ class PhpMessDetector implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin /** * @var string, based on the assumption the root may not hold the code to be - * tested, exteds the base path only if the provided path is relative. Absolute + * tested, extends the base path only if the provided path is relative. Absolute * paths are used verbatim */ protected $path; @@ -50,7 +50,7 @@ class PhpMessDetector implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin /** * Array of PHPMD rules. Can be one of the builtins (codesize, unusedcode, naming, design, controversial) - * or a filenname (detected by checking for a / in it), either absolute or relative to the project root. + * or a filename (detected by checking for a / in it), either absolute or relative to the project root. * @var array */ protected $rules; @@ -121,16 +121,10 @@ class PhpMessDetector implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin $phpmdBinaryPath = $this->phpci->findBinary('phpmd'); - if (!$phpmdBinaryPath) { - $this->phpci->logFailure(PHPCI\Helper\Lang::get('could_not_find', 'phpmd')); - return false; - } - $this->executePhpMd($phpmdBinaryPath); - list($errorCount, $data) = $this->processReport(trim($this->phpci->getLastOutput())); + $errorCount = $this->processReport(trim($this->phpci->getLastOutput())); $this->build->storeMeta('phpmd-warnings', $errorCount); - $this->build->storeMeta('phpmd-data', $data); return $this->wasLastExecSuccessful($errorCount); } @@ -163,7 +157,6 @@ class PhpMessDetector implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin } $warnings = 0; - $data = array(); foreach ($xml->file as $file) { $fileName = (string)$file['name']; @@ -171,21 +164,20 @@ class PhpMessDetector implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin foreach ($file->violation as $violation) { $warnings++; - $warning = array( - 'file' => $fileName, - 'line_start' => (int)$violation['beginline'], - 'line_end' => (int)$violation['endline'], - 'rule' => (string)$violation['rule'], - 'ruleset' => (string)$violation['ruleset'], - 'priority' => (int)$violation['priority'], - 'message' => (string)$violation, - ); - $data[] = $warning; + $this->build->reportError( + $this->phpci, + 'php_mess_detector', + (string)$violation, + PHPCI\Model\BuildError::SEVERITY_HIGH, + $fileName, + (int)$violation['beginline'], + (int)$violation['endline'] + ); } } - return array($warnings, $data); + return $warnings; } /** diff --git a/PHPCI/Plugin/PhpParallelLint.php b/PHPCI/Plugin/PhpParallelLint.php index fdaeaf65..febed528 100644 --- a/PHPCI/Plugin/PhpParallelLint.php +++ b/PHPCI/Plugin/PhpParallelLint.php @@ -55,10 +55,10 @@ class PhpParallelLint implements \PHPCI\Plugin */ public function __construct(Builder $phpci, Build $build, array $options = array()) { - $this->phpci = $phpci; - $this->build = $build; - $this->directory = $phpci->buildPath; - $this->ignore = $this->phpci->ignore; + $this->phpci = $phpci; + $this->build = $build; + $this->directory = $phpci->buildPath; + $this->ignore = $this->phpci->ignore; if (isset($options['directory'])) { $this->directory = $phpci->buildPath.$options['directory']; @@ -78,11 +78,6 @@ class PhpParallelLint implements \PHPCI\Plugin $phplint = $this->phpci->findBinary('parallel-lint'); - if (!$phplint) { - $this->phpci->logFailure(Lang::get('could_not_find', 'parallel-lint')); - return false; - } - $cmd = $phplint . ' %s "%s"'; $success = $this->phpci->executeCommand( $cmd, diff --git a/PHPCI/Plugin/PhpSpec.php b/PHPCI/Plugin/PhpSpec.php index 681a5a6c..e468a718 100644 --- a/PHPCI/Plugin/PhpSpec.php +++ b/PHPCI/Plugin/PhpSpec.php @@ -59,11 +59,6 @@ class PhpSpec implements PHPCI\Plugin $phpspec = $this->phpci->findBinary(array('phpspec', 'phpspec.php')); - if (!$phpspec) { - $this->phpci->logFailure(PHPCI\Helper\Lang::get('could_not_find', 'phpspec')); - return false; - } - $success = $this->phpci->executeCommand($phpspec . ' --format=junit --no-code-generation run'); $output = $this->phpci->getLastOutput(); diff --git a/PHPCI/Plugin/PhpTalLint.php b/PHPCI/Plugin/PhpTalLint.php index 01e70b3e..8513ec36 100644 --- a/PHPCI/Plugin/PhpTalLint.php +++ b/PHPCI/Plugin/PhpTalLint.php @@ -155,7 +155,7 @@ class PhpTalLint implements PHPCI\Plugin if (!$this->lintFile($itemPath)) { $success = false; } - } elseif ($item->isDir() && $this->recursive && !$this->lintDirectory($itemPath . '/')) { + } elseif ($item->isDir() && $this->recursive && !$this->lintDirectory($itemPath . DIRECTORY_SEPARATOR)) { $success = false; } @@ -202,17 +202,16 @@ class PhpTalLint implements PHPCI\Plugin list($suffixes, $tales) = $this->getFlags(); - // FIXME: Find a way to clean this up - $lint = dirname(__FILE__) . '/../../vendor/phptal/phptal/tools/phptal_lint.php'; + $lint = dirname(__FILE__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR; + $lint .= 'vendor' . DIRECTORY_SEPARATOR . 'phptal' . DIRECTORY_SEPARATOR . 'phptal' . DIRECTORY_SEPARATOR; + $lint .= 'tools' . DIRECTORY_SEPARATOR . 'phptal_lint.php'; $cmd = '/usr/bin/env php ' . $lint . ' %s %s "%s"'; $this->phpci->executeCommand($cmd, $suffixes, $tales, $this->phpci->buildPath . $path); $output = $this->phpci->getLastOutput(); - // FIXME: This is very messy, clean it up if (preg_match('/Found (.+?) (error|warning)/i', $output, $matches)) { - $rows = explode(PHP_EOL, $output); unset($rows[0]); @@ -225,7 +224,7 @@ class PhpTalLint implements PHPCI\Plugin $row = str_replace('(use -i to include your custom modifier functions)', '', $row); $message = str_replace($name . ': ', '', $row); - + $parts = explode(' (line ', $message); $message = trim($parts[0]); diff --git a/PHPCI/Plugin/PhpUnit.php b/PHPCI/Plugin/PhpUnit.php index 3ea1ae8d..f716f079 100644 --- a/PHPCI/Plugin/PhpUnit.php +++ b/PHPCI/Plugin/PhpUnit.php @@ -76,8 +76,8 @@ class PhpUnit implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin return 'phpunit.xml'; } - if (file_exists($buildPath . 'tests/phpunit.xml')) { - return 'tests/phpunit.xml'; + if (file_exists($buildPath . 'tests' . DIRECTORY_SEPARATOR . 'phpunit.xml')) { + return 'tests' . DIRECTORY_SEPARATOR . 'phpunit.xml'; } if (file_exists($buildPath . 'phpunit.xml.dist')) { @@ -85,7 +85,7 @@ class PhpUnit implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin } if (file_exists($buildPath . 'tests/phpunit.xml.dist')) { - return 'tests/phpunit.xml.dist'; + return 'tests' . DIRECTORY_SEPARATOR . 'phpunit.xml.dist'; } return null; @@ -133,7 +133,7 @@ class PhpUnit implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin } if (isset($options['coverage'])) { - $this->coverage = " --coverage-html {$options['coverage']} "; + $this->coverage = ' --coverage-html ' . $this->phpci->interpolate($options['coverage']) . ' '; } } @@ -162,6 +162,7 @@ class PhpUnit implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin } $tapString = $this->phpci->getLastOutput(); + $tapString = mb_convert_encoding($tapString, "UTF-8", "ISO-8859-1"); try { $tapParser = new TapParser($tapString); @@ -193,18 +194,11 @@ class PhpUnit implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin } else { if ($this->runFrom) { $curdir = getcwd(); - chdir($this->phpci->buildPath.'/'.$this->runFrom); + chdir($this->phpci->buildPath . DIRECTORY_SEPARATOR . $this->runFrom); } - $phpunit = $this->phpci->findBinary('phpunit'); - if (!$phpunit) { - $this->phpci->logFailure(PHPCI\Helper\Lang::get('could_not_find', 'phpunit')); - return false; - } - - $cmd = $phpunit . ' --tap %s -c "%s" ' . $this->coverage . $this->path; $success = $this->phpci->executeCommand($cmd, $this->args, $this->phpci->buildPath . $configPath); @@ -231,11 +225,6 @@ class PhpUnit implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin $phpunit = $this->phpci->findBinary('phpunit'); - if (!$phpunit) { - $this->phpci->logFailure(PHPCI\Helper\Lang::get('could_not_find', 'phpunit')); - return false; - } - $cmd = $phpunit . ' --tap %s "%s"'; $success = $this->phpci->executeCommand($cmd, $this->args, $this->phpci->buildPath . $directory); chdir($curdir); diff --git a/PHPCI/Plugin/SlackNotify.php b/PHPCI/Plugin/SlackNotify.php index cff30e5a..0e8d1cad 100644 --- a/PHPCI/Plugin/SlackNotify.php +++ b/PHPCI/Plugin/SlackNotify.php @@ -1,7 +1,6 @@ username = 'PHPCI'; } + if (isset($options['show_status'])) { + $this->show_status = (bool) $options['show_status']; + } else { + $this->show_status = true; + } + if (isset($options['icon'])) { $this->icon = $options['icon']; } - } else { throw new \Exception('Please define the webhook_url for slack_notify plugin!'); } @@ -76,52 +81,57 @@ class SlackNotify implements \PHPCI\Plugin */ public function execute() { - $message = $this->phpci->interpolate($this->message); - - $successfulBuild = $this->build->isSuccessful(); - - if ($successfulBuild) { - $message = 'Success'; - $color = 'good'; - } else { - $message = 'Failed'; - $color = 'danger'; - } - - // Build up the attachment data - $attachment = new \Maknz\Slack\Attachment(array( - 'fallback' => $message, - 'pretext' => $message, - 'color' => $color, - 'fields' => array( - new \Maknz\Slack\AttachmentField(array( - 'title' => 'Status', - 'value' => $message, - 'short' => false - )) - ) - )); + $body = $this->phpci->interpolate($this->message); $client = new \Maknz\Slack\Client($this->webHook); + $message = $client->createMessage(); + if (!empty($this->room)) { - $client->setChannel($this->room); + $message->setChannel($this->room); } if (!empty($this->username)) { - $client->setUsername($this->username); + $message->setUsername($this->username); } if (!empty($this->icon)) { - $client->setIcon($this->icon); + $message->setIcon($this->icon); } - $client->attach($attachment); + // Include an attachment which shows the status and hide the message + if ($this->show_status) { + $successfulBuild = $this->build->isSuccessful(); - $success = true; + if ($successfulBuild) { + $status = 'Success'; + $color = 'good'; + } else { + $status = 'Failed'; + $color = 'danger'; + } - $client->send(''); // FIXME: Handle errors + // Build up the attachment data + $attachment = new \Maknz\Slack\Attachment(array( + 'fallback' => $body, + 'pretext' => $body, + 'color' => $color, + 'fields' => array( + new \Maknz\Slack\AttachmentField(array( + 'title' => 'Status', + 'value' => $status, + 'short' => false + )) + ) + )); - return $success; + $message->attach($attachment); + + $body = ''; + } + + $message->send($body); + + return true; } } diff --git a/PHPCI/Plugin/Sqlite.php b/PHPCI/Plugin/Sqlite.php index 1ffdcc88..f80ece3d 100644 --- a/PHPCI/Plugin/Sqlite.php +++ b/PHPCI/Plugin/Sqlite.php @@ -70,7 +70,7 @@ class Sqlite implements \PHPCI\Plugin $pdo = new PDO('sqlite:' . $this->path, $opts); foreach ($this->queries as $query) { - $pdo->query($query); + $pdo->query($this->phpci->interpolate($query)); } } catch (\Exception $ex) { $this->phpci->logFailure($ex->getMessage()); diff --git a/PHPCI/Plugin/TechnicalDebt.php b/PHPCI/Plugin/TechnicalDebt.php new file mode 100755 index 00000000..6d4711b5 --- /dev/null +++ b/PHPCI/Plugin/TechnicalDebt.php @@ -0,0 +1,207 @@ + +* @package PHPCI +* @subpackage Plugins +*/ +class TechnicalDebt implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin +{ + /** + * @var \PHPCI\Builder + */ + protected $phpci; + + /** + * @var array + */ + protected $suffixes; + + /** + * @var string + */ + protected $directory; + + /** + * @var int + */ + protected $allowed_errors; + + /** + * @var string, based on the assumption the root may not hold the code to be + * tested, extends the base path + */ + protected $path; + + /** + * @var array - paths to ignore + */ + protected $ignore; + + /** + * @var array - terms to search for + */ + protected $searches; + + + /** + * Check if this plugin can be executed. + * + * @param $stage + * @param Builder $builder + * @param Build $build + * @return bool + */ + public static function canExecute($stage, Builder $builder, Build $build) + { + if ($stage == 'test') { + return true; + } + + return false; + } + + /** + * @param \PHPCI\Builder $phpci + * @param \PHPCI\Model\Build $build + * @param array $options + */ + public function __construct(Builder $phpci, Build $build, array $options = array()) + { + $this->phpci = $phpci; + $this->build = $build; + $this->suffixes = array('php'); + $this->directory = $phpci->buildPath; + $this->path = ''; + $this->ignore = $this->phpci->ignore; + $this->allowed_errors = 0; + $this->searches = array('TODO', 'FIXME', 'TO DO', 'FIX ME'); + + if (isset($options['searches']) && is_array($options['searches'])) { + $this->searches = $options['searches']; + } + + if (isset($options['zero_config']) && $options['zero_config']) { + $this->allowed_errors = -1; + } + + $this->setOptions($options); + } + + /** + * Handle this plugin's options. + * @param $options + */ + protected function setOptions($options) + { + foreach (array('directory', 'path', 'ignore', 'allowed_errors') as $key) { + if (array_key_exists($key, $options)) { + $this->{$key} = $options[$key]; + } + } + } + + /** + * Runs the plugin + */ + public function execute() + { + $success = true; + $this->phpci->logExecOutput(false); + + $errorCount = $this->getErrorList(); + + $this->phpci->log("Found $errorCount instances of " . implode(', ', $this->searches)); + + $this->build->storeMeta('technical_debt-warnings', $errorCount); + + if ($this->allowed_errors != -1 && $errorCount > $this->allowed_errors) { + $success = false; + } + + return $success; + } + + /** + * Gets the number and list of errors returned from the search + * + * @return array + */ + public function getErrorList() + { + $dirIterator = new \RecursiveDirectoryIterator($this->directory); + $iterator = new \RecursiveIteratorIterator($dirIterator, \RecursiveIteratorIterator::SELF_FIRST); + $files = array(); + + $ignores = $this->ignore; + $ignores[] = 'phpci.yml'; + $ignores[] = '.phpci.yml'; + + foreach ($iterator as $file) { + $filePath = $file->getRealPath(); + $skipFile = false; + foreach ($ignores as $ignore) { + if (stripos($filePath, $ignore) !== false) { + $skipFile = true; + break; + } + } + + // Ignore hidden files, else .git, .sass_cache, etc. all get looped over + if (stripos($filePath, DIRECTORY_SEPARATOR . '.') !== false) { + $skipFile = true; + } + + if ($skipFile == false) { + $files[] = $file->getRealPath(); + } + } + + $files = array_filter(array_unique($files)); + $errorCount = 0; + + foreach ($files as $file) { + foreach ($this->searches as $search) { + $fileContent = file_get_contents($file); + $allLines = explode(PHP_EOL, $fileContent); + $beforeString = strstr($fileContent, $search, true); + + if (false !== $beforeString) { + $lines = explode(PHP_EOL, $beforeString); + $lineNumber = count($lines); + $content = trim($allLines[$lineNumber - 1]); + + $errorCount++; + + $fileName = str_replace($this->directory, '', $file); + + $this->build->reportError( + $this->phpci, + 'technical_debt', + $content, + PHPCI\Model\BuildError::SEVERITY_LOW, + $fileName, + $lineNumber + ); + } + } + } + + return $errorCount; + } +} diff --git a/PHPCI/Plugin/Util/ComposerPluginInformation.php b/PHPCI/Plugin/Util/ComposerPluginInformation.php index 1f022b4a..d8dcc91f 100644 --- a/PHPCI/Plugin/Util/ComposerPluginInformation.php +++ b/PHPCI/Plugin/Util/ComposerPluginInformation.php @@ -2,6 +2,8 @@ namespace PHPCI\Plugin\Util; +use PHPCI\Plugin; + /** * Class ComposerPluginInformation * @package PHPCI\Plugin\Util @@ -63,7 +65,7 @@ class ComposerPluginInformation implements InstalledPluginInformation public function getPluginClasses() { return array_map( - function ($plugin) { + function (Plugin $plugin) { return $plugin->class; }, $this->getInstalledPlugins() diff --git a/PHPCI/Plugin/Util/Executor.php b/PHPCI/Plugin/Util/Executor.php index bbc9507c..bdd06b7e 100644 --- a/PHPCI/Plugin/Util/Executor.php +++ b/PHPCI/Plugin/Util/Executor.php @@ -2,8 +2,12 @@ namespace PHPCI\Plugin\Util; +use b8\Store\Factory as StoreFactory; +use Exception; use PHPCI\Helper\Lang; -use \PHPCI\Logging\BuildLogger; +use PHPCI\Logging\BuildLogger; +use PHPCI\Model\Build; +use PHPCI\Store\BuildStore; /** * Plugin Executor - Runs the configured plugins for a given build stage. @@ -21,14 +25,20 @@ class Executor */ protected $pluginFactory; + /** + * @var BuildStore + */ + protected $store; + /** * @param Factory $pluginFactory * @param BuildLogger $logger */ - public function __construct(Factory $pluginFactory, BuildLogger $logger) + public function __construct(Factory $pluginFactory, BuildLogger $logger, BuildStore $store = null) { $this->pluginFactory = $pluginFactory; $this->logger = $logger; + $this->store = $store ?: StoreFactory::getStore('Build'); } /** @@ -40,34 +50,114 @@ class Executor public function executePlugins(&$config, $stage) { $success = true; - // Ignore any stages for which we don't have plugins set: - if (!array_key_exists($stage, $config) || !is_array($config[$stage])) { - return $success; + $pluginsToExecute = array(); + + // If we have global plugins to execute for this stage, add them to the list to be executed: + if (array_key_exists($stage, $config) && is_array($config[$stage])) { + $pluginsToExecute[] = $config[$stage]; } - foreach ($config[$stage] as $plugin => $options) { + $pluginsToExecute = $this->getBranchSpecificPlugins($config, $stage, $pluginsToExecute); + + foreach ($pluginsToExecute as $pluginSet) { + if (!$this->doExecutePlugins($pluginSet, $stage)) { + $success = false; + } + } + + return $success; + } + + /** + * Check the config for any plugins specific to the branch we're currently building. + * @param $config + * @param $stage + * @param $pluginsToExecute + * @return array + */ + protected function getBranchSpecificPlugins(&$config, $stage, $pluginsToExecute) + { + /** @var \PHPCI\Model\Build $build */ + $build = $this->pluginFactory->getResourceFor('PHPCI\Model\Build'); + $branch = $build->getBranch(); + + // If we don't have any branch-specific plugins: + if (!isset($config['branch-' . $branch][$stage]) || !is_array($config['branch-' . $branch][$stage])) { + return $pluginsToExecute; + } + + // If we have branch-specific plugins to execute, add them to the list to be executed: + $branchConfig = $config['branch-' . $branch]; + $plugins = $branchConfig[$stage]; + + $runOption = 'after'; + + if (!empty($branchConfig['run-option'])) { + $runOption = $branchConfig['run-option']; + } + + switch ($runOption) { + // Replace standard plugin set for this stage with just the branch-specific ones: + case 'replace': + $pluginsToExecute = array(); + $pluginsToExecute[] = $plugins; + break; + + // Run branch-specific plugins before standard plugins: + case 'before': + array_unshift($pluginsToExecute, $plugins); + break; + + // Run branch-specific plugins after standard plugins: + case 'after': + array_push($pluginsToExecute, $plugins); + break; + + default: + array_push($pluginsToExecute, $plugins); + break; + } + + return $pluginsToExecute; + } + + /** + * Execute the list of plugins found for a given testing stage. + * @param $plugins + * @param $stage + * @return bool + * @throws \Exception + */ + protected function doExecutePlugins(&$plugins, $stage) + { + $success = true; + + foreach ($plugins as $plugin => $options) { $this->logger->log(Lang::get('running_plugin', $plugin)); - // Is this plugin allowed to fail? - if ($stage == 'test' && !isset($options['allow_failures'])) { - $options['allow_failures'] = false; - } + $this->setPluginStatus($stage, $plugin, Build::STATUS_RUNNING); - // Try and execute it: + // Try and execute it if ($this->executePlugin($plugin, $options)) { - - // Execution was successful: + // Execution was successful $this->logger->logSuccess(Lang::get('plugin_success')); - + $this->setPluginStatus($stage, $plugin, Build::STATUS_SUCCESS); } else { - - // If we're in the "test" stage and the plugin is not allowed to fail, - // then mark the build as failed: - if ($stage == 'test' && !$options['allow_failures']) { - $success = false; - } - + // Execution failed $this->logger->logFailure(Lang::get('plugin_failed')); + $this->setPluginStatus($stage, $plugin, Build::STATUS_FAILED); + + if ($stage === 'setup') { + // If we're in the "setup" stage, execution should not continue after + // a plugin has failed: + throw new Exception('Plugin failed: ' . $plugin); + } elseif ($stage === 'test') { + // If we're in the "test" stage and the plugin is not allowed to fail, + // then mark the build as failed: + if (empty($options['allow_failures'])) { + $success = false; + } + } } } @@ -95,20 +185,62 @@ class Executor return false; } - $rtn = true; - - // Try running it: try { + // Build and run it $obj = $this->pluginFactory->buildPlugin($class, $options); - - if (!$obj->execute()) { - $rtn = false; - } + return $obj->execute(); } catch (\Exception $ex) { $this->logger->logFailure(Lang::get('exception') . $ex->getMessage(), $ex); - $rtn = false; + return false; + } + } + + /** + * Change the status of a plugin for a given stage. + * + * @param string $stage The builder stage. + * @param string $plugin The plugin name. + * @param int $status The new status. + */ + protected function setPluginStatus($stage, $plugin, $status) + { + $summary = $this->getBuildSummary(); + + if (!isset($summary[$stage][$plugin])) { + $summary[$stage][$plugin] = array(); } - return $rtn; + $summary[$stage][$plugin]['status'] = $status; + + if ($status === Build::STATUS_RUNNING) { + $summary[$stage][$plugin]['started'] = time(); + } elseif ($status >= Build::STATUS_SUCCESS) { + $summary[$stage][$plugin]['ended'] = time(); + } + + $this->setBuildSummary($summary); + } + + /** + * Fetch the summary data of the current build. + * + * @return array + */ + private function getBuildSummary() + { + $build = $this->pluginFactory->getResourceFor('PHPCI\Model\Build'); + $metas = $this->store->getMeta('plugin-summary', $build->getProjectId(), $build->getId()); + return isset($metas[0]['meta_value']) ? $metas[0]['meta_value'] : array(); + } + + /** + * Sets the summary data of the current build. + * + * @param array summary + */ + private function setBuildSummary($summary) + { + $build = $this->pluginFactory->getResourceFor('PHPCI\Model\Build'); + $this->store->setMeta($build->getProjectId(), $build->getId(), 'plugin-summary', json_encode($summary)); } } diff --git a/PHPCI/Plugin/Util/Factory.php b/PHPCI/Plugin/Util/Factory.php index 5430b56f..b6d11e5e 100644 --- a/PHPCI/Plugin/Util/Factory.php +++ b/PHPCI/Plugin/Util/Factory.php @@ -8,8 +8,8 @@ namespace PHPCI\Plugin\Util; */ class Factory { - const TYPE_ARRAY = "array"; - const TYPE_CALLABLE = "callable"; + const TYPE_ARRAY = "array"; + const TYPE_CALLABLE = "callable"; const INTERFACE_PHPCI_PLUGIN = '\PHPCI\Plugin'; private $currentPluginOptions; @@ -76,11 +76,11 @@ class Factory * be passed along with any resources registered with the factory. * * @param $className - * @param array $options + * @param array|null $options * @throws \InvalidArgumentException if $className doesn't represent a valid plugin * @return \PHPCI\Plugin */ - public function buildPlugin($className, array $options = array()) + public function buildPlugin($className, $options = array()) { $this->currentPluginOptions = $options; @@ -150,11 +150,11 @@ class Factory } /** - * @param null $type - * @param null $name - * @return null + * @param string $type + * @param string $name + * @return mixed */ - private function getResourceFor($type = null, $name = null) + public function getResourceFor($type = null, $name = null) { $fullId = $this->getInternalID($type, $name); if (isset($this->container[$fullId])) { @@ -185,7 +185,7 @@ class Factory return $class->getName(); } elseif ($param->isArray()) { return self::TYPE_ARRAY; - } elseif ($param->isCallable()) { + } elseif (is_callable($param)) { return self::TYPE_CALLABLE; } else { return null; diff --git a/PHPCI/Plugin/Util/FilesPluginInformation.php b/PHPCI/Plugin/Util/FilesPluginInformation.php index 6bad028f..35587283 100644 --- a/PHPCI/Plugin/Util/FilesPluginInformation.php +++ b/PHPCI/Plugin/Util/FilesPluginInformation.php @@ -2,6 +2,8 @@ namespace PHPCI\Plugin\Util; +use PHPCI\Plugin; + /** * Class FilesPluginInformation * @package PHPCI\Plugin\Util @@ -54,6 +56,7 @@ class FilesPluginInformation implements InstalledPluginInformation if ($this->pluginInfo === null) { $this->loadPluginInfo(); } + return $this->pluginInfo; } @@ -66,8 +69,8 @@ class FilesPluginInformation implements InstalledPluginInformation public function getPluginClasses() { return array_map( - function ($plugin) { - return $plugin->class; + function (\stdClass $plugin) { + return $plugin->class; }, $this->getInstalledPlugins() ); @@ -81,7 +84,7 @@ class FilesPluginInformation implements InstalledPluginInformation $this->pluginInfo = array(); foreach ($this->files as $fileInfo) { if ($fileInfo instanceof \SplFileInfo) { - if ($fileInfo->isFile() && $fileInfo->getExtension()=='php') { + if ($fileInfo->isFile() && $fileInfo->getExtension() == 'php') { $this->addPluginFromFile($fileInfo); } } @@ -97,11 +100,11 @@ class FilesPluginInformation implements InstalledPluginInformation $class = $this->getFullClassFromFile($fileInfo); if (!is_null($class)) { - $newPlugin = new \stdClass(); - $newPlugin->class = $class; + $newPlugin = new \stdClass(); + $newPlugin->class = $class; $newPlugin->source = "core"; - $parts = explode('\\', $newPlugin->class); - $newPlugin->name = end($parts); + $parts = explode('\\', $newPlugin->class); + $newPlugin->name = end($parts); $this->pluginInfo[] = $newPlugin; } @@ -114,8 +117,6 @@ class FilesPluginInformation implements InstalledPluginInformation */ protected function getFullClassFromFile(\SplFileInfo $fileInfo) { - //TODO: Something less horrible than a regular expression - // on the contents of a file $contents = file_get_contents($fileInfo->getRealPath()); $matches = array(); @@ -123,11 +124,11 @@ class FilesPluginInformation implements InstalledPluginInformation if (isset($matches[1])) { $className = $matches[1]; - + $matches = array(); preg_match('#namespace +([A-Za-z\\\\]+);#i', $contents, $matches); $namespace = $matches[1]; - + return $namespace . '\\' . $className; } else { return null; diff --git a/PHPCI/Plugin/Util/PluginInformationCollection.php b/PHPCI/Plugin/Util/PluginInformationCollection.php index 16341733..906935e5 100644 --- a/PHPCI/Plugin/Util/PluginInformationCollection.php +++ b/PHPCI/Plugin/Util/PluginInformationCollection.php @@ -32,9 +32,11 @@ class PluginInformationCollection implements InstalledPluginInformation public function getInstalledPlugins() { $arr = array(); + foreach ($this->pluginInformations as $single) { $arr = array_merge($arr, $single->getInstalledPlugins()); } + return $arr; } @@ -47,9 +49,11 @@ class PluginInformationCollection implements InstalledPluginInformation public function getPluginClasses() { $arr = array(); + foreach ($this->pluginInformations as $single) { $arr = array_merge($arr, $single->getPluginClasses()); } + return $arr; } } diff --git a/PHPCI/Plugin/Util/TapParser.php b/PHPCI/Plugin/Util/TapParser.php index 57b92b55..86981566 100644 --- a/PHPCI/Plugin/Util/TapParser.php +++ b/PHPCI/Plugin/Util/TapParser.php @@ -2,7 +2,9 @@ namespace PHPCI\Plugin\Util; +use Exception; use PHPCI\Helper\Lang; +use Symfony\Component\Yaml\Yaml; /** * Processes TAP format strings into usable test result data. @@ -10,18 +12,42 @@ use PHPCI\Helper\Lang; */ class TapParser { - const TEST_COUNTS_PATTERN = '/([0-9]+)\.\.([0-9]+)/'; - const TEST_LINE_PATTERN = '/(ok|not ok)\s+[0-9]+\s+\-\s+([^\n]+)::([^\n]+)/'; - const TEST_MESSAGE_PATTERN = '/message\:\s+\'([^\']+)\'/'; - const TEST_COVERAGE_PATTERN = '/Generating code coverage report/'; - const TEST_SKIP_PATTERN = '/ok\s+[0-9]+\s+\-\s+#\s+SKIP/'; + const TEST_COUNTS_PATTERN = '/^\d+\.\.(\d+)/'; + const TEST_LINE_PATTERN = '/^(ok|not ok)(?:\s+\d+)?(?:\s+\-)?\s*(.*?)(?:\s*#\s*(skip|todo)\s*(.*))?\s*$/i'; + const TEST_YAML_START = '/^(\s*)---/'; + const TEST_DIAGNOSTIC = '/^#/'; + const TEST_COVERAGE = '/^Generating/'; /** * @var string */ protected $tapString; + + /** + * @var int + */ protected $failures = 0; + /** + * @var array + */ + protected $lines; + + /** + * @var integer + */ + protected $lineNumber; + + /** + * @var integer + */ + protected $testCount; + + /** + * @var array + */ + protected $results; + /** * Create a new TAP parser for a given string. * @param string $tapString The TAP format string to be parsed. @@ -38,81 +64,215 @@ class TapParser { // Split up the TAP string into an array of lines, then // trim all of the lines so there's no leading or trailing whitespace. - $lines = explode("\n", $this->tapString); - $lines = array_map(function ($line) { - return trim($line); - }, $lines); + $this->lines = array_map('rtrim', explode("\n", $this->tapString)); + $this->lineNumber = 0; - // Check TAP version: - $versionLine = array_shift($lines); + $this->testCount = false; + $this->results = array(); - if ($versionLine != 'TAP version 13') { - throw new \Exception(Lang::get('tap_version')); + $header = $this->findTapLog(); + + $line = $this->nextLine(); + if ($line === $header) { + throw new Exception("Duplicated TAP log, please check the configuration."); } - if (isset($lines[count($lines) - 1]) && preg_match(self::TEST_COVERAGE_PATTERN, $lines[count($lines) - 1])) { - array_pop($lines); - if ($lines[count($lines) - 1] == "") { - array_pop($lines); - } + while ($line !== false && ($this->testCount === false || count($this->results) < $this->testCount)) { + $this->parseLine($line); + $line = $this->nextLine(); } - $matches = array(); - $totalTests = 0; - if (preg_match(self::TEST_COUNTS_PATTERN, $lines[0], $matches)) { - array_shift($lines); - $totalTests = (int) $matches[2]; + if (false !== $this->testCount && count($this->results) !== $this->testCount) { + throw new Exception(Lang::get('tap_error')); } - if (isset($lines[count($lines) - 1]) && - preg_match(self::TEST_COUNTS_PATTERN, $lines[count($lines) - 1], $matches)) { - array_pop($lines); - $totalTests = (int) $matches[2]; + return $this->results; + } + + /** Looks for the start of the TAP log in the string. + * + * @return string The TAP header line. + * + * @throws Exception if no TAP log is found or versions mismatch. + */ + protected function findTapLog() + { + // Look for the beginning of the TAP output + do { + $header = $this->nextLine(); + } while ($header !== false && substr($header, 0, 12) !== 'TAP version '); + + // + if ($header === false) { + throw new Exception('No TAP log found, please check the configuration.'); + } elseif ($header !== 'TAP version 13') { + throw new Exception(Lang::get('tap_version')); } - $rtn = $this->processTestLines($lines); + return $header; + } - if ($totalTests != count($rtn)) { - throw new \Exception(Lang::get('tap_error')); + /** Fetch the next line. + * + * @return string|false The next line or false if the end has been reached. + */ + protected function nextLine() + { + if ($this->lineNumber < count($this->lines)) { + return $this->lines[$this->lineNumber++]; } - - return $rtn; + return false; } /** - * Process the individual test lines within a TAP string. - * @param $lines - * @return array + * @param string $line + * + * @return boolean */ - protected function processTestLines($lines) + protected function testLine($line) { - $rtn = array(); + if (preg_match(self::TEST_LINE_PATTERN, $line, $matches)) { + $this->results[] = $this->processTestLine( + $matches[1], + isset($matches[2]) ? $matches[2] : '', + isset($matches[3]) ? $matches[3] : null, + isset($matches[4]) ? $matches[4] : null + ); - foreach ($lines as $line) { - $matches = array(); - - if (preg_match(self::TEST_LINE_PATTERN, $line, $matches)) { - $ok = ($matches[1] == 'ok' ? true : false); - - if (!$ok) { - $this->failures++; - } - - $item = array( - 'pass' => $ok, - 'suite' => $matches[2], - 'test' => $matches[3], - ); - - $rtn[] = $item; - } elseif (preg_match(self::TEST_SKIP_PATTERN, $line, $matches)) { - $rtn[] = array('message' => 'SKIP'); - } elseif (preg_match(self::TEST_MESSAGE_PATTERN, $line, $matches)) { - $rtn[count($rtn) - 1]['message'] = $matches[1]; - } + return true; } - return $rtn; + return false; + } + + /** + * @param string $line + * + * @return boolean + */ + protected function yamlLine($line) + { + if (preg_match(self::TEST_YAML_START, $line, $matches)) { + $diagnostic = $this->processYamlBlock($matches[1]); + $test = array_pop($this->results); + if (isset($test['message'], $diagnostic['message'])) { + $test['message'] .= PHP_EOL . $diagnostic['message']; + unset($diagnostic['message']); + } + $this->results[] = array_replace($test, $diagnostic); + + return true; + } + + return false; + } + + /** Parse a single line. + * + * @param string $line + * + * @throws Exception + */ + protected function parseLine($line) + { + if (preg_match(self::TEST_DIAGNOSTIC, $line) || preg_match(self::TEST_COVERAGE, $line) || !$line) { + return; + } + + if (preg_match(self::TEST_COUNTS_PATTERN, $line, $matches)) { + $this->testCount = intval($matches[1]); + + return; + } + + if ($this->testLine($line)) { + return; + } + + if ($this->yamlLine($line)) { + return; + } + + throw new Exception(sprintf('Incorrect TAP data, line %d: %s', $this->lineNumber, $line)); + } + + /** + * Process an individual test line. + * + * @param string $result + * @param string $message + * @param string $directive + * @param string $reason + * + * @return array + */ + protected function processTestLine($result, $message, $directive, $reason) + { + $test = array( + 'pass' => true, + 'message' => $message, + 'severity' => 'success', + ); + + if ($result !== 'ok') { + $test['pass'] = false; + $test['severity'] = substr($message, 0, 6) === 'Error:' ? 'error' : 'fail'; + $this->failures++; + } + + if ($directive) { + $test = $this->processDirective($test, $directive, $reason); + } + + return $test; + } + + /** Process an indented Yaml block. + * + * @param string $indent The block indentation to ignore. + * + * @return array The processed Yaml content. + */ + protected function processYamlBlock($indent) + { + $startLine = $this->lineNumber + 1; + $endLine = $indent . '...'; + $yamlLines = array(); + + do { + $line = $this->nextLine(); + + if ($line === false) { + throw new Exception(Lang::get('tap_error_endless_yaml', $startLine)); + } elseif ($line === $endLine) { + break; + } + + $yamlLines[] = substr($line, strlen($indent)); + } while (true); + + return Yaml::parse(join("\n", $yamlLines)); + } + + /** Process a TAP directive + * + * @param array $test + * @param string $directive + * @param string $reason + * @return array + */ + protected function processDirective($test, $directive, $reason) + { + $test['severity'] = strtolower($directive) === 'skip' ? 'skipped' : 'todo'; + + if (!empty($reason)) { + if (!empty($test['message'])) { + $test['message'] .= ', '.$test['severity'].': '; + } + $test['message'] .= $reason; + } + + return $test; } /** diff --git a/PHPCI/Plugin/Util/TestResultParsers/Codeception.php b/PHPCI/Plugin/Util/TestResultParsers/Codeception.php new file mode 100644 index 00000000..24af62e4 --- /dev/null +++ b/PHPCI/Plugin/Util/TestResultParsers/Codeception.php @@ -0,0 +1,114 @@ + + * @package PHPCI\Plugin\Util\TestResultParsers + */ +class Codeception implements ParserInterface +{ + protected $phpci; + protected $resultsXml; + + protected $results; + + protected $totalTests; + protected $totalTimeTaken; + protected $totalFailures; + protected $totalErrors; + + /** + * @param Builder $phpci + * @param $resultsXml + */ + public function __construct(Builder $phpci, $resultsXml) + { + $this->phpci = $phpci; + $this->resultsXml = $resultsXml; + $this->totalTests = 0; + } + + /** + * @return array An array of key/value pairs for storage in the plugins result metadata + */ + public function parse() + { + $rtn = array(); + + $this->results = new \SimpleXMLElement($this->resultsXml); + + // calculate total results + foreach ($this->results->testsuite as $testsuite) { + $this->totalTests += (int) $testsuite['tests']; + $this->totalTimeTaken += (float) $testsuite['time']; + $this->totalFailures += (int) $testsuite['failures']; + $this->totalErrors += (int) $testsuite['errors']; + + foreach ($testsuite->testcase as $testcase) { + $testresult = array( + 'suite' => (string) $testsuite['name'], + 'file' => str_replace($this->phpci->buildPath, '/', (string) $testcase['file']), + 'name' => (string) $testcase['name'], + 'feature' => (string) $testcase['feature'], + 'assertions' => (int) $testcase['assertions'], + 'time' => (float) $testcase['time'] + ); + + if (isset($testcase['class'])) { + $testresult['class'] = (string) $testcase['class']; + } + + // PHPUnit testcases does not have feature field. Use class::method instead + if (!$testresult['feature']) { + $testresult['feature'] = sprintf('%s::%s', $testresult['class'], $testresult['name']); + } + + if (isset($testcase->failure) || isset($testcase->error)) { + $testresult['pass'] = false; + $testresult['message'] = (string)$testcase->failure . (string)$testcase->error; + } else { + $testresult['pass'] = true; + } + + $rtn[] = $testresult; + } + } + + return $rtn; + } + + /** + * Get the total number of tests performed. + * + * @return int + */ + public function getTotalTests() + { + return $this->totalTests; + } + + /** + * The time take to complete all tests + * + * @return mixed + */ + public function getTotalTimeTaken() + { + return $this->totalTimeTaken; + } + + /** + * A count of the test failures + * + * @return mixed + */ + public function getTotalFailures() + { + return $this->totalFailures + $this->totalErrors; + } +} diff --git a/PHPCI/Plugin/Util/TestResultParsers/ParserInterface.php b/PHPCI/Plugin/Util/TestResultParsers/ParserInterface.php new file mode 100644 index 00000000..d0c77cb7 --- /dev/null +++ b/PHPCI/Plugin/Util/TestResultParsers/ParserInterface.php @@ -0,0 +1,16 @@ +buildPath; $this->phpci = $phpci; $this->build = $build; - $this->directory = isset($options['directory']) ? $options['directory'] : $path; + $this->directory = isset($options['directory']) ? $this->phpci->interpolate($options['directory']) : $path; } /** @@ -61,8 +61,8 @@ class Wipe implements \PHPCI\Plugin if (IS_WIN) { $cmd = 'rmdir /S /Q "%s"'; } - $success = $this->phpci->executeCommand($cmd, $this->directory); + return $this->phpci->executeCommand($cmd, $this->directory); } - return $success; + return true; } } diff --git a/PHPCI/Plugin/Xmpp.php b/PHPCI/Plugin/Xmpp.php index 8614e208..ccfc4399 100644 --- a/PHPCI/Plugin/Xmpp.php +++ b/PHPCI/Plugin/Xmpp.php @@ -132,8 +132,9 @@ class XMPP implements \PHPCI\Plugin */ public function findConfigFile() { - if (file_exists('.sendxmpprc')) { - if (md5(file_get_contents('.sendxmpprc')) !== md5($this->getConfigFormat())) { + if (file_exists($this->phpci->buildPath . DIRECTORY_SEPARATOR . '.sendxmpprc')) { + if (md5(file_get_contents($this->phpci->buildPath . DIRECTORY_SEPARATOR . '.sendxmpprc')) + !== md5($this->getConfigFormat())) { return null; } @@ -148,12 +149,7 @@ class XMPP implements \PHPCI\Plugin */ public function execute() { - $sendxmpp = $this->phpci->findBinary('/usr/bin/sendxmpp'); - - if (!$sendxmpp) { - $this->phpci->logFailure('Could not find sendxmpp.'); - return false; - } + $sendxmpp = $this->phpci->findBinary('sendxmpp'); /* * Without recipients we can't send notification @@ -165,9 +161,10 @@ class XMPP implements \PHPCI\Plugin /* * Try to build conf file */ + $config_file = $this->phpci->buildPath . DIRECTORY_SEPARATOR . '.sendxmpprc'; if (is_null($this->findConfigFile())) { - file_put_contents('.sendxmpprc', $this->getConfigFormat()); - chmod('.sendxmpprc', 0600); + file_put_contents($config_file, $this->getConfigFormat()); + chmod($config_file, 0600); } /* @@ -178,7 +175,7 @@ class XMPP implements \PHPCI\Plugin $tls = ' -t'; } - $message_file = uniqid('xmppmessage'); + $message_file = $this->phpci->buildPath . DIRECTORY_SEPARATOR . uniqid('xmppmessage'); if ($this->buildMessage($message_file) === false) { return false; } @@ -186,10 +183,10 @@ class XMPP implements \PHPCI\Plugin /* * Send XMPP notification for all recipients */ - $cmd = $sendxmpp . "%s -f .sendxmpprc -m %s %s"; + $cmd = $sendxmpp . "%s -f %s -m %s %s"; $recipients = implode(' ', $this->recipients); - $success = $this->phpci->executeCommand($cmd, $tls, $message_file, $recipients); + $success = $this->phpci->executeCommand($cmd, $tls, $config_file, $message_file, $recipients); print $this->phpci->getLastOutput(); diff --git a/PHPCI/ProcessControl/Factory.php b/PHPCI/ProcessControl/Factory.php new file mode 100644 index 00000000..7622fd49 --- /dev/null +++ b/PHPCI/ProcessControl/Factory.php @@ -0,0 +1,63 @@ + + */ +class Factory +{ + /** + * ProcessControl singleton. + * + * @var ProcessControlInterface + */ + protected static $instance = null; + + /** + * Returns the ProcessControl singleton. + * + * @return ProcessControlInterface + */ + public static function getInstance() + { + if (static::$instance === null) { + static::$instance = static::createProcessControl(); + } + return static::$instance; + } + + /** + * Create a ProcessControl depending on available extensions and the underlying OS. + * + * Check PosixProcessControl, WindowsProcessControl and UnixProcessControl, in that order. + * + * @return ProcessControlInterface + * + * @internal + */ + public static function createProcessControl() + { + switch (true) { + case PosixProcessControl::isAvailable(): + return new PosixProcessControl(); + + case WindowsProcessControl::isAvailable(): + return new WindowsProcessControl(); + + case UnixProcessControl::isAvailable(): + return new UnixProcessControl(); + } + + throw new \Exception("No ProcessControl implementation available."); + } +} diff --git a/PHPCI/ProcessControl/PosixProcessControl.php b/PHPCI/ProcessControl/PosixProcessControl.php new file mode 100644 index 00000000..bac55ee2 --- /dev/null +++ b/PHPCI/ProcessControl/PosixProcessControl.php @@ -0,0 +1,52 @@ + + */ +class PosixProcessControl implements ProcessControlInterface +{ + /** + * + * @param int $pid + * @return bool + */ + public function isRunning($pid) + { + // Signal "0" is not sent to the process, but posix_kill checks the process anyway; + return posix_kill($pid, 0); + } + + /** + * Sends a TERMINATE or KILL signal to the process using posix_kill. + * + * @param int $pid + * @param bool $forcefully Whether to send TERMINATE (false) or KILL (true). + */ + public function kill($pid, $forcefully = false) + { + posix_kill($pid, $forcefully ? 9 : 15); + } + + /** + * Check whether this posix_kill is available. + * + * @return bool + * + * @internal + */ + public static function isAvailable() + { + return function_exists('posix_kill'); + } +} diff --git a/PHPCI/ProcessControl/ProcessControlInterface.php b/PHPCI/ProcessControl/ProcessControlInterface.php new file mode 100644 index 00000000..709e0bee --- /dev/null +++ b/PHPCI/ProcessControl/ProcessControlInterface.php @@ -0,0 +1,33 @@ + + */ +interface ProcessControlInterface +{ + /** Checks if a process exists. + * + * @param int $pid The process identifier. + * + * @return boolean true is the process is running, else false. + */ + public function isRunning($pid); + + /** Terminate a running process. + * + * @param int $pid The process identifier. + * @param bool $forcefully Whether to gently (false) or forcefully (true) terminate the process. + */ + public function kill($pid, $forcefully = false); +} diff --git a/PHPCI/ProcessControl/UnixProcessControl.php b/PHPCI/ProcessControl/UnixProcessControl.php new file mode 100644 index 00000000..8b638073 --- /dev/null +++ b/PHPCI/ProcessControl/UnixProcessControl.php @@ -0,0 +1,54 @@ + + */ +class UnixProcessControl implements ProcessControlInterface +{ + /** + * Check process using the "ps" command. + * + * @param int $pid + * @return boolean + */ + public function isRunning($pid) + { + $output = $exitCode = null; + exec(sprintf("ps %d", $pid), $output, $exitCode); + return $exitCode === 0; + } + + /** + * Sends a signal using the "kill" command. + * + * @param int $pid + * @param bool $forcefully + */ + public function kill($pid, $forcefully = false) + { + exec(sprintf("kill -%d %d", $forcefully ? 9 : 15, $pid)); + } + + /** + * Check whether the commands "ps" and "kill" are available. + * + * @return bool + * + * @internal + */ + public static function isAvailable() + { + return DIRECTORY_SEPARATOR === '/' && exec("which ps") && exec("which kill"); + } +} diff --git a/PHPCI/ProcessControl/WindowsProcessControl.php b/PHPCI/ProcessControl/WindowsProcessControl.php new file mode 100644 index 00000000..e750d321 --- /dev/null +++ b/PHPCI/ProcessControl/WindowsProcessControl.php @@ -0,0 +1,54 @@ + + */ +class WindowsProcessControl implements ProcessControlInterface +{ + /** + * Check if the process is running using the "tasklist" command. + * + * @param type $pid + * @return bool + */ + public function isRunning($pid) + { + $lastLine = exec(sprintf('tasklist /fi "PID eq %d" /nh /fo csv 2>nul:', $pid)); + $record = str_getcsv($lastLine); + return isset($record[1]) && intval($record[1]) === $pid; + } + + /** + * Terminate the process using the "taskkill" command. + * + * @param type $pid + * @param bool $forcefully + */ + public function kill($pid, $forcefully = false) + { + exec(sprintf("taskkill /t /pid %d %s 2>nul:", $pid, $forcefully ? '/f' : '')); + } + + /** + * Check whether the commands "tasklist" and "taskkill" are available. + * + * @return bool + * + * @internal + */ + public static function isAvailable() + { + return DIRECTORY_SEPARATOR === '\\' && exec("where tasklist") && exec("where taskkill"); + } +} diff --git a/PHPCI/Service/BuildService.php b/PHPCI/Service/BuildService.php index b4721779..a120a64e 100644 --- a/PHPCI/Service/BuildService.php +++ b/PHPCI/Service/BuildService.php @@ -9,6 +9,11 @@ namespace PHPCI\Service; +use b8\Config; +use Pheanstalk\Pheanstalk; +use Pheanstalk\PheanstalkInterface; +use PHPCI\BuildFactory; +use PHPCI\Helper\Lang; use PHPCI\Model\Build; use PHPCI\Model\Project; use PHPCI\Store\BuildStore; @@ -25,6 +30,11 @@ class BuildService */ protected $buildStore; + /** + * @var bool + */ + public $queueError = false; + /** * @param BuildStore $buildStore */ @@ -59,6 +69,7 @@ class BuildService $build->setCommitId($commitId); } else { $build->setCommitId('Manual'); + $build->setCommitMessage(Lang::get('manual_build')); } if (!is_null($branch)) { @@ -79,7 +90,17 @@ class BuildService $build->setExtra(json_encode($extra)); } - return $this->buildStore->save($build); + $build = $this->buildStore->save($build); + + $buildId = $build->getId(); + + if (!empty($buildId)) { + $build = BuildFactory::getBuild($build); + $build->sendStatusPostback(); + $this->addBuildToQueue($build); + } + + return $build; } /** @@ -100,8 +121,19 @@ class BuildService $build = new Build(); $build->setValues($data); $build->setCreated(new \DateTime()); + $build->setStatus(0); - return $this->buildStore->save($build); + $build = $this->buildStore->save($build); + + $buildId = $build->getId(); + + if (!empty($buildId)) { + $build = BuildFactory::getBuild($build); + $build->sendStatusPostback(); + $this->addBuildToQueue($build); + } + + return $build; } /** @@ -111,6 +143,47 @@ class BuildService */ public function deleteBuild(Build $build) { + $build->removeBuildDirectory(); return $this->buildStore->delete($build); } + + /** + * Takes a build and puts it into the queue to be run (if using a queue) + * @param Build $build + */ + public function addBuildToQueue(Build $build) + { + $buildId = $build->getId(); + + if (empty($buildId)) { + return; + } + + $config = Config::getInstance(); + $settings = $config->get('phpci.worker', []); + + if (!empty($settings['host']) && !empty($settings['queue'])) { + try { + $jobData = array( + 'type' => 'phpci.build', + 'build_id' => $build->getId(), + ); + + if ($config->get('using_custom_file')) { + $jobData['config'] = $config->getArray(); + } + + $pheanstalk = new Pheanstalk($settings['host']); + $pheanstalk->useTube($settings['queue']); + $pheanstalk->put( + json_encode($jobData), + PheanstalkInterface::DEFAULT_PRIORITY, + PheanstalkInterface::DEFAULT_DELAY, + $config->get('phpci.worker.job_timeout', 600) + ); + } catch (\Exception $ex) { + $this->queueError = true; + } + } + } } diff --git a/PHPCI/Service/BuildStatusService.php b/PHPCI/Service/BuildStatusService.php new file mode 100644 index 00000000..b4f3c009 --- /dev/null +++ b/PHPCI/Service/BuildStatusService.php @@ -0,0 +1,222 @@ +project = $project; + $this->branch = $branch; + $this->build = $build; + if ($this->build) { + $this->loadParentBuild($isParent); + } + if (defined('PHPCI_URL')) { + $this->setUrl(PHPCI_URL); + } + } + + /** + * @param $url + */ + public function setUrl($url) + { + $this->url = $url; + } + + /** + * @return Build + */ + public function getBuild() + { + return $this->build; + } + + /** + * @param bool $isParent + * @throws \Exception + */ + protected function loadParentBuild($isParent = true) + { + if ($isParent === false && !$this->isFinished()) { + $lastFinishedBuild = $this->project->getLatestBuild($this->branch, $this->finishedStatusIds); + + if ($lastFinishedBuild) { + $this->prevService = new BuildStatusService( + $this->branch, + $this->project, + $lastFinishedBuild, + true + ); + } + } + } + + /** + * @return string + */ + public function getActivity() + { + if (in_array($this->build->getStatus(), $this->finishedStatusIds)) { + return 'Sleeping'; + } elseif ($this->build->getStatus() == Build::STATUS_NEW) { + return 'Pending'; + } elseif ($this->build->getStatus() == Build::STATUS_RUNNING) { + return 'Building'; + } + return 'Unknown'; + } + + /** + * @return string + */ + public function getName() + { + return $this->project->getTitle() . ' / ' . $this->branch; + } + + /** + * @return bool + */ + public function isFinished() + { + if (in_array($this->build->getStatus(), $this->finishedStatusIds)) { + return true; + } + return false; + } + + /** + * @return null|Build + */ + public function getFinishedBuildInfo() + { + if ($this->isFinished()) { + return $this->build; + } elseif ($this->prevService) { + return $this->prevService->getBuild(); + } + return null; + } + + /** + * @return int|string + */ + public function getLastBuildLabel() + { + if ($buildInfo = $this->getFinishedBuildInfo()) { + return $buildInfo->getId(); + } + return ''; + } + + /** + * @return string + */ + public function getLastBuildTime() + { + $dateFormat = 'Y-m-d\\TH:i:sO'; + if ($buildInfo = $this->getFinishedBuildInfo()) { + return ($buildInfo->getFinished()) ? $buildInfo->getFinished()->format($dateFormat) : ''; + } + return ''; + } + + /** + * @param Build $build + * @return string + */ + public function getBuildStatus(Build $build) + { + switch ($build->getStatus()) { + case Build::STATUS_SUCCESS: + return 'Success'; + case Build::STATUS_FAILED: + return 'Failure'; + } + return 'Unknown'; + } + + /** + * @return string + */ + public function getLastBuildStatus() + { + if ($build = $this->getFinishedBuildInfo()) { + return $this->getBuildStatus($build); + } + return ''; + } + + /** + * @return string + */ + public function getBuildUrl() + { + return $this->url . 'build/view/' . $this->build->getId(); + } + + /** + * @return array + */ + public function toArray() + { + if (!$this->build) { + return array(); + } + return array( + 'name' => $this->getName(), + 'activity' => $this->getActivity(), + 'lastBuildLabel' => $this->getLastBuildLabel(), + 'lastBuildStatus' => $this->getLastBuildStatus(), + 'lastBuildTime' => $this->getLastBuildTime(), + 'webUrl' => $this->getBuildUrl(), + ); + } +} diff --git a/PHPCI/Service/ProjectService.php b/PHPCI/Service/ProjectService.php index 22e940ac..8b07b0a9 100644 --- a/PHPCI/Service/ProjectService.php +++ b/PHPCI/Service/ProjectService.php @@ -81,10 +81,18 @@ class ProjectService $project->setAllowPublicStatus((int)$options['allow_public_status']); } + if (array_key_exists('archived', $options)) { + $project->setArchived((bool)$options['archived']); + } + if (array_key_exists('branch', $options)) { $project->setBranch($options['branch']); } + if (array_key_exists('group', $options)) { + $project->setGroup($options['group']); + } + // Allow certain project types to set access information: $this->processAccessInformation($project); diff --git a/PHPCI/Store/Base/BuildErrorStoreBase.php b/PHPCI/Store/Base/BuildErrorStoreBase.php new file mode 100644 index 00000000..627b9d54 --- /dev/null +++ b/PHPCI/Store/Base/BuildErrorStoreBase.php @@ -0,0 +1,85 @@ +getById($value, $useConnection); + } + + /** + * Get a single BuildError by Id. + * @return null|BuildError + */ + public function getById($value, $useConnection = 'read') + { + if (is_null($value)) { + throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.'); + } + + $query = 'SELECT * FROM `build_error` WHERE `id` = :id LIMIT 1'; + $stmt = Database::getConnection($useConnection)->prepare($query); + $stmt->bindValue(':id', $value); + + if ($stmt->execute()) { + if ($data = $stmt->fetch(\PDO::FETCH_ASSOC)) { + return new BuildError($data); + } + } + + return null; + } + + /** + * Get multiple BuildError by BuildId. + * @return array + */ + public function getByBuildId($value, $limit = 1000, $useConnection = 'read') + { + if (is_null($value)) { + throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.'); + } + + + $query = 'SELECT * FROM `build_error` WHERE `build_id` = :build_id LIMIT :limit'; + $stmt = Database::getConnection($useConnection)->prepare($query); + $stmt->bindValue(':build_id', $value); + $stmt->bindValue(':limit', (int)$limit, \PDO::PARAM_INT); + + if ($stmt->execute()) { + $res = $stmt->fetchAll(\PDO::FETCH_ASSOC); + + $map = function ($item) { + return new BuildError($item); + }; + $rtn = array_map($map, $res); + + $count = count($rtn); + + return array('items' => $rtn, 'count' => $count); + } else { + return array('items' => array(), 'count' => 0); + } + } +} diff --git a/PHPCI/Store/Base/BuildMetaStoreBase.php b/PHPCI/Store/Base/BuildMetaStoreBase.php index 36a94f9d..52665d79 100644 --- a/PHPCI/Store/Base/BuildMetaStoreBase.php +++ b/PHPCI/Store/Base/BuildMetaStoreBase.php @@ -21,10 +21,7 @@ class BuildMetaStoreBase extends Store protected $primaryKey = 'id'; /** - * Get a BuildMeta by primary key. - * @param mixed $value Primary key. - * @param string $useConnection Connection to use (read / write) - * @return \PHPCI\Model\BuildMeta|null + * Get a BuildMeta by primary key (Id) */ public function getByPrimaryKey($value, $useConnection = 'read') { @@ -32,11 +29,8 @@ class BuildMetaStoreBase extends Store } /** - * Get a BuildMeta by Id. - * @param mixed $value. - * @param string $useConnection Connection to use (read / write) - * @throws \b8\Exception\HttpException - * @return \PHPCI\Model\BuildMeta|null; + * Get a single BuildMeta by Id. + * @return null|BuildMeta */ public function getById($value, $useConnection = 'read') { @@ -58,30 +52,20 @@ class BuildMetaStoreBase extends Store } /** - * Get an array of BuildMeta by ProjectId. - * @param mixed $value. - * @param int $limit - * @param string $useConnection Connection to use (read / write) - * @throws \b8\Exception\HttpException - * @return \PHPCI\Model\BuildMeta[] + * Get multiple BuildMeta by ProjectId. + * @return array */ - public function getByProjectId($value, $limit = null, $useConnection = 'read') + public function getByProjectId($value, $limit = 1000, $useConnection = 'read') { if (is_null($value)) { throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.'); } - $add = ''; - if ($limit) { - $add .= ' LIMIT ' . $limit; - } - - $count = null; - - $query = 'SELECT * FROM `build_meta` WHERE `project_id` = :project_id' . $add; + $query = 'SELECT * FROM `build_meta` WHERE `project_id` = :project_id LIMIT :limit'; $stmt = Database::getConnection($useConnection)->prepare($query); $stmt->bindValue(':project_id', $value); + $stmt->bindValue(':limit', (int)$limit, \PDO::PARAM_INT); if ($stmt->execute()) { $res = $stmt->fetchAll(\PDO::FETCH_ASSOC); @@ -91,6 +75,8 @@ class BuildMetaStoreBase extends Store }; $rtn = array_map($map, $res); + $count = count($rtn); + return array('items' => $rtn, 'count' => $count); } else { return array('items' => array(), 'count' => 0); @@ -98,30 +84,20 @@ class BuildMetaStoreBase extends Store } /** - * Get an array of BuildMeta by BuildId. - * @param mixed $value. - * @param int $limit - * @param string $useConnection Connection to use (read / write) - * @throws \b8\Exception\HttpException - * @return \PHPCI\Model\BuildMeta[] + * Get multiple BuildMeta by BuildId. + * @return array */ - public function getByBuildId($value, $limit = null, $useConnection = 'read') + public function getByBuildId($value, $limit = 1000, $useConnection = 'read') { if (is_null($value)) { throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.'); } - $add = ''; - if ($limit) { - $add .= ' LIMIT ' . $limit; - } - - $count = null; - - $query = 'SELECT * FROM `build_meta` WHERE `build_id` = :build_id' . $add; + $query = 'SELECT * FROM `build_meta` WHERE `build_id` = :build_id LIMIT :limit'; $stmt = Database::getConnection($useConnection)->prepare($query); $stmt->bindValue(':build_id', $value); + $stmt->bindValue(':limit', (int)$limit, \PDO::PARAM_INT); if ($stmt->execute()) { $res = $stmt->fetchAll(\PDO::FETCH_ASSOC); @@ -131,6 +107,8 @@ class BuildMetaStoreBase extends Store }; $rtn = array_map($map, $res); + $count = count($rtn); + return array('items' => $rtn, 'count' => $count); } else { return array('items' => array(), 'count' => 0); diff --git a/PHPCI/Store/Base/BuildStoreBase.php b/PHPCI/Store/Base/BuildStoreBase.php index cb1b2824..b8b49cb7 100644 --- a/PHPCI/Store/Base/BuildStoreBase.php +++ b/PHPCI/Store/Base/BuildStoreBase.php @@ -21,10 +21,7 @@ class BuildStoreBase extends Store protected $primaryKey = 'id'; /** - * Get a Build by primary key. - * @param mixed $value Primary key. - * @param string $useConnection Connection to use (read / write) - * @return \PHPCI\Model\Build|null + * Get a Build by primary key (Id) */ public function getByPrimaryKey($value, $useConnection = 'read') { @@ -32,11 +29,8 @@ class BuildStoreBase extends Store } /** - * Get a Build by Id. - * @param mixed $value. - * @param string $useConnection Connection to use (read / write) - * @throws \b8\Exception\HttpException - * @return \PHPCI\Model\Build|null; + * Get a single Build by Id. + * @return null|Build */ public function getById($value, $useConnection = 'read') { @@ -58,30 +52,20 @@ class BuildStoreBase extends Store } /** - * Get an array of Build by ProjectId. - * @param mixed $value. - * @param int $limit - * @param string $useConnection Connection to use (read / write) - * @throws \b8\Exception\HttpException - * @return \PHPCI\Model\Build[] + * Get multiple Build by ProjectId. + * @return array */ - public function getByProjectId($value, $limit = null, $useConnection = 'read') + public function getByProjectId($value, $limit = 1000, $useConnection = 'read') { if (is_null($value)) { throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.'); } - $add = ''; - if ($limit) { - $add .= ' LIMIT ' . $limit; - } - - $count = null; - - $query = 'SELECT * FROM `build` WHERE `project_id` = :project_id' . $add; + $query = 'SELECT * FROM `build` WHERE `project_id` = :project_id LIMIT :limit'; $stmt = Database::getConnection($useConnection)->prepare($query); $stmt->bindValue(':project_id', $value); + $stmt->bindValue(':limit', (int)$limit, \PDO::PARAM_INT); if ($stmt->execute()) { $res = $stmt->fetchAll(\PDO::FETCH_ASSOC); @@ -91,6 +75,8 @@ class BuildStoreBase extends Store }; $rtn = array_map($map, $res); + $count = count($rtn); + return array('items' => $rtn, 'count' => $count); } else { return array('items' => array(), 'count' => 0); @@ -98,30 +84,20 @@ class BuildStoreBase extends Store } /** - * Get an array of Build by Status. - * @param mixed $value. - * @param int $limit - * @param string $useConnection Connection to use (read / write) - * @throws \b8\Exception\HttpException - * @return \PHPCI\Model\Build[] + * Get multiple Build by Status. + * @return array */ - public function getByStatus($value, $limit = null, $useConnection = 'read') + public function getByStatus($value, $limit = 1000, $useConnection = 'read') { if (is_null($value)) { throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.'); } - $add = ''; - if ($limit) { - $add .= ' LIMIT ' . $limit; - } - - $count = null; - - $query = 'SELECT * FROM `build` WHERE `status` = :status' . $add; + $query = 'SELECT * FROM `build` WHERE `status` = :status LIMIT :limit'; $stmt = Database::getConnection($useConnection)->prepare($query); $stmt->bindValue(':status', $value); + $stmt->bindValue(':limit', (int)$limit, \PDO::PARAM_INT); if ($stmt->execute()) { $res = $stmt->fetchAll(\PDO::FETCH_ASSOC); @@ -131,6 +107,8 @@ class BuildStoreBase extends Store }; $rtn = array_map($map, $res); + $count = count($rtn); + return array('items' => $rtn, 'count' => $count); } else { return array('items' => array(), 'count' => 0); diff --git a/PHPCI/Store/Base/ProjectGroupStoreBase.php b/PHPCI/Store/Base/ProjectGroupStoreBase.php new file mode 100644 index 00000000..c7cd8772 --- /dev/null +++ b/PHPCI/Store/Base/ProjectGroupStoreBase.php @@ -0,0 +1,53 @@ +getById($value, $useConnection); + } + + /** + * Get a single ProjectGroup by Id. + * @return null|ProjectGroup + */ + public function getById($value, $useConnection = 'read') + { + if (is_null($value)) { + throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.'); + } + + $query = 'SELECT * FROM `project_group` WHERE `id` = :id LIMIT 1'; + $stmt = Database::getConnection($useConnection)->prepare($query); + $stmt->bindValue(':id', $value); + + if ($stmt->execute()) { + if ($data = $stmt->fetch(\PDO::FETCH_ASSOC)) { + return new ProjectGroup($data); + } + } + + return null; + } +} diff --git a/PHPCI/Store/Base/ProjectStoreBase.php b/PHPCI/Store/Base/ProjectStoreBase.php index 02692f62..1e2bf65b 100644 --- a/PHPCI/Store/Base/ProjectStoreBase.php +++ b/PHPCI/Store/Base/ProjectStoreBase.php @@ -21,10 +21,7 @@ class ProjectStoreBase extends Store protected $primaryKey = 'id'; /** - * Get a Project by primary key. - * @param mixed $value Primary key. - * @param string $useConnection Connection to use (read / write) - * @return \PHPCI\Model\Project|null + * Get a Project by primary key (Id) */ public function getByPrimaryKey($value, $useConnection = 'read') { @@ -32,11 +29,8 @@ class ProjectStoreBase extends Store } /** - * Get a Project by Id. - * @param mixed $value. - * @param string $useConnection Connection to use (read / write) - * @throws \b8\Exception\HttpException - * @return \PHPCI\Model\Project|null; + * Get a single Project by Id. + * @return null|Project */ public function getById($value, $useConnection = 'read') { @@ -58,30 +52,20 @@ class ProjectStoreBase extends Store } /** - * Get an array of Project by Title. - * @param mixed $value. - * @param int $limit - * @param string $useConnection Connection to use (read / write) - * @throws \b8\Exception\HttpException - * @return \PHPCI\Model\Project[] + * Get multiple Project by Title. + * @return array */ - public function getByTitle($value, $limit = null, $useConnection = 'read') + public function getByTitle($value, $limit = 1000, $useConnection = 'read') { if (is_null($value)) { throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.'); } - $add = ''; - if ($limit) { - $add .= ' LIMIT ' . $limit; - } - - $count = null; - - $query = 'SELECT * FROM `project` WHERE `title` = :title' . $add; + $query = 'SELECT * FROM `project` WHERE `title` = :title LIMIT :limit'; $stmt = Database::getConnection($useConnection)->prepare($query); $stmt->bindValue(':title', $value); + $stmt->bindValue(':limit', (int)$limit, \PDO::PARAM_INT); if ($stmt->execute()) { $res = $stmt->fetchAll(\PDO::FETCH_ASSOC); @@ -91,6 +75,40 @@ class ProjectStoreBase extends Store }; $rtn = array_map($map, $res); + $count = count($rtn); + + return array('items' => $rtn, 'count' => $count); + } else { + return array('items' => array(), 'count' => 0); + } + } + + /** + * Get multiple Project by GroupId. + * @return array + */ + public function getByGroupId($value, $limit = 1000, $useConnection = 'read') + { + if (is_null($value)) { + throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.'); + } + + + $query = 'SELECT * FROM `project` WHERE `group_id` = :group_id LIMIT :limit'; + $stmt = Database::getConnection($useConnection)->prepare($query); + $stmt->bindValue(':group_id', $value); + $stmt->bindValue(':limit', (int)$limit, \PDO::PARAM_INT); + + if ($stmt->execute()) { + $res = $stmt->fetchAll(\PDO::FETCH_ASSOC); + + $map = function ($item) { + return new Project($item); + }; + $rtn = array_map($map, $res); + + $count = count($rtn); + return array('items' => $rtn, 'count' => $count); } else { return array('items' => array(), 'count' => 0); diff --git a/PHPCI/Store/Base/UserStoreBase.php b/PHPCI/Store/Base/UserStoreBase.php index 24d247e3..105ccd3e 100644 --- a/PHPCI/Store/Base/UserStoreBase.php +++ b/PHPCI/Store/Base/UserStoreBase.php @@ -21,10 +21,7 @@ class UserStoreBase extends Store protected $primaryKey = 'id'; /** - * Get a User by primary key. - * @param mixed $value Primary key. - * @param string $useConnection Connection to use (read / write) - * @return \PHPCI\Model\User|null + * Get a User by primary key (Id) */ public function getByPrimaryKey($value, $useConnection = 'read') { @@ -32,11 +29,8 @@ class UserStoreBase extends Store } /** - * Get a User by Id. - * @param mixed $value. - * @param string $useConnection Connection to use (read / write) - * @throws \b8\Exception\HttpException - * @return \PHPCI\Model\User|null; + * Get a single User by Id. + * @return null|User */ public function getById($value, $useConnection = 'read') { @@ -58,11 +52,8 @@ class UserStoreBase extends Store } /** - * Get a User by Email. - * @param mixed $value. - * @param string $useConnection Connection to use (read / write) - * @throws \b8\Exception\HttpException - * @return \PHPCI\Model\User|null; + * Get a single User by Email. + * @return null|User */ public function getByEmail($value, $useConnection = 'read') { @@ -82,4 +73,36 @@ class UserStoreBase extends Store return null; } + + /** + * Get multiple User by Name. + * @return array + */ + public function getByName($value, $limit = 1000, $useConnection = 'read') + { + if (is_null($value)) { + throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.'); + } + + + $query = 'SELECT * FROM `user` WHERE `name` = :name LIMIT :limit'; + $stmt = Database::getConnection($useConnection)->prepare($query); + $stmt->bindValue(':name', $value); + $stmt->bindValue(':limit', (int)$limit, \PDO::PARAM_INT); + + if ($stmt->execute()) { + $res = $stmt->fetchAll(\PDO::FETCH_ASSOC); + + $map = function ($item) { + return new User($item); + }; + $rtn = array_map($map, $res); + + $count = count($rtn); + + return array('items' => $rtn, 'count' => $count); + } else { + return array('items' => array(), 'count' => 0); + } + } } diff --git a/PHPCI/Store/BuildErrorStore.php b/PHPCI/Store/BuildErrorStore.php new file mode 100644 index 00000000..c2d32468 --- /dev/null +++ b/PHPCI/Store/BuildErrorStore.php @@ -0,0 +1,80 @@ + :since'; + } + + $query .= ' LIMIT 15000'; + + $stmt = Database::getConnection('read')->prepare($query); + + $stmt->bindValue(':build', $buildId, \PDO::PARAM_INT); + + if (!is_null($since)) { + $stmt->bindValue(':since', $since); + } + + if ($stmt->execute()) { + $res = $stmt->fetchAll(\PDO::FETCH_ASSOC); + + $map = function ($item) { + return new BuildError($item); + }; + $rtn = array_map($map, $res); + + return $rtn; + } else { + return array(); + } + } + + /** + * Gets the total number of errors for a given build. + * @param $buildId + * @param string $since date string + * @return array + */ + public function getErrorTotalForBuild($buildId) + { + $query = 'SELECT COUNT(*) AS total FROM build_error + WHERE build_id = :build'; + + $stmt = Database::getConnection('read')->prepare($query); + + $stmt->bindValue(':build', $buildId, \PDO::PARAM_INT); + + if ($stmt->execute()) { + $res = $stmt->fetch(\PDO::FETCH_ASSOC); + return $res['total']; + } else { + return array(); + } + } +} diff --git a/PHPCI/Store/BuildMetaStore.php b/PHPCI/Store/BuildMetaStore.php index 9800dcad..f932bc11 100644 --- a/PHPCI/Store/BuildMetaStore.php +++ b/PHPCI/Store/BuildMetaStore.php @@ -10,6 +10,8 @@ namespace PHPCI\Store; use PHPCI\Store\Base\BuildMetaStoreBase; +use b8\Database; +use PHPCI\Model\BuildMeta; /** * BuildMeta Store @@ -17,5 +19,33 @@ use PHPCI\Store\Base\BuildMetaStoreBase; */ class BuildMetaStore extends BuildMetaStoreBase { - // This class has been left blank so that you can modify it - changes in this file will not be overwritten. + /** + * Only used by an upgrade migration to move errors from build_meta to build_error + * @param $start + * @param $limit + * @return array + */ + public function getErrorsForUpgrade($limit) + { + $query = 'SELECT * FROM build_meta + WHERE meta_key IN (\'phpmd-data\', \'phpcs-data\', \'phpdoccheck-data\') + ORDER BY id ASC LIMIT :limit'; + + $stmt = Database::getConnection('read')->prepare($query); + + $stmt->bindValue(':limit', $limit, \PDO::PARAM_INT); + + if ($stmt->execute()) { + $res = $stmt->fetchAll(\PDO::FETCH_ASSOC); + + $map = function ($item) { + return new BuildMeta($item); + }; + $rtn = array_map($map, $res); + + return $rtn; + } else { + return array(); + } + } } diff --git a/PHPCI/Store/BuildStore.php b/PHPCI/Store/BuildStore.php index 39ff7c78..d6feb084 100644 --- a/PHPCI/Store/BuildStore.php +++ b/PHPCI/Store/BuildStore.php @@ -10,7 +10,6 @@ namespace PHPCI\Store; use b8\Database; -use PHPCI\BuildFactory; use PHPCI\Model\Build; use PHPCI\Store\Base\BuildStoreBase; @@ -30,13 +29,12 @@ class BuildStore extends BuildStoreBase */ public function getLatestBuilds($projectId = null, $limit = 5) { - $where = ''; - if (!is_null($projectId)) { - $where = ' WHERE `project_id` = :pid '; + $query = 'SELECT * FROM build WHERE `project_id` = :pid ORDER BY id DESC LIMIT :limit'; + } else { + $query = 'SELECT * FROM build ORDER BY id DESC LIMIT :limit'; } - $query = 'SELECT * FROM build '.$where.' ORDER BY id DESC LIMIT :limit'; $stmt = Database::getConnection('read')->prepare($query); if (!is_null($projectId)) { @@ -109,6 +107,27 @@ class BuildStore extends BuildStoreBase } } + /** + * Returns all registered branches for project + * + * @param $projectId + * @return array + * @throws \Exception + */ + public function getBuildBranches($projectId) + { + $query = 'SELECT DISTINCT `branch` FROM `build` WHERE `project_id` = :project_id'; + $stmt = Database::getConnection('read')->prepare($query); + $stmt->bindValue(':project_id', $projectId); + + if ($stmt->execute()) { + $res = $stmt->fetchAll(\PDO::FETCH_COLUMN); + return $res; + } else { + return array(); + } + } + /** * Return build metadata by key, project and optionally build id. * @param $key @@ -120,24 +139,36 @@ class BuildStore extends BuildStoreBase */ public function getMeta($key, $projectId, $buildId = null, $branch = null, $numResults = 1) { - $select = '`bm`.`build_id`, `bm`.`meta_key`, `bm`.`meta_value`'; - $and = $numResults > 1 ? ' AND (`bm`.`build_id` <= :buildId) ' : ' AND (`bm`.`build_id` = :buildId) '; - $where = '`bm`.`meta_key` = :key AND `bm`.`project_id` = :projectId ' . $and; - $from = ' `build_meta` AS `bm`'; + $query = 'SELECT bm.build_id, bm.meta_key, bm.meta_value + FROM build_meta AS bm + LEFT JOIN build b ON b.id = bm.build_id + WHERE bm.meta_key = :key + AND bm.project_id = :projectId'; - if ($branch !== null) { - $where .= ' AND `b`.`branch` = :branch AND `b`.`id`= `bm`.`build_id` '; - $from .= ', `build` AS `b`'; + // If we're getting comparative meta data, include previous builds + // otherwise just include the specified build ID: + if ($numResults > 1) { + $query .= ' AND bm.build_id <= :buildId '; + } else { + $query .= ' AND bm.build_id = :buildId '; } - $query = 'SELECT '.$select.' FROM '.$from.' WHERE '.$where.' ORDER BY `bm`.id DESC LIMIT :numResults'; + // Include specific branch information if required: + if (!is_null($branch)) { + $query .= ' AND b.branch = :branch '; + } + + $query .= ' ORDER BY bm.id DESC LIMIT :numResults'; $stmt = Database::getConnection('read')->prepare($query); $stmt->bindValue(':key', $key, \PDO::PARAM_STR); $stmt->bindValue(':projectId', (int)$projectId, \PDO::PARAM_INT); $stmt->bindValue(':buildId', (int)$buildId, \PDO::PARAM_INT); $stmt->bindValue(':numResults', (int)$numResults, \PDO::PARAM_INT); - $stmt->bindValue(':branch', $branch, \PDO::PARAM_STR); + + if (!is_null($branch)) { + $stmt->bindValue(':branch', $branch, \PDO::PARAM_STR); + } if ($stmt->execute()) { $rtn = $stmt->fetchAll(\PDO::FETCH_ASSOC); @@ -153,7 +184,6 @@ class BuildStore extends BuildStoreBase } else { return $rtn; } - } else { return null; } diff --git a/PHPCI/Store/ProjectGroupStore.php b/PHPCI/Store/ProjectGroupStore.php new file mode 100644 index 00000000..fa254e3e --- /dev/null +++ b/PHPCI/Store/ProjectGroupStore.php @@ -0,0 +1,18 @@ + $rtn, 'count' => $count); + } else { + return array('items' => array(), 'count' => 0); + } + } + + /** + * Get multiple Project by GroupId. + * @param int $value + * @param int $limit + * @param string $useConnection + * @return array + * @throws \Exception + */ + public function getByGroupId($value, $limit = 1000, $useConnection = 'read') + { + if (is_null($value)) { + throw new \Exception('Value passed to ' . __FUNCTION__ . ' cannot be null.'); + } + + $query = 'SELECT * FROM `project` WHERE `group_id` = :group_id ORDER BY title LIMIT :limit'; + $stmt = Database::getConnection($useConnection)->prepare($query); + $stmt->bindValue(':group_id', $value); + $stmt->bindValue(':limit', (int)$limit, \PDO::PARAM_INT); + + if ($stmt->execute()) { + $res = $stmt->fetchAll(\PDO::FETCH_ASSOC); + + $map = function ($item) { + return new Project($item); + }; + $rtn = array_map($map, $res); + + $count = count($rtn); + return array('items' => $rtn, 'count' => $count); } else { return array('items' => array(), 'count' => 0); diff --git a/PHPCI/View/Build/errors.phtml b/PHPCI/View/Build/errors.phtml new file mode 100644 index 00000000..04ab9c25 --- /dev/null +++ b/PHPCI/View/Build/errors.phtml @@ -0,0 +1,37 @@ +getFileLinkTemplate(); + +/** @var \PHPCI\Model\BuildError $error */ +foreach ($errors as $error): + + $link = str_replace('{FILE}', $error->getFile(), $linkTemplate); + $link = str_replace('{LINE}', $error->getLineStart(), $link); + $link = str_replace('{LINE_END}', $error->getLineEnd(), $link); +?> + + + + + getSeverityString()); ?> + + + getPlugin()); ?> + getFile(); ?> + + + getLineStart() == $error->getLineEnd() || !$error->getLineEnd()) { + print $error->getLineStart(); + } else { + print $error->getLineStart() . ' - ' . $error->getLineEnd(); + } + ?> + + + getMessage(); ?> + + + + \ No newline at end of file diff --git a/PHPCI/View/Build/view.phtml b/PHPCI/View/Build/view.phtml index 1fcb57d8..61fafd33 100644 --- a/PHPCI/View/Build/view.phtml +++ b/PHPCI/View/Build/view.phtml @@ -1,36 +1,161 @@ -
- -
-

- getCommitterEmail()); ?> - -

-
- -
- - -
- getCommitMessage()): ?> -
- getCommitMessage(); ?> -
- - - getBranch()); ?> - - getCommitId() != 'Manual'): ?> -
getCommitId()); ?> - -
-
-
-
-
-
+
+
+
+

+ Build Details +

+
+ +
+ + + + + + + + + + + + + + + +
Project + + + getProject()->getTitle(); ?> + +
Branch + + getBranch(); ?> + +
Duration + +
+
+
+
+ +
+
+
+

+ Commit Details +

+
+ +
+ + + + + + + + + + + + + + +
Commit + + getCommitId(), 0, 7); ?> + +
Committer + getCommitterEmail(); ?> +
+ getCommitMessage(); ?> +
+
+
+
+ +
+
+
+

+ Timing +

+
+ +
+ + + + + + + + + + + + + + + +
Created +
Started +
Finished + +
+
+
+
+ +
+ + @@ -38,14 +163,13 @@ '; + print '' . PHP_EOL; } ?> @@ -59,47 +183,7 @@ foreach ($plugins as $plugin) { "build/delete/getId(); ?>", "Build" ).onCloseConfirmed = function () {window.location = '/'}; }); - - $(window).on('build-updated', function(data) { - updateBuildStatus(data.queryData.status); - }); - - updateBuildStatus(getStatus(); ?>); }); - function updateBuildStatus(status) { - switch (status) { - case 0: - $('.build-info-panel') - .removeClass('bg-yellow') - .removeClass('bg-green') - .removeClass('bg-red') - .addClass('bg-blue'); - break; - case 1: - $('.build-info-panel') - .removeClass('bg-green') - .removeClass('bg-red') - .removeClass('bg-blue') - .addClass('bg-yellow'); - break; - - case 2: - $('.build-info-panel') - .removeClass('bg-yellow') - .removeClass('bg-red') - .removeClass('bg-blue') - .addClass('bg-green'); - break; - - case 3: - $('.build-info-panel') - .removeClass('bg-yellow') - .removeClass('bg-green') - .removeClass('bg-blue') - .addClass('bg-red'); - break; - } - } diff --git a/PHPCI/View/BuildsTable.phtml b/PHPCI/View/BuildsTable.phtml index c9d44930..f26eb250 100644 --- a/PHPCI/View/BuildsTable.phtml +++ b/PHPCI/View/BuildsTable.phtml @@ -39,8 +39,11 @@ switch($build->getStatus()) ?> #getId(), 6, '0', STR_PAD_LEFT); ?> + getCreated()->format('Y-m-d H:i:s'); ?> - getProject()->getIcon(); ?>"> + + getProject())) { print htmlspecialchars($build->getProject()->getTitle()); } else { diff --git a/PHPCI/View/Email/failed.phtml b/PHPCI/View/Email/failed.phtml deleted file mode 100644 index 4391748f..00000000 --- a/PHPCI/View/Email/failed.phtml +++ /dev/null @@ -1,15 +0,0 @@ - \ No newline at end of file diff --git a/PHPCI/View/Email/layout.phtml b/PHPCI/View/Email/layout.phtml new file mode 100644 index 00000000..878a9c9e --- /dev/null +++ b/PHPCI/View/Email/layout.phtml @@ -0,0 +1,28 @@ + + + + + +
+
+
getTitle(); ?> - Build #getId(); ?>
+
+

+ Your commit getCommitId(); ?> generated a + isSuccessful() ? 'successful' : 'failed'; ?> build in project + getTitle(); ?>. +

+ +
+ +
+
+ + diff --git a/PHPCI/View/Email/long.phtml b/PHPCI/View/Email/long.phtml new file mode 100644 index 00000000..35464504 --- /dev/null +++ b/PHPCI/View/Email/long.phtml @@ -0,0 +1,2 @@ +

getCommitMessage(); ?>

+
getLog()); ?>
diff --git a/PHPCI/View/Email/short.phtml b/PHPCI/View/Email/short.phtml new file mode 100644 index 00000000..75df4f83 --- /dev/null +++ b/PHPCI/View/Email/short.phtml @@ -0,0 +1 @@ +

getCommitMessage(); ?>

diff --git a/PHPCI/View/Group/edit.phtml b/PHPCI/View/Group/edit.phtml new file mode 100644 index 00000000..1e32165b --- /dev/null +++ b/PHPCI/View/Group/edit.phtml @@ -0,0 +1,9 @@ +
+
+

Add / Edit Group

+
+ +
+ +
+
\ No newline at end of file diff --git a/PHPCI/View/Group/index.phtml b/PHPCI/View/Group/index.phtml new file mode 100644 index 00000000..e07c9af1 --- /dev/null +++ b/PHPCI/View/Group/index.phtml @@ -0,0 +1,41 @@ + + + +
+
+

Project Groups

+
+ + + + + + + + + + + + + + + + + + +
TitleProjects
+ + Edit + + + + + Delete + + +
+
\ No newline at end of file diff --git a/PHPCI/View/Home/index.phtml b/PHPCI/View/Home/index.phtml index 11db43cf..6bce4be8 100644 --- a/PHPCI/View/Home/index.phtml +++ b/PHPCI/View/Home/index.phtml @@ -2,7 +2,17 @@
- + +
+
+

+
+ +
+ +
+
+
@@ -17,7 +27,6 @@ getStatus()) { case \PHPCI\Model\Build::STATUS_NEW: $updated = $build->getCreated(); @@ -44,11 +53,15 @@ break; } + if (!$updated) { + $updated = $build->getCreated(); + } + if ($updated->format('Y-m-d') != $last->format('Y-m-d')): $last = $updated; ?>
  • - format('M j Y'); ?> +
  • @@ -58,7 +71,7 @@
  • - format('H:i'); ?> +

    getProject()->getTitle(); ?> diff --git a/PHPCI/View/Plugin/index.phtml b/PHPCI/View/Plugin/index.phtml index b595a4df..5c186012 100644 --- a/PHPCI/View/Plugin/index.phtml +++ b/PHPCI/View/Plugin/index.phtml @@ -1,45 +1,40 @@ - -

    - - -

    - - - -

    - - -
    -
    -

    -
    - - - - - - - - - - - - - - - - - - -
    name; ?>class; ?>source; ?>
    +
    +

    Adding requirements to the PHPCI composer.json file is no longer recommended as a method of installing your required testing tools.
    + For this reason, we have removed the ability for PHPCI to modify the composer.json file for you. + We recommend that you install testing tools using your project's own composer.json file, by adding them to the "require-dev" section of the file.

    - -
    -
    +
    +
    +
    +

    +
    + + + + + + + + + + + + + + + + + + +
    name; ?>class; ?>source; ?>
    +
    +
    + +
    - -
    -
    -
    -

    -
    - - - - - - - - - - - $version): ?> - - - - - @@ -105,108 +62,3 @@ -
    -
    -

    -
    - -
    -
    - - - - -
    - -
    - - - -
    - - - - - - - - - - -
    -
    -
    - -
    - - - - diff --git a/PHPCI/View/Project/view.phtml b/PHPCI/View/Project/view.phtml index 0bfd5e59..79b7ef0e 100644 --- a/PHPCI/View/Project/view.phtml +++ b/PHPCI/View/Project/view.phtml @@ -5,8 +5,16 @@
    + + + + + + + +
    - + @@ -36,13 +44,13 @@
    - -

    +

    ()

    + @@ -153,4 +161,4 @@ if ($page < $pages - 1) { print ''; -?> \ No newline at end of file +?> diff --git a/PHPCI/View/Session.phtml b/PHPCI/View/Session.phtml index 7667b576..4597e43e 100644 --- a/PHPCI/View/Session.phtml +++ b/PHPCI/View/Session.phtml @@ -7,9 +7,9 @@ - - - + + + - + +
    + -
    +
    -
    -
    '; + } + ?> + - +
    - - - - + + + + + + + diff --git a/PHPCI/Worker/BuildWorker.php b/PHPCI/Worker/BuildWorker.php new file mode 100644 index 00000000..92ee4ced --- /dev/null +++ b/PHPCI/Worker/BuildWorker.php @@ -0,0 +1,210 @@ +host = $host; + $this->queue = $queue; + $this->pheanstalk = new Pheanstalk($this->host); + } + + /** + * @param int $maxJobs + */ + public function setMaxJobs($maxJobs = -1) + { + $this->maxJobs = $maxJobs; + } + + /** + * @param Logger $logger + */ + public function setLogger(Logger $logger) + { + $this->logger = $logger; + } + + /** + * Start the worker. + */ + public function startWorker() + { + $this->pheanstalk->watch($this->queue); + $this->pheanstalk->ignore('default'); + $buildStore = Factory::getStore('Build'); + + while ($this->run) { + // Get a job from the queue: + $job = $this->pheanstalk->reserve(); + + $this->checkJobLimit(); + + // Get the job data and run the job: + $jobData = json_decode($job->getData(), true); + + if (!$this->verifyJob($job, $jobData)) { + continue; + } + + $this->logger->addInfo('Received build #'.$jobData['build_id'].' from Beanstalkd'); + + // If the job comes with config data, reset our config and database connections + // and then make sure we kill the worker afterwards: + if (!empty($jobData['config'])) { + $this->logger->addDebug('Using job-specific config.'); + $currentConfig = Config::getInstance()->getArray(); + $config = new Config($jobData['config']); + Database::reset($config); + } + + try { + $build = BuildFactory::getBuildById($jobData['build_id']); + } catch (\Exception $ex) { + $this->logger->addWarning('Build #' . $jobData['build_id'] . ' does not exist in the database.'); + $this->pheanstalk->delete($job); + } + + try { + // Logging relevant to this build should be stored + // against the build itself. + $buildDbLog = new BuildDBLogHandler($build, Logger::INFO); + $this->logger->pushHandler($buildDbLog); + + $builder = new Builder($build, $this->logger); + $builder->execute(); + + // After execution we no longer want to record the information + // back to this specific build so the handler should be removed. + $this->logger->popHandler($buildDbLog); + } catch (\PDOException $ex) { + // If we've caught a PDO Exception, it is probably not the fault of the build, but of a failed + // connection or similar. Release the job and kill the worker. + $this->run = false; + $this->pheanstalk->release($job); + } catch (\Exception $ex) { + $build->setStatus(Build::STATUS_FAILED); + $build->setFinished(new \DateTime()); + $build->setLog($build->getLog() . PHP_EOL . PHP_EOL . $ex->getMessage()); + $buildStore->save($build); + $build->sendStatusPostback(); + } + + // Reset the config back to how it was prior to running this job: + if (!empty($currentConfig)) { + $config = new Config($currentConfig); + Database::reset($config); + } + + // Delete the job when we're done: + $this->pheanstalk->delete($job); + } + } + + /** + * Stops the worker after the current build. + */ + public function stopWorker() + { + $this->run = false; + } + + /** + * Checks if this worker has done the amount of jobs it is allowed to do, and if so tells it to stop + * after this job completes. + */ + protected function checkJobLimit() + { + // Make sure we don't run more than maxJobs jobs on this worker: + $this->totalJobs++; + + if ($this->maxJobs != -1 && $this->maxJobs <= $this->totalJobs) { + $this->stopWorker(); + } + } + + /** + * Checks that the job received is actually from PHPCI, and has a valid type. + * @param Job $job + * @param $jobData + * @return bool + */ + protected function verifyJob(Job $job, $jobData) + { + if (empty($jobData) || !is_array($jobData)) { + // Probably not from PHPCI. + $this->pheanstalk->delete($job); + return false; + } + + if (!array_key_exists('type', $jobData) || $jobData['type'] !== 'phpci.build') { + // Probably not from PHPCI. + $this->pheanstalk->delete($job); + return false; + } + + return true; + } +} diff --git a/PHPCI/build/.gitignore b/PHPCI/build/.gitignore old mode 100755 new mode 100644 index c96a04f0..d6b7ef32 --- a/PHPCI/build/.gitignore +++ b/PHPCI/build/.gitignore @@ -1,2 +1,2 @@ * -!.gitignore \ No newline at end of file +!.gitignore diff --git a/README.md b/README.md index 759f715d..77683b91 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,13 @@ PHPCI is a free and open source (BSD License) continuous integration tool specif We have a chat room for discussing PHPCI, you can access it here: [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/Block8/PHPCI?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=body_badge) -##What it does: +**Support the development of PHPCI** + +We [now accept donations](https://www.phptesting.org/support) to directly support the ongoing development of PHPCI. There is of course no obligation to donate, nor any commitment if you do. + +[Donate](https://www.phptesting.org/support) + +## What it does: * Clones your project from Github, Bitbucket or a local path * Allows you to set up and tear down test databases. * Installs your project's Composer dependencies. @@ -19,18 +25,17 @@ We have a chat room for discussing PHPCI, you can access it here: [![Gitter](htt * You can mark directories for the plugins to ignore. * You can mark certain plugins as being allowed to fail (but still run.) -##What it doesn't do (yet): -* Virtualised testing. *(In progress)* -* Multiple PHP-version tests. *(In progress)* -* Multiple testing workers. *(In progress)* +### What it doesn't do (yet): +* Virtualised testing. +* Multiple PHP-version tests. * Install PEAR or PECL extensions. -* Deployments. +* Deployments - We strongly recommend using [Deployer](http://phpdeployment.org) ## Getting Started: We've got documentation on our website on [installing PHPCI](https://www.phptesting.org/install-phpci) and [adding support for PHPCI to your projects](https://www.phptesting.org/wiki/Adding-PHPCI-Support-to-Your-Projects). -##Contributing -Contributions from others would be very much appreciated! Please read our [guide to contributing](https://www.phptesting.org/wiki/Contributing-to-PHPCI) for more information on how to get involved. +## Contributing +Contributions from others would be very much appreciated! Please read our [guide to contributing](https://github.com/Block8/PHPCI/blob/master/.github/CONTRIBUTING.md) for more information on how to get involved. -##Questions? -Your best place to go is the [mailing list](https://groups.google.com/forum/#!forum/php-ci), if you're already a member of the mailing list, you can simply email php-ci@googlegroups.com. +## Questions? +Your best place to go is the [mailing list](https://groups.google.com/forum/#!forum/php-ci). If you're already a member of the mailing list, you can simply email php-ci@googlegroups.com. diff --git a/Tests/PHPCI/Command/CreateAdminCommandTest.php b/Tests/PHPCI/Command/CreateAdminCommandTest.php new file mode 100644 index 00000000..10b7b7f3 --- /dev/null +++ b/Tests/PHPCI/Command/CreateAdminCommandTest.php @@ -0,0 +1,79 @@ +command = $this->getMockBuilder('PHPCI\\Command\\CreateAdminCommand') + ->setConstructorArgs(array($this->getMock('PHPCI\\Store\\UserStore'))) + ->setMethods(array('reloadConfig')) + ->getMock() + ; + + $this->dialog = $this->getMockBuilder('Symfony\\Component\\Console\\Helper\\DialogHelper') + ->setMethods(array( + 'ask', + 'askAndValidate', + 'askHiddenResponse', + )) + ->getMock() + ; + + $this->application = new Application(); + } + + /** + * @return CommandTester + */ + protected function getCommandTester() + { + $this->application->getHelperSet()->set($this->dialog, 'dialog'); + $this->application->add($this->command); + $command = $this->application->find('phpci:create-admin'); + $commandTester = new CommandTester($command); + + return $commandTester; + } + + public function testExecute() + { + $this->dialog->expects($this->at(0))->method('askAndValidate')->will($this->returnValue('test@example.com')); + $this->dialog->expects($this->at(1))->method('ask')->will($this->returnValue('A name')); + $this->dialog->expects($this->at(2))->method('askHiddenResponse')->will($this->returnValue('foobar123')); + + $commandTester = $this->getCommandTester(); + $commandTester->execute(array()); + + $this->assertEquals('User account created!' . PHP_EOL, $commandTester->getDisplay()); + } +} diff --git a/Tests/PHPCI/Command/CreateBuildCommandTest.php b/Tests/PHPCI/Command/CreateBuildCommandTest.php new file mode 100644 index 00000000..e82ae517 --- /dev/null +++ b/Tests/PHPCI/Command/CreateBuildCommandTest.php @@ -0,0 +1,86 @@ +getMock('PHPCI\\Model\\Project'); + + $projectStoreMock = $this->getMockBuilder('PHPCI\\Store\\ProjectStore') + ->getMock(); + $projectStoreMock->method('getById') + ->will($this->returnValueMap(array( + array(1, 'read', $projectMock), + array(2, 'read', null), + ))); + + $buildServiceMock = $this->getMockBuilder('PHPCI\\Service\\BuildService') + ->disableOriginalConstructor() + ->getMock(); + $buildServiceMock->method('createBuild') + ->withConsecutive( + array($projectMock, null, null, null, null, null), + array($projectMock, '92c8c6e', null, null, null, null), + array($projectMock, null, 'master', null, null, null) + ); + + $this->command = $this->getMockBuilder('PHPCI\\Command\\CreateBuildCommand') + ->setConstructorArgs(array($projectStoreMock, $buildServiceMock)) + ->setMethods(array('reloadConfig')) + ->getMock(); + + $this->application = new Application(); + } + + protected function getCommandTester() + { + $this->application->add($this->command); + + $command = $this->application->find('phpci:create-build'); + $commandTester = new CommandTester($command); + + return $commandTester; + } + + public function testExecute() + { + $commandTester = $this->getCommandTester(); + + $commandTester->execute(array('projectId' => 1)); + $commandTester->execute(array('projectId' => 1, '--commit' => '92c8c6e')); + $commandTester->execute(array('projectId' => 1, '--branch' => 'master')); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testExecuteWithUnknownProjectId() + { + $commandTester = $this->getCommandTester(); + $commandTester->execute(array('projectId' => 2)); + } +} diff --git a/Tests/PHPCI/Command/InstallCommandTest.php b/Tests/PHPCI/Command/InstallCommandTest.php index 29c22303..5d70f31c 100644 --- a/Tests/PHPCI/Command/InstallCommandTest.php +++ b/Tests/PHPCI/Command/InstallCommandTest.php @@ -1,28 +1,60 @@ application = new Application(); + $this->application->setHelperSet(new HelperSet()); + } + + /** + * @return \PHPUnit_Framework_MockObject_MockBuilder + */ + protected function getDialogHelperMock() + { + // We check that there's no interaction with user. + $dialog = $this->getMockBuilder('Symfony\\Component\\Console\\Helper\\DialogHelper') + ->setMethods(array( + 'ask', + 'askConfirmation', + 'askAndValidate', + 'askHiddenResponse', + 'askHiddenResponseAndValidate', + )) + ->getMock(); + + return $dialog; + } + + /** + * @return \PHPUnit_Framework_MockObject_MockBuilder + */ + protected function getInstallCommandMock() + { // Current command, we need to mock all method that interact with // Database & File system. - $this->command = $this->getMockBuilder('PHPCI\\Command\\InstallCommand') + $command = $this->getMockBuilder('PHPCI\\Command\\InstallCommand') ->setMethods(array( 'reloadConfig', 'verifyNotInstalled', @@ -30,41 +62,34 @@ class InstallCommandTest extends ProphecyTestCase 'setupDatabase', 'createAdminUser', 'writeConfigFile', + 'checkRequirements', )) ->getMock(); - $this->command->expects($this->once())->method('verifyDatabaseDetails')->willReturn(true); - $this->command->expects($this->once())->method('setupDatabase')->willReturn(true); - $this->command->expects($this->once())->method('createAdminUser')->will( - $this->returnCallback(function ($adm) {// use (&$admin) { - $this->admin = $adm; + $self = $this; + + $command->expects($this->once())->method('verifyNotInstalled')->willReturn(true); + $command->expects($this->once())->method('verifyDatabaseDetails')->willReturn(true); + $command->expects($this->once())->method('setupDatabase')->willReturn(true); + $command->expects($this->once())->method('createAdminUser')->will( + $this->returnCallback(function ($adm) use ($self) { + $self->admin = $adm; }) ); - $this->command->expects($this->once())->method('writeConfigFile')->will( - $this->returnCallback(function ($cfg) { //use (&$config) { - $this->config = $cfg; + $command->expects($this->once())->method('writeConfigFile')->will( + $this->returnCallback(function ($cfg) use ($self) { + $self->config = $cfg; }) ); + $command->expects($this->once())->method('checkRequirements'); - // We check that there's no interaction with user. - $this->dialog = $this->getMockBuilder('Symfony\\Component\\Console\\Helper\\DialogHelper') - ->setMethods(array( - 'ask', - 'askConfirmation', - 'askAndValidate', - 'askHiddenResponse', - 'askHiddenResponseAndValidate', - )) - ->getMock(); - - $this->application = new Application(); - $this->application->setHelperSet(new HelperSet()); + return $command; } - protected function getCommandTester() + protected function getCommandTester($dialog) { - $this->application->getHelperSet()->set($this->dialog, 'dialog'); - $this->application->add($this->command); + $this->application->getHelperSet()->set($dialog, 'dialog'); + $this->application->add($this->getInstallCommandMock()); $command = $this->application->find('phpci:install'); $commandTester = new CommandTester($command); @@ -82,6 +107,7 @@ class InstallCommandTest extends ProphecyTestCase '--admin-name' => 'phpci4', '--admin-pass' => 'phpci5', '--url' => 'http://test.phpci.org', + '--queue-disabled' => null, ); if (!is_null($exclude)) { @@ -91,39 +117,42 @@ class InstallCommandTest extends ProphecyTestCase return $config; } - protected function executeWithoutParam($param = null) + protected function executeWithoutParam($param = null, $dialog) { // Clean result variables. $this->admin = array(); $this->config = array(); // Get tester and execute with extracted parameters. - $commandTester = $this->getCommandTester(); + $commandTester = $this->getCommandTester($dialog); $parameters = $this->getConfig($param); $commandTester->execute($parameters); } - public function testAutomticInstallation() + public function testAutomaticInstallation() { - $this->dialog->expects($this->never())->method('ask'); - $this->dialog->expects($this->never())->method('askConfirmation'); - $this->dialog->expects($this->never())->method('askAndValidate'); - $this->dialog->expects($this->never())->method('askHiddenResponse'); - $this->dialog->expects($this->never())->method('askHiddenResponseAndValidate'); + $dialog = $this->getDialogHelperMock(); + $dialog->expects($this->never())->method('ask'); + $dialog->expects($this->never())->method('askConfirmation'); + $dialog->expects($this->never())->method('askAndValidate'); + $dialog->expects($this->never())->method('askHiddenResponse'); + $dialog->expects($this->never())->method('askHiddenResponseAndValidate'); - $this->executeWithoutParam(); + $this->executeWithoutParam(null, $dialog); } public function testDatabaseHostnameConfig() { - // We specified an input value for hostname. - $this->dialog->expects($this->once())->method('ask')->willReturn('testedvalue'); - $this->dialog->expects($this->never())->method('askConfirmation'); - $this->dialog->expects($this->never())->method('askAndValidate'); - $this->dialog->expects($this->never())->method('askHiddenResponse'); - $this->dialog->expects($this->never())->method('askHiddenResponseAndValidate'); + $dialog = $this->getDialogHelperMock(); - $this->executeWithoutParam('--db-host'); + // We specified an input value for hostname. + $dialog->expects($this->once())->method('ask')->willReturn('testedvalue'); + $dialog->expects($this->never())->method('askConfirmation'); + $dialog->expects($this->never())->method('askAndValidate'); + $dialog->expects($this->never())->method('askHiddenResponse'); + $dialog->expects($this->never())->method('askHiddenResponseAndValidate'); + + $this->executeWithoutParam('--db-host', $dialog); // Check that specified arguments are correctly loaded. $this->assertEquals('testedvalue', $this->config['b8']['database']['servers']['read']); @@ -132,29 +161,33 @@ class InstallCommandTest extends ProphecyTestCase public function testDatabaseNameConfig() { - // We specified an input value for hostname. - $this->dialog->expects($this->once())->method('ask')->willReturn('testedvalue'); - $this->dialog->expects($this->never())->method('askConfirmation'); - $this->dialog->expects($this->never())->method('askAndValidate'); - $this->dialog->expects($this->never())->method('askHiddenResponse'); - $this->dialog->expects($this->never())->method('askHiddenResponseAndValidate'); + $dialog = $this->getDialogHelperMock(); - $this->executeWithoutParam('--db-name'); + // We specified an input value for hostname. + $dialog->expects($this->once())->method('ask')->willReturn('testedvalue'); + $dialog->expects($this->never())->method('askConfirmation'); + $dialog->expects($this->never())->method('askAndValidate'); + $dialog->expects($this->never())->method('askHiddenResponse'); + $dialog->expects($this->never())->method('askHiddenResponseAndValidate'); + + $this->executeWithoutParam('--db-name', $dialog); // Check that specified arguments are correctly loaded. $this->assertEquals('testedvalue', $this->config['b8']['database']['name']); } - public function testDatabaseUserameConfig() + public function testDatabaseUserConfig() { - // We specified an input value for hostname. - $this->dialog->expects($this->once())->method('ask')->willReturn('testedvalue'); - $this->dialog->expects($this->never())->method('askConfirmation'); - $this->dialog->expects($this->never())->method('askAndValidate'); - $this->dialog->expects($this->never())->method('askHiddenResponse'); - $this->dialog->expects($this->never())->method('askHiddenResponseAndValidate'); + $dialog = $this->getDialogHelperMock(); - $this->executeWithoutParam('--db-user'); + // We specified an input value for hostname. + $dialog->expects($this->once())->method('ask')->willReturn('testedvalue'); + $dialog->expects($this->never())->method('askConfirmation'); + $dialog->expects($this->never())->method('askAndValidate'); + $dialog->expects($this->never())->method('askHiddenResponse'); + $dialog->expects($this->never())->method('askHiddenResponseAndValidate'); + + $this->executeWithoutParam('--db-user', $dialog); // Check that specified arguments are correctly loaded. $this->assertEquals('testedvalue', $this->config['b8']['database']['username']); @@ -162,14 +195,16 @@ class InstallCommandTest extends ProphecyTestCase public function testDatabasePasswordConfig() { - // We specified an input value for hostname. - $this->dialog->expects($this->never())->method('ask'); - $this->dialog->expects($this->never())->method('askConfirmation'); - $this->dialog->expects($this->never())->method('askAndValidate'); - $this->dialog->expects($this->once())->method('askHiddenResponse')->willReturn('testedvalue'); - $this->dialog->expects($this->never())->method('askHiddenResponseAndValidate'); + $dialog = $this->getDialogHelperMock(); - $this->executeWithoutParam('--db-pass'); + // We specified an input value for hostname. + $dialog->expects($this->never())->method('ask'); + $dialog->expects($this->never())->method('askConfirmation'); + $dialog->expects($this->never())->method('askAndValidate'); + $dialog->expects($this->once())->method('askHiddenResponse')->willReturn('testedvalue'); + $dialog->expects($this->never())->method('askHiddenResponseAndValidate'); + + $this->executeWithoutParam('--db-pass', $dialog); // Check that specified arguments are correctly loaded. $this->assertEquals('testedvalue', $this->config['b8']['database']['password']); @@ -177,14 +212,16 @@ class InstallCommandTest extends ProphecyTestCase public function testPhpciUrlConfig() { - // We specified an input value for hostname. - $this->dialog->expects($this->never())->method('ask'); - $this->dialog->expects($this->never())->method('askConfirmation'); - $this->dialog->expects($this->once())->method('askAndValidate')->willReturn('http://testedvalue.com'); - $this->dialog->expects($this->never())->method('askHiddenResponse'); - $this->dialog->expects($this->never())->method('askHiddenResponseAndValidate'); + $dialog = $this->getDialogHelperMock(); - $this->executeWithoutParam('--url'); + // We specified an input value for hostname. + $dialog->expects($this->never())->method('ask'); + $dialog->expects($this->never())->method('askConfirmation'); + $dialog->expects($this->once())->method('askAndValidate')->willReturn('http://testedvalue.com'); + $dialog->expects($this->never())->method('askHiddenResponse'); + $dialog->expects($this->never())->method('askHiddenResponseAndValidate'); + + $this->executeWithoutParam('--url', $dialog); // Check that specified arguments are correctly loaded. $this->assertEquals('http://testedvalue.com', $this->config['phpci']['url']); @@ -192,29 +229,33 @@ class InstallCommandTest extends ProphecyTestCase public function testAdminEmailConfig() { - // We specified an input value for hostname. - $this->dialog->expects($this->never())->method('ask'); - $this->dialog->expects($this->never())->method('askConfirmation'); - $this->dialog->expects($this->once())->method('askAndValidate')->willReturn('test@phpci.com'); - $this->dialog->expects($this->never())->method('askHiddenResponse'); - $this->dialog->expects($this->never())->method('askHiddenResponseAndValidate'); + $dialog = $this->getDialogHelperMock(); - $this->executeWithoutParam('--admin-mail'); + // We specified an input value for hostname. + $dialog->expects($this->never())->method('ask'); + $dialog->expects($this->never())->method('askConfirmation'); + $dialog->expects($this->once())->method('askAndValidate')->willReturn('test@phpci.com'); + $dialog->expects($this->never())->method('askHiddenResponse'); + $dialog->expects($this->never())->method('askHiddenResponseAndValidate'); + + $this->executeWithoutParam('--admin-mail', $dialog); // Check that specified arguments are correctly loaded. $this->assertEquals('test@phpci.com', $this->admin['mail']); } - public function testAdminUserameConfig() + public function testAdminNameConfig() { - // Define expectation for dialog. - $this->dialog->expects($this->once())->method('ask')->willReturn('testedvalue'); - $this->dialog->expects($this->never())->method('askConfirmation'); - $this->dialog->expects($this->never())->method('askAndValidate'); - $this->dialog->expects($this->never())->method('askHiddenResponse'); - $this->dialog->expects($this->never())->method('askHiddenResponseAndValidate'); + $dialog = $this->getDialogHelperMock(); - $this->executeWithoutParam('--admin-name'); + // Define expectation for dialog. + $dialog->expects($this->once())->method('ask')->willReturn('testedvalue'); + $dialog->expects($this->never())->method('askConfirmation'); + $dialog->expects($this->never())->method('askAndValidate'); + $dialog->expects($this->never())->method('askHiddenResponse'); + $dialog->expects($this->never())->method('askHiddenResponseAndValidate'); + + $this->executeWithoutParam('--admin-name', $dialog); // Check that specified arguments are correctly loaded. $this->assertEquals('testedvalue', $this->admin['name']); @@ -222,14 +263,16 @@ class InstallCommandTest extends ProphecyTestCase public function testAdminPasswordConfig() { - // We specified an input value for hostname. - $this->dialog->expects($this->never())->method('ask'); - $this->dialog->expects($this->never())->method('askConfirmation'); - $this->dialog->expects($this->never())->method('askAndValidate'); - $this->dialog->expects($this->once())->method('askHiddenResponse')->willReturn('testedvalue'); - $this->dialog->expects($this->never())->method('askHiddenResponseAndValidate'); + $dialog = $this->getDialogHelperMock(); - $this->executeWithoutParam('--admin-pass'); + // We specified an input value for hostname. + $dialog->expects($this->never())->method('ask'); + $dialog->expects($this->never())->method('askConfirmation'); + $dialog->expects($this->never())->method('askAndValidate'); + $dialog->expects($this->once())->method('askHiddenResponse')->willReturn('testedvalue'); + $dialog->expects($this->never())->method('askHiddenResponseAndValidate'); + + $this->executeWithoutParam('--admin-pass', $dialog); // Check that specified arguments are correctly loaded. $this->assertEquals('testedvalue', $this->admin['pass']); diff --git a/Tests/PHPCI/Controller/WebhookControllerTest.php b/Tests/PHPCI/Controller/WebhookControllerTest.php new file mode 100644 index 00000000..b3b31e42 --- /dev/null +++ b/Tests/PHPCI/Controller/WebhookControllerTest.php @@ -0,0 +1,41 @@ +prophesize('b8\Config')->reveal(), + $this->prophesize('b8\Http\Request')->reveal(), + $this->prophesize('b8\Http\Response')->reveal() + ); + + $error = $webController->handleAction('test', []); + + $this->assertInstanceOf('b8\Http\Response\JsonResponse', $error); + + $responseData = $error->getData(); + $this->assertEquals(500, $responseData['code']); + + $this->assertEquals('failed', $responseData['body']['status']); + + $this->assertEquals('application/json', $responseData['headers']['Content-Type']); + + // @todo: we can't text the result is JSON file with + // $this->assertJson((string) $error); + // since the flush method automatically add the header and break the + // testing framework. + } +} diff --git a/Tests/PHPCI/Helper/AnsiConverterTest.php b/Tests/PHPCI/Helper/AnsiConverterTest.php new file mode 100644 index 00000000..09930d12 --- /dev/null +++ b/Tests/PHPCI/Helper/AnsiConverterTest.php @@ -0,0 +1,35 @@ +markTestSkipped('External library do not support PHP 5.3'); + } + } + + public function testConvert_convertToHtml() + { + $input = "\e[31mThis is red !\e[0m"; + + $expectedOutput = 'This is red !'; + + $actualOutput = AnsiConverter::convert($input); + + $this->assertEquals($expectedOutput, $actualOutput); + } +} diff --git a/Tests/PHPCI/Helper/BuildInterpolatorTest.php b/Tests/PHPCI/Helper/BuildInterpolatorTest.php index c45e1b8c..8961b2d8 100644 --- a/Tests/PHPCI/Helper/BuildInterpolatorTest.php +++ b/Tests/PHPCI/Helper/BuildInterpolatorTest.php @@ -1,11 +1,18 @@ assertEquals($expectedOutput, $actualOutput); } } - \ No newline at end of file + diff --git a/Tests/PHPCI/Helper/CommandExecutorTest.php b/Tests/PHPCI/Helper/CommandExecutorTest.php index 8ae045dc..5d5dc08b 100644 --- a/Tests/PHPCI/Helper/CommandExecutorTest.php +++ b/Tests/PHPCI/Helper/CommandExecutorTest.php @@ -1,11 +1,18 @@ markTestSkipped("Cannot test UnixCommandExecutor on ".PHP_OS); + return; + } parent::setUp(); $mockBuildLogger = $this->prophesize('PHPCI\Logging\BuildLogger'); - $this->testedExecutor = new UnixCommandExecutor($mockBuildLogger->reveal(), __DIR__ . "/"); + $class = IS_WIN ? 'PHPCI\Helper\WindowsCommandExecutor' : 'PHPCI\Helper\UnixCommandExecutor'; + $this->testedExecutor = new $class($mockBuildLogger->reveal(), __DIR__ . "/"); } public function testGetLastOutput_ReturnsOutputOfCommand() @@ -52,4 +64,20 @@ class CommandExecutorTest extends ProphecyTestCase $returnValue = $this->testedExecutor->findBinary($thisFileName); $this->assertEquals(__DIR__ . "/" . $thisFileName, $returnValue); } -} \ No newline at end of file + + /** + * @expectedException \Exception + * @expectedMessageRegex WorldWidePeace + */ + public function testFindBinary_ThrowsWhenNotFound() + { + $thisFileName = "WorldWidePeace"; + $this->testedExecutor->findBinary($thisFileName); + } + + public function testFindBinary_ReturnsNullWihQuietArgument() + { + $thisFileName = "WorldWidePeace"; + $this->assertNull($this->testedExecutor->findBinary($thisFileName, true)); + } +} diff --git a/Tests/PHPCI/Helper/LangTest.php b/Tests/PHPCI/Helper/LangTest.php new file mode 100644 index 00000000..b71ee41d --- /dev/null +++ b/Tests/PHPCI/Helper/LangTest.php @@ -0,0 +1,35 @@ +prophesize('DateTime'); + $dateTime->format(DateTime::ISO8601)->willReturn("ISODATE"); + $dateTime->format(DateTime::RFC2822)->willReturn("RFCDATE"); + + $this->assertEquals('', Lang::formatDateTime($dateTime->reveal(), 'FORMAT')); + } + + public function testLang_UseDefaultFormat() + { + $dateTime = $this->prophesize('DateTime'); + $dateTime->format(DateTime::ISO8601)->willReturn("ISODATE"); + $dateTime->format(DateTime::RFC2822)->willReturn("RFCDATE"); + + $this->assertEquals('', Lang::formatDateTime($dateTime->reveal())); + } +} diff --git a/Tests/PHPCI/Helper/MailerFactoryTest.php b/Tests/PHPCI/Helper/MailerFactoryTest.php index d4140c55..d59685d1 100644 --- a/Tests/PHPCI/Helper/MailerFactoryTest.php +++ b/Tests/PHPCI/Helper/MailerFactoryTest.php @@ -1,13 +1,14 @@ testedBuildLogger->logFailure($message, $exception); } } - \ No newline at end of file + diff --git a/Tests/PHPCI/Logging/LoggerConfigTest.php b/Tests/PHPCI/Logging/LoggerConfigTest.php index f1e78245..7fb95ef8 100644 --- a/Tests/PHPCI/Logging/LoggerConfigTest.php +++ b/Tests/PHPCI/Logging/LoggerConfigTest.php @@ -1,6 +1,14 @@ assertSame($expectedHandler, $actualHandler); $this->assertNotSame($alternativeHandler, $actualHandler); } + + public function testGetFor_SameInstance() + { + $config = new LoggerConfig(array()); + + $logger1 = $config->getFor("something"); + $logger2 = $config->getFor("something"); + + $this->assertSame($logger1, $logger2); + } } - \ No newline at end of file diff --git a/Tests/PHPCI/Model/BuildTest.php b/Tests/PHPCI/Model/BuildTest.php index b8ee3432..24508fe7 100644 --- a/Tests/PHPCI/Model/BuildTest.php +++ b/Tests/PHPCI/Model/BuildTest.php @@ -1,13 +1,15 @@ message = array(); + $this->mailDelivered = true; + $self = $this; + + $this->mockProject = $this->getMock( + '\PHPCI\Model\Project', + array('getTitle'), + array(), + "mockProject", + false + ); + + $this->mockProject->expects($this->any()) + ->method('getTitle') + ->will($this->returnValue("Test-Project")); + $this->mockBuild = $this->getMock( '\PHPCI\Model\Build', - array('getLog', 'getStatus'), + array('getLog', 'getStatus', 'getProject', 'getCommitterEmail'), array(), "mockBuild", false @@ -55,13 +87,22 @@ class EmailTest extends \PHPUnit_Framework_TestCase $this->mockBuild->expects($this->any()) ->method('getStatus') - ->will($this->returnValue(\PHPCI\Model\Build::STATUS_SUCCESS)); + ->will($this->returnCallback(function () use ($self) { + return $self->buildStatus; + })); + + $this->mockBuild->expects($this->any()) + ->method('getProject') + ->will($this->returnValue($this->mockProject)); + + $this->mockBuild->expects($this->any()) + ->method('getCommitterEmail') + ->will($this->returnValue('committer-email@example.com')); $this->mockCiBuilder = $this->getMock( '\PHPCI\Builder', array( 'getSystemConfig', - 'getBuildProjectTitle', 'getBuild', 'log' ), @@ -84,40 +125,54 @@ class EmailTest extends \PHPUnit_Framework_TestCase ) ) ); - $this->mockCiBuilder->expects($this->any()) - ->method('getBuildProjectTitle') - ->will($this->returnValue('Test-Project')); - $this->mockCiBuilder->expects($this->any()) - ->method('getBuild') - ->will($this->returnValue($this->mockBuild)); - - $this->mockMailer = $this->getMock( - '\Swift_Mailer', - array('send'), - array(), - "mockMailer", - false - ); - - $this->loadEmailPluginWithOptions(); } - protected function loadEmailPluginWithOptions($arrOptions = array()) + protected function loadEmailPluginWithOptions($arrOptions = array(), $buildStatus = null, $mailDelivered = true) { - $this->testedEmailPlugin = new EmailPlugin( - $this->mockCiBuilder, - $this->mockBuild, - $this->mockMailer, - $arrOptions + $this->mailDelivered = $mailDelivered; + + if (is_null($buildStatus)) { + $this->buildStatus = Build::STATUS_SUCCESS; + } else { + $this->buildStatus = $buildStatus; + } + + // Reset current message. + $this->message = array(); + + $self = $this; + + $this->testedEmailPlugin = $this->getMock( + '\PHPCI\Plugin\Email', + array('sendEmail'), + array( + $this->mockCiBuilder, + $this->mockBuild, + $arrOptions + ) ); + + $this->testedEmailPlugin->expects($this->any()) + ->method('sendEmail') + ->will($this->returnCallback(function ($to, $cc, $subject, $body) use ($self) { + $self->message['to'][] = $to; + $self->message['cc'] = $cc; + $self->message['subject'] = $subject; + $self->message['body'] = $body; + + return $self->mailDelivered; + })); } /** * @covers PHPUnit::execute */ - public function testExecute_ReturnsFalseWithoutArgs() + public function testReturnsFalseWithoutArgs() { + $this->loadEmailPluginWithOptions(); + $returnValue = $this->testedEmailPlugin->execute(); + // As no addresses will have been mailed as non are configured. $expectedReturn = false; @@ -127,146 +182,227 @@ class EmailTest extends \PHPUnit_Framework_TestCase /** * @covers PHPUnit::execute */ - public function testExecute_BuildsBasicEmails() + public function testBuildsBasicEmails() { $this->loadEmailPluginWithOptions( array( 'addresses' => array('test-receiver@example.com') + ), + Build::STATUS_SUCCESS + ); + + $this->testedEmailPlugin->execute(); + + $this->assertContains('test-receiver@example.com', $this->message['to']); + } + + /** + * @covers PHPUnit::execute + */ + public function testBuildsDefaultEmails() + { + $this->loadEmailPluginWithOptions( + array( + 'default_mailto_address' => 'default-mailto-address@example.com' + ), + Build::STATUS_SUCCESS + ); + + $this->testedEmailPlugin->execute(); + + $this->assertContains('default-mailto-address@example.com', $this->message['to']); + } + + /** + * @covers PHPUnit::execute + */ + public function testExecute_UniqueRecipientsFromWithCommitter() + { + $this->loadEmailPluginWithOptions( + array( + 'addresses' => array('test-receiver@example.com', 'test-receiver2@example.com') ) ); - /** @var \Swift_Message $actualMail */ - $actualMail = null; - $this->catchMailPassedToSend($actualMail); + $returnValue = $this->testedEmailPlugin->execute(); + $this->assertTrue($returnValue); + + $this->assertCount(2, $this->message['to']); + + $this->assertContains('test-receiver@example.com', $this->message['to']); + $this->assertContains('test-receiver2@example.com', $this->message['to']); + } + + /** + * @covers PHPUnit::execute + */ + public function testExecute_UniqueRecipientsWithCommitter() + { + $this->loadEmailPluginWithOptions( + array( + 'committer' => true, + 'addresses' => array('test-receiver@example.com', 'committer@test.com') + ) + ); $returnValue = $this->testedEmailPlugin->execute(); - $expectedReturn = true; + $this->assertTrue($returnValue); - $this->assertSystemMail( - 'test-receiver@example.com', - 'test-from-address@example.com', - "Log Output:
    Build Log
    ", - "PHPCI - Test-Project - Passing Build", - $actualMail + $this->assertContains('test-receiver@example.com', $this->message['to']); + $this->assertContains('committer@test.com', $this->message['to']); + } + + /** + * @covers PHPUnit::execute + */ + public function testCcDefaultEmails() + { + $this->loadEmailPluginWithOptions( + array( + 'default_mailto_address' => 'default-mailto-address@example.com', + 'cc' => array( + 'cc-email-1@example.com', + 'cc-email-2@example.com', + 'cc-email-3@example.com', + ), + ), + Build::STATUS_SUCCESS ); - $this->assertEquals($expectedReturn, $returnValue); - - - } - - /** - * @covers PHPUnit::sendEmail - */ - public function testSendEmail_CallsMailerSend() - { - $this->mockMailer->expects($this->once()) - ->method('send'); - $this->testedEmailPlugin->sendEmail("test@email.com", array(), "hello", "body"); - } - - /** - * @covers PHPUnit::sendEmail - */ - public function testSendEmail_BuildsAMessageObject() - { - $subject = "Test mail"; - $body = "Message Body"; - $toAddress = "test@example.com"; - - $this->mockMailer->expects($this->once()) - ->method('send') - ->with($this->isInstanceOf('\Swift_Message'), $this->anything()); - $this->testedEmailPlugin->sendEmail($toAddress, array(), $subject, $body); - } - - /** - * @covers PHPUnit::sendEmail - */ - public function testSendEmail_BuildsExpectedMessage() - { - $subject = "Test mail"; - $body = "Message Body"; - $toAddress = "test@example.com"; - $expectedMessage = \Swift_Message::newInstance($subject) - ->setFrom('test-from-address@example.com') - ->setTo($toAddress) - ->setBody($body); - - /** @var \Swift_Message $actualMail */ - $actualMail = null; - $this->catchMailPassedToSend($actualMail); - - $this->testedEmailPlugin->sendEmail($toAddress, array(), $subject, $body); - - $this->assertSystemMail( - $toAddress, - 'test-from-address@example.com', - $body, - $subject, - $actualMail - ); - } - - /** - * @param \Swift_Message $actualMail passed by ref and populated with - * the message object the mock mailer - * receives. - */ - protected function catchMailPassedToSend(&$actualMail) - { - $this->mockMailer->expects($this->once()) - ->method('send') - ->will( - $this->returnCallback( - function ($passedMail) use (&$actualMail) { - $actualMail = $passedMail; - return array(); - } - ) - ); - } - - /** - * Asserts that the actual mail object is populated as expected. - * - * @param string $expectedToAddress - * @param $expectedFromAddress - * @param string $expectedBody - * @param string $expectedSubject - * @param \Swift_Message $actualMail - */ - protected function assertSystemMail( - $expectedToAddress, - $expectedFromAddress, - $expectedBody, - $expectedSubject, - $actualMail - ) { - if (!($actualMail instanceof \Swift_Message)) { - $type = is_object($actualMail) ? get_class($actualMail) : gettype( - $actualMail - ); - throw new \Exception("Expected Swift_Message got " . $type); - } - $this->assertEquals( - array($expectedFromAddress => null), - $actualMail->getFrom() - ); + $this->testedEmailPlugin->execute(); $this->assertEquals( - array($expectedToAddress => null), - $actualMail->getTo() - ); - - $this->assertEquals( - $expectedBody, - $actualMail->getBody() - ); - - $this->assertEquals( - $expectedSubject, - $actualMail->getSubject() + array( + 'cc-email-1@example.com', + 'cc-email-2@example.com', + 'cc-email-3@example.com', + ), + $this->message['cc'] ); } -} \ No newline at end of file + + /** + * @covers PHPUnit::execute + */ + public function testBuildsCommitterEmails() + { + $this->loadEmailPluginWithOptions( + array( + 'committer' => true + ), + Build::STATUS_SUCCESS + ); + + $this->testedEmailPlugin->execute(); + + $this->assertContains('committer-email@example.com', $this->message['to']); + } + + /** + * @covers PHPUnit::execute + */ + public function testMailSuccessfulBuildHaveProjectName() + { + $this->loadEmailPluginWithOptions( + array( + 'addresses' => array('test-receiver@example.com') + ), + Build::STATUS_SUCCESS + ); + + $this->testedEmailPlugin->execute(); + + $this->assertContains('Test-Project', $this->message['subject']); + $this->assertContains('Test-Project', $this->message['body']); + } + + /** + * @covers PHPUnit::execute + */ + public function testMailFailingBuildHaveProjectName() + { + $this->loadEmailPluginWithOptions( + array( + 'addresses' => array('test-receiver@example.com') + ), + Build::STATUS_FAILED + ); + + $this->testedEmailPlugin->execute(); + + $this->assertContains('Test-Project', $this->message['subject']); + $this->assertContains('Test-Project', $this->message['body']); + } + + /** + * @covers PHPUnit::execute + */ + public function testMailSuccessfulBuildHaveStatus() + { + $this->loadEmailPluginWithOptions( + array( + 'addresses' => array('test-receiver@example.com') + ), + Build::STATUS_SUCCESS + ); + + $this->testedEmailPlugin->execute(); + + $this->assertContains('Passing', $this->message['subject']); + $this->assertContains('successful', $this->message['body']); + } + + /** + * @covers PHPUnit::execute + */ + public function testMailFailingBuildHaveStatus() + { + $this->loadEmailPluginWithOptions( + array( + 'addresses' => array('test-receiver@example.com') + ), + Build::STATUS_FAILED + ); + + $this->testedEmailPlugin->execute(); + + $this->assertContains('Failing', $this->message['subject']); + $this->assertContains('failed', $this->message['body']); + } + + /** + * @covers PHPUnit::execute + */ + public function testMailDeliverySuccess() + { + $this->loadEmailPluginWithOptions( + array( + 'addresses' => array('test-receiver@example.com') + ), + Build::STATUS_FAILED, + true + ); + + $returnValue = $this->testedEmailPlugin->execute(); + + $this->assertEquals(true, $returnValue); + } + + /** + * @covers PHPUnit::execute + */ + public function testMailDeliveryFail() + { + $this->loadEmailPluginWithOptions( + array( + 'addresses' => array('test-receiver@example.com') + ), + Build::STATUS_FAILED, + false + ); + + $returnValue = $this->testedEmailPlugin->execute(); + + $this->assertEquals(false, $returnValue); + } +} diff --git a/Tests/PHPCI/Plugin/PharTest.php b/Tests/PHPCI/Plugin/PharTest.php index 69f63a6a..edb17d69 100644 --- a/Tests/PHPCI/Plugin/PharTest.php +++ b/Tests/PHPCI/Plugin/PharTest.php @@ -1,5 +1,14 @@ markTestSkipped(); - throw new RuntimeException('Readonly Phar'); + $this->markTestSkipped('phar writing disabled in php.ini.'); } } diff --git a/Tests/PHPCI/Plugin/Util/ComposerPluginInformationTest.php b/Tests/PHPCI/Plugin/Util/ComposerPluginInformationTest.php index 113c1087..1174d44f 100644 --- a/Tests/PHPCI/Plugin/Util/ComposerPluginInformationTest.php +++ b/Tests/PHPCI/Plugin/Util/ComposerPluginInformationTest.php @@ -1,6 +1,14 @@ assertContainsOnly("string", $classes); } } - \ No newline at end of file + diff --git a/Tests/PHPCI/Plugin/Util/ExamplePluginConfig.php b/Tests/PHPCI/Plugin/Util/ExamplePluginConfig.php index 0b883071..5b0819c4 100644 --- a/Tests/PHPCI/Plugin/Util/ExamplePluginConfig.php +++ b/Tests/PHPCI/Plugin/Util/ExamplePluginConfig.php @@ -1,4 +1,13 @@ registerResource( // This function will be called when the resource is needed. @@ -10,4 +19,4 @@ return function (PHPCI\Plugin\Util\Factory $factory) { "requiredArgument", null ); -}; \ No newline at end of file +}; diff --git a/Tests/PHPCI/Plugin/Util/ExamplePlugins.php b/Tests/PHPCI/Plugin/Util/ExamplePlugins.php deleted file mode 100644 index bc67bd3f..00000000 --- a/Tests/PHPCI/Plugin/Util/ExamplePlugins.php +++ /dev/null @@ -1,78 +0,0 @@ -RequiredArgument = $requiredArgument; - } - - public function execute() - { - - } -} - -class ExamplePluginWithSingleTypedRequiredArg implements Plugin -{ - - public $RequiredArgument; - - function __construct(\stdClass $requiredArgument) - { - $this->RequiredArgument = $requiredArgument; - } - - public function execute() - { - - } -} - -class ExamplePluginFull implements Plugin { - - public $Options; - - public function __construct( - Builder $phpci, - Build $build, - array $options = array() - ) - { - $this->Options = $options; - } - - public function execute() - { - - } - -} \ No newline at end of file diff --git a/Tests/PHPCI/Plugin/Util/ExecutorTest.php b/Tests/PHPCI/Plugin/Util/ExecutorTest.php index 2bcc7780..e9083cec 100644 --- a/Tests/PHPCI/Plugin/Util/ExecutorTest.php +++ b/Tests/PHPCI/Plugin/Util/ExecutorTest.php @@ -1,14 +1,19 @@ mockBuildLogger = $this->prophesize('\PHPCI\Logging\BuildLogger'); $this->mockFactory = $this->prophesize('\PHPCI\Plugin\Util\Factory'); - $this->testedExecutor = new Executor($this->mockFactory->reveal(), $this->mockBuildLogger->reveal()); + $this->mockStore = $this->prophesize('\PHPCI\Store\BuildStore'); + $this->testedExecutor = new Executor( + $this->mockFactory->reveal(), + $this->mockBuildLogger->reveal(), + $this->mockStore->reveal() + ); } public function testExecutePlugin_AssumesPHPCINamespaceIfNoneGiven() @@ -43,25 +55,26 @@ class ExecutorTest extends ProphecyTestCase public function testExecutePlugin_KeepsCalledNameSpace() { $options = array(); - $pluginName = 'ExamplePluginFull'; - $pluginNamespace = '\\PHPCI\\Plugin\\Tests\\Util\\'; + $pluginClass = $this->getFakePluginClassName('ExamplePluginFull'); - $this->mockFactory->buildPlugin($pluginNamespace . $pluginName, $options) + $this->mockFactory->buildPlugin($pluginClass, $options) ->shouldBeCalledTimes(1) ->willReturn($this->prophesize('PHPCI\Plugin')->reveal()); - $this->testedExecutor->executePlugin($pluginNamespace . $pluginName, $options); + $this->testedExecutor->executePlugin($pluginClass, $options); } public function testExecutePlugin_CallsExecuteOnFactoryBuildPlugin() { $options = array(); $pluginName = 'PhpUnit'; + $build = new \PHPCI\Model\Build(); $mockPlugin = $this->prophesize('PHPCI\Plugin'); $mockPlugin->execute()->shouldBeCalledTimes(1); $this->mockFactory->buildPlugin(Argument::any(), Argument::any())->willReturn($mockPlugin->reveal()); + $this->mockFactory->getResourceFor('PHPCI\Model\Build')->willReturn($build); $this->testedExecutor->executePlugin($pluginName, $options); } @@ -115,6 +128,7 @@ class ExecutorTest extends ProphecyTestCase { $phpUnitPluginOptions = array(); $behatPluginOptions = array(); + $build = new \PHPCI\Model\Build(); $config = array( 'stageOne' => array( @@ -130,7 +144,7 @@ class ExecutorTest extends ProphecyTestCase $this->mockFactory->buildPlugin($pluginNamespace . 'PhpUnit', $phpUnitPluginOptions) ->willReturn($mockPhpUnitPlugin->reveal()); - + $this->mockFactory->getResourceFor('PHPCI\Model\Build')->willReturn($build); $mockBehatPlugin = $this->prophesize('PHPCI\Plugin'); $mockBehatPlugin->execute()->shouldBeCalledTimes(1)->willReturn(true); @@ -138,9 +152,14 @@ class ExecutorTest extends ProphecyTestCase $this->mockFactory->buildPlugin($pluginNamespace . 'Behat', $behatPluginOptions) ->willReturn($mockBehatPlugin->reveal()); - $this->testedExecutor->executePlugins($config, 'stageOne'); } + protected function getFakePluginClassName($pluginName) + { + $pluginNamespace = '\\Tests\\PHPCI\\Plugin\\Util\\Fake\\'; + + return $pluginNamespace . $pluginName; + } } - \ No newline at end of file + diff --git a/Tests/PHPCI/Plugin/Util/FactoryTest.php b/Tests/PHPCI/Plugin/Util/FactoryTest.php index 72ed714b..e609011a 100644 --- a/Tests/PHPCI/Plugin/Util/FactoryTest.php +++ b/Tests/PHPCI/Plugin/Util/FactoryTest.php @@ -1,8 +1,14 @@ testedFactory->buildPlugin($expectedPluginClass); - $this->assertInstanceOf($expectedPluginClass, $plugin); + $pluginClass = $this->getFakePluginClassName('ExamplePluginWithNoConstructorArgs'); + $plugin = $this->testedFactory->buildPlugin($pluginClass); + $this->assertInstanceOf($pluginClass, $plugin); } public function testBuildPluginFailsForNonPluginClasses() @@ -63,10 +68,9 @@ class FactoryTest extends \PHPUnit_Framework_TestCase { public function testBuildPluginWorksWithSingleOptionalArgConstructor() { - $namespace = '\\PHPCI\\Plugin\\Tests\\Util\\'; - $expectedPluginClass = $namespace . 'ExamplePluginWithSingleOptionalArg'; - $plugin = $this->testedFactory->buildPlugin($expectedPluginClass); - $this->assertInstanceOf($expectedPluginClass, $plugin); + $pluginClass = $this->getFakePluginClassName('ExamplePluginWithSingleOptionalArg'); + $plugin = $this->testedFactory->buildPlugin($pluginClass); + $this->assertInstanceOf($pluginClass, $plugin); } public function testBuildPluginThrowsExceptionIfMissingResourcesForRequiredArg() @@ -76,15 +80,13 @@ class FactoryTest extends \PHPUnit_Framework_TestCase { 'Unsatisfied dependency: requiredArgument' ); - $namespace = '\\PHPCI\\Plugin\\Tests\\Util\\'; - $expectedPluginClass = $namespace . 'ExamplePluginWithSingleRequiredArg'; - $plugin = $this->testedFactory->buildPlugin($expectedPluginClass); + $pluginClass = $this->getFakePluginClassName('ExamplePluginWithSingleRequiredArg'); + $plugin = $this->testedFactory->buildPlugin($pluginClass); } public function testBuildPluginLoadsArgumentsBasedOnName() { - $namespace = '\\PHPCI\\Plugin\\Tests\\Util\\'; - $expectedPluginClass = $namespace . 'ExamplePluginWithSingleRequiredArg'; + $pluginClass = $this->getFakePluginClassName('ExamplePluginWithSingleRequiredArg'); $this->testedFactory->registerResource( $this->resourceLoader, @@ -92,15 +94,14 @@ class FactoryTest extends \PHPUnit_Framework_TestCase { ); /** @var ExamplePluginWithSingleRequiredArg $plugin */ - $plugin = $this->testedFactory->buildPlugin($expectedPluginClass); + $plugin = $this->testedFactory->buildPlugin($pluginClass); $this->assertEquals($this->expectedResource, $plugin->RequiredArgument); } public function testBuildPluginLoadsArgumentsBasedOnType() { - $namespace = '\\PHPCI\\Plugin\\Tests\\Util\\'; - $expectedPluginClass = $namespace . 'ExamplePluginWithSingleTypedRequiredArg'; + $pluginClass = $this->getFakePluginClassName('ExamplePluginWithSingleTypedRequiredArg'); $this->testedFactory->registerResource( $this->resourceLoader, @@ -109,28 +110,26 @@ class FactoryTest extends \PHPUnit_Framework_TestCase { ); /** @var ExamplePluginWithSingleTypedRequiredArg $plugin */ - $plugin = $this->testedFactory->buildPlugin($expectedPluginClass); + $plugin = $this->testedFactory->buildPlugin($pluginClass); $this->assertEquals($this->expectedResource, $plugin->RequiredArgument); } public function testBuildPluginLoadsFullExample() { - $namespace = '\\PHPCI\\Plugin\\Tests\\Util\\'; - $expectedPluginClass = $namespace . 'ExamplePluginFull'; + $pluginClass = $this->getFakePluginClassName('ExamplePluginFull'); $this->registerBuildAndBuilder(); /** @var ExamplePluginFull $plugin */ - $plugin = $this->testedFactory->buildPlugin($expectedPluginClass); + $plugin = $this->testedFactory->buildPlugin($pluginClass); - $this->assertInstanceOf($expectedPluginClass, $plugin); + $this->assertInstanceOf($pluginClass, $plugin); } public function testBuildPluginLoadsFullExampleWithOptions() { - $namespace = '\\PHPCI\\Plugin\\Tests\\Util\\'; - $expectedPluginClass = $namespace . 'ExamplePluginFull'; + $pluginClass = $this->getFakePluginClassName('ExamplePluginFull'); $expectedArgs = array( 'thing' => "stuff" @@ -140,7 +139,7 @@ class FactoryTest extends \PHPUnit_Framework_TestCase { /** @var ExamplePluginFull $plugin */ $plugin = $this->testedFactory->buildPlugin( - $expectedPluginClass, + $pluginClass, $expectedArgs ); @@ -163,10 +162,8 @@ class FactoryTest extends \PHPUnit_Framework_TestCase { realpath(__DIR__ . "/ExamplePluginConfig.php") ); - $namespace = '\\PHPCI\\Plugin\\Tests\\Util\\'; - $pluginName = $namespace . 'ExamplePluginWithSingleRequiredArg'; - - $plugin = $this->testedFactory->buildPlugin($pluginName); + $pluginClass = $this->getFakePluginClassName('ExamplePluginWithSingleRequiredArg'); + $plugin = $this->testedFactory->buildPlugin($pluginClass); // The Example config file defines an array as the resource. $this->assertEquals( @@ -181,9 +178,11 @@ class FactoryTest extends \PHPUnit_Framework_TestCase { */ private function registerBuildAndBuilder() { + $self = $this; + $this->testedFactory->registerResource( - function () { - return $this->getMock( + function () use ($self) { + return $self->getMock( 'PHPCI\Builder', array(), array(), @@ -196,8 +195,8 @@ class FactoryTest extends \PHPUnit_Framework_TestCase { ); $this->testedFactory->registerResource( - function () { - return $this->getMock( + function () use ($self) { + return $self->getMock( 'PHPCI\Model\Build', array(), array(), @@ -206,8 +205,15 @@ class FactoryTest extends \PHPUnit_Framework_TestCase { ); }, null, - 'PHPCI\\Model\Build' + 'PHPCI\\Model\\Build' ); } + + protected function getFakePluginClassName($pluginName) + { + $pluginNamespace = '\\Tests\\PHPCI\\Plugin\\Util\\Fake\\'; + + return $pluginNamespace . $pluginName; + } } - \ No newline at end of file + diff --git a/Tests/PHPCI/Plugin/Util/Fake/ExamplePluginFull.php b/Tests/PHPCI/Plugin/Util/Fake/ExamplePluginFull.php new file mode 100644 index 00000000..fa81a352 --- /dev/null +++ b/Tests/PHPCI/Plugin/Util/Fake/ExamplePluginFull.php @@ -0,0 +1,36 @@ +Options = $options; + } + + public function execute() + { + + } +} diff --git a/Tests/PHPCI/Plugin/Util/Fake/ExamplePluginWithNoConstructorArgs.php b/Tests/PHPCI/Plugin/Util/Fake/ExamplePluginWithNoConstructorArgs.php new file mode 100644 index 00000000..544ec4e3 --- /dev/null +++ b/Tests/PHPCI/Plugin/Util/Fake/ExamplePluginWithNoConstructorArgs.php @@ -0,0 +1,20 @@ +RequiredArgument = $requiredArgument; + } + + public function execute() + { + + } +} diff --git a/Tests/PHPCI/Plugin/Util/Fake/ExamplePluginWithSingleTypedRequiredArg.php b/Tests/PHPCI/Plugin/Util/Fake/ExamplePluginWithSingleTypedRequiredArg.php new file mode 100644 index 00000000..b256c58c --- /dev/null +++ b/Tests/PHPCI/Plugin/Util/Fake/ExamplePluginWithSingleTypedRequiredArg.php @@ -0,0 +1,29 @@ +RequiredArgument = $requiredArgument; + } + + public function execute() + { + + } +} diff --git a/Tests/PHPCI/Plugin/Util/FilesPluginInformationTest.php b/Tests/PHPCI/Plugin/Util/FilesPluginInformationTest.php index 6e1605ab..4af2d7a6 100644 --- a/Tests/PHPCI/Plugin/Util/FilesPluginInformationTest.php +++ b/Tests/PHPCI/Plugin/Util/FilesPluginInformationTest.php @@ -1,13 +1,21 @@ assertContainsOnly('string', $pluginInfos); } } - \ No newline at end of file + diff --git a/Tests/PHPCI/Plugin/Util/TapParserTest.php b/Tests/PHPCI/Plugin/Util/TapParserTest.php index c4438b79..8d31d7c9 100644 --- a/Tests/PHPCI/Plugin/Util/TapParserTest.php +++ b/Tests/PHPCI/Plugin/Util/TapParserTest.php @@ -1,26 +1,303 @@ parse(); + + $this->assertEquals(array( + array('pass' => true, 'severity' => 'success', 'message' => 'SomeTest::testAnother'), + array('pass' => false, 'severity' => 'fail', 'message' => ''), + ), $result); + + $this->assertEquals(1, $parser->getTotalFailures()); + } + + public function testSimple2() + { + $content = <<parse(); + + $this->assertEquals(array( + array('pass' => true, 'severity' => 'success', 'message' => 'SomeTest::testAnother'), + array('pass' => false, 'severity' => 'fail', 'message' => ''), + ), $result); + + $this->assertEquals(1, $parser->getTotalFailures()); + } + + /** + * @expectedException \Exception + * @expectedExceptionMessageRegExp /No TAP/ + */ + public function testNoTapData() + { + $content = <<parse(); + } + + public function testTapCoverage() + { + $content = <<parse(); + + $this->assertEquals(array(), $result); + } + + /** + * @expectedException \Exception + * @expectedExceptionMessageRegExp /Duplicated TAP/ + */ + public function testDuplicateOutput() + { + $content = <<parse(); + } + + public function testSuiteAndTest() { $content = <<parse(); + + $this->assertEquals(array( + array('pass' => true, 'severity' => 'success', 'message' => 'SomeTest::testAnother',), + array('pass' => false, 'severity' => 'fail', 'message' => 'Failure: SomeTest::testAnother'), + array('pass' => false, 'severity' => 'error', 'message' => 'Error: SomeTest::testAnother'), + ), $result); + + $this->assertEquals(2, $parser->getTotalFailures()); + } + + + public function testSkipped() + { + $content = <<parse(); + + $this->assertEquals(array( + array('pass' => true, 'severity' => 'skipped', 'message' => ''), + array('pass' => true, 'severity' => 'skipped', 'message' => 'foobar'), + array('pass' => true, 'severity' => 'skipped', 'message' => 'foo, skipped: bar'), + ), $result); + + $this->assertEquals(0, $parser->getTotalFailures()); + } + + public function testTodo() + { + $content = <<parse(); + + $this->assertEquals(array( + array('pass' => true, 'severity' => 'todo', 'message' => 'SomeTest::testAnother, todo: really implement this test'), + array('pass' => true, 'severity' => 'todo', 'message' => 'really implement this test'), + array('pass' => true, 'severity' => 'todo', 'message' => 'this is a message, todo: really implement this test'), + array('pass' => true, 'severity' => 'todo', 'message' => ''), + ), $result); + + $this->assertEquals(0, $parser->getTotalFailures()); + } + + public function testYamlDiagnostic() + { + // From https://phpunit.de/manual/current/en/logging.html#logging.tap + $content = <<parse(); + + $this->assertEquals(array( + array( + 'pass' => false, + 'severity' => 'fail', + 'message' => 'FOO' . PHP_EOL . 'BAR', + ), + ), $result); + + $this->assertEquals(1, $parser->getTotalFailures()); + } + + public function testFailureAndError() + { + // From https://phpunit.de/manual/current/en/logging.html#logging.tap + $content = <<parse(); $this->assertEquals(array( - array('pass' => true, 'suite' => 'SomeTest', 'test' => 'testAnother'), - array('message' => 'SKIP'), + array( + 'pass' => false, + 'severity' => 'fail', + 'message' => 'Failure: testFailure::FailureErrorTest', + ), + array( + 'pass' => false, + 'severity' => 'error', + 'message' => 'Error: testError::FailureErrorTest', + ) ), $result); + $this->assertEquals(2, $parser->getTotalFailures()); + } + + /** + * @expectedException \Exception + */ + public function testGarbage() + { + $content = "Garbage !"; + + $parser = new TapParser($content); + $parser->parse(); + } + + /** + * @expectedException \Exception + */ + public function testInvalidTestCount() + { + $content = <<parse(); + } + + /** + * @expectedException \Exception + */ + public function testEndlessYaml() + { + $content = <<parse(); + } + + public function testCodeception() + { + $content = <<< TAP +TAP version 13 +ok 1 - try to access the dashboard as a guest (Auth/GuestAccessDashboardAndRedirectCept) +ok 2 - see the login page (Auth/SeeLoginCept) +ok 3 - click forgot password and see the email form (Auth/SeeLoginForgotPasswordCept) +ok 4 - see powered by runmybusiness branding (Auth/ShouldSeePoweredByBrandingCept) +ok 5 - submit invalid credentials (Auth/SubmitLoginAndFailCept) +ok 6 - submit valid credentials and see the dashboard (Auth/SubmitLoginAndSucceedCept) +1..6 +TAP; + + $parser = new TapParser($content); + $result = $parser->parse(); + + $this->assertEquals( + array( + array('pass' => true, 'severity' => 'success', 'message' => 'try to access the dashboard as a guest (Auth/GuestAccessDashboardAndRedirectCept)'), + array('pass' => true, 'severity' => 'success', 'message' => 'see the login page (Auth/SeeLoginCept)'), + array('pass' => true, 'severity' => 'success', 'message' => 'click forgot password and see the email form (Auth/SeeLoginForgotPasswordCept)'), + array('pass' => true, 'severity' => 'success', 'message' => 'see powered by runmybusiness branding (Auth/ShouldSeePoweredByBrandingCept)'), + array('pass' => true, 'severity' => 'success', 'message' => 'submit invalid credentials (Auth/SubmitLoginAndFailCept)'), + array('pass' => true, 'severity' => 'success', 'message' => 'submit valid credentials and see the dashboard (Auth/SubmitLoginAndSucceedCept)'), + ), + $result + ); + $this->assertEquals(0, $parser->getTotalFailures()); + } } diff --git a/Tests/PHPCI/ProcessControl/PosixProcessControlTest.php b/Tests/PHPCI/ProcessControl/PosixProcessControlTest.php new file mode 100644 index 00000000..96bbf5b4 --- /dev/null +++ b/Tests/PHPCI/ProcessControl/PosixProcessControlTest.php @@ -0,0 +1,17 @@ +object = new PosixProcessControl(); + } + + public function testIsAvailable() + { + $this->assertEquals(function_exists('posix_kill'), PosixProcessControl::isAvailable()); + } +} diff --git a/Tests/PHPCI/ProcessControl/ProcessControlTest.php b/Tests/PHPCI/ProcessControl/ProcessControlTest.php new file mode 100644 index 00000000..52022743 --- /dev/null +++ b/Tests/PHPCI/ProcessControl/ProcessControlTest.php @@ -0,0 +1,126 @@ +pipes = array(); + + $this->process = proc_open($this->getTestCommand(), $desc, $this->pipes); + usleep(500); + + $this->assertTrue(is_resource($this->process)); + $this->assertTrue($this->isRunning()); + + $status = proc_get_status($this->process); + return $status['pid']; + } + + /** End the running process. + * + * @return int + */ + protected function endProcess() + { + if (!is_resource($this->process)) { + return; + } + array_map('fclose', $this->pipes); + $exitCode = proc_close($this->process); + $this->assertFalse($this->isRunning()); + $this->process = null; + return $exitCode; + } + + /** + * @return bool + */ + protected function isRunning() + { + if (!is_resource($this->process)) { + return false; + } + $status = proc_get_status($this->process); + return $status['running']; + } + + public function testIsRunning() + { + if (!$this->object->isAvailable()) { + $this->markTestSkipped(); + } + + $pid = $this->startProcess(); + + $this->assertTrue($this->object->isRunning($pid)); + + fwrite($this->pipes[0], PHP_EOL); + + $exitCode = $this->endProcess(); + + $this->assertEquals(0, $exitCode); + $this->assertFalse($this->object->isRunning($pid)); + } + + public function testSoftKill() + { + if (!$this->object->isAvailable()) { + $this->markTestSkipped(); + } + + $pid = $this->startProcess(); + + $this->object->kill($pid); + usleep(500); + + $this->assertFalse($this->isRunning()); + } + + public function testForcefullyKill() + { + if (!$this->object->isAvailable()) { + $this->markTestSkipped(); + } + + $pid = $this->startProcess(); + + $this->object->kill($pid, true); + usleep(500); + + $this->assertFalse($this->isRunning()); + } + + abstract public function testIsAvailable(); + + abstract public function getTestCommand(); + + protected function tearDown() + { + parent::tearDown(); + $this->endProcess(); + } +} diff --git a/Tests/PHPCI/ProcessControl/UnixProcessControlTest.php b/Tests/PHPCI/ProcessControl/UnixProcessControlTest.php new file mode 100644 index 00000000..9b102a73 --- /dev/null +++ b/Tests/PHPCI/ProcessControl/UnixProcessControlTest.php @@ -0,0 +1,22 @@ +object = new UnixProcessControl(); + } + + public function getTestCommand() + { + return "read SOMETHING"; + } + + public function testIsAvailable() + { + $this->assertEquals(DIRECTORY_SEPARATOR === '/', UnixProcessControl::isAvailable()); + } +} diff --git a/Tests/PHPCI/ProcessControl/WindowsProcessControlTest.php b/Tests/PHPCI/ProcessControl/WindowsProcessControlTest.php new file mode 100644 index 00000000..ed10fc95 --- /dev/null +++ b/Tests/PHPCI/ProcessControl/WindowsProcessControlTest.php @@ -0,0 +1,22 @@ +object = new WindowsProcessControl; + } + + public function getTestCommand() + { + return "pause"; + } + + public function testIsAvailable() + { + $this->assertEquals(DIRECTORY_SEPARATOR === '\\', WindowsProcessControl::isAvailable()); + } +} diff --git a/Tests/PHPCI/Service/BuildServiceTest.php b/Tests/PHPCI/Service/BuildServiceTest.php index 9b1097a3..3c96b131 100644 --- a/Tests/PHPCI/Service/BuildServiceTest.php +++ b/Tests/PHPCI/Service/BuildServiceTest.php @@ -1,13 +1,14 @@ assertNull($returnValue->getStarted()); $this->assertNull($returnValue->getFinished()); $this->assertNull($returnValue->getLog()); - $this->assertNull($returnValue->getCommitMessage()); + $this->assertEquals(\PHPCI\Helper\Lang::get('manual_build'), $returnValue->getCommitMessage()); $this->assertNull($returnValue->getCommitterEmail()); $this->assertNull($returnValue->getExtra()); $this->assertEquals('master', $returnValue->getBranch()); @@ -102,7 +103,7 @@ class BuildServiceTest extends \PHPUnit_Framework_TestCase { $build = new Build(); $build->setId(1); - $build->setProjectId(101); + $build->setProject(101); $build->setCommitId('abcde'); $build->setStatus(Build::STATUS_FAILED); $build->setLog('Test'); diff --git a/Tests/PHPCI/Service/BuiltStatusServiceTest.php b/Tests/PHPCI/Service/BuiltStatusServiceTest.php new file mode 100644 index 00000000..91e115e4 --- /dev/null +++ b/Tests/PHPCI/Service/BuiltStatusServiceTest.php @@ -0,0 +1,212 @@ + + */ +class BuildStatusServiceTest extends \PHPUnit_Framework_TestCase +{ + const BRANCH = 'master'; + + /** @var Project */ + protected $project; + + protected $timezone; + + public function setUp() + { + $project = new Project(); + $project->setId(3); + $project->setBranch(self::BRANCH); + $project->setTitle('Test'); + + $this->project = $project; + $this->timezone = date_default_timezone_get(); + + date_default_timezone_set('UTC'); + } + + public function tearDown() + { + date_default_timezone_set($this->timezone); + } + + /** + * @param $configId + * @param bool $setProject + * @return Build + */ + protected function getBuild($configId, $setProject = true) + { + $config = array( + '1' => array( + 'status' => Build::STATUS_RUNNING, + 'id' => 77, + 'finishDateTime' => null, + 'startedDate' => '2014-10-25 21:20:02', + 'previousBuild' => null, + ), + '2' => array( + 'status' => Build::STATUS_RUNNING, + 'id' => 78, + 'finishDateTime' => null, + 'startedDate' => '2014-10-25 21:20:02', + 'previousBuild' => 4, + ), + '3' => array( + 'status' => Build::STATUS_SUCCESS, + 'id' => 7, + 'finishDateTime' => '2014-10-25 21:50:02', + 'startedDate' => '2014-10-25 21:20:02', + 'previousBuild' => null, + ), + '4' => array( + 'status' => Build::STATUS_FAILED, + 'id' => 13, + 'finishDateTime' => '2014-10-13 13:13:13', + 'previousBuild' => null, + ), + '5' => array( + 'status' => Build::STATUS_NEW, + 'id' => 1000, + 'finishDateTime' => '2014-12-25 21:12:21', + 'previousBuild' => 3, + ) + ); + + $build = new Build(); + $build->setId($config[$configId]['id']); + $build->setBranch(self::BRANCH); + $build->setStatus($config[$configId]['status']); + if ($config[$configId]['finishDateTime']) { + $build->setFinished(new \DateTime($config[$configId]['finishDateTime'])); + } + if (!empty($config[$configId]['startedDate'])) { + $build->setStarted(new \DateTime('2014-10-25 21:20:02')); + } + + $project = $this->getProjectMock($config[$configId]['previousBuild'], $setProject); + + $build->setProjectObject($project); + + return $build; + } + + /** + * @param null|int $prevBuildId + * @param bool $setProject + * @return Project + */ + protected function getProjectMock($prevBuildId = null, $setProject = true) { + + $project = $this->getMock('PHPCI\Model\Project', array('getLatestBuild')); + + $prevBuild = ($prevBuildId) ? $this->getBuild($prevBuildId, false) : null; + + $project->expects($this->any()) + ->method('getLatestBuild') + ->will($this->returnValue($prevBuild)); + + /* @var $project Project */ + + $project->setId(3); + $project->setBranch(self::BRANCH); + $project->setTitle('Test'); + + if ($setProject) { + $this->project = $project; + } + + return $project; + + } + + /** + * @dataProvider finishedProvider + * + * @param int $buildConfigId + * @param array $expectedResult + */ + public function testFinished($buildConfigId, array $expectedResult) + { + $build = $this->getBuild($buildConfigId); + $service = new BuildStatusService(self::BRANCH, $this->project, $build); + $service->setUrl('http://phpci.dev/'); + $this->assertEquals($expectedResult, $service->toArray()); + } + + public function finishedProvider() + { + return array( + 'buildingStatus' => array( + 1, + array( + 'name' => 'Test / master', + 'activity' => 'Building', + 'lastBuildLabel' => '', + 'lastBuildStatus' => '', + 'lastBuildTime' => '', + 'webUrl' => 'http://phpci.dev/build/view/77', + ) + ), + 'buildingStatusWithPrev' => array( + 2, + array( + 'name' => 'Test / master', + 'activity' => 'Building', + 'lastBuildLabel' => 13, + 'lastBuildStatus' => 'Failure', + 'lastBuildTime' => '2014-10-13T13:13:13+0000', + 'webUrl' => 'http://phpci.dev/build/view/78', + ) + ), + 'successStatus' => array( + 3, + array( + 'name' => 'Test / master', + 'activity' => 'Sleeping', + 'lastBuildLabel' => 7, + 'lastBuildStatus' => 'Success', + 'lastBuildTime' => '2014-10-25T21:50:02+0000', + 'webUrl' => 'http://phpci.dev/build/view/7', + ) + ), + 'failureStatus' => array( + 4, + array( + 'name' => 'Test / master', + 'activity' => 'Sleeping', + 'lastBuildLabel' => 13, + 'lastBuildStatus' => 'Failure', + 'lastBuildTime' => '2014-10-13T13:13:13+0000', + 'webUrl' => 'http://phpci.dev/build/view/13', + ) + ), + 'pending' => array( + 5, + array( + 'name' => 'Test / master', + 'activity' => 'Pending', + 'lastBuildLabel' => 7, + 'lastBuildStatus' => 'Success', + 'lastBuildTime' => '2014-10-25T21:50:02+0000', + 'webUrl' => 'http://phpci.dev/build/view/1000', + ) + ), + ); + } +} \ No newline at end of file diff --git a/Tests/PHPCI/Service/ProjectServiceTest.php b/Tests/PHPCI/Service/ProjectServiceTest.php index abb06d8f..229a5d22 100644 --- a/Tests/PHPCI/Service/ProjectServiceTest.php +++ b/Tests/PHPCI/Service/ProjectServiceTest.php @@ -1,13 +1,15 @@ loadYaml($configFile); } require_once(dirname(__DIR__) . '/vars.php'); \PHPCI\Helper\Lang::init($config); +\PHPCI\Helper\Lang::setLanguage("en"); diff --git a/bootstrap.php b/bootstrap.php old mode 100755 new mode 100644 index 89d7c95b..ebecad81 --- a/bootstrap.php +++ b/bootstrap.php @@ -8,7 +8,6 @@ */ // Let PHP take a guess as to the default timezone, if the user hasn't set one: -use PHPCI\Logging\Handler; use PHPCI\Logging\LoggerConfig; $timezone = ini_get('date.timezone'); @@ -16,13 +15,13 @@ if (empty($timezone)) { date_default_timezone_set('UTC'); } -// If the PHPCI config file is not where we expect it, try looking in -// env for an alternative config path. $configFile = dirname(__FILE__) . '/PHPCI/config.yml'; - $configEnv = getenv('phpci_config_file'); -if (!empty($configEnv)) { +$usingCustomConfigFile = false; + +if (!empty($configEnv) && file_exists($configEnv)) { $configFile = $configEnv; + $usingCustomConfigFile = true; } // If we don't have a config file at all, fail at this point and tell the user to install: @@ -45,9 +44,10 @@ if (!file_exists(dirname(__FILE__) . '/vendor/autoload.php') && defined('PHPCI_I // Load Composer autoloader: require_once(dirname(__FILE__) . '/vendor/autoload.php'); +\PHPCI\ErrorHandler::register(); + if (defined('PHPCI_IS_CONSOLE') && PHPCI_IS_CONSOLE) { $loggerConfig = LoggerConfig::newFromFile(__DIR__ . "/loggerconfig.php"); - Handler::register($loggerConfig->getFor('_')); } // Load configuration if present: @@ -55,6 +55,7 @@ $conf = array(); $conf['b8']['app']['namespace'] = 'PHPCI'; $conf['b8']['app']['default_controller'] = 'Home'; $conf['b8']['view']['path'] = dirname(__FILE__) . '/PHPCI/View/'; +$conf['using_custom_file'] = $usingCustomConfigFile; $config = new b8\Config($conf); @@ -62,6 +63,17 @@ if (file_exists($configFile)) { $config->loadYaml($configFile); } +/** + * Allow to modify PHPCI configuration without modify versioned code. + * Daemons should be killed to apply changes in the file. + * + * @ticket 781 + */ +$localVarsFile = dirname(__FILE__) . '/local_vars.php'; +if (is_readable($localVarsFile)) { + require_once $localVarsFile; +} + require_once(dirname(__FILE__) . '/vars.php'); \PHPCI\Helper\Lang::init($config); diff --git a/changelog.md b/changelog.md new file mode 100644 index 00000000..541e4a13 --- /dev/null +++ b/changelog.md @@ -0,0 +1,10 @@ +# PHPCI Changelog + +## v.Next + +### New Features: +- SSH-based Mercurial clones (Commit: [e98647bd](https://github.com/Block8/PHPCI/commit/e98647bd97d49741242d252514b8703504a62869), PR: [#812](https://github.com/Block8/PHPCI/pull/812)) +- Ability to archive projects (Commit: [1466ad06](https://github.com/Block8/PHPCI/commit/1466ad06ef708cbab2b53112fc59e8c1d70c2e33), PR: [#771](https://github.com/Block8/PHPCI/pull/771)) + +### Bug Fixes and Tweaks: + diff --git a/composer.json b/composer.json index 2d3930e3..a9080a94 100644 --- a/composer.json +++ b/composer.json @@ -28,6 +28,12 @@ } }, + "autoload-dev": { + "psr-4": { + "Tests\\PHPCI\\": "Tests/PHPCI/" + } + }, + "require": { "php": ">=5.3.8", "ext-pdo": "*", @@ -40,16 +46,21 @@ "psr/log": "~1.0", "monolog/monolog": "~1.6", "pimple/pimple": "~1.1", - "robmorgan/phinx": "~0.3" + "robmorgan/phinx": "~0.4", + "sensiolabs/ansi-to-html": "~1.1", + "pda/pheanstalk": "~3.1", + "maknz/slack": "~1.7", + "hipchat/hipchat-php": "~1.4", + "mremi/flowdock": "~1.0" }, "require-dev": { - "phpunit/phpunit": "~4.0", - "phpspec/prophecy-phpunit": "~1.0", + "phpunit/phpunit": "~4.5", "phpmd/phpmd": "~2.0", - "squizlabs/php_codesniffer": "~1.5", + "squizlabs/php_codesniffer": "~2.3", "block8/php-docblock-checker": "~1.0", - "phploc/phploc": "~2.0" + "phploc/phploc": "~2.0", + "jakub-onderka/php-parallel-lint": "0.8.*" }, "suggest": { @@ -58,13 +69,11 @@ "sebastian/phpcpd": "PHP Copy/Paste Detector", "squizlabs/php_codesniffer": "PHP Code Sniffer", "phpspec/phpspec": "PHP Spec", - "fabpot/php-cs-fixer": "PHP Code Sniffer Fixer", + "fabpot/php-cs-fixer": "PHP Coding Standards Fixer", "phploc/phploc": "PHP Lines of Code", "atoum/atoum": "Atoum", "jakub-onderka/php-parallel-lint": "Parallel Linting Tool", "behat/behat": "Behat BDD Testing", - "hipchat/hipchat-php": "Hipchat integration", - "phptal/phptal": "PHPTAL templating engine", - "maknz/slack": "Slack integration" + "phptal/phptal": "PHPTAL templating engine" } } diff --git a/composer.lock b/composer.lock index f5e1b0a0..9714ff78 100644 --- a/composer.lock +++ b/composer.lock @@ -1,23 +1,24 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "8b68ffb25f62f3245d64c9e97e8cd70e", + "hash": "de65276e03e231d7072c744a3c63662e", + "content-hash": "1d9f6f487e6d906bbed73e2667c276d6", "packages": [ { "name": "block8/b8framework", - "version": "1.1.9", + "version": "1.1.10", "source": { "type": "git", "url": "https://github.com/Block8/b8framework.git", - "reference": "3952dabee84cbf5be3dd8d20eadd13b6219e7a6a" + "reference": "5d2d2863ce15a6b91e0b2aed4250dd29c6224446" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Block8/b8framework/zipball/3952dabee84cbf5be3dd8d20eadd13b6219e7a6a", - "reference": "3952dabee84cbf5be3dd8d20eadd13b6219e7a6a", + "url": "https://api.github.com/repos/Block8/b8framework/zipball/5d2d2863ce15a6b91e0b2aed4250dd29c6224446", + "reference": "5d2d2863ce15a6b91e0b2aed4250dd29c6224446", "shasum": "" }, "require": { @@ -51,7 +52,315 @@ "mvc", "php" ], - "time": "2014-12-01 21:02:58" + "time": "2015-10-05 10:50:20" + }, + { + "name": "guzzle/guzzle", + "version": "v3.9.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle3.git", + "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle3/zipball/0645b70d953bc1c067bbc8d5bc53194706b628d9", + "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "php": ">=5.3.3", + "symfony/event-dispatcher": "~2.1" + }, + "replace": { + "guzzle/batch": "self.version", + "guzzle/cache": "self.version", + "guzzle/common": "self.version", + "guzzle/http": "self.version", + "guzzle/inflection": "self.version", + "guzzle/iterator": "self.version", + "guzzle/log": "self.version", + "guzzle/parser": "self.version", + "guzzle/plugin": "self.version", + "guzzle/plugin-async": "self.version", + "guzzle/plugin-backoff": "self.version", + "guzzle/plugin-cache": "self.version", + "guzzle/plugin-cookie": "self.version", + "guzzle/plugin-curlauth": "self.version", + "guzzle/plugin-error-response": "self.version", + "guzzle/plugin-history": "self.version", + "guzzle/plugin-log": "self.version", + "guzzle/plugin-md5": "self.version", + "guzzle/plugin-mock": "self.version", + "guzzle/plugin-oauth": "self.version", + "guzzle/service": "self.version", + "guzzle/stream": "self.version" + }, + "require-dev": { + "doctrine/cache": "~1.3", + "monolog/monolog": "~1.0", + "phpunit/phpunit": "3.7.*", + "psr/log": "~1.0", + "symfony/class-loader": "~2.1", + "zendframework/zend-cache": "2.*,<2.3", + "zendframework/zend-log": "2.*,<2.3" + }, + "suggest": { + "guzzlehttp/guzzle": "Guzzle 5 has moved to a new package name. The package you have installed, Guzzle 3, is deprecated." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.9-dev" + } + }, + "autoload": { + "psr-0": { + "Guzzle": "src/", + "Guzzle\\Tests": "tests/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Guzzle Community", + "homepage": "https://github.com/guzzle/guzzle/contributors" + } + ], + "description": "PHP HTTP client. This library is deprecated in favor of https://packagist.org/packages/guzzlehttp/guzzle", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2015-03-18 18:23:50" + }, + { + "name": "guzzlehttp/guzzle", + "version": "6.2.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "d094e337976dff9d8e2424e8485872194e768662" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/d094e337976dff9d8e2424e8485872194e768662", + "reference": "d094e337976dff9d8e2424e8485872194e768662", + "shasum": "" + }, + "require": { + "guzzlehttp/promises": "~1.0", + "guzzlehttp/psr7": "~1.1", + "php": ">=5.5.0" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "~4.0", + "psr/log": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.2-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2016-03-21 20:02:09" + }, + { + "name": "guzzlehttp/promises", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "bb9024c526b22f3fe6ae55a561fd70653d470aa8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/bb9024c526b22f3fe6ae55a561fd70653d470aa8", + "reference": "bb9024c526b22f3fe6ae55a561fd70653d470aa8", + "shasum": "" + }, + "require": { + "php": ">=5.5.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "time": "2016-03-08 01:15:46" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "31382fef2889136415751badebbd1cb022a4ed72" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/31382fef2889136415751badebbd1cb022a4ed72", + "reference": "31382fef2889136415751badebbd1cb022a4ed72", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "PSR-7 message implementation", + "keywords": [ + "http", + "message", + "stream", + "uri" + ], + "time": "2016-04-13 19:56:01" + }, + { + "name": "hipchat/hipchat-php", + "version": "v1.4", + "source": { + "type": "git", + "url": "https://github.com/hipchat/hipchat-php.git", + "reference": "5936c0a48d2d514d94bfc1d774b04c42cd3bc39e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hipchat/hipchat-php/zipball/5936c0a48d2d514d94bfc1d774b04c42cd3bc39e", + "reference": "5936c0a48d2d514d94bfc1d774b04c42cd3bc39e", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "HipChat": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "HipChat", + "email": "support@hipchat.com", + "homepage": "https://www.hipchat.com", + "role": "Company" + } + ], + "description": "PHP library for HipChat", + "homepage": "http://github.com/hipchat/hipchat-php", + "keywords": [ + "hipchat" + ], + "time": "2015-04-28 22:48:40" }, { "name": "ircmaxell/password-compat", @@ -96,17 +405,66 @@ "time": "2014-11-20 16:49:30" }, { - "name": "monolog/monolog", - "version": "1.11.0", + "name": "maknz/slack", + "version": "1.7.0", "source": { "type": "git", - "url": "https://github.com/Seldaek/monolog.git", - "reference": "ec3961874c43840e96da3a8a1ed20d8c73d7e5aa" + "url": "https://github.com/maknz/slack.git", + "reference": "7f21fefc70c76b304adc1b3a780c8740dfcfb595" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/ec3961874c43840e96da3a8a1ed20d8c73d7e5aa", - "reference": "ec3961874c43840e96da3a8a1ed20d8c73d7e5aa", + "url": "https://api.github.com/repos/maknz/slack/zipball/7f21fefc70c76b304adc1b3a780c8740dfcfb595", + "reference": "7f21fefc70c76b304adc1b3a780c8740dfcfb595", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "guzzlehttp/guzzle": "~6.0|~5.0|~4.0", + "php": ">=5.4.0" + }, + "require-dev": { + "mockery/mockery": "0.9.*", + "phpunit/phpunit": "4.2.*" + }, + "suggest": { + "illuminate/support": "Required for Laravel support" + }, + "type": "library", + "autoload": { + "psr-4": { + "Maknz\\Slack\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "maknz", + "email": "github@mak.geek.nz" + } + ], + "description": "A simple PHP package for sending messages to Slack, with a focus on ease of use and elegant syntax. Includes Laravel support out of the box.", + "keywords": [ + "laravel", + "slack" + ], + "time": "2015-06-03 03:35:16" + }, + { + "name": "monolog/monolog", + "version": "1.19.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "5f56ed5212dc509c8dc8caeba2715732abb32dbf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/5f56ed5212dc509c8dc8caeba2715732abb32dbf", + "reference": "5f56ed5212dc509c8dc8caeba2715732abb32dbf", "shasum": "" }, "require": { @@ -117,13 +475,17 @@ "psr/log-implementation": "1.0.0" }, "require-dev": { - "aws/aws-sdk-php": "~2.4, >2.4.8", + "aws/aws-sdk-php": "^2.4.9", "doctrine/couchdb": "~1.0@dev", "graylog2/gelf-php": "~1.0", - "phpunit/phpunit": "~3.7.0", - "raven/raven": "~0.5", - "ruflin/elastica": "0.90.*", - "videlalvaro/php-amqplib": "~2.4" + "jakub-onderka/php-parallel-lint": "0.9", + "php-amqplib/php-amqplib": "~2.4", + "php-console/php-console": "^3.1.3", + "phpunit/phpunit": "~4.5", + "phpunit/phpunit-mock-objects": "2.3.0", + "raven/raven": "^0.13", + "ruflin/elastica": ">=0.90 <3.0", + "swiftmailer/swiftmailer": "~5.3" }, "suggest": { "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", @@ -131,15 +493,17 @@ "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", "ext-mongo": "Allow sending log messages to a MongoDB server", "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "php-console/php-console": "Allow sending log messages to Google Chrome", "raven/raven": "Allow sending log messages to a Sentry server", "rollbar/rollbar": "Allow sending log messages to Rollbar", - "ruflin/elastica": "Allow sending log messages to an Elastic Search server", - "videlalvaro/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib" + "ruflin/elastica": "Allow sending log messages to an Elastic Search server" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.11.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -165,7 +529,104 @@ "logging", "psr-3" ], - "time": "2014-09-30 13:30:58" + "time": "2016-04-12 18:29:35" + }, + { + "name": "mremi/flowdock", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/mremi/Flowdock.git", + "reference": "e34ca78bbd4f974366e979186e876d78ae488e51" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mremi/Flowdock/zipball/e34ca78bbd4f974366e979186e876d78ae488e51", + "reference": "e34ca78bbd4f974366e979186e876d78ae488e51", + "shasum": "" + }, + "require": { + "guzzle/guzzle": "~3.7", + "php": ">=5.3.3", + "symfony/console": "~2.5" + }, + "require-dev": { + "phpunit/phpunit": "~4.1" + }, + "type": "library", + "autoload": { + "psr-0": { + "Mremi\\Flowdock": "src", + "Mremi\\Flowdock\\Tests": "tests/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Rémi Marseille", + "email": "marseille.remi@gmail.com" + } + ], + "description": "A PHP5 library to interact with the Flowdock API", + "homepage": "https://github.com/mremi/Flowdock", + "keywords": [ + "api", + "flowdock" + ], + "time": "2015-01-08 21:03:29" + }, + { + "name": "pda/pheanstalk", + "version": "v3.1.0", + "source": { + "type": "git", + "url": "https://github.com/pda/pheanstalk.git", + "reference": "430e77c551479aad0c6ada0450ee844cf656a18b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pda/pheanstalk/zipball/430e77c551479aad0c6ada0450ee844cf656a18b", + "reference": "430e77c551479aad0c6ada0450ee844cf656a18b", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Pheanstalk\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paul Annesley", + "email": "paul@annesley.cc", + "homepage": "http://paul.annesley.cc/", + "role": "Developer" + } + ], + "description": "PHP client for beanstalkd queue", + "homepage": "https://github.com/pda/pheanstalk", + "keywords": [ + "beanstalkd" + ], + "time": "2015-08-07 21:42:41" }, { "name": "pimple/pimple", @@ -202,7 +663,9 @@ "authors": [ { "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" } ], "description": "Pimple is a simple Dependency Injection Container for PHP 5.3", @@ -213,6 +676,55 @@ ], "time": "2013-11-22 08:30:29" }, + { + "name": "psr/http-message", + "version": "1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", + "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2015-05-04 20:22:00" + }, { "name": "psr/log", "version": "1.0.0", @@ -253,36 +765,34 @@ }, { "name": "robmorgan/phinx", - "version": "v0.3.8", + "version": "v0.5.3", "source": { "type": "git", "url": "https://github.com/robmorgan/phinx.git", - "reference": "589319c8bd7f819580bbab11a8987fb38853bfe7" + "reference": "4e7fee7792f4bf3dbf55ee29001850ba26c86a88" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/robmorgan/phinx/zipball/589319c8bd7f819580bbab11a8987fb38853bfe7", - "reference": "589319c8bd7f819580bbab11a8987fb38853bfe7", + "url": "https://api.github.com/repos/robmorgan/phinx/zipball/4e7fee7792f4bf3dbf55ee29001850ba26c86a88", + "reference": "4e7fee7792f4bf3dbf55ee29001850ba26c86a88", "shasum": "" }, "require": { - "php": ">=5.3.2", - "symfony/class-loader": "2.*", - "symfony/config": "2.*", - "symfony/console": "2.*", - "symfony/yaml": "2.*" + "php": ">=5.4", + "symfony/config": "~2.8|~3.0", + "symfony/console": "~2.8|~3.0", + "symfony/yaml": "~2.8|~3.0" }, "require-dev": { - "phpunit/phpunit": "3.7.*", - "squizlabs/php_codesniffer": "dev-phpcs-fixer" + "phpunit/phpunit": "^3.7|^4.0|^5.0" }, "bin": [ "bin/phinx" ], "type": "library", "autoload": { - "psr-0": { - "Phinx": "src/" + "psr-4": { + "Phinx\\": "src/Phinx" } }, "notification-url": "https://packagist.org/downloads/", @@ -295,10 +805,16 @@ "email": "robbym@gmail.com", "homepage": "http://robmorgan.id.au", "role": "Lead Developer" + }, + { + "name": "Woody Gilk", + "email": "woody.gilk@gmail.com", + "homepage": "http://shadowhand.me", + "role": "Developer" } ], "description": "Phinx makes it ridiculously easy to manage the database migrations for your PHP app.", - "homepage": "http://phinx.org", + "homepage": "https://phinx.org", "keywords": [ "database", "database migrations", @@ -306,32 +822,76 @@ "migrations", "phinx" ], - "time": "2014-10-06 09:27:17" + "time": "2016-03-07 14:09:22" }, { - "name": "swiftmailer/swiftmailer", - "version": "v5.3.1", + "name": "sensiolabs/ansi-to-html", + "version": "v1.1.2", "source": { "type": "git", - "url": "https://github.com/swiftmailer/swiftmailer.git", - "reference": "c5f963e7f9d6f6438fda4f22d5cc2db296ec621a" + "url": "https://github.com/sensiolabs/ansi-to-html.git", + "reference": "02598b975c510e9e7d07d0be0a89c7a6b43464d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/c5f963e7f9d6f6438fda4f22d5cc2db296ec621a", - "reference": "c5f963e7f9d6f6438fda4f22d5cc2db296ec621a", + "url": "https://api.github.com/repos/sensiolabs/ansi-to-html/zipball/02598b975c510e9e7d07d0be0a89c7a6b43464d6", + "reference": "02598b975c510e9e7d07d0be0a89c7a6b43464d6", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "suggest": { + "twig/twig": "Provides nice templating features" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-0": { + "SensioLabs\\AnsiConverter": "." + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "A library to convert a text with ANSI codes to HTML", + "time": "2015-07-22 03:07:58" + }, + { + "name": "swiftmailer/swiftmailer", + "version": "v5.4.1", + "source": { + "type": "git", + "url": "https://github.com/swiftmailer/swiftmailer.git", + "reference": "0697e6aa65c83edf97bb0f23d8763f94e3f11421" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/0697e6aa65c83edf97bb0f23d8763f94e3f11421", + "reference": "0697e6aa65c83edf97bb0f23d8763f94e3f11421", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { - "mockery/mockery": "~0.9.1" + "mockery/mockery": "~0.9.1,<0.9.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.3-dev" + "dev-master": "5.4-dev" } }, "autoload": { @@ -355,131 +915,87 @@ "description": "Swiftmailer, free feature-rich PHP mailer", "homepage": "http://swiftmailer.org", "keywords": [ + "email", "mail", "mailer" ], - "time": "2014-12-05 14:17:14" - }, - { - "name": "symfony/class-loader", - "version": "v2.6.1", - "target-dir": "Symfony/Component/ClassLoader", - "source": { - "type": "git", - "url": "https://github.com/symfony/ClassLoader.git", - "reference": "ba3300e6d79eb51ca9edf77791bbd0497f6030dc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/ClassLoader/zipball/ba3300e6d79eb51ca9edf77791bbd0497f6030dc", - "reference": "ba3300e6d79eb51ca9edf77791bbd0497f6030dc", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "symfony/finder": "~2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.6-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\ClassLoader\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "description": "Symfony ClassLoader Component", - "homepage": "http://symfony.com", - "time": "2014-12-02 20:19:20" + "time": "2015-06-06 14:19:39" }, { "name": "symfony/config", - "version": "v2.5.8", - "target-dir": "Symfony/Component/Config", + "version": "v3.0.4", "source": { "type": "git", - "url": "https://github.com/symfony/Config.git", - "reference": "92f0b4c625b8c42d394b53f879d2795d84bb8c4f" + "url": "https://github.com/symfony/config.git", + "reference": "980ee40c28f00acff8906c11b778aab5f0db74c2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Config/zipball/92f0b4c625b8c42d394b53f879d2795d84bb8c4f", - "reference": "92f0b4c625b8c42d394b53f879d2795d84bb8c4f", + "url": "https://api.github.com/repos/symfony/config/zipball/980ee40c28f00acff8906c11b778aab5f0db74c2", + "reference": "980ee40c28f00acff8906c11b778aab5f0db74c2", "shasum": "" }, "require": { - "php": ">=5.3.3", - "symfony/filesystem": "~2.3" + "php": ">=5.5.9", + "symfony/filesystem": "~2.8|~3.0" + }, + "suggest": { + "symfony/yaml": "To use the yaml reference dumper" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev" + "dev-master": "3.0-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\Config\\": "" - } + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Config Component", - "homepage": "http://symfony.com", - "time": "2014-12-02 20:15:53" + "homepage": "https://symfony.com", + "time": "2016-03-04 07:55:57" }, { "name": "symfony/console", - "version": "v2.6.1", - "target-dir": "Symfony/Component/Console", + "version": "v2.8.4", "source": { "type": "git", - "url": "https://github.com/symfony/Console.git", - "reference": "ef825fd9f809d275926547c9e57cbf14968793e8" + "url": "https://github.com/symfony/console.git", + "reference": "9a5aef5fc0d4eff86853d44202b02be8d5a20154" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Console/zipball/ef825fd9f809d275926547c9e57cbf14968793e8", - "reference": "ef825fd9f809d275926547c9e57cbf14968793e8", + "url": "https://api.github.com/repos/symfony/console/zipball/9a5aef5fc0d4eff86853d44202b02be8d5a20154", + "reference": "9a5aef5fc0d4eff86853d44202b02be8d5a20154", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.9", + "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { "psr/log": "~1.0", - "symfony/event-dispatcher": "~2.1", - "symfony/process": "~2.1" + "symfony/event-dispatcher": "~2.1|~3.0.0", + "symfony/process": "~2.1|~3.0.0" }, "suggest": { "psr/log": "For using the console logger", @@ -489,107 +1005,177 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.8-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\Console\\": "" - } + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Console Component", - "homepage": "http://symfony.com", - "time": "2014-12-02 20:19:20" + "homepage": "https://symfony.com", + "time": "2016-03-17 09:19:04" + }, + { + "name": "symfony/event-dispatcher", + "version": "v2.8.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "47d2d8cade9b1c3987573d2943bb9352536cdb87" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/47d2d8cade9b1c3987573d2943bb9352536cdb87", + "reference": "47d2d8cade9b1c3987573d2943bb9352536cdb87", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~2.0,>=2.0.5|~3.0.0", + "symfony/dependency-injection": "~2.6|~3.0.0", + "symfony/expression-language": "~2.6|~3.0.0", + "symfony/stopwatch": "~2.3|~3.0.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com", + "time": "2016-03-07 14:04:32" }, { "name": "symfony/filesystem", - "version": "v2.5.8", - "target-dir": "Symfony/Component/Filesystem", + "version": "v3.0.4", "source": { "type": "git", - "url": "https://github.com/symfony/Filesystem.git", - "reference": "e5fc05a3a1dbb4ea0bed80fe7bd21ba3cab88c42" + "url": "https://github.com/symfony/filesystem.git", + "reference": "f82499a459dcade2ea56df94cc58b19c8bde3d20" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Filesystem/zipball/e5fc05a3a1dbb4ea0bed80fe7bd21ba3cab88c42", - "reference": "e5fc05a3a1dbb4ea0bed80fe7bd21ba3cab88c42", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/f82499a459dcade2ea56df94cc58b19c8bde3d20", + "reference": "f82499a459dcade2ea56df94cc58b19c8bde3d20", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.5.9" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev" + "dev-master": "3.0-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\Filesystem\\": "" - } + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Filesystem Component", - "homepage": "http://symfony.com", - "time": "2014-12-02 20:15:53" + "homepage": "https://symfony.com", + "time": "2016-03-27 10:24:39" }, { - "name": "symfony/yaml", - "version": "v2.6.1", - "target-dir": "Symfony/Component/Yaml", + "name": "symfony/polyfill-mbstring", + "version": "v1.1.1", "source": { "type": "git", - "url": "https://github.com/symfony/Yaml.git", - "reference": "3346fc090a3eb6b53d408db2903b241af51dcb20" + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "1289d16209491b584839022f29257ad859b8532d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/3346fc090a3eb6b53d408db2903b241af51dcb20", - "reference": "3346fc090a3eb6b53d408db2903b241af51dcb20", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/1289d16209491b584839022f29257ad859b8532d", + "reference": "1289d16209491b584839022f29257ad859b8532d", "shasum": "" }, "require": { "php": ">=5.3.3" }, + "suggest": { + "ext-mbstring": "For best performance" + }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "1.1-dev" } }, "autoload": { - "psr-0": { - "Symfony\\Component\\Yaml\\": "" - } + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -597,17 +1183,73 @@ ], "authors": [ { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "time": "2016-01-20 09:13:37" + }, + { + "name": "symfony/yaml", + "version": "v2.8.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "584e52cb8f788a887553ba82db6caacb1d6260bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/584e52cb8f788a887553ba82db6caacb1d6260bb", + "reference": "584e52cb8f788a887553ba82db6caacb1d6260bb", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Yaml Component", - "homepage": "http://symfony.com", - "time": "2014-12-02 20:19:20" + "homepage": "https://symfony.com", + "time": "2016-03-04 07:54:35" } ], "packages-dev": [ @@ -666,16 +1308,16 @@ }, { "name": "doctrine/instantiator", - "version": "1.0.4", + "version": "1.0.5", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119" + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f976e5de371104877ebc89bd8fecb0019ed9c119", - "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", "shasum": "" }, "require": { @@ -686,7 +1328,7 @@ "ext-pdo": "*", "ext-phar": "*", "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "2.0.*@ALPHA" + "squizlabs/php_codesniffer": "~2.0" }, "type": "library", "extra": { @@ -695,8 +1337,8 @@ } }, "autoload": { - "psr-0": { - "Doctrine\\Instantiator\\": "src" + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" } }, "notification-url": "https://packagist.org/downloads/", @@ -716,38 +1358,86 @@ "constructor", "instantiate" ], - "time": "2014-10-13 12:58:55" + "time": "2015-06-14 21:17:01" }, { - "name": "pdepend/pdepend", - "version": "2.0.4", + "name": "jakub-onderka/php-parallel-lint", + "version": "v0.8", "source": { "type": "git", - "url": "https://github.com/pdepend/pdepend.git", - "reference": "1b0acf162da4f30237987e61e177a57f78e3d87e" + "url": "https://github.com/JakubOnderka/PHP-Parallel-Lint.git", + "reference": "2b242dcdbdd7369d2a746518ac31bb30c514b728" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pdepend/pdepend/zipball/1b0acf162da4f30237987e61e177a57f78e3d87e", - "reference": "1b0acf162da4f30237987e61e177a57f78e3d87e", + "url": "https://api.github.com/repos/JakubOnderka/PHP-Parallel-Lint/zipball/2b242dcdbdd7369d2a746518ac31bb30c514b728", + "reference": "2b242dcdbdd7369d2a746518ac31bb30c514b728", "shasum": "" }, "require": { - "symfony/config": ">=2.4", - "symfony/dependency-injection": ">=2.4", - "symfony/filesystem": ">=2.4" + "php": ">=5.3.3" }, "require-dev": { - "phpunit/phpunit": "4.*@stable", - "squizlabs/php_codesniffer": "@stable" + "jakub-onderka/php-console-highlighter": "~0.3", + "nette/tester": "~1.3" + }, + "suggest": { + "jakub-onderka/php-console-highlighter": "Highlight syntax in code snippet" + }, + "bin": [ + "parallel-lint" + ], + "type": "library", + "autoload": { + "classmap": [ + "./" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD" + ], + "authors": [ + { + "name": "Jakub Onderka", + "email": "jakub.onderka@gmail.com" + } + ], + "description": "This tool check syntax of PHP files about 20x faster than serial check.", + "homepage": "https://github.com/JakubOnderka/PHP-Parallel-Lint", + "time": "2014-10-05 10:19:39" + }, + { + "name": "pdepend/pdepend", + "version": "2.2.4", + "source": { + "type": "git", + "url": "https://github.com/pdepend/pdepend.git", + "reference": "b086687f3a01dc6bb92d633aef071d2c5dd0db06" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pdepend/pdepend/zipball/b086687f3a01dc6bb92d633aef071d2c5dd0db06", + "reference": "b086687f3a01dc6bb92d633aef071d2c5dd0db06", + "shasum": "" + }, + "require": { + "php": ">=5.3.7", + "symfony/config": "^2.3.0|^3", + "symfony/dependency-injection": "^2.3.0|^3", + "symfony/filesystem": "^2.3.0|^3" + }, + "require-dev": { + "phpunit/phpunit": "^4.4.0,<4.8", + "squizlabs/php_codesniffer": "^2.0.0" }, "bin": [ "src/bin/pdepend" ], "type": "library", "autoload": { - "psr-0": { - "PDepend\\": "src/main/php/" + "psr-4": { + "PDepend\\": "src/main/php/PDepend" } }, "notification-url": "https://packagist.org/downloads/", @@ -755,31 +1445,31 @@ "BSD-3-Clause" ], "description": "Official version of pdepend to be handled with Composer", - "time": "2014-12-04 12:38:39" + "time": "2016-03-10 15:15:04" }, { "name": "phpdocumentor/reflection-docblock", - "version": "2.0.3", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "38743b677965c48a637097b2746a281264ae2347" + "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/38743b677965c48a637097b2746a281264ae2347", - "reference": "38743b677965c48a637097b2746a281264ae2347", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", + "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { - "phpunit/phpunit": "3.7.*@stable" + "phpunit/phpunit": "~4.0" }, "suggest": { - "dflydev/markdown": "1.0.*", - "erusev/parsedown": "~0.7" + "dflydev/markdown": "~1.0", + "erusev/parsedown": "~1.0" }, "type": "library", "extra": { @@ -804,28 +1494,31 @@ "email": "mike.vanriel@naenius.com" } ], - "time": "2014-08-09 10:27:07" + "time": "2015-02-03 12:10:50" }, { "name": "phploc/phploc", - "version": "2.0.6", + "version": "2.1.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phploc.git", - "reference": "322ad07c112d5c6832abed4269d648cacff5959b" + "reference": "50e063abd41833b3a5d29a2e8fbef5859ac28bdc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phploc/zipball/322ad07c112d5c6832abed4269d648cacff5959b", - "reference": "322ad07c112d5c6832abed4269d648cacff5959b", + "url": "https://api.github.com/repos/sebastianbergmann/phploc/zipball/50e063abd41833b3a5d29a2e8fbef5859ac28bdc", + "reference": "50e063abd41833b3a5d29a2e8fbef5859ac28bdc", "shasum": "" }, "require": { "php": ">=5.3.3", "sebastian/finder-facade": "~1.1", - "sebastian/git": "~1.0", - "sebastian/version": "~1.0", - "symfony/console": "~2.2" + "sebastian/git": "~2.0", + "sebastian/version": "~1.0.3", + "symfony/console": "~2.5" + }, + "require-dev": { + "phpunit/phpunit": "~4" }, "bin": [ "phploc" @@ -833,7 +1526,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "2.1-dev" } }, "autoload": { @@ -854,33 +1547,34 @@ ], "description": "A tool for quickly measuring the size of a PHP project.", "homepage": "https://github.com/sebastianbergmann/phploc", - "time": "2014-06-25 08:11:02" + "time": "2015-10-22 13:44:19" }, { "name": "phpmd/phpmd", - "version": "2.1.3", + "version": "2.4.3", "source": { "type": "git", "url": "https://github.com/phpmd/phpmd.git", - "reference": "1a485d9db869137af5e9678bd844568c92998b25" + "reference": "2b9c2417a18696dfb578b38c116cd0ddc19b256e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpmd/phpmd/zipball/1a485d9db869137af5e9678bd844568c92998b25", - "reference": "1a485d9db869137af5e9678bd844568c92998b25", + "url": "https://api.github.com/repos/phpmd/phpmd/zipball/2b9c2417a18696dfb578b38c116cd0ddc19b256e", + "reference": "2b9c2417a18696dfb578b38c116cd0ddc19b256e", "shasum": "" }, "require": { - "pdepend/pdepend": "2.0.*", - "php": ">=5.3.0", - "symfony/config": "2.5.*", - "symfony/dependency-injection": "2.5.*", - "symfony/filesystem": "2.5.*" + "pdepend/pdepend": "^2.0.4", + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0", + "squizlabs/php_codesniffer": "^2.0" }, "bin": [ "src/bin/phpmd" ], - "type": "library", + "type": "project", "autoload": { "psr-0": { "PHPMD\\": "src/main/php" @@ -890,26 +1584,56 @@ "license": [ "BSD-3-Clause" ], - "description": "Official version of PHPMD handled with Composer.", - "time": "2014-09-25 15:56:22" + "authors": [ + { + "name": "Manuel Pichler", + "email": "github@manuel-pichler.de", + "homepage": "https://github.com/manuelpichler", + "role": "Project Founder" + }, + { + "name": "Other contributors", + "homepage": "https://github.com/phpmd/phpmd/graphs/contributors", + "role": "Contributors" + }, + { + "name": "Marc Würth", + "email": "ravage@bluewin.ch", + "homepage": "https://github.com/ravage84", + "role": "Project Maintainer" + } + ], + "description": "PHPMD is a spin-off project of PHP Depend and aims to be a PHP equivalent of the well known Java tool PMD.", + "homepage": "http://phpmd.org/", + "keywords": [ + "mess detection", + "mess detector", + "pdepend", + "phpmd", + "pmd" + ], + "time": "2016-04-04 11:52:04" }, { "name": "phpspec/prophecy", - "version": "v1.3.1", + "version": "v1.6.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "9ca52329bcdd1500de24427542577ebf3fc2f1c9" + "reference": "3c91bdf81797d725b14cb62906f9a4ce44235972" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/9ca52329bcdd1500de24427542577ebf3fc2f1c9", - "reference": "9ca52329bcdd1500de24427542577ebf3fc2f1c9", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/3c91bdf81797d725b14cb62906f9a4ce44235972", + "reference": "3c91bdf81797d725b14cb62906f9a4ce44235972", "shasum": "" }, "require": { - "doctrine/instantiator": "~1.0,>=1.0.2", - "phpdocumentor/reflection-docblock": "~2.0" + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "~2.0", + "sebastian/comparator": "~1.1", + "sebastian/recursion-context": "~1.0" }, "require-dev": { "phpspec/phpspec": "~2.0" @@ -917,7 +1641,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-master": "1.5.x-dev" } }, "autoload": { @@ -941,7 +1665,7 @@ } ], "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "http://phpspec.org", + "homepage": "https://github.com/phpspec/prophecy", "keywords": [ "Double", "Dummy", @@ -950,70 +1674,20 @@ "spy", "stub" ], - "time": "2014-11-17 16:23:49" - }, - { - "name": "phpspec/prophecy-phpunit", - "version": "v1.0.1", - "target-dir": "Prophecy/PhpUnit", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy-phpunit.git", - "reference": "640c8c3bc9e02d7878e5ed22b1f79818d6bb6caf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy-phpunit/zipball/640c8c3bc9e02d7878e5ed22b1f79818d6bb6caf", - "reference": "640c8c3bc9e02d7878e5ed22b1f79818d6bb6caf", - "shasum": "" - }, - "require": { - "phpspec/prophecy": "~1.0" - }, - "suggest": { - "phpunit/phpunit": "if it is not installed globally" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "Prophecy\\PhpUnit\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Christophe Coevoet", - "email": "stof@notk.org" - } - ], - "description": "PhpUnit test case integrating the Prophecy mocking library", - "homepage": "http://phpspec.org", - "keywords": [ - "phpunit", - "prophecy" - ], - "time": "2014-03-03 23:03:12" + "time": "2016-02-15 07:46:21" }, { "name": "phpunit/php-code-coverage", - "version": "2.0.13", + "version": "2.2.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "0e7d2eec5554f869fa7a4ec2d21e4b37af943ea5" + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/0e7d2eec5554f869fa7a4ec2d21e4b37af943ea5", - "reference": "0e7d2eec5554f869fa7a4ec2d21e4b37af943ea5", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", "shasum": "" }, "require": { @@ -1021,12 +1695,12 @@ "phpunit/php-file-iterator": "~1.3", "phpunit/php-text-template": "~1.2", "phpunit/php-token-stream": "~1.3", - "sebastian/environment": "~1.0", + "sebastian/environment": "^1.3.2", "sebastian/version": "~1.0" }, "require-dev": { "ext-xdebug": ">=2.1.4", - "phpunit/phpunit": "~4.1" + "phpunit/phpunit": "~4" }, "suggest": { "ext-dom": "*", @@ -1036,7 +1710,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "2.2.x-dev" } }, "autoload": { @@ -1045,9 +1719,6 @@ ] }, "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], "license": [ "BSD-3-Clause" ], @@ -1065,35 +1736,37 @@ "testing", "xunit" ], - "time": "2014-12-03 06:41:44" + "time": "2015-10-06 15:47:00" }, { "name": "phpunit/php-file-iterator", - "version": "1.3.4", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb" + "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb", - "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", + "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", "shasum": "" }, "require": { "php": ">=5.3.3" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, "autoload": { "classmap": [ - "File/" + "src/" ] }, "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], "license": [ "BSD-3-Clause" ], @@ -1110,20 +1783,20 @@ "filesystem", "iterator" ], - "time": "2013-10-10 15:34:57" + "time": "2015-06-21 13:08:43" }, { "name": "phpunit/php-text-template", - "version": "1.2.0", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a" + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", - "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", "shasum": "" }, "require": { @@ -1132,20 +1805,17 @@ "type": "library", "autoload": { "classmap": [ - "Text/" + "src/" ] }, "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], @@ -1154,20 +1824,20 @@ "keywords": [ "template" ], - "time": "2014-01-30 17:20:04" + "time": "2015-06-21 13:50:34" }, { "name": "phpunit/php-timer", - "version": "1.0.5", + "version": "1.0.7", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c" + "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/19689d4354b295ee3d8c54b4f42c3efb69cbc17c", - "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b", + "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b", "shasum": "" }, "require": { @@ -1176,13 +1846,10 @@ "type": "library", "autoload": { "classmap": [ - "PHP/" + "src/" ] }, "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], "license": [ "BSD-3-Clause" ], @@ -1198,20 +1865,20 @@ "keywords": [ "timer" ], - "time": "2013-08-02 07:42:54" + "time": "2015-06-21 08:01:12" }, { "name": "phpunit/php-token-stream", - "version": "1.3.0", + "version": "1.4.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "f8d5d08c56de5cfd592b3340424a81733259a876" + "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/f8d5d08c56de5cfd592b3340424a81733259a876", - "reference": "f8d5d08c56de5cfd592b3340424a81733259a876", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", + "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", "shasum": "" }, "require": { @@ -1224,7 +1891,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "1.4-dev" } }, "autoload": { @@ -1247,20 +1914,20 @@ "keywords": [ "tokenizer" ], - "time": "2014-08-31 06:12:13" + "time": "2015-09-15 10:49:45" }, { "name": "phpunit/phpunit", - "version": "4.4.0", + "version": "4.8.24", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "bbe7bcb83b6ec1a9eaabbe1b70d4795027c53ee0" + "reference": "a1066c562c52900a142a0e2bbf0582994671385e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bbe7bcb83b6ec1a9eaabbe1b70d4795027c53ee0", - "reference": "bbe7bcb83b6ec1a9eaabbe1b70d4795027c53ee0", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a1066c562c52900a142a0e2bbf0582994671385e", + "reference": "a1066c562c52900a142a0e2bbf0582994671385e", "shasum": "" }, "require": { @@ -1270,18 +1937,19 @@ "ext-reflection": "*", "ext-spl": "*", "php": ">=5.3.3", - "phpunit/php-code-coverage": "~2.0", - "phpunit/php-file-iterator": "~1.3.2", + "phpspec/prophecy": "^1.3.1", + "phpunit/php-code-coverage": "~2.1", + "phpunit/php-file-iterator": "~1.4", "phpunit/php-text-template": "~1.2", - "phpunit/php-timer": "~1.0.2", + "phpunit/php-timer": ">=1.0.6", "phpunit/phpunit-mock-objects": "~2.3", - "sebastian/comparator": "~1.0", - "sebastian/diff": "~1.1", - "sebastian/environment": "~1.1", - "sebastian/exporter": "~1.0", + "sebastian/comparator": "~1.1", + "sebastian/diff": "~1.2", + "sebastian/environment": "~1.3", + "sebastian/exporter": "~1.2", "sebastian/global-state": "~1.0", "sebastian/version": "~1.0", - "symfony/yaml": "~2.0" + "symfony/yaml": "~2.1|~3.0" }, "suggest": { "phpunit/php-invoker": "~1.1" @@ -1292,7 +1960,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.4.x-dev" + "dev-master": "4.8.x-dev" } }, "autoload": { @@ -1318,29 +1986,30 @@ "testing", "xunit" ], - "time": "2014-12-05 06:49:03" + "time": "2016-03-14 06:16:08" }, { "name": "phpunit/phpunit-mock-objects", - "version": "2.3.0", + "version": "2.3.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "c63d2367247365f688544f0d500af90a11a44c65" + "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/c63d2367247365f688544f0d500af90a11a44c65", - "reference": "c63d2367247365f688544f0d500af90a11a44c65", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", + "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", "shasum": "" }, "require": { - "doctrine/instantiator": "~1.0,>=1.0.1", + "doctrine/instantiator": "^1.0.2", "php": ">=5.3.3", - "phpunit/php-text-template": "~1.2" + "phpunit/php-text-template": "~1.2", + "sebastian/exporter": "~1.2" }, "require-dev": { - "phpunit/phpunit": "~4.3" + "phpunit/phpunit": "~4.4" }, "suggest": { "ext-soap": "*" @@ -1373,34 +2042,34 @@ "mock", "xunit" ], - "time": "2014-10-03 05:12:11" + "time": "2015-10-02 06:51:40" }, { "name": "sebastian/comparator", - "version": "1.1.0", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "c484a80f97573ab934e37826dba0135a3301b26a" + "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/c484a80f97573ab934e37826dba0135a3301b26a", - "reference": "c484a80f97573ab934e37826dba0135a3301b26a", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", + "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", "shasum": "" }, "require": { "php": ">=5.3.3", - "sebastian/diff": "~1.1", - "sebastian/exporter": "~1.0" + "sebastian/diff": "~1.2", + "sebastian/exporter": "~1.2" }, "require-dev": { - "phpunit/phpunit": "~4.1" + "phpunit/phpunit": "~4.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "1.2.x-dev" } }, "autoload": { @@ -1437,32 +2106,32 @@ "compare", "equality" ], - "time": "2014-11-16 21:32:38" + "time": "2015-07-26 15:48:44" }, { "name": "sebastian/diff", - "version": "1.2.0", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "5843509fed39dee4b356a306401e9dd1a931fec7" + "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/5843509fed39dee4b356a306401e9dd1a931fec7", - "reference": "5843509fed39dee4b356a306401e9dd1a931fec7", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", + "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { - "phpunit/phpunit": "~4.2" + "phpunit/phpunit": "~4.8" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2-dev" + "dev-master": "1.4-dev" } }, "autoload": { @@ -1485,36 +2154,36 @@ } ], "description": "Diff implementation", - "homepage": "http://www.github.com/sebastianbergmann/diff", + "homepage": "https://github.com/sebastianbergmann/diff", "keywords": [ "diff" ], - "time": "2014-08-15 10:29:00" + "time": "2015-12-08 07:14:41" }, { "name": "sebastian/environment", - "version": "1.2.1", + "version": "1.3.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "6e6c71d918088c251b181ba8b3088af4ac336dd7" + "reference": "dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6e6c71d918088c251b181ba8b3088af4ac336dd7", - "reference": "6e6c71d918088c251b181ba8b3088af4ac336dd7", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf", + "reference": "dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { - "phpunit/phpunit": "~4.3" + "phpunit/phpunit": "~4.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-master": "1.3.x-dev" } }, "autoload": { @@ -1539,32 +2208,33 @@ "environment", "hhvm" ], - "time": "2014-10-25 08:00:45" + "time": "2016-02-26 18:40:46" }, { "name": "sebastian/exporter", - "version": "1.0.2", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "c7d59948d6e82818e1bdff7cadb6c34710eb7dc0" + "reference": "7ae5513327cb536431847bcc0c10edba2701064e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/c7d59948d6e82818e1bdff7cadb6c34710eb7dc0", - "reference": "c7d59948d6e82818e1bdff7cadb6c34710eb7dc0", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e", + "reference": "7ae5513327cb536431847bcc0c10edba2701064e", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.3", + "sebastian/recursion-context": "~1.0" }, "require-dev": { - "phpunit/phpunit": "~4.0" + "phpunit/phpunit": "~4.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.2.x-dev" } }, "autoload": { @@ -1604,25 +2274,25 @@ "export", "exporter" ], - "time": "2014-09-10 00:51:36" + "time": "2015-06-21 07:55:53" }, { "name": "sebastian/finder-facade", - "version": "1.1.0", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/finder-facade.git", - "reference": "1e396fda3449fce9df032749fa4fa2619e0347e0" + "reference": "2a6f7f57efc0aa2d23297d9fd9e2a03111a8c0b9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/finder-facade/zipball/1e396fda3449fce9df032749fa4fa2619e0347e0", - "reference": "1e396fda3449fce9df032749fa4fa2619e0347e0", + "url": "https://api.github.com/repos/sebastianbergmann/finder-facade/zipball/2a6f7f57efc0aa2d23297d9fd9e2a03111a8c0b9", + "reference": "2a6f7f57efc0aa2d23297d9fd9e2a03111a8c0b9", "shasum": "" }, "require": { - "symfony/finder": ">=2.2.0", - "theseer/fdomdocument": ">=1.3.1" + "symfony/finder": "~2.3|~3.0", + "theseer/fdomdocument": "~1.3" }, "type": "library", "autoload": { @@ -1643,20 +2313,20 @@ ], "description": "FinderFacade is a convenience wrapper for Symfony's Finder component.", "homepage": "https://github.com/sebastianbergmann/finder-facade", - "time": "2013-05-28 06:10:03" + "time": "2016-02-17 07:02:23" }, { "name": "sebastian/git", - "version": "1.2.0", + "version": "2.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/git.git", - "reference": "a99fbc102e982c1404041ef3e4d431562b29bcba" + "reference": "38638de3e94830a5cd7a5956135589b967609cd5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/git/zipball/a99fbc102e982c1404041ef3e4d431562b29bcba", - "reference": "a99fbc102e982c1404041ef3e4d431562b29bcba", + "url": "https://api.github.com/repos/sebastianbergmann/git/zipball/38638de3e94830a5cd7a5956135589b967609cd5", + "reference": "38638de3e94830a5cd7a5956135589b967609cd5", "shasum": "" }, "require": { @@ -1665,7 +2335,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2-dev" + "dev-master": "2.1-dev" } }, "autoload": { @@ -1680,8 +2350,7 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "email": "sebastian@phpunit.de" } ], "description": "Simple wrapper for Git", @@ -1689,20 +2358,20 @@ "keywords": [ "git" ], - "time": "2013-08-04 09:35:29" + "time": "2016-02-21 15:02:23" }, { "name": "sebastian/global-state", - "version": "1.0.0", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01" + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/c7428acdb62ece0a45e6306f1ae85e1c05b09c01", - "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", "shasum": "" }, "require": { @@ -1740,20 +2409,73 @@ "keywords": [ "global state" ], - "time": "2014-10-06 09:23:50" + "time": "2015-10-12 03:26:01" }, { - "name": "sebastian/version", - "version": "1.0.3", + "name": "sebastian/recursion-context", + "version": "1.0.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43" + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "913401df809e99e4f47b27cdd781f4a258d58791" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43", - "reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791", + "reference": "913401df809e99e4f47b27cdd781f4a258d58791", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2015-11-11 19:50:13" + }, + { + "name": "sebastian/version", + "version": "1.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", + "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", "shasum": "" }, "type": "library", @@ -1775,36 +2497,39 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", - "time": "2014-03-07 15:35:33" + "time": "2015-06-21 13:59:46" }, { "name": "squizlabs/php_codesniffer", - "version": "1.5.6", + "version": "2.6.0", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "6f3e42d311b882b25b4d409d23a289f4d3b803d5" + "reference": "1bcdf03b068a530ac1962ce671dead356eeba43b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/6f3e42d311b882b25b4d409d23a289f4d3b803d5", - "reference": "6f3e42d311b882b25b4d409d23a289f4d3b803d5", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1bcdf03b068a530ac1962ce671dead356eeba43b", + "reference": "1bcdf03b068a530ac1962ce671dead356eeba43b", "shasum": "" }, "require": { + "ext-simplexml": "*", "ext-tokenizer": "*", + "ext-xmlwriter": "*", "php": ">=5.1.2" }, - "suggest": { - "phpunit/php-timer": "dev-master" + "require-dev": { + "phpunit/phpunit": "~4.0" }, "bin": [ - "scripts/phpcs" + "scripts/phpcs", + "scripts/phpcbf" ], "type": "library", "extra": { "branch-alias": { - "dev-phpcs-fixer": "2.0.x-dev" + "dev-master": "2.x-dev" } }, "autoload": { @@ -1813,12 +2538,12 @@ "CodeSniffer/CLI.php", "CodeSniffer/Exception.php", "CodeSniffer/File.php", + "CodeSniffer/Fixer.php", "CodeSniffer/Report.php", "CodeSniffer/Reporting.php", "CodeSniffer/Sniff.php", "CodeSniffer/Tokens.php", "CodeSniffer/Reports/", - "CodeSniffer/CommentParser/", "CodeSniffer/Tokenizers/", "CodeSniffer/DocGenerators/", "CodeSniffer/Standards/AbstractPatternSniff.php", @@ -1844,36 +2569,35 @@ "role": "lead" } ], - "description": "PHP_CodeSniffer tokenises PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", "homepage": "http://www.squizlabs.com/php-codesniffer", "keywords": [ "phpcs", "standards" ], - "time": "2014-12-04 22:32:15" + "time": "2016-04-03 22:58:34" }, { "name": "symfony/dependency-injection", - "version": "v2.5.8", - "target-dir": "Symfony/Component/DependencyInjection", + "version": "v3.0.4", "source": { "type": "git", - "url": "https://github.com/symfony/DependencyInjection.git", - "reference": "b4afda3c24867a17f93237ac1fcce917cc9d7695" + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "6a9058101b591edced21ca3c83c80a3978f5c6b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/b4afda3c24867a17f93237ac1fcce917cc9d7695", - "reference": "b4afda3c24867a17f93237ac1fcce917cc9d7695", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/6a9058101b591edced21ca3c83c80a3978f5c6b0", + "reference": "6a9058101b591edced21ca3c83c80a3978f5c6b0", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.5.9" }, "require-dev": { - "symfony/config": "~2.2", - "symfony/expression-language": "~2.4", - "symfony/yaml": "~2.0" + "symfony/config": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", + "symfony/yaml": "~2.8|~3.0" }, "suggest": { "symfony/config": "", @@ -1883,91 +2607,96 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev" + "dev-master": "3.0-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\DependencyInjection\\": "" - } + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony DependencyInjection Component", - "homepage": "http://symfony.com", - "time": "2014-12-02 21:48:32" + "homepage": "https://symfony.com", + "time": "2016-03-30 10:41:14" }, { "name": "symfony/finder", - "version": "v2.6.1", - "target-dir": "Symfony/Component/Finder", + "version": "v3.0.4", "source": { "type": "git", - "url": "https://github.com/symfony/Finder.git", - "reference": "0d3ef7f6ec55a7af5eca7914eaa0dacc04ccc721" + "url": "https://github.com/symfony/finder.git", + "reference": "c54e407b35bc098916704e9fd090da21da4c4f52" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Finder/zipball/0d3ef7f6ec55a7af5eca7914eaa0dacc04ccc721", - "reference": "0d3ef7f6ec55a7af5eca7914eaa0dacc04ccc721", + "url": "https://api.github.com/repos/symfony/finder/zipball/c54e407b35bc098916704e9fd090da21da4c4f52", + "reference": "c54e407b35bc098916704e9fd090da21da4c4f52", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.5.9" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "3.0-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\Finder\\": "" - } + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Finder Component", - "homepage": "http://symfony.com", - "time": "2014-12-02 20:19:20" + "homepage": "https://symfony.com", + "time": "2016-03-10 11:13:05" }, { "name": "theseer/fdomdocument", - "version": "1.6.0", + "version": "1.6.1", "source": { "type": "git", "url": "https://github.com/theseer/fDOMDocument.git", - "reference": "d08cf070350f884c63fc9078d27893c2ab6c7cef" + "reference": "d9ad139d6c2e8edf5e313ffbe37ff13344cf0684" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/fDOMDocument/zipball/d08cf070350f884c63fc9078d27893c2ab6c7cef", - "reference": "d08cf070350f884c63fc9078d27893c2ab6c7cef", + "url": "https://api.github.com/repos/theseer/fDOMDocument/zipball/d9ad139d6c2e8edf5e313ffbe37ff13344cf0684", + "reference": "d9ad139d6c2e8edf5e313ffbe37ff13344cf0684", "shasum": "" }, "require": { @@ -1994,13 +2723,14 @@ ], "description": "The classes contained within this repository extend the standard DOM to use exceptions at all occasions of errors instead of PHP warnings or notices. They also add various custom methods and shortcuts for convenience and to simplify the usage of DOM.", "homepage": "https://github.com/theseer/fDOMDocument", - "time": "2014-09-13 10:57:19" + "time": "2015-05-27 22:58:02" } ], "aliases": [], "minimum-stability": "stable", "stability-flags": [], "prefer-stable": false, + "prefer-lowest": false, "platform": { "php": ">=5.3.8", "ext-pdo": "*", diff --git a/console b/console index 43fc2b8f..992462e5 100755 --- a/console +++ b/console @@ -13,22 +13,32 @@ define('PHPCI_IS_CONSOLE', true); require('bootstrap.php'); use PHPCI\Command\RunCommand; +use PHPCI\Command\RebuildCommand; use PHPCI\Command\GenerateCommand; use PHPCI\Command\UpdateCommand; use PHPCI\Command\InstallCommand; use PHPCI\Command\DaemonCommand; use PHPCI\Command\PollCommand; use PHPCI\Command\CreateAdminCommand; +use PHPCI\Command\CreateBuildCommand; +use PHPCI\Command\WorkerCommand; +use PHPCI\Command\RebuildQueueCommand; +use PHPCI\Service\BuildService; use Symfony\Component\Console\Application; +use b8\Store\Factory; $application = new Application(); $application->add(new RunCommand($loggerConfig->getFor('RunCommand'))); +$application->add(new RebuildCommand($loggerConfig->getFor('RunCommand'))); $application->add(new InstallCommand); $application->add(new UpdateCommand($loggerConfig->getFor('UpdateCommand'))); $application->add(new GenerateCommand); $application->add(new DaemonCommand($loggerConfig->getFor('DaemonCommand'))); $application->add(new PollCommand($loggerConfig->getFor('PollCommand'))); -$application->add(new CreateAdminCommand); +$application->add(new CreateAdminCommand(Factory::getStore('User'))); +$application->add(new CreateBuildCommand(Factory::getStore('Project'), new BuildService(Factory::getStore('Build')))); +$application->add(new WorkerCommand($loggerConfig->getFor('WorkerCommand'))); +$application->add(new RebuildQueueCommand($loggerConfig->getFor('RebuildQueueCommand'))); -$application->run(); \ No newline at end of file +$application->run(); diff --git a/console.bat b/console.bat new file mode 100644 index 00000000..391a2617 --- /dev/null +++ b/console.bat @@ -0,0 +1 @@ +@php console %* \ No newline at end of file diff --git a/daemon/.gitignore b/daemon/.gitignore index c96a04f0..d6b7ef32 100644 --- a/daemon/.gitignore +++ b/daemon/.gitignore @@ -1,2 +1,2 @@ * -!.gitignore \ No newline at end of file +!.gitignore diff --git a/daemonise b/daemonise index 5117e414..c6238568 100755 --- a/daemonise +++ b/daemonise @@ -15,8 +15,6 @@ require('bootstrap.php'); use PHPCI\Command\DaemoniseCommand; use Symfony\Component\Console\Application; -$loggerConfig = \PHPCI\Logging\LoggerConfig::newFromFile(__DIR__ . "/loggerconfig.php"); - $application = new Application(); $application->add(new DaemoniseCommand($loggerConfig->getFor('DaemoniseCommand'))); $application->run(); diff --git a/loggerconfig.php.example b/loggerconfig.php.example index c306673b..ffa22204 100644 --- a/loggerconfig.php.example +++ b/loggerconfig.php.example @@ -1,5 +1,13 @@ function() { @@ -13,4 +21,4 @@ return array( new \Monolog\Handler\RotatingFileHandler(__DIR__ . DIRECTORY_SEPARATOR . 'everything',3, \Monolog\Logger::DEBUG), ); }, -); \ No newline at end of file +); diff --git a/phinx.php b/phinx.php index 3c407b1e..d64749dd 100644 --- a/phinx.php +++ b/phinx.php @@ -1,5 +1,13 @@ get('b8.database.servers.write'); diff --git a/phpcs.xml b/phpcs.xml new file mode 100644 index 00000000..a392a201 --- /dev/null +++ b/phpcs.xml @@ -0,0 +1,19 @@ + + + + Codestyle ruleset for PHPCI + + + + PHPCI + + + + + PHPCI/Migrations/* + PHPCI/Model/Base/* + PHPCI/Languages/* + Tests/* + vendor/* + + diff --git a/phpmd.xml b/phpmd.xml new file mode 100644 index 00000000..69b822fd --- /dev/null +++ b/phpmd.xml @@ -0,0 +1,17 @@ + + + + PHPCI rule set + + + + + + + diff --git a/pluginconfig.php.example b/pluginconfig.php.example index 4e4279b9..5c182401 100644 --- a/pluginconfig.php.example +++ b/pluginconfig.php.example @@ -19,4 +19,4 @@ return function (PHPCI\Plugin\Util\Factory $factory) { // The resource will only be given when the type hint is: PHPCI\Plugin\Util\Factory::TYPE_ARRAY ); -}; \ No newline at end of file +}; diff --git a/public/assets/css/AdminLTE-custom.css b/public/assets/css/AdminLTE-custom.css new file mode 100644 index 00000000..ff75c31a --- /dev/null +++ b/public/assets/css/AdminLTE-custom.css @@ -0,0 +1,84 @@ +.phpci .main-header .logo, .phpci .main-header .logo:hover { + background-image: url('/assets/img/logo-large.png'); + background-repeat: no-repeat; + background-size: 40%; + background-position: 65px; + text-indent: -5000px; +} + +.build-info-panel { + +} + + .build-info-panel .box-header h1.box-title { + border: 0; + font-size: 1.5em; + font-weight: bold; + margin-left: 110px; + } + + .build-info-panel h1.box-title span { + font-weight: normal; + } + + .build-info-panel img { + border: 2px solid #fff; + border-radius: 50%; + margin-top: -40px; + } + + .build-info-panel #build-info { + margin-left: 110px; + min-height: 50px; + } + + .build-info-panel .commit-message { + margin-bottom: 20px; + } + +.small-box h3 a, .small-box h4 a { + color: #fff; +} + +.pagination>li>span { + font-weight: bold; + background: #337ab7; + color: #fff; +} + +#plugins table td { + max-width: 300px; + overflow: hidden; + text-overflow: ellipsis; +} + +.small-box > .inner { + border-bottom: 1px solid rgba(0, 0, 0, 0.15); +} + +.small-box > .small-box-footer-project { + width: 60%; + float: left; +} +.small-box > .small-box-footer-build { + width: 8%; + float: left; +} +.small-box-minimal > .inner { + width: 71%; + float: left; +} +.small-box-minimal > .small-box-footer-build { + width: 5%; + border: 1px solid rgba(0, 0, 0, 0.15); + margin-left: 1px; + margin-top: 19px; + font-size: 11px; +} + +#phpunit-data th div { margin: 0 0.5em; } +#phpunit-data .success td { background: none; color: #00a65a; } +#phpunit-data .fail td { background: none; color: #f56954; } +#phpunit-data .error td { background: none; color: #f56954; } +#phpunit-data .skipped td { background: none; color: #e08e0b; } +#phpunit-data .todo td { background: none; color: #00c0ef; } diff --git a/public/assets/css/AdminLTE-skins.min.css b/public/assets/css/AdminLTE-skins.min.css new file mode 100644 index 00000000..1710db5c --- /dev/null +++ b/public/assets/css/AdminLTE-skins.min.css @@ -0,0 +1 @@ +.skin-blue .main-header .navbar{background-color:#3c8dbc}.skin-blue .main-header .navbar .nav>li>a{color:#fff}.skin-blue .main-header .navbar .nav>li>a:hover,.skin-blue .main-header .navbar .nav>li>a:active,.skin-blue .main-header .navbar .nav>li>a:focus,.skin-blue .main-header .navbar .nav .open>a,.skin-blue .main-header .navbar .nav .open>a:hover,.skin-blue .main-header .navbar .nav .open>a:focus,.skin-blue .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-blue .main-header .navbar .sidebar-toggle{color:#fff}.skin-blue .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-blue .main-header .navbar .sidebar-toggle{color:#fff}.skin-blue .main-header .navbar .sidebar-toggle:hover{background-color:#367fa9}@media (max-width:767px){.skin-blue .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-blue .main-header .navbar .dropdown-menu li a{color:#fff}.skin-blue .main-header .navbar .dropdown-menu li a:hover{background:#367fa9}}.skin-blue .main-header .logo{background-color:#367fa9;color:#fff;border-bottom:0 solid transparent}.skin-blue .main-header .logo:hover{background-color:#357ca5}.skin-blue .main-header li.user-header{background-color:#3c8dbc}.skin-blue .content-header{background:transparent}.skin-blue .wrapper,.skin-blue .main-sidebar,.skin-blue .left-side{background-color:#222d32}.skin-blue .user-panel>.info,.skin-blue .user-panel>.info>a{color:#fff}.skin-blue .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-blue .sidebar-menu>li>a{border-left:3px solid transparent}.skin-blue .sidebar-menu>li:hover>a,.skin-blue .sidebar-menu>li.active>a{color:#fff;background:#1e282c;border-left-color:#3c8dbc}.skin-blue .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-blue .sidebar a{color:#b8c7ce}.skin-blue .sidebar a:hover{text-decoration:none}.skin-blue .treeview-menu>li>a{color:#8aa4af}.skin-blue .treeview-menu>li.active>a,.skin-blue .treeview-menu>li>a:hover{color:#fff}.skin-blue .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px 10px}.skin-blue .sidebar-form input[type="text"],.skin-blue .sidebar-form .btn{box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px;-webkit-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.skin-blue .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-blue .sidebar-form input[type="text"]:focus,.skin-blue .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-blue .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-blue .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-blue.layout-top-nav .main-header>.logo{background-color:#3c8dbc;color:#fff;border-bottom:0 solid transparent}.skin-blue.layout-top-nav .main-header>.logo:hover{background-color:#3b8ab8}.skin-blue-light .main-header .navbar{background-color:#3c8dbc}.skin-blue-light .main-header .navbar .nav>li>a{color:#fff}.skin-blue-light .main-header .navbar .nav>li>a:hover,.skin-blue-light .main-header .navbar .nav>li>a:active,.skin-blue-light .main-header .navbar .nav>li>a:focus,.skin-blue-light .main-header .navbar .nav .open>a,.skin-blue-light .main-header .navbar .nav .open>a:hover,.skin-blue-light .main-header .navbar .nav .open>a:focus,.skin-blue-light .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-blue-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-blue-light .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-blue-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-blue-light .main-header .navbar .sidebar-toggle:hover{background-color:#367fa9}@media (max-width:767px){.skin-blue-light .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-blue-light .main-header .navbar .dropdown-menu li a{color:#fff}.skin-blue-light .main-header .navbar .dropdown-menu li a:hover{background:#367fa9}}.skin-blue-light .main-header .logo{background-color:#3c8dbc;color:#fff;border-bottom:0 solid transparent}.skin-blue-light .main-header .logo:hover{background-color:#3b8ab8}.skin-blue-light .main-header li.user-header{background-color:#3c8dbc}.skin-blue-light .content-header{background:transparent}.skin-blue-light .wrapper,.skin-blue-light .main-sidebar,.skin-blue-light .left-side{background-color:#f9fafc}.skin-blue-light .content-wrapper,.skin-blue-light .main-footer{border-left:1px solid #d2d6de}.skin-blue-light .user-panel>.info,.skin-blue-light .user-panel>.info>a{color:#444}.skin-blue-light .sidebar-menu>li{-webkit-transition:border-left-color .3s ease;-o-transition:border-left-color .3s ease;transition:border-left-color .3s ease}.skin-blue-light .sidebar-menu>li.header{color:#848484;background:#f9fafc}.skin-blue-light .sidebar-menu>li>a{border-left:3px solid transparent;font-weight:600}.skin-blue-light .sidebar-menu>li:hover>a,.skin-blue-light .sidebar-menu>li.active>a{color:#000;background:#f4f4f5}.skin-blue-light .sidebar-menu>li.active{border-left-color:#3c8dbc}.skin-blue-light .sidebar-menu>li.active>a{font-weight:600}.skin-blue-light .sidebar-menu>li>.treeview-menu{background:#f4f4f5}.skin-blue-light .sidebar a{color:#444}.skin-blue-light .sidebar a:hover{text-decoration:none}.skin-blue-light .treeview-menu>li>a{color:#777}.skin-blue-light .treeview-menu>li.active>a,.skin-blue-light .treeview-menu>li>a:hover{color:#000}.skin-blue-light .treeview-menu>li.active>a{font-weight:600}.skin-blue-light .sidebar-form{border-radius:3px;border:1px solid #d2d6de;margin:10px 10px}.skin-blue-light .sidebar-form input[type="text"],.skin-blue-light .sidebar-form .btn{box-shadow:none;background-color:#fff;border:1px solid transparent;height:35px;-webkit-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.skin-blue-light .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-blue-light .sidebar-form input[type="text"]:focus,.skin-blue-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-blue-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-blue-light .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}@media (min-width:768px){.skin-blue-light.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu{border-left:1px solid #d2d6de}}.skin-blue-light .main-footer{border-top-color:#d2d6de}.skin-blue.layout-top-nav .main-header>.logo{background-color:#3c8dbc;color:#fff;border-bottom:0 solid transparent}.skin-blue.layout-top-nav .main-header>.logo:hover{background-color:#3b8ab8}.skin-black .main-header{-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.skin-black .main-header .navbar-toggle{color:#333}.skin-black .main-header .navbar-brand{color:#333;border-right:1px solid #eee}.skin-black .main-header>.navbar{background-color:#fff}.skin-black .main-header>.navbar .nav>li>a{color:#333}.skin-black .main-header>.navbar .nav>li>a:hover,.skin-black .main-header>.navbar .nav>li>a:active,.skin-black .main-header>.navbar .nav>li>a:focus,.skin-black .main-header>.navbar .nav .open>a,.skin-black .main-header>.navbar .nav .open>a:hover,.skin-black .main-header>.navbar .nav .open>a:focus,.skin-black .main-header>.navbar .nav>.active>a{background:#fff;color:#999}.skin-black .main-header>.navbar .sidebar-toggle{color:#333}.skin-black .main-header>.navbar .sidebar-toggle:hover{color:#999;background:#fff}.skin-black .main-header>.navbar>.sidebar-toggle{color:#333;border-right:1px solid #eee}.skin-black .main-header>.navbar .navbar-nav>li>a{border-right:1px solid #eee}.skin-black .main-header>.navbar .navbar-custom-menu .navbar-nav>li>a,.skin-black .main-header>.navbar .navbar-right>li>a{border-left:1px solid #eee;border-right-width:0}.skin-black .main-header>.logo{background-color:#fff;color:#333;border-bottom:0 solid transparent;border-right:1px solid #eee}.skin-black .main-header>.logo:hover{background-color:#fcfcfc}@media (max-width:767px){.skin-black .main-header>.logo{background-color:#222;color:#fff;border-bottom:0 solid transparent;border-right:none}.skin-black .main-header>.logo:hover{background-color:#1f1f1f}}.skin-black .main-header li.user-header{background-color:#222}.skin-black .content-header{background:transparent;box-shadow:none}.skin-black .wrapper,.skin-black .main-sidebar,.skin-black .left-side{background-color:#222d32}.skin-black .user-panel>.info,.skin-black .user-panel>.info>a{color:#fff}.skin-black .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-black .sidebar-menu>li>a{border-left:3px solid transparent}.skin-black .sidebar-menu>li:hover>a,.skin-black .sidebar-menu>li.active>a{color:#fff;background:#1e282c;border-left-color:#fff}.skin-black .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-black .sidebar a{color:#b8c7ce}.skin-black .sidebar a:hover{text-decoration:none}.skin-black .treeview-menu>li>a{color:#8aa4af}.skin-black .treeview-menu>li.active>a,.skin-black .treeview-menu>li>a:hover{color:#fff}.skin-black .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px 10px}.skin-black .sidebar-form input[type="text"],.skin-black .sidebar-form .btn{box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px;-webkit-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.skin-black .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-black .sidebar-form input[type="text"]:focus,.skin-black .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-black .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-black .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-black-light .main-header{-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.skin-black-light .main-header .navbar-toggle{color:#333}.skin-black-light .main-header .navbar-brand{color:#333;border-right:1px solid #eee}.skin-black-light .main-header>.navbar{background-color:#fff}.skin-black-light .main-header>.navbar .nav>li>a{color:#333}.skin-black-light .main-header>.navbar .nav>li>a:hover,.skin-black-light .main-header>.navbar .nav>li>a:active,.skin-black-light .main-header>.navbar .nav>li>a:focus,.skin-black-light .main-header>.navbar .nav .open>a,.skin-black-light .main-header>.navbar .nav .open>a:hover,.skin-black-light .main-header>.navbar .nav .open>a:focus,.skin-black-light .main-header>.navbar .nav>.active>a{background:#fff;color:#999}.skin-black-light .main-header>.navbar .sidebar-toggle{color:#333}.skin-black-light .main-header>.navbar .sidebar-toggle:hover{color:#999;background:#fff}.skin-black-light .main-header>.navbar>.sidebar-toggle{color:#333;border-right:1px solid #eee}.skin-black-light .main-header>.navbar .navbar-nav>li>a{border-right:1px solid #eee}.skin-black-light .main-header>.navbar .navbar-custom-menu .navbar-nav>li>a,.skin-black-light .main-header>.navbar .navbar-right>li>a{border-left:1px solid #eee;border-right-width:0}.skin-black-light .main-header>.logo{background-color:#fff;color:#333;border-bottom:0 solid transparent;border-right:1px solid #eee}.skin-black-light .main-header>.logo:hover{background-color:#fcfcfc}@media (max-width:767px){.skin-black-light .main-header>.logo{background-color:#222;color:#fff;border-bottom:0 solid transparent;border-right:none}.skin-black-light .main-header>.logo:hover{background-color:#1f1f1f}}.skin-black-light .main-header li.user-header{background-color:#222}.skin-black-light .content-header{background:transparent;box-shadow:none}.skin-black-light .wrapper,.skin-black-light .main-sidebar,.skin-black-light .left-side{background-color:#f9fafc}.skin-black-light .content-wrapper,.skin-black-light .main-footer{border-left:1px solid #d2d6de}.skin-black-light .user-panel>.info,.skin-black-light .user-panel>.info>a{color:#444}.skin-black-light .sidebar-menu>li{-webkit-transition:border-left-color .3s ease;-o-transition:border-left-color .3s ease;transition:border-left-color .3s ease}.skin-black-light .sidebar-menu>li.header{color:#848484;background:#f9fafc}.skin-black-light .sidebar-menu>li>a{border-left:3px solid transparent;font-weight:600}.skin-black-light .sidebar-menu>li:hover>a,.skin-black-light .sidebar-menu>li.active>a{color:#000;background:#f4f4f5}.skin-black-light .sidebar-menu>li.active{border-left-color:#fff}.skin-black-light .sidebar-menu>li.active>a{font-weight:600}.skin-black-light .sidebar-menu>li>.treeview-menu{background:#f4f4f5}.skin-black-light .sidebar a{color:#444}.skin-black-light .sidebar a:hover{text-decoration:none}.skin-black-light .treeview-menu>li>a{color:#777}.skin-black-light .treeview-menu>li.active>a,.skin-black-light .treeview-menu>li>a:hover{color:#000}.skin-black-light .treeview-menu>li.active>a{font-weight:600}.skin-black-light .sidebar-form{border-radius:3px;border:1px solid #d2d6de;margin:10px 10px}.skin-black-light .sidebar-form input[type="text"],.skin-black-light .sidebar-form .btn{box-shadow:none;background-color:#fff;border:1px solid transparent;height:35px;-webkit-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.skin-black-light .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-black-light .sidebar-form input[type="text"]:focus,.skin-black-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-black-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-black-light .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}@media (min-width:768px){.skin-black-light.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu{border-left:1px solid #d2d6de}}.skin-green .main-header .navbar{background-color:#00a65a}.skin-green .main-header .navbar .nav>li>a{color:#fff}.skin-green .main-header .navbar .nav>li>a:hover,.skin-green .main-header .navbar .nav>li>a:active,.skin-green .main-header .navbar .nav>li>a:focus,.skin-green .main-header .navbar .nav .open>a,.skin-green .main-header .navbar .nav .open>a:hover,.skin-green .main-header .navbar .nav .open>a:focus,.skin-green .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-green .main-header .navbar .sidebar-toggle{color:#fff}.skin-green .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-green .main-header .navbar .sidebar-toggle{color:#fff}.skin-green .main-header .navbar .sidebar-toggle:hover{background-color:#008d4c}@media (max-width:767px){.skin-green .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-green .main-header .navbar .dropdown-menu li a{color:#fff}.skin-green .main-header .navbar .dropdown-menu li a:hover{background:#008d4c}}.skin-green .main-header .logo{background-color:#008d4c;color:#fff;border-bottom:0 solid transparent}.skin-green .main-header .logo:hover{background-color:#008749}.skin-green .main-header li.user-header{background-color:#00a65a}.skin-green .content-header{background:transparent}.skin-green .wrapper,.skin-green .main-sidebar,.skin-green .left-side{background-color:#222d32}.skin-green .user-panel>.info,.skin-green .user-panel>.info>a{color:#fff}.skin-green .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-green .sidebar-menu>li>a{border-left:3px solid transparent}.skin-green .sidebar-menu>li:hover>a,.skin-green .sidebar-menu>li.active>a{color:#fff;background:#1e282c;border-left-color:#00a65a}.skin-green .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-green .sidebar a{color:#b8c7ce}.skin-green .sidebar a:hover{text-decoration:none}.skin-green .treeview-menu>li>a{color:#8aa4af}.skin-green .treeview-menu>li.active>a,.skin-green .treeview-menu>li>a:hover{color:#fff}.skin-green .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px 10px}.skin-green .sidebar-form input[type="text"],.skin-green .sidebar-form .btn{box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px;-webkit-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.skin-green .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-green .sidebar-form input[type="text"]:focus,.skin-green .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-green .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-green .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-green-light .main-header .navbar{background-color:#00a65a}.skin-green-light .main-header .navbar .nav>li>a{color:#fff}.skin-green-light .main-header .navbar .nav>li>a:hover,.skin-green-light .main-header .navbar .nav>li>a:active,.skin-green-light .main-header .navbar .nav>li>a:focus,.skin-green-light .main-header .navbar .nav .open>a,.skin-green-light .main-header .navbar .nav .open>a:hover,.skin-green-light .main-header .navbar .nav .open>a:focus,.skin-green-light .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-green-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-green-light .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-green-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-green-light .main-header .navbar .sidebar-toggle:hover{background-color:#008d4c}@media (max-width:767px){.skin-green-light .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-green-light .main-header .navbar .dropdown-menu li a{color:#fff}.skin-green-light .main-header .navbar .dropdown-menu li a:hover{background:#008d4c}}.skin-green-light .main-header .logo{background-color:#00a65a;color:#fff;border-bottom:0 solid transparent}.skin-green-light .main-header .logo:hover{background-color:#00a157}.skin-green-light .main-header li.user-header{background-color:#00a65a}.skin-green-light .content-header{background:transparent}.skin-green-light .wrapper,.skin-green-light .main-sidebar,.skin-green-light .left-side{background-color:#f9fafc}.skin-green-light .content-wrapper,.skin-green-light .main-footer{border-left:1px solid #d2d6de}.skin-green-light .user-panel>.info,.skin-green-light .user-panel>.info>a{color:#444}.skin-green-light .sidebar-menu>li{-webkit-transition:border-left-color .3s ease;-o-transition:border-left-color .3s ease;transition:border-left-color .3s ease}.skin-green-light .sidebar-menu>li.header{color:#848484;background:#f9fafc}.skin-green-light .sidebar-menu>li>a{border-left:3px solid transparent;font-weight:600}.skin-green-light .sidebar-menu>li:hover>a,.skin-green-light .sidebar-menu>li.active>a{color:#000;background:#f4f4f5}.skin-green-light .sidebar-menu>li.active{border-left-color:#00a65a}.skin-green-light .sidebar-menu>li.active>a{font-weight:600}.skin-green-light .sidebar-menu>li>.treeview-menu{background:#f4f4f5}.skin-green-light .sidebar a{color:#444}.skin-green-light .sidebar a:hover{text-decoration:none}.skin-green-light .treeview-menu>li>a{color:#777}.skin-green-light .treeview-menu>li.active>a,.skin-green-light .treeview-menu>li>a:hover{color:#000}.skin-green-light .treeview-menu>li.active>a{font-weight:600}.skin-green-light .sidebar-form{border-radius:3px;border:1px solid #d2d6de;margin:10px 10px}.skin-green-light .sidebar-form input[type="text"],.skin-green-light .sidebar-form .btn{box-shadow:none;background-color:#fff;border:1px solid transparent;height:35px;-webkit-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.skin-green-light .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-green-light .sidebar-form input[type="text"]:focus,.skin-green-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-green-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-green-light .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}@media (min-width:768px){.skin-green-light.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu{border-left:1px solid #d2d6de}}.skin-red .main-header .navbar{background-color:#dd4b39}.skin-red .main-header .navbar .nav>li>a{color:#fff}.skin-red .main-header .navbar .nav>li>a:hover,.skin-red .main-header .navbar .nav>li>a:active,.skin-red .main-header .navbar .nav>li>a:focus,.skin-red .main-header .navbar .nav .open>a,.skin-red .main-header .navbar .nav .open>a:hover,.skin-red .main-header .navbar .nav .open>a:focus,.skin-red .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-red .main-header .navbar .sidebar-toggle{color:#fff}.skin-red .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-red .main-header .navbar .sidebar-toggle{color:#fff}.skin-red .main-header .navbar .sidebar-toggle:hover{background-color:#d73925}@media (max-width:767px){.skin-red .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-red .main-header .navbar .dropdown-menu li a{color:#fff}.skin-red .main-header .navbar .dropdown-menu li a:hover{background:#d73925}}.skin-red .main-header .logo{background-color:#d73925;color:#fff;border-bottom:0 solid transparent}.skin-red .main-header .logo:hover{background-color:#d33724}.skin-red .main-header li.user-header{background-color:#dd4b39}.skin-red .content-header{background:transparent}.skin-red .wrapper,.skin-red .main-sidebar,.skin-red .left-side{background-color:#222d32}.skin-red .user-panel>.info,.skin-red .user-panel>.info>a{color:#fff}.skin-red .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-red .sidebar-menu>li>a{border-left:3px solid transparent}.skin-red .sidebar-menu>li:hover>a,.skin-red .sidebar-menu>li.active>a{color:#fff;background:#1e282c;border-left-color:#dd4b39}.skin-red .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-red .sidebar a{color:#b8c7ce}.skin-red .sidebar a:hover{text-decoration:none}.skin-red .treeview-menu>li>a{color:#8aa4af}.skin-red .treeview-menu>li.active>a,.skin-red .treeview-menu>li>a:hover{color:#fff}.skin-red .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px 10px}.skin-red .sidebar-form input[type="text"],.skin-red .sidebar-form .btn{box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px;-webkit-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.skin-red .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-red .sidebar-form input[type="text"]:focus,.skin-red .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-red .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-red .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-red-light .main-header .navbar{background-color:#dd4b39}.skin-red-light .main-header .navbar .nav>li>a{color:#fff}.skin-red-light .main-header .navbar .nav>li>a:hover,.skin-red-light .main-header .navbar .nav>li>a:active,.skin-red-light .main-header .navbar .nav>li>a:focus,.skin-red-light .main-header .navbar .nav .open>a,.skin-red-light .main-header .navbar .nav .open>a:hover,.skin-red-light .main-header .navbar .nav .open>a:focus,.skin-red-light .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-red-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-red-light .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-red-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-red-light .main-header .navbar .sidebar-toggle:hover{background-color:#d73925}@media (max-width:767px){.skin-red-light .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-red-light .main-header .navbar .dropdown-menu li a{color:#fff}.skin-red-light .main-header .navbar .dropdown-menu li a:hover{background:#d73925}}.skin-red-light .main-header .logo{background-color:#dd4b39;color:#fff;border-bottom:0 solid transparent}.skin-red-light .main-header .logo:hover{background-color:#dc4735}.skin-red-light .main-header li.user-header{background-color:#dd4b39}.skin-red-light .content-header{background:transparent}.skin-red-light .wrapper,.skin-red-light .main-sidebar,.skin-red-light .left-side{background-color:#f9fafc}.skin-red-light .content-wrapper,.skin-red-light .main-footer{border-left:1px solid #d2d6de}.skin-red-light .user-panel>.info,.skin-red-light .user-panel>.info>a{color:#444}.skin-red-light .sidebar-menu>li{-webkit-transition:border-left-color .3s ease;-o-transition:border-left-color .3s ease;transition:border-left-color .3s ease}.skin-red-light .sidebar-menu>li.header{color:#848484;background:#f9fafc}.skin-red-light .sidebar-menu>li>a{border-left:3px solid transparent;font-weight:600}.skin-red-light .sidebar-menu>li:hover>a,.skin-red-light .sidebar-menu>li.active>a{color:#000;background:#f4f4f5}.skin-red-light .sidebar-menu>li.active{border-left-color:#dd4b39}.skin-red-light .sidebar-menu>li.active>a{font-weight:600}.skin-red-light .sidebar-menu>li>.treeview-menu{background:#f4f4f5}.skin-red-light .sidebar a{color:#444}.skin-red-light .sidebar a:hover{text-decoration:none}.skin-red-light .treeview-menu>li>a{color:#777}.skin-red-light .treeview-menu>li.active>a,.skin-red-light .treeview-menu>li>a:hover{color:#000}.skin-red-light .treeview-menu>li.active>a{font-weight:600}.skin-red-light .sidebar-form{border-radius:3px;border:1px solid #d2d6de;margin:10px 10px}.skin-red-light .sidebar-form input[type="text"],.skin-red-light .sidebar-form .btn{box-shadow:none;background-color:#fff;border:1px solid transparent;height:35px;-webkit-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.skin-red-light .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-red-light .sidebar-form input[type="text"]:focus,.skin-red-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-red-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-red-light .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}@media (min-width:768px){.skin-red-light.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu{border-left:1px solid #d2d6de}}.skin-yellow .main-header .navbar{background-color:#f39c12}.skin-yellow .main-header .navbar .nav>li>a{color:#fff}.skin-yellow .main-header .navbar .nav>li>a:hover,.skin-yellow .main-header .navbar .nav>li>a:active,.skin-yellow .main-header .navbar .nav>li>a:focus,.skin-yellow .main-header .navbar .nav .open>a,.skin-yellow .main-header .navbar .nav .open>a:hover,.skin-yellow .main-header .navbar .nav .open>a:focus,.skin-yellow .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-yellow .main-header .navbar .sidebar-toggle{color:#fff}.skin-yellow .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-yellow .main-header .navbar .sidebar-toggle{color:#fff}.skin-yellow .main-header .navbar .sidebar-toggle:hover{background-color:#e08e0b}@media (max-width:767px){.skin-yellow .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-yellow .main-header .navbar .dropdown-menu li a{color:#fff}.skin-yellow .main-header .navbar .dropdown-menu li a:hover{background:#e08e0b}}.skin-yellow .main-header .logo{background-color:#e08e0b;color:#fff;border-bottom:0 solid transparent}.skin-yellow .main-header .logo:hover{background-color:#db8b0b}.skin-yellow .main-header li.user-header{background-color:#f39c12}.skin-yellow .content-header{background:transparent}.skin-yellow .wrapper,.skin-yellow .main-sidebar,.skin-yellow .left-side{background-color:#222d32}.skin-yellow .user-panel>.info,.skin-yellow .user-panel>.info>a{color:#fff}.skin-yellow .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-yellow .sidebar-menu>li>a{border-left:3px solid transparent}.skin-yellow .sidebar-menu>li:hover>a,.skin-yellow .sidebar-menu>li.active>a{color:#fff;background:#1e282c;border-left-color:#f39c12}.skin-yellow .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-yellow .sidebar a{color:#b8c7ce}.skin-yellow .sidebar a:hover{text-decoration:none}.skin-yellow .treeview-menu>li>a{color:#8aa4af}.skin-yellow .treeview-menu>li.active>a,.skin-yellow .treeview-menu>li>a:hover{color:#fff}.skin-yellow .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px 10px}.skin-yellow .sidebar-form input[type="text"],.skin-yellow .sidebar-form .btn{box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px;-webkit-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.skin-yellow .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-yellow .sidebar-form input[type="text"]:focus,.skin-yellow .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-yellow .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-yellow .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-yellow-light .main-header .navbar{background-color:#f39c12}.skin-yellow-light .main-header .navbar .nav>li>a{color:#fff}.skin-yellow-light .main-header .navbar .nav>li>a:hover,.skin-yellow-light .main-header .navbar .nav>li>a:active,.skin-yellow-light .main-header .navbar .nav>li>a:focus,.skin-yellow-light .main-header .navbar .nav .open>a,.skin-yellow-light .main-header .navbar .nav .open>a:hover,.skin-yellow-light .main-header .navbar .nav .open>a:focus,.skin-yellow-light .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-yellow-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-yellow-light .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-yellow-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-yellow-light .main-header .navbar .sidebar-toggle:hover{background-color:#e08e0b}@media (max-width:767px){.skin-yellow-light .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-yellow-light .main-header .navbar .dropdown-menu li a{color:#fff}.skin-yellow-light .main-header .navbar .dropdown-menu li a:hover{background:#e08e0b}}.skin-yellow-light .main-header .logo{background-color:#f39c12;color:#fff;border-bottom:0 solid transparent}.skin-yellow-light .main-header .logo:hover{background-color:#f39a0d}.skin-yellow-light .main-header li.user-header{background-color:#f39c12}.skin-yellow-light .content-header{background:transparent}.skin-yellow-light .wrapper,.skin-yellow-light .main-sidebar,.skin-yellow-light .left-side{background-color:#f9fafc}.skin-yellow-light .content-wrapper,.skin-yellow-light .main-footer{border-left:1px solid #d2d6de}.skin-yellow-light .user-panel>.info,.skin-yellow-light .user-panel>.info>a{color:#444}.skin-yellow-light .sidebar-menu>li{-webkit-transition:border-left-color .3s ease;-o-transition:border-left-color .3s ease;transition:border-left-color .3s ease}.skin-yellow-light .sidebar-menu>li.header{color:#848484;background:#f9fafc}.skin-yellow-light .sidebar-menu>li>a{border-left:3px solid transparent;font-weight:600}.skin-yellow-light .sidebar-menu>li:hover>a,.skin-yellow-light .sidebar-menu>li.active>a{color:#000;background:#f4f4f5}.skin-yellow-light .sidebar-menu>li.active{border-left-color:#f39c12}.skin-yellow-light .sidebar-menu>li.active>a{font-weight:600}.skin-yellow-light .sidebar-menu>li>.treeview-menu{background:#f4f4f5}.skin-yellow-light .sidebar a{color:#444}.skin-yellow-light .sidebar a:hover{text-decoration:none}.skin-yellow-light .treeview-menu>li>a{color:#777}.skin-yellow-light .treeview-menu>li.active>a,.skin-yellow-light .treeview-menu>li>a:hover{color:#000}.skin-yellow-light .treeview-menu>li.active>a{font-weight:600}.skin-yellow-light .sidebar-form{border-radius:3px;border:1px solid #d2d6de;margin:10px 10px}.skin-yellow-light .sidebar-form input[type="text"],.skin-yellow-light .sidebar-form .btn{box-shadow:none;background-color:#fff;border:1px solid transparent;height:35px;-webkit-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.skin-yellow-light .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-yellow-light .sidebar-form input[type="text"]:focus,.skin-yellow-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-yellow-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-yellow-light .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}@media (min-width:768px){.skin-yellow-light.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu{border-left:1px solid #d2d6de}}.skin-purple .main-header .navbar{background-color:#605ca8}.skin-purple .main-header .navbar .nav>li>a{color:#fff}.skin-purple .main-header .navbar .nav>li>a:hover,.skin-purple .main-header .navbar .nav>li>a:active,.skin-purple .main-header .navbar .nav>li>a:focus,.skin-purple .main-header .navbar .nav .open>a,.skin-purple .main-header .navbar .nav .open>a:hover,.skin-purple .main-header .navbar .nav .open>a:focus,.skin-purple .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-purple .main-header .navbar .sidebar-toggle{color:#fff}.skin-purple .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-purple .main-header .navbar .sidebar-toggle{color:#fff}.skin-purple .main-header .navbar .sidebar-toggle:hover{background-color:#555299}@media (max-width:767px){.skin-purple .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-purple .main-header .navbar .dropdown-menu li a{color:#fff}.skin-purple .main-header .navbar .dropdown-menu li a:hover{background:#555299}}.skin-purple .main-header .logo{background-color:#555299;color:#fff;border-bottom:0 solid transparent}.skin-purple .main-header .logo:hover{background-color:#545096}.skin-purple .main-header li.user-header{background-color:#605ca8}.skin-purple .content-header{background:transparent}.skin-purple .wrapper,.skin-purple .main-sidebar,.skin-purple .left-side{background-color:#222d32}.skin-purple .user-panel>.info,.skin-purple .user-panel>.info>a{color:#fff}.skin-purple .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-purple .sidebar-menu>li>a{border-left:3px solid transparent}.skin-purple .sidebar-menu>li:hover>a,.skin-purple .sidebar-menu>li.active>a{color:#fff;background:#1e282c;border-left-color:#605ca8}.skin-purple .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-purple .sidebar a{color:#b8c7ce}.skin-purple .sidebar a:hover{text-decoration:none}.skin-purple .treeview-menu>li>a{color:#8aa4af}.skin-purple .treeview-menu>li.active>a,.skin-purple .treeview-menu>li>a:hover{color:#fff}.skin-purple .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px 10px}.skin-purple .sidebar-form input[type="text"],.skin-purple .sidebar-form .btn{box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px;-webkit-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.skin-purple .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-purple .sidebar-form input[type="text"]:focus,.skin-purple .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-purple .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-purple .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-purple-light .main-header .navbar{background-color:#605ca8}.skin-purple-light .main-header .navbar .nav>li>a{color:#fff}.skin-purple-light .main-header .navbar .nav>li>a:hover,.skin-purple-light .main-header .navbar .nav>li>a:active,.skin-purple-light .main-header .navbar .nav>li>a:focus,.skin-purple-light .main-header .navbar .nav .open>a,.skin-purple-light .main-header .navbar .nav .open>a:hover,.skin-purple-light .main-header .navbar .nav .open>a:focus,.skin-purple-light .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-purple-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-purple-light .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-purple-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-purple-light .main-header .navbar .sidebar-toggle:hover{background-color:#555299}@media (max-width:767px){.skin-purple-light .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-purple-light .main-header .navbar .dropdown-menu li a{color:#fff}.skin-purple-light .main-header .navbar .dropdown-menu li a:hover{background:#555299}}.skin-purple-light .main-header .logo{background-color:#605ca8;color:#fff;border-bottom:0 solid transparent}.skin-purple-light .main-header .logo:hover{background-color:#5d59a6}.skin-purple-light .main-header li.user-header{background-color:#605ca8}.skin-purple-light .content-header{background:transparent}.skin-purple-light .wrapper,.skin-purple-light .main-sidebar,.skin-purple-light .left-side{background-color:#f9fafc}.skin-purple-light .content-wrapper,.skin-purple-light .main-footer{border-left:1px solid #d2d6de}.skin-purple-light .user-panel>.info,.skin-purple-light .user-panel>.info>a{color:#444}.skin-purple-light .sidebar-menu>li{-webkit-transition:border-left-color .3s ease;-o-transition:border-left-color .3s ease;transition:border-left-color .3s ease}.skin-purple-light .sidebar-menu>li.header{color:#848484;background:#f9fafc}.skin-purple-light .sidebar-menu>li>a{border-left:3px solid transparent;font-weight:600}.skin-purple-light .sidebar-menu>li:hover>a,.skin-purple-light .sidebar-menu>li.active>a{color:#000;background:#f4f4f5}.skin-purple-light .sidebar-menu>li.active{border-left-color:#605ca8}.skin-purple-light .sidebar-menu>li.active>a{font-weight:600}.skin-purple-light .sidebar-menu>li>.treeview-menu{background:#f4f4f5}.skin-purple-light .sidebar a{color:#444}.skin-purple-light .sidebar a:hover{text-decoration:none}.skin-purple-light .treeview-menu>li>a{color:#777}.skin-purple-light .treeview-menu>li.active>a,.skin-purple-light .treeview-menu>li>a:hover{color:#000}.skin-purple-light .treeview-menu>li.active>a{font-weight:600}.skin-purple-light .sidebar-form{border-radius:3px;border:1px solid #d2d6de;margin:10px 10px}.skin-purple-light .sidebar-form input[type="text"],.skin-purple-light .sidebar-form .btn{box-shadow:none;background-color:#fff;border:1px solid transparent;height:35px;-webkit-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.skin-purple-light .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-purple-light .sidebar-form input[type="text"]:focus,.skin-purple-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-purple-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-purple-light .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}@media (min-width:768px){.skin-purple-light.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu{border-left:1px solid #d2d6de}} \ No newline at end of file diff --git a/public/assets/css/AdminLTE.css b/public/assets/css/AdminLTE.css deleted file mode 100755 index cbb95dc3..00000000 --- a/public/assets/css/AdminLTE.css +++ /dev/null @@ -1,3539 +0,0 @@ -@import url(//fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic); -@import url(//fonts.googleapis.com/css?family=Kaushan+Script); -/*! - * AdminLTE v1.2 - * Author: AlmsaeedStudio.com - * License: Open source - MIT - * Please visit http://opensource.org/licenses/MIT for more information -!*/ -/* - Core: General style ----------------------------- -*/ -html, -body { - overflow-x: hidden!important; - font-family: 'Source Sans Pro', sans-serif; - -webkit-font-smoothing: antialiased; - min-height: 100%; - background: #f9f9f9; -} -a { - color: #3c8dbc; -} -a:hover, -a:active, -a:focus { - outline: none; - text-decoration: none; - color: #72afd2; -} -/* Layouts */ -.wrapper { - min-height: 100%; -} -.wrapper:before, -.wrapper:after { - display: table; - content: " "; -} -.wrapper:after { - clear: both; -} -/* Header */ -body > .header { - position: absolute; - top: 0; - left: 0; - right: 0; - z-index: 1030; -} -/* Define 2 column template */ -.right-side, -.left-side { - min-height: 100%; - display: block; -} -/*right side - contins main content*/ -.right-side { - background-color: #f9f9f9; - margin-left: 220px; -} -/*left side - contains sidebar*/ -.left-side { - position: absolute; - width: 220px; - top: 0; -} -@media screen and (min-width: 992px) { - .left-side { - top: 50px; - } - /*Right side strech mode*/ - .right-side.strech { - margin-left: 0; - } - .right-side.strech > .content-header { - margin-top: 0px; - } - /* Left side collapse */ - .left-side.collapse-left { - left: -220px; - } -} -/*Give content full width on xs screens*/ -@media screen and (max-width: 992px) { - .right-side { - margin-left: 0; - } -} -/* - By default the layout is not fixed but if you add the class .fixed to the body element - the sidebar and the navbar will automatically become poisitioned fixed -*/ -body.fixed > .header, -body.fixed .left-side, -body.fixed .navbar { - position: fixed; -} -body.fixed > .header { - top: 0; - right: 0; - left: 0; -} -body.fixed .navbar { - left: 0; - right: 0; -} -body.fixed .wrapper { - margin-top: 50px; -} -/* Content */ -.content { - padding: 20px 15px; - background: #f9f9f9; - overflow: auto; -} -/* Utility */ -/* H1 - H6 font */ -h1, -h2, -h3, -h4, -h5, -h6, -.h1, -.h2, -.h3, -.h4, -.h5, -.h6 { - font-family: 'Source Sans Pro', sans-serif; -} -/* Page Header */ -.page-header { - margin: 10px 0 20px 0; - font-size: 22px; -} -.page-header > small { - color: #666; - display: block; - margin-top: 5px; -} -/* All images should be responsive */ -img { - max-width: 100% !important; -} -.sort-highlight { - background: #f4f4f4; - border: 1px dashed #ddd; - margin-bottom: 10px; -} -/* 10px padding and margins */ -.pad { - padding: 10px; -} -.margin { - margin: 10px; -} -/* Display inline */ -.inline { - display: inline; - width: auto; -} -/* Background colors */ -.bg-red, -.bg-yellow, -.bg-aqua, -.bg-blue, -.bg-light-blue, -.bg-green, -.bg-navy, -.bg-teal, -.bg-olive, -.bg-lime, -.bg-orange, -.bg-fuchsia, -.bg-purple, -.bg-maroon, -.bg-black { - color: #f9f9f9 !important; -} -.bg-gray { - background-color: #eaeaec !important; -} -.bg-black { - background-color: #222222 !important; -} -.bg-red { - background-color: #f56954 !important; -} -.bg-yellow { - background-color: #f39c12 !important; -} -.bg-aqua { - background-color: #00c0ef !important; -} -.bg-blue { - background-color: #0073b7 !important; -} -.bg-light-blue { - background-color: #3c8dbc !important; -} -.bg-green { - background-color: #00a65a !important; -} -.bg-navy { - background-color: #001f3f !important; -} -.bg-teal { - background-color: #39cccc !important; -} -.bg-olive { - background-color: #3d9970 !important; -} -.bg-lime { - background-color: #01ff70 !important; -} -.bg-orange { - background-color: #ff851b !important; -} -.bg-fuchsia { - background-color: #f012be !important; -} -.bg-purple { - background-color: #932ab6 !important; -} -.bg-maroon { - background-color: #85144b !important; -} -/* Text colors */ -.text-red { - color: #f56954 !important; -} -.text-yellow { - color: #f39c12 !important; -} -.text-aqua { - color: #00c0ef !important; -} -.text-blue { - color: #0073b7 !important; -} -.text-black { - color: #222222 !important; -} -.text-light-blue { - color: #3c8dbc !important; -} -.text-green { - color: #00a65a !important; -} -.text-navy { - color: #001f3f !important; -} -.text-teal { - color: #39cccc !important; -} -.text-olive { - color: #3d9970 !important; -} -.text-lime { - color: #01ff70 !important; -} -.text-orange { - color: #ff851b !important; -} -.text-fuchsia { - color: #f012be !important; -} -.text-purple { - color: #932ab6 !important; -} -.text-maroon { - color: #85144b !important; -} -/*Hide elements by display none only*/ -.hide { - display: none !important; -} -/* Remove borders */ -.no-border { - border: 0px !important; -} -/* Remove padding */ -.no-padding { - padding: 0px !important; -} -/* Remove margins */ -.no-margin { - margin: 0px !important; -} -/* Remove box shadow */ -.no-shadow { - box-shadow: none!important; -} -/* Don't display when printing */ -@media print { - .no-print { - display: none; - } - .left-side, - .header, - .content-header { - display: none; - } - .right-side { - margin: 0; - } -} -/* Remove border radius */ -.flat { - -webkit-border-radius: 0 !important; - -moz-border-radius: 0 !important; - border-radius: 0 !important; -} -/* Change the color of the striped tables */ -.table-striped > tbody > tr:nth-child(odd) > td, -.table-striped > tbody > tr:nth-child(odd) > th { - background-color: #f3f4f5; -} -.table.no-border, -.table.no-border td, -.table.no-border th { - border: 0; -} -/* .text-center in tables */ -table.text-center, -table.text-center td, -table.text-center th { - text-align: center; -} -.table.align th { - text-align: left; -} -.table.align td { - text-align: right; -} -.text-bold, -.text-bold.table td, -.text-bold.table th { - font-weight: 700; -} -.border-radius-none { - -webkit-border-radius: 0 !important; - -moz-border-radius: 0 !important; - border-radius: 0 !important; -} -/* _fix for sparkline tooltip */ -.jqstooltip { - padding: 5px!important; - width: auto!important; - height: auto!important; -} -/* -Gradient Background colors -*/ -.bg-teal-gradient { - background: #39cccc !important; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #39cccc), color-stop(1, #7adddd)) !important; - background: -ms-linear-gradient(bottom, #39cccc, #7adddd) !important; - background: -moz-linear-gradient(center bottom, #39cccc 0%, #7adddd 100%) !important; - background: -o-linear-gradient(#7adddd, #39cccc) !important; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#7adddd', endColorstr='#39cccc', GradientType=0) !important; - color: #fff; -} -.bg-light-blue-gradient { - background: #3c8dbc !important; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #3c8dbc), color-stop(1, #67a8ce)) !important; - background: -ms-linear-gradient(bottom, #3c8dbc, #67a8ce) !important; - background: -moz-linear-gradient(center bottom, #3c8dbc 0%, #67a8ce 100%) !important; - background: -o-linear-gradient(#67a8ce, #3c8dbc) !important; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#67a8ce', endColorstr='#3c8dbc', GradientType=0) !important; - color: #fff; -} -.bg-blue-gradient { - background: #0073b7 !important; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #0073b7), color-stop(1, #0089db)) !important; - background: -ms-linear-gradient(bottom, #0073b7, #0089db) !important; - background: -moz-linear-gradient(center bottom, #0073b7 0%, #0089db 100%) !important; - background: -o-linear-gradient(#0089db, #0073b7) !important; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0089db', endColorstr='#0073b7', GradientType=0) !important; - color: #fff; -} -.bg-aqua-gradient { - background: #00c0ef !important; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #00c0ef), color-stop(1, #14d1ff)) !important; - background: -ms-linear-gradient(bottom, #00c0ef, #14d1ff) !important; - background: -moz-linear-gradient(center bottom, #00c0ef 0%, #14d1ff 100%) !important; - background: -o-linear-gradient(#14d1ff, #00c0ef) !important; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#14d1ff', endColorstr='#00c0ef', GradientType=0) !important; - color: #fff; -} -.bg-yellow-gradient { - background: #f39c12 !important; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #f39c12), color-stop(1, #f7bc60)) !important; - background: -ms-linear-gradient(bottom, #f39c12, #f7bc60) !important; - background: -moz-linear-gradient(center bottom, #f39c12 0%, #f7bc60 100%) !important; - background: -o-linear-gradient(#f7bc60, #f39c12) !important; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f7bc60', endColorstr='#f39c12', GradientType=0) !important; - color: #fff; -} -.bg-purple-gradient { - background: #932ab6 !important; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #932ab6), color-stop(1, #b959d9)) !important; - background: -ms-linear-gradient(bottom, #932ab6, #b959d9) !important; - background: -moz-linear-gradient(center bottom, #932ab6 0%, #b959d9 100%) !important; - background: -o-linear-gradient(#b959d9, #932ab6) !important; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#b959d9', endColorstr='#932ab6', GradientType=0) !important; - color: #fff; -} -.bg-green-gradient { - background: #00a65a !important; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #00a65a), color-stop(1, #00ca6d)) !important; - background: -ms-linear-gradient(bottom, #00a65a, #00ca6d) !important; - background: -moz-linear-gradient(center bottom, #00a65a 0%, #00ca6d 100%) !important; - background: -o-linear-gradient(#00ca6d, #00a65a) !important; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ca6d', endColorstr='#00a65a', GradientType=0) !important; - color: #fff; -} -.bg-red-gradient { - background: #f56954 !important; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #f56954), color-stop(1, #f89384)) !important; - background: -ms-linear-gradient(bottom, #f56954, #f89384) !important; - background: -moz-linear-gradient(center bottom, #f56954 0%, #f89384 100%) !important; - background: -o-linear-gradient(#f89384, #f56954) !important; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f89384', endColorstr='#f56954', GradientType=0) !important; - color: #fff; -} -.bg-black-gradient { - background: #222222 !important; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #222222), color-stop(1, #3c3c3c)) !important; - background: -ms-linear-gradient(bottom, #222222, #3c3c3c) !important; - background: -moz-linear-gradient(center bottom, #222222 0%, #3c3c3c 100%) !important; - background: -o-linear-gradient(#3c3c3c, #222222) !important; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#3c3c3c', endColorstr='#222222', GradientType=0) !important; - color: #fff; -} -.bg-maroon-gradient { - background: #85144b !important; - background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #85144b), color-stop(1, #b11b64)) !important; - background: -ms-linear-gradient(bottom, #85144b, #b11b64) !important; - background: -moz-linear-gradient(center bottom, #85144b 0%, #b11b64 100%) !important; - background: -o-linear-gradient(#b11b64, #85144b) !important; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#b11b64', endColorstr='#85144b', GradientType=0) !important; - color: #fff; -} -.connectedSortable { - min-height: 100px; -} -/*--------------------------------------------------- - LESS Elements 0.9 - --------------------------------------------------- - A set of useful LESS mixins - More info at: http://lesselements.com - ---------------------------------------------------*/ -/* - Components: navbar, logo and content header -------------------------------------------------- -*/ -body > .header { - position: relative; - max-height: 100px; - z-index: 1030; -} -body > .header .navbar { - height: 50px; - margin-bottom: 0; - margin-left: 220px; -} -body > .header .navbar .sidebar-toggle { - float: left; - padding: 9px 5px; - margin-top: 8px; - margin-right: 0; - margin-bottom: 8px; - margin-left: 5px; - background-color: transparent; - background-image: none; - border: 1px solid transparent; - -webkit-border-radius: 0 !important; - -moz-border-radius: 0 !important; - border-radius: 0 !important; -} -body > .header .navbar .sidebar-toggle:hover .icon-bar { - background: #f6f6f6; -} -body > .header .navbar .sidebar-toggle .icon-bar { - display: block; - width: 22px; - height: 2px; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} -body > .header .navbar .sidebar-toggle .icon-bar + .icon-bar { - margin-top: 4px; -} -body > .header .navbar .nav > li.user > a { - font-weight: bold; -} -body > .header .navbar .nav > li.user > a > .fa, -body > .header .navbar .nav > li.user > a > .glyphicon, -body > .header .navbar .nav > li.user > a > .ion { - margin-right: 5px; -} -body > .header .navbar .nav > li > a > .label { - -webkit-border-radius: 50%; - -moz-border-radius: 50%; - border-radius: 50%; - position: absolute; - top: 7px; - right: 2px; - font-size: 10px; - font-weight: normal; - width: 15px; - height: 15px; - line-height: 1.0em; - text-align: center; - padding: 2px; -} -body > .header .navbar .nav > li > a:hover > .label { - top: 3px; -} -body > .header .logo { - float: left; - font-size: 20px; - line-height: 50px; - text-align: center; - padding: 0 10px; - width: 220px; - font-family: 'Kaushan Script', cursive; - font-weight: 500; - height: 50px; - display: block; -} -body > .header .logo .icon { - margin-right: 10px; -} -.right-side > .content-header { - position: relative; - padding: 15px 15px 10px 20px; -} -.right-side > .content-header > h1 { - margin: 0; - font-size: 24px; -} -.right-side > .content-header > h1 > small { - font-size: 15px; - display: inline-block; - padding-left: 4px; - font-weight: 300; -} -.right-side > .content-header > .breadcrumb { - float: right; - background: transparent; - margin-top: 0px; - margin-bottom: 0; - font-size: 12px; - padding: 7px 5px; - position: absolute; - top: 15px; - right: 10px; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} -.right-side > .content-header > .breadcrumb > li > a { - color: #444; - text-decoration: none; -} -.right-side > .content-header > .breadcrumb > li > a > .fa, -.right-side > .content-header > .breadcrumb > li > a > .glyphicon, -.right-side > .content-header > .breadcrumb > li > a > .ion { - margin-right: 5px; -} -.right-side > .content-header > .breadcrumb > li + li:before { - content: '>\00a0'; -} -@media screen and (max-width: 767px) { - .right-side > .content-header > .breadcrumb { - position: relative; - margin-top: 5px; - top: 0; - right: 0; - float: none; - background: #efefef; - } -} -@media (max-width: 767px) { - .navbar .navbar-nav > li { - float: left; - } - .navbar-nav { - margin: 0; - float: left; - } - .navbar-nav > li > a { - padding-top: 15px; - padding-bottom: 15px; - line-height: 20px; - } - .navbar .navbar-right { - float: right; - } -} -@media screen and (max-width: 560px) { - body > .header { - position: relative; - } - body > .header .logo, - body > .header .navbar { - width: 100%; - float: none; - position: relative!important; - } - body > .header .navbar { - margin: 0; - } - body.fixed > .header { - position: fixed; - } - body.fixed > .wrapper, - body.fixed .sidebar-offcanvas { - margin-top: 100px!important; - } -} -/* - Component: Sidebar --------------------------- -*/ -.sidebar { - margin-bottom: 5px; -} -.sidebar .sidebar-form input:focus { - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; - border-color: transparent!important; -} -.sidebar .sidebar-menu { - list-style: none; - margin: 0; - padding: 0; -} -.sidebar .sidebar-menu > li { - margin: 0; - padding: 0; -} -.sidebar .sidebar-menu > li > a { - padding: 12px 5px 12px 15px; - display: block; -} -.sidebar .sidebar-menu > li > a > .fa, -.sidebar .sidebar-menu > li > a > .glyphicon, -.sidebar .sidebar-menu > li > a > .ion { - width: 20px; -} -.sidebar .sidebar-menu .treeview-menu { - display: none; - list-style: none; - padding: 0; - margin: 0; -} -.sidebar .sidebar-menu .treeview-menu > li { - margin: 0; -} -.sidebar .sidebar-menu .treeview-menu > li > a { - padding: 5px 5px 5px 15px; - display: block; - font-size: 14px; - margin: 0px 0px; -} -.sidebar .sidebar-menu .treeview-menu > li > a > .fa, -.sidebar .sidebar-menu .treeview-menu > li > a > .glyphicon, -.sidebar .sidebar-menu .treeview-menu > li > a > .ion { - width: 20px; -} -.user-panel { - padding: 10px; -} -.user-panel:before, -.user-panel:after { - display: table; - content: " "; -} -.user-panel:after { - clear: both; -} -.user-panel > .image > img { - width: 45px; - height: 45px; -} -.user-panel > .info { - font-weight: 600; - padding: 5px 5px 5px 15px; - font-size: 14px; - line-height: 1; -} -.user-panel > .info > p { - margin-bottom: 9px; -} -.user-panel > .info > a { - text-decoration: none; - padding-right: 5px; - margin-top: 3px; - font-size: 11px; - font-weight: normal; -} -.user-panel > .info > a > .fa, -.user-panel > .info > a > .ion, -.user-panel > .info > a > .glyphicon { - margin-right: 3px; -} -/* - * Off Canvas - * -------------------------------------------------- - * Gives us the push menu effect - */ -@media screen and (max-width: 992px) { - .relative { - position: relative; - } - .row-offcanvas-right .sidebar-offcanvas { - right: -220px; - } - .row-offcanvas-left .sidebar-offcanvas { - left: -220px; - } - .row-offcanvas-right.active { - right: 220px; - } - .row-offcanvas-left.active { - left: 220px; - } - .sidebar-offcanvas { - left: 0; - } - body.fixed .sidebar-offcanvas { - margin-top: 50px; - left: -220px; - } - body.fixed .row-offcanvas-left.active .navbar { - left: 220px !important; - right: 0; - } - body.fixed .row-offcanvas-left.active .sidebar-offcanvas { - left: 0px; - } -} -/* - Dropdown menus ----------------------------- -*/ -/*Dropdowns in general*/ -.dropdown-menu { - -webkit-box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.1); - box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.1); - z-index: 2300; -} -.dropdown-menu > li > a > .glyphicon, -.dropdown-menu > li > a > .fa, -.dropdown-menu > li > a > .ion { - margin-right: 10px; -} -.dropdown-menu > li > a:hover { - background-color: #3c8dbc; - color: #f9f9f9; -} -/*Drodown in navbars*/ -.skin-blue .navbar .dropdown-menu > li > a { - color: #444444; -} -/* - Navbar custom dropdown menu ------------------------------------- -*/ -.navbar-nav > .notifications-menu > .dropdown-menu, -.navbar-nav > .messages-menu > .dropdown-menu, -.navbar-nav > .tasks-menu > .dropdown-menu { - width: 280px; - padding: 0 0 0 0!important; - margin: 0!important; - top: 100%; - border: 1px solid #dfdfdf; - -webkit-border-radius: 4px !important; - -moz-border-radius: 4px !important; - border-radius: 4px !important; -} -.navbar-nav > .notifications-menu > .dropdown-menu > li.header, -.navbar-nav > .messages-menu > .dropdown-menu > li.header, -.navbar-nav > .tasks-menu > .dropdown-menu > li.header { - -webkit-border-top-left-radius: 4px; - -webkit-border-top-right-radius: 4px; - -webkit-border-bottom-right-radius: 0; - -webkit-border-bottom-left-radius: 0; - -moz-border-radius-topleft: 4px; - -moz-border-radius-topright: 4px; - -moz-border-radius-bottomright: 0; - -moz-border-radius-bottomleft: 0; - border-top-left-radius: 4px; - border-top-right-radius: 4px; - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; - background-color: #ffffff; - padding: 7px 10px; - border-bottom: 1px solid #f4f4f4; - color: #444444; - font-size: 14px; -} -.navbar-nav > .notifications-menu > .dropdown-menu > li.header:after, -.navbar-nav > .messages-menu > .dropdown-menu > li.header:after, -.navbar-nav > .tasks-menu > .dropdown-menu > li.header:after { - bottom: 100%; - left: 92%; - border: solid transparent; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - border-color: rgba(255, 255, 255, 0); - border-bottom-color: #ffffff; - border-width: 7px; - margin-left: -7px; -} -.navbar-nav > .notifications-menu > .dropdown-menu > li.footer > a, -.navbar-nav > .messages-menu > .dropdown-menu > li.footer > a, -.navbar-nav > .tasks-menu > .dropdown-menu > li.footer > a { - -webkit-border-top-left-radius: 0px; - -webkit-border-top-right-radius: 0px; - -webkit-border-bottom-right-radius: 4px; - -webkit-border-bottom-left-radius: 4px; - -moz-border-radius-topleft: 0px; - -moz-border-radius-topright: 0px; - -moz-border-radius-bottomright: 4px; - -moz-border-radius-bottomleft: 4px; - border-top-left-radius: 0px; - border-top-right-radius: 0px; - border-bottom-right-radius: 4px; - border-bottom-left-radius: 4px; - font-size: 12px; - background-color: #f4f4f4; - padding: 7px 10px; - border-bottom: 1px solid #eeeeee; - color: #444444; - text-align: center; -} -.navbar-nav > .notifications-menu > .dropdown-menu > li.footer > a:hover, -.navbar-nav > .messages-menu > .dropdown-menu > li.footer > a:hover, -.navbar-nav > .tasks-menu > .dropdown-menu > li.footer > a:hover { - background: #f4f4f4; - text-decoration: none; - font-weight: normal; -} -.navbar-nav > .notifications-menu > .dropdown-menu > li .menu, -.navbar-nav > .messages-menu > .dropdown-menu > li .menu, -.navbar-nav > .tasks-menu > .dropdown-menu > li .menu { - margin: 0; - padding: 0; - list-style: none; - overflow-x: hidden; -} -.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a, -.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a, -.navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a { - display: block; - white-space: nowrap; - /* Prevent text from breaking */ - border-bottom: 1px solid #f4f4f4; -} -.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a:hover, -.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a:hover, -.navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a:hover { - background: #f6f6f6; - text-decoration: none; -} -.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a { - font-size: 12px; - color: #444444; -} -.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .glyphicon, -.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .fa, -.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .ion { - font-size: 20px; - width: 50px; - text-align: center; - padding: 15px 0px; - margin-right: 5px; - /* Default background and font colors */ - background: #00c0ef; - color: #f9f9f9; - /* Fallback for browsers that doesn't support rgba */ - color: rgba(255, 255, 255, 0.7); -} -.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .glyphicon.danger, -.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .fa.danger, -.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .ion.danger { - background: #f56954; -} -.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .glyphicon.warning, -.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .fa.warning, -.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .ion.warning { - background: #f39c12; -} -.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .glyphicon.success, -.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .fa.success, -.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .ion.success { - background: #00a65a; -} -.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .glyphicon.info, -.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .fa.info, -.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .ion.info { - background: #00c0ef; -} -.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a { - margin: 0px; - line-height: 20px; - padding: 10px 5px 10px 5px; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} -.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a > div > img { - margin: auto 10px auto auto; - width: 40px; - height: 40px; - border: 1px solid #dddddd; -} -.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a > h4 { - padding: 0; - margin: 0 0 0 45px; - color: #444444; - font-size: 15px; -} -.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a > h4 > small { - color: #999999; - font-size: 10px; - float: right; -} -.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a > p { - margin: 0 0 0 45px; - font-size: 12px; - color: #888888; -} -.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a:before, -.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a:after { - display: table; - content: " "; -} -.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a:after { - clear: both; -} -.navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a { - padding: 10px; -} -.navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a > h3 { - font-size: 14px; - padding: 0; - margin: 0 0 10px 0; - color: #666666; -} -.navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a > .progress { - padding: 0; - margin: 0; -} -.navbar-nav > .user-menu > .dropdown-menu { - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; - padding: 1px 0 0 0; - border-top-width: 0; - width: 280px; -} -.navbar-nav > .user-menu > .dropdown-menu:after { - bottom: 100%; - right: 10px; - border: solid transparent; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - border-color: rgba(255, 255, 255, 0); - border-bottom-color: #ffffff; - border-width: 10px; - margin-left: -10px; -} -.navbar-nav > .user-menu > .dropdown-menu > li.user-header { - height: 175px; - padding: 10px; - background: #3c8dbc; - text-align: center; -} -.navbar-nav > .user-menu > .dropdown-menu > li.user-header > img { - z-index: 5; - height: 90px; - width: 90px; - border: 8px solid; - border-color: transparent; - border-color: rgba(255, 255, 255, 0.2); -} -.navbar-nav > .user-menu > .dropdown-menu > li.user-header > p { - z-index: 5; - color: #f9f9f9; - color: rgba(255, 255, 255, 0.8); - font-size: 17px; - text-shadow: 2px 2px 3px #333333; - margin-top: 10px; -} -.navbar-nav > .user-menu > .dropdown-menu > li.user-header > p > small { - display: block; - font-size: 12px; -} -.navbar-nav > .user-menu > .dropdown-menu > li.user-body { - padding: 15px; - border-bottom: 1px solid #f4f4f4; - border-top: 1px solid #dddddd; -} -.navbar-nav > .user-menu > .dropdown-menu > li.user-body:before, -.navbar-nav > .user-menu > .dropdown-menu > li.user-body:after { - display: table; - content: " "; -} -.navbar-nav > .user-menu > .dropdown-menu > li.user-body:after { - clear: both; -} -.navbar-nav > .user-menu > .dropdown-menu > li.user-body > div > a { - color: #0073b7; -} -.navbar-nav > .user-menu > .dropdown-menu > li.user-footer { - background-color: #f9f9f9; - padding: 10px; -} -.navbar-nav > .user-menu > .dropdown-menu > li.user-footer:before, -.navbar-nav > .user-menu > .dropdown-menu > li.user-footer:after { - display: table; - content: " "; -} -.navbar-nav > .user-menu > .dropdown-menu > li.user-footer:after { - clear: both; -} -.navbar-nav > .user-menu > .dropdown-menu > li.user-footer .btn-default { - color: #666666; -} -/* Add fade animation to dropdown menus */ -.open > .dropdown-menu { - animation-name: fadeAnimation; - animation-duration: .7s; - animation-iteration-count: 1; - animation-timing-function: ease; - animation-fill-mode: forwards; - -webkit-animation-name: fadeAnimation; - -webkit-animation-duration: .7s; - -webkit-animation-iteration-count: 1; - -webkit-animation-timing-function: ease; - -webkit-animation-fill-mode: forwards; - -moz-animation-name: fadeAnimation; - -moz-animation-duration: .7s; - -moz-animation-iteration-count: 1; - -moz-animation-timing-function: ease; - -moz-animation-fill-mode: forwards; -} -@keyframes fadeAnimation { - from { - opacity: 0; - top: 120%; - } - to { - opacity: 1; - top: 100%; - } -} -@-webkit-keyframes fadeAnimation { - from { - opacity: 0; - top: 120%; - } - to { - opacity: 1; - top: 100%; - } -} -/* Fix dropdown menu for small screens to display correctly on small screens */ -@media screen and (max-width: 767px) { - .navbar-nav > .notifications-menu > .dropdown-menu, - .navbar-nav > .user-menu > .dropdown-menu, - .navbar-nav > .tasks-menu > .dropdown-menu, - .navbar-nav > .messages-menu > .dropdown-menu { - position: absolute; - top: 100%; - right: 0; - left: auto; - border-right: 1px solid #dddddd; - border-bottom: 1px solid #dddddd; - border-left: 1px solid #dddddd; - background: #ffffff; - } -} -/* Fix menu positions on xs screens to appear correctly and fully */ -@media screen and (max-width: 480px) { - .navbar-nav > .notifications-menu > .dropdown-menu > li.header, - .navbar-nav > .tasks-menu > .dropdown-menu > li.header, - .navbar-nav > .messages-menu > .dropdown-menu > li.header { - /* Remove arrow from the top */ - } - .navbar-nav > .notifications-menu > .dropdown-menu > li.header:after, - .navbar-nav > .tasks-menu > .dropdown-menu > li.header:after, - .navbar-nav > .messages-menu > .dropdown-menu > li.header:after { - border-width: 0px!important; - } - .navbar-nav > .tasks-menu > .dropdown-menu { - position: absolute; - right: -120px; - left: auto; - } - .navbar-nav > .notifications-menu > .dropdown-menu { - position: absolute; - right: -170px; - left: auto; - } - .navbar-nav > .messages-menu > .dropdown-menu { - position: absolute; - right: -210px; - left: auto; - } -} -/* - All form elements including input, select, textarea etc. ------------------------------------------------------------------ -*/ -.form-control { - -webkit-border-radius: 0px !important; - -moz-border-radius: 0px !important; - border-radius: 0px !important; - box-shadow: none; -} -.form-control:focus { - border-color: #3c8dbc !important; - box-shadow: none; -} -.form-group.has-success label { - color: #00a65a; -} -.form-group.has-success .form-control { - border-color: #00a65a !important; - box-shadow: none; -} -.form-group.has-warning label { - color: #f39c12; -} -.form-group.has-warning .form-control { - border-color: #f39c12 !important; - box-shadow: none; -} -.form-group.has-error label { - color: #f56954; -} -.form-group.has-error .form-control { - border-color: #f56954 !important; - box-shadow: none; -} -/* Input group */ -.input-group .input-group-addon { - border-radius: 0; - background-color: #f4f4f4; -} -/* button groups */ -.btn-group-vertical .btn.btn-flat:first-of-type, -.btn-group-vertical .btn.btn-flat:last-of-type { - border-radius: 0; -} -/* Checkbox and radio inputs */ -.checkbox, -.radio { - padding-left: 0; -} -/* - Compenent: Progress bars --------------------------------- -*/ -/* size variation */ -.progress.sm { - height: 10px; -} -.progress.xs { - height: 7px; -} -/* Vertical bars */ -.progress.vertical { - position: relative; - width: 30px; - height: 200px; - display: inline-block; - margin-right: 10px; -} -.progress.vertical > .progress-bar { - width: 100%!important; - position: absolute; - bottom: 0; -} -.progress.vertical.sm { - width: 20px; -} -.progress.vertical.xs { - width: 10px; -} -/* Remove margins from progress bars when put in a table */ -.table tr > td .progress { - margin: 0; -} -.progress-bar-light-blue, -.progress-bar-primary { - background-color: #3c8dbc; -} -.progress-striped .progress-bar-light-blue, -.progress-striped .progress-bar-primary { - 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: 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-bar-green, -.progress-bar-success { - background-color: #00a65a; -} -.progress-striped .progress-bar-green, -.progress-striped .progress-bar-success { - 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: 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-bar-aqua, -.progress-bar-info { - background-color: #00c0ef; -} -.progress-striped .progress-bar-aqua, -.progress-striped .progress-bar-info { - 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: 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-bar-yellow, -.progress-bar-warning { - background-color: #f39c12; -} -.progress-striped .progress-bar-yellow, -.progress-striped .progress-bar-warning { - 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: 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-bar-red, -.progress-bar-danger { - background-color: #f56954; -} -.progress-striped .progress-bar-red, -.progress-striped .progress-bar-danger { - 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: 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); -} -/* - Component: Small boxes -*/ -.small-box { - position: relative; - display: block; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; - margin-bottom: 15px; -} -.small-box > .inner { - padding: 10px; -} -.small-box > .small-box-footer { - position: relative; - text-align: center; - padding: 3px 0; - color: #fff; - color: rgba(255, 255, 255, 0.8); - display: block; - z-index: 10; - background: rgba(0, 0, 0, 0.1); - text-decoration: none; -} -.small-box > .small-box-footer:hover { - color: #fff; - background: rgba(0, 0, 0, 0.15); -} -.small-box h3 { - font-size: 38px; - font-weight: bold; - margin: 0 0 10px 0; - white-space: nowrap; - padding: 0; -} -.small-box p { - font-size: 15px; -} -.small-box p > small { - display: block; - color: #f9f9f9; - font-size: 13px; - margin-top: 5px; -} -.small-box h3, -.small-box p { - z-index: 5px; -} -.small-box .icon { - position: absolute; - top: auto; - bottom: 5px; - right: 5px; - z-index: 0; - font-size: 90px; - color: rgba(0, 0, 0, 0.15); -} -.small-box:hover { - text-decoration: none; - color: #f9f9f9; -} -.small-box:hover .icon { - animation-name: tansformAnimation; - animation-duration: .5s; - animation-iteration-count: 1; - animation-timing-function: ease; - animation-fill-mode: forwards; - -webkit-animation-name: tansformAnimation; - -webkit-animation-duration: .5s; - -webkit-animation-iteration-count: 1; - -webkit-animation-timing-function: ease; - -webkit-animation-fill-mode: forwards; - -moz-animation-name: tansformAnimation; - -moz-animation-duration: .5s; - -moz-animation-iteration-count: 1; - -moz-animation-timing-function: ease; - -moz-animation-fill-mode: forwards; -} -@keyframes tansformAnimation { - from { - font-size: 90px; - } - to { - font-size: 100px; - } -} -@-webkit-keyframes tansformAnimation { - from { - font-size: 90px; - } - to { - font-size: 100px; - } -} -@media screen and (max-width: 480px) { - .small-box { - text-align: center; - } - .small-box .icon { - display: none; - } - .small-box p { - font-size: 12px; - } -} -/* - component: Boxes -------------------------- -*/ -.box { - position: relative; - background: #ffffff; - border-top: 2px solid #c1c1c1; - margin-bottom: 20px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - width: 100%; - box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1); -} -.box.box-primary { - border-top-color: #3c8dbc; -} -.box.box-info { - border-top-color: #00c0ef; -} -.box.box-danger { - border-top-color: #f56954; -} -.box.box-warning { - border-top-color: #f39c12; -} -.box.box-success { - border-top-color: #00a65a; -} -.box.height-control .box-body { - max-height: 300px; - overflow: auto; -} -.box .box-header { - position: relative; - -webkit-border-top-left-radius: 3px; - -webkit-border-top-right-radius: 3px; - -webkit-border-bottom-right-radius: 0; - -webkit-border-bottom-left-radius: 0; - -moz-border-radius-topleft: 3px; - -moz-border-radius-topright: 3px; - -moz-border-radius-bottomright: 0; - -moz-border-radius-bottomleft: 0; - border-top-left-radius: 3px; - border-top-right-radius: 3px; - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; - border-bottom: 0px solid #f4f4f4; - color: #444; -} -.box .box-header:before, -.box .box-header:after { - display: table; - content: " "; -} -.box .box-header:after { - clear: both; -} -.box .box-header > .fa, -.box .box-header > .glyphicon, -.box .box-header > .ion, -.box .box-header .box-title { - display: inline-block; - padding: 10px 10px 10px 10px; - margin: 0; - font-size: 20px; - font-weight: 400; - float: left; - cursor: default; -} -.box .box-header a { - color: #444; -} -.box .box-header > .box-tools { - padding: 5px 10px 5px 5px; -} -.box .box-body { - padding: 10px; - -webkit-border-top-left-radius: 0; - -webkit-border-top-right-radius: 0; - -webkit-border-bottom-right-radius: 3px; - -webkit-border-bottom-left-radius: 3px; - -moz-border-radius-topleft: 0; - -moz-border-radius-topright: 0; - -moz-border-radius-bottomright: 3px; - -moz-border-radius-bottomleft: 3px; - border-top-left-radius: 0; - border-top-right-radius: 0; - border-bottom-right-radius: 3px; - border-bottom-left-radius: 3px; -} -.box .box-body > table, -.box .box-body > .table { - margin-bottom: 0; -} -.box .box-body.chart-responsive { - width: 100%; - overflow: hidden; -} -.box .box-body > .chart { - position: relative; - overflow: hidden; - width: 100%; -} -.box .box-body > .chart svg, -.box .box-body > .chart canvas { - width: 100%!important; -} -.box .box-body .fc { - margin-top: 5px; -} -.box .box-body .fc-header-title h2 { - font-size: 15px; - line-height: 1.6em; - color: #666; - margin-left: 10px; -} -.box .box-body .fc-header-right { - padding-right: 10px; -} -.box .box-body .fc-header-left { - padding-left: 10px; -} -.box .box-body .fc-widget-header { - background: #fafafa; - box-shadow: inset 0px -3px 1px rgba(0, 0, 0, 0.02); -} -.box .box-body .fc-grid { - width: 100%; - border: 0; -} -.box .box-body .fc-widget-header:first-of-type, -.box .box-body .fc-widget-content:first-of-type { - border-left: 0; - border-right: 0; -} -.box .box-body .fc-widget-header:last-of-type, -.box .box-body .fc-widget-content:last-of-type { - border-right: 0; -} -.box .box-body .table { - margin-bottom: 0; -} -.box .box-body .full-width-chart { - margin: -19px; -} -.box .box-body.no-padding .full-width-chart { - margin: -9px; -} -.box .box-footer { - border-top: 1px solid #f4f4f4; - -webkit-border-top-left-radius: 0; - -webkit-border-top-right-radius: 0; - -webkit-border-bottom-right-radius: 3px; - -webkit-border-bottom-left-radius: 3px; - -moz-border-radius-topleft: 0; - -moz-border-radius-topright: 0; - -moz-border-radius-bottomright: 3px; - -moz-border-radius-bottomleft: 3px; - border-top-left-radius: 0; - border-top-right-radius: 0; - border-bottom-right-radius: 3px; - border-bottom-left-radius: 3px; - padding: 10px; - background-color: #ffffff; -} -.box.box-solid { - border-top: 0px; -} -.box.box-solid > .box-header { - padding-bottom: 0px!important; -} -.box.box-solid > .box-header .btn.btn-default { - background: transparent; -} -.box.box-solid.box-primary > .box-header { - color: #fff; - background: #3c8dbc; - background-color: #3c8dbc; -} -.box.box-solid.box-primary > .box-header a { - color: #444; -} -.box.box-solid.box-info > .box-header { - color: #fff; - background: #00c0ef; - background-color: #00c0ef; -} -.box.box-solid.box-info > .box-header a { - color: #444; -} -.box.box-solid.box-danger > .box-header { - color: #fff; - background: #f56954; - background-color: #f56954; -} -.box.box-solid.box-danger > .box-header a { - color: #444; -} -.box.box-solid.box-warning > .box-header { - color: #fff; - background: #f39c12; - background-color: #f39c12; -} -.box.box-solid.box-warning > .box-header a { - color: #444; -} -.box.box-solid.box-success > .box-header { - color: #fff; - background: #00a65a; - background-color: #00a65a; -} -.box.box-solid.box-success > .box-header a { - color: #444; -} -.box.box-solid > .box-header > .box-tools .btn { - border: 0; - box-shadow: none; -} -.box.box-solid.collapsed-box .box-header { - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.box.box-solid[class*='bg'] > .box-header { - color: #fff; -} -.box .box-group > .box { - margin-bottom: 5px; -} -.box .knob-label { - text-align: center; - color: #333; - font-weight: 100; - font-size: 12px; - margin-bottom: 0.3em; -} -.box .todo-list { - margin: 0; - padding: 0px 0px; - list-style: none; -} -.box .todo-list > li { - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; - padding: 10px; - background: #f3f4f5; - margin-bottom: 2px; - border-left: 2px solid #e6e7e8; - color: #444; -} -.box .todo-list > li:last-of-type { - margin-bottom: 0; -} -.box .todo-list > li.danger { - border-left-color: #f56954; -} -.box .todo-list > li.warning { - border-left-color: #f39c12; -} -.box .todo-list > li.info { - border-left-color: #00c0ef; -} -.box .todo-list > li.success { - border-left-color: #00a65a; -} -.box .todo-list > li.primary { - border-left-color: #3c8dbc; -} -.box .todo-list > li > input[type='checkbox'] { - margin: 0 10px 0 5px; -} -.box .todo-list > li .text { - display: inline-block; - margin-left: 5px; - font-weight: 600; -} -.box .todo-list > li .label { - margin-left: 10px; - font-size: 9px; -} -.box .todo-list > li .tools { - display: none; - float: right; - color: #f56954; -} -.box .todo-list > li .tools > .fa, -.box .todo-list > li .tools > .glyphicon, -.box .todo-list > li .tools > .ion { - margin-right: 5px; - cursor: pointer; -} -.box .todo-list > li:hover .tools { - display: inline-block; -} -.box .todo-list > li.done { - color: #999; -} -.box .todo-list > li.done .text { - text-decoration: line-through; - font-weight: 500; -} -.box .todo-list > li.done .label { - background: #eaeaec !important; -} -.box .todo-list .handle { - display: inline-block; - cursor: move; - margin: 0 5px; -} -.box .chat { - padding: 5px 20px 5px 10px; -} -.box .chat .item { - margin-bottom: 10px; -} -.box .chat .item:before, -.box .chat .item:after { - display: table; - content: " "; -} -.box .chat .item:after { - clear: both; -} -.box .chat .item > img { - width: 40px; - height: 40px; - border: 2px solid transparent; - -webkit-border-radius: 50% !important; - -moz-border-radius: 50% !important; - border-radius: 50% !important; -} -.box .chat .item > img.online { - border: 2px solid #00a65a; -} -.box .chat .item > img.offline { - border: 2px solid #f56954; -} -.box .chat .item > .message { - margin-left: 55px; - margin-top: -40px; -} -.box .chat .item > .message > .name { - display: block; - font-weight: 600; -} -.box .chat .item > .attachment { - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - background: #f0f0f0; - margin-left: 65px; - margin-right: 15px; - padding: 10px; -} -.box .chat .item > .attachment > h4 { - margin: 0 0 5px 0; - font-weight: 600; - font-size: 14px; -} -.box .chat .item > .attachment > p, -.box .chat .item > .attachment > .filename { - font-weight: 600; - font-size: 13px; - font-style: italic; - margin: 0; -} -.box .chat .item > .attachment:before, -.box .chat .item > .attachment:after { - display: table; - content: " "; -} -.box .chat .item > .attachment:after { - clear: both; -} -.box > .overlay, -.box > .loading-img { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; -} -.box > .overlay { - z-index: 1010; - background: rgba(255, 255, 255, 0.7); -} -.box > .overlay.dark { - background: rgba(0, 0, 0, 0.5); -} -.box > .loading-img { - z-index: 1020; - background: transparent url('../img/ajax-loader1.gif') 50% 50% no-repeat; -} -/* -Component: timeline --------------------- -*/ -.timeline { - position: relative; - margin: 0 0 30px 0; - padding: 0; - list-style: none; -} -.timeline:before { - content: ''; - position: absolute; - top: 0px; - bottom: 0; - width: 5px; - background: #ddd; - left: 30px; - border: 1px solid #eee; - margin: 0; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} -.timeline > li { - position: relative; - margin-right: 10px; - margin-bottom: 15px; -} -.timeline > li:before, -.timeline > li:after { - display: table; - content: " "; -} -.timeline > li:after { - clear: both; -} -.timeline > li > .timeline-item { - margin-top: 10px; - border: 0px solid #dfdfdf; - background: #fff; - color: #555; - margin-left: 60px; - margin-right: 15px; - padding: 5px; - position: relative; - box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1); -} -.timeline > li > .timeline-item > .time { - color: #999; - float: right; - margin: 2px 0 0 0; -} -.timeline > li > .timeline-item > .timeline-header { - margin: 0; - color: #555; - border-bottom: 1px solid #f4f4f4; - padding: 5px; - font-size: 16px; - line-height: 1.1; -} -.timeline > li > .timeline-item > .timeline-header > a { - font-weight: 600; -} -.timeline > li > .timeline-item > .timeline-body, -.timeline > li > .timeline-item > .timeline-footer { - padding: 10px; -} -.timeline > li.time-label > span { - font-weight: 600; - padding: 5px; - display: inline-block; - background-color: #fff; - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.5); - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} -.timeline > li > .fa, -.timeline > li > .glyphicon, -.timeline > li > .ion { - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); - width: 30px; - height: 30px; - font-size: 15px; - line-height: 30px; - position: absolute; - color: #666; - background: #eee; - border-radius: 50%; - text-align: center; - left: 18px; - top: 0; -} -/* - Component: Buttons -------------------------- -*/ -.btn { - font-weight: 500; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - border: 1px solid transparent; - -webkit-box-shadow: inset 0px -2px 0px 0px rgba(0, 0, 0, 0.09); - -moz-box-shadow: inset 0px -2px 0px 0px rgba(0, 0, 0, 0.09); - box-shadow: inset 0px -1px 0px 0px rgba(0, 0, 0, 0.09); -} -.btn.btn-default { - background-color: #fafafa; - color: #666; - border-color: #ddd; - border-bottom-color: #ddd; -} -.btn.btn-default:hover, -.btn.btn-default:active, -.btn.btn-default.hover { - background-color: #f4f4f4!important; -} -.btn.btn-default.btn-flat { - border-bottom-color: #d9dadc; -} -.btn.btn-primary { - background-color: #3c8dbc; - border-color: #367fa9; -} -.btn.btn-primary:hover, -.btn.btn-primary:active, -.btn.btn-primary.hover { - background-color: #367fa9; -} -.btn.btn-success { - background-color: #00a65a; - border-color: #008d4c; -} -.btn.btn-success:hover, -.btn.btn-success:active, -.btn.btn-success.hover { - background-color: #008d4c; -} -.btn.btn-info { - background-color: #00c0ef; - border-color: #00acd6; -} -.btn.btn-info:hover, -.btn.btn-info:active, -.btn.btn-info.hover { - background-color: #00acd6; -} -.btn.btn-danger { - background-color: #f56954; - border-color: #f4543c; -} -.btn.btn-danger:hover, -.btn.btn-danger:active, -.btn.btn-danger.hover { - background-color: #f4543c; -} -.btn.btn-warning { - background-color: #f39c12; - border-color: #e08e0b; -} -.btn.btn-warning:hover, -.btn.btn-warning:active, -.btn.btn-warning.hover { - background-color: #e08e0b; -} -.btn.btn-flat { - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; - border-width: 1px; -} -.btn:active { - -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - -moz-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); -} -.btn:focus { - outline: none; -} -.btn.btn-file { - position: relative; - overflow: hidden; -} -.btn.btn-file > input[type='file'] { - position: absolute; - top: 0; - right: 0; - min-width: 100%; - min-height: 100%; - font-size: 100px; - text-align: right; - filter: alpha(opacity=0); - opacity: 0; - outline: none; - background: white; - cursor: inherit; - display: block; -} -.btn.btn-app { - position: relative; - padding: 15px 5px; - margin: 0 0 10px 10px; - min-width: 80px; - height: 60px; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; - text-align: center; - color: #666; - border: 1px solid #ddd; - background-color: #fafafa; - font-size: 12px; -} -.btn.btn-app > .fa, -.btn.btn-app > .glyphicon, -.btn.btn-app > .ion { - font-size: 20px; - display: block; -} -.btn.btn-app:hover { - background: #f4f4f4; - color: #444; - border-color: #aaa; -} -.btn.btn-app:active, -.btn.btn-app:focus { - -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - -moz-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); -} -.btn.btn-app > .badge { - position: absolute; - top: -3px; - right: -10px; - font-size: 10px; - font-weight: 400; -} -.btn.btn-social-old { - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; - opacity: 0.9; - padding: 0; -} -.btn.btn-social-old > .fa { - padding: 10px 0; - width: 40px; -} -.btn.btn-social-old > .fa + span { - border-left: 1px solid rgba(255, 255, 255, 0.3); -} -.btn.btn-social-old span { - padding: 10px; -} -.btn.btn-social-old:hover { - opacity: 1; -} -.btn.btn-circle { - width: 30px; - height: 30px; - line-height: 30px; - padding: 0; - -webkit-border-radius: 50%; - -moz-border-radius: 50%; - border-radius: 50%; -} -/* - Component: callout ------------------------- -*/ -.callout { - margin: 0 0 20px 0; - padding: 15px 30px 15px 15px; - border-left: 5px solid #eee; -} -.callout h4 { - margin-top: 0; -} -.callout p:last-child { - margin-bottom: 0; -} -.callout code, -.callout .highlight { - background-color: #fff; -} -.callout.callout-danger { - background-color: #fcf2f2; - border-color: #dFb5b4; -} -.callout.callout-warning { - background-color: #fefbed; - border-color: #f1e7bc; -} -.callout.callout-info { - background-color: #f0f7fd; - border-color: #d0e3f0; -} -.callout.callout-danger h4 { - color: #B94A48; -} -.callout.callout-warning h4 { - color: #C09853; -} -.callout.callout-info h4 { - color: #3A87AD; -} -/* - Component: alert ------------------------- -*/ -.alert { - padding-left: 30px; - margin-left: 15px; - position: relative; -} -.alert > .fa, -.alert > .glyphicon { - position: absolute; - left: -15px; - top: -15px; - width: 35px; - height: 35px; - -webkit-border-radius: 50%; - -moz-border-radius: 50%; - border-radius: 50%; - line-height: 35px; - text-align: center; - background: inherit; - border: inherit; -} -/* - Component: Navs -*/ -/* NAV PILLS */ -.nav.nav-pills > li > a { - border-top: 3px solid transparent; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; - color: #444; -} -.nav.nav-pills > li > a > .fa, -.nav.nav-pills > li > a > .glyphicon, -.nav.nav-pills > li > a > .ion { - margin-right: 5px; -} -.nav.nav-pills > li.active > a, -.nav.nav-pills > li.active > a:hover { - background-color: #f6f6f6; - border-top-color: #3c8dbc; - color: #444; -} -.nav.nav-pills > li.active > a { - font-weight: 600; -} -.nav.nav-pills > li > a:hover { - background-color: #f6f6f6; -} -.nav.nav-pills.nav-stacked > li > a { - border-top: 0; - border-left: 3px solid transparent; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; - color: #444; -} -.nav.nav-pills.nav-stacked > li.active > a, -.nav.nav-pills.nav-stacked > li.active > a:hover { - background-color: #f6f6f6; - border-left-color: #3c8dbc; - color: #444; -} -.nav.nav-pills.nav-stacked > li.header { - border-bottom: 1px solid #ddd; - color: #777; - margin-bottom: 10px; - padding: 5px 10px; - text-transform: uppercase; -} -/* NAV TABS */ -.nav-tabs-custom { - margin-bottom: 20px; - background: #fff; - box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1); -} -.nav-tabs-custom > .nav-tabs { - margin: 0; - border-bottom-color: #f4f4f4; -} -.nav-tabs-custom > .nav-tabs > li { - border-top: 3px solid transparent; - margin-bottom: -2px; - margin-right: 5px; -} -.nav-tabs-custom > .nav-tabs > li > a { - -webkit-border-radius: 0 !important; - -moz-border-radius: 0 !important; - border-radius: 0 !important; -} -.nav-tabs-custom > .nav-tabs > li > a, -.nav-tabs-custom > .nav-tabs > li > a:hover { - background: transparent; - margin: 0; -} -.nav-tabs-custom > .nav-tabs > li:not(.active) > a:hover, -.nav-tabs-custom > .nav-tabs > li:not(.active) > a:focus, -.nav-tabs-custom > .nav-tabs > li:not(.active) > a:active { - border-color: transparent; -} -.nav-tabs-custom > .nav-tabs > li.active { - border-top-color: #3c8dbc; -} -.nav-tabs-custom > .nav-tabs > li.active > a, -.nav-tabs-custom > .nav-tabs > li.active:hover > a { - background-color: #fff; -} -.nav-tabs-custom > .nav-tabs > li.active > a { - border-top: 0; - border-left-color: #f4f4f4; - border-right-color: #f4f4f4; -} -.nav-tabs-custom > .nav-tabs > li:first-of-type { - margin-left: 0px; -} -.nav-tabs-custom > .nav-tabs > li:first-of-type.active > a { - border-left-width: 0; -} -.nav-tabs-custom > .nav-tabs.pull-right { - float: none!important; -} -.nav-tabs-custom > .nav-tabs.pull-right > li { - float: right; -} -.nav-tabs-custom > .nav-tabs.pull-right > li:first-of-type { - margin-right: 0px; -} -.nav-tabs-custom > .nav-tabs.pull-right > li:first-of-type.active > a { - border-left-width: 1px; - border-right-width: 0px; -} -.nav-tabs-custom > .nav-tabs > li.header { - font-weight: 400; - line-height: 35px; - padding: 0 10px; - font-size: 20px; - color: #444; - cursor: default; -} -.nav-tabs-custom > .nav-tabs > li.header > .fa, -.nav-tabs-custom > .nav-tabs > li.header > .glyphicon, -.nav-tabs-custom > .nav-tabs > li.header > .ion { - margin-right: 10px; -} -.nav-tabs-custom > .tab-content { - background: #fff; - padding: 10px; -} -/* Nav tabs bottom */ -.tabs-bottom.nav-3 li a { - width: 3333.33333333% !important; -} -.tabs-bottom li a { - border: 0; -} -/* PAGINATION */ -.pagination > li > a { - background: #fafafa; - color: #666; - -webkit-box-shadow: inset 0px -2px 0px 0px rgba(0, 0, 0, 0.09); - -moz-box-shadow: inset 0px -2px 0px 0px rgba(0, 0, 0, 0.09); - box-shadow: inset 0px -1px 0px 0px rgba(0, 0, 0, 0.09); -} -.pagination > li:first-of-type a, -.pagination > li:last-of-type a { - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -/* - Component: Mailbox -*/ -.mailbox .table-mailbox { - border-left: 1px solid #ddd; - border-right: 1px solid #ddd; - border-bottom: 1px solid #ddd; -} -.mailbox .table-mailbox tr.unread > td { - background-color: rgba(0, 0, 0, 0.05); - color: #000; - font-weight: 600; -} -.mailbox .table-mailbox tr > td > .fa.fa-star, -.mailbox .table-mailbox tr > td > .fa.fa-star-o, -.mailbox .table-mailbox tr > td > .glyphicon.glyphicon-star, -.mailbox .table-mailbox tr > td > .glyphicon.glyphicon-star-empty { - color: #f39c12; - cursor: pointer; -} -.mailbox .table-mailbox tr > td.small-col { - width: 30px; -} -.mailbox .table-mailbox tr > td.name { - width: 150px; - font-weight: 600; -} -.mailbox .table-mailbox tr > td.time { - text-align: right; - width: 100px; -} -.mailbox .table-mailbox tr > td { - white-space: nowrap; -} -.mailbox .table-mailbox tr > td > a { - color: #444; -} -@media screen and (max-width: 767px) { - .mailbox .nav-stacked > li:not(.header) { - float: left; - width: 50%; - } - .mailbox .nav-stacked > li:not(.header).header { - border: 0!important; - } - .mailbox .search-form { - margin-top: 10px; - } -} -/* - Page: locked screen -*/ -/* ADD THIS CLASS TO THE TAG */ -.lockscreen { - background: url(../img/blur-background09.jpg) repeat center center fixed; - -webkit-background-size: cover; - -moz-background-size: cover; - -o-background-size: cover; - background-size: cover; -} -/* Remove the background from the body element */ -.lockscreen > body { - background: transparent; -} -/* We will put the dynamically generated digital clock here */ -.lockscreen .headline { - color: #fff; - text-shadow: 1px 3px 5px rgba(0, 0, 0, 0.5); - font-weight: 300; - -webkit-font-smoothing: antialiased !important; - opacity: 0.8; - margin: 10px 0 30px 0; - font-size: 90px; -} -@media screen and (max-width: 480px) { - .lockscreen .headline { - font-size: 60px; - margin-bottom: 40px; - } -} -/* User name [optional] */ -.lockscreen .lockscreen-name { - text-align: center; - font-weight: 600; - font-size: 16px; -} -/* Will contain the image and the sign in form */ -.lockscreen-item { - padding: 0; - background: #fff; - position: relative; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - margin: 10px auto; - width: 290px; -} -.lockscreen-item:before, -.lockscreen-item:after { - display: table; - content: " "; -} -.lockscreen-item:after { - clear: both; -} -/* User image */ -.lockscreen-item > .lockscreen-image { - position: absolute; - left: -10px; - top: -30px; - background: #fff; - padding: 10px; - -webkit-border-radius: 50%; - -moz-border-radius: 50%; - border-radius: 50%; - z-index: 10; -} -.lockscreen-item > .lockscreen-image > img { - width: 70px; - height: 70px; - -webkit-border-radius: 50%; - -moz-border-radius: 50%; - border-radius: 50%; -} -/* Contains the password input and the login button */ -.lockscreen-item > .lockscreen-credentials { - margin-left: 80px; -} -.lockscreen-item > .lockscreen-credentials input { - border: 0 !important; -} -.lockscreen-item > .lockscreen-credentials .btn { - background-color: #fff; - border: 0; -} -/* Extra to give the user an option to navigate the website [optional]*/ -.lockscreen-link { - margin-top: 30px; - text-align: center; -} -/* - Page: register and login -*/ -.form-box { - width: 360px; - margin: 90px auto 0 auto; -} -.form-box .header { - -webkit-border-top-left-radius: 4px; - -webkit-border-top-right-radius: 4px; - -webkit-border-bottom-right-radius: 0; - -webkit-border-bottom-left-radius: 0; - -moz-border-radius-topleft: 4px; - -moz-border-radius-topright: 4px; - -moz-border-radius-bottomright: 0; - -moz-border-radius-bottomleft: 0; - border-top-left-radius: 4px; - border-top-right-radius: 4px; - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; - background: #3d9970; - box-shadow: inset 0px -3px 0px rgba(0, 0, 0, 0.2); - padding: 20px 10px; - text-align: center; - font-size: 26px; - font-weight: 300; - color: #fff; -} -.form-box .body, -.form-box .footer { - padding: 10px 20px; - background: #fff; - color: #444; -} -.form-box .body > .form-group, -.form-box .footer > .form-group { - margin-top: 20px; -} -.form-box .body > .form-group > input, -.form-box .footer > .form-group > input { - border: #fff; -} -.form-box .body > .btn, -.form-box .footer > .btn { - margin-bottom: 10px; -} -.form-box .footer { - -webkit-border-top-left-radius: 0; - -webkit-border-top-right-radius: 0; - -webkit-border-bottom-right-radius: 4px; - -webkit-border-bottom-left-radius: 4px; - -moz-border-radius-topleft: 0; - -moz-border-radius-topright: 0; - -moz-border-radius-bottomright: 4px; - -moz-border-radius-bottomleft: 4px; - border-top-left-radius: 0; - border-top-right-radius: 0; - border-bottom-right-radius: 4px; - border-bottom-left-radius: 4px; -} -@media (max-width: 767px) { - .form-box { - width: 90%; - } -} -/* - Page: 404 and 500 error pages ------------------------------------- -*/ -.error-page { - width: 600px; - margin: 20px auto 0 auto; -} -@media screen and (max-width: 767px) { - .error-page { - width: 100%; - } -} -.error-page > .headline { - float: left; - font-size: 100px; - font-weight: 300; -} -@media screen and (max-width: 767px) { - .error-page > .headline { - float: none; - text-align: center; - } -} -.error-page > .error-content { - margin-left: 190px; - display: block; -} -@media screen and (max-width: 767px) { - .error-page > .error-content { - margin-left: 0; - } -} -.error-page > .error-content > h3 { - font-weight: 300; - font-size: 25px; -} -@media screen and (max-width: 767px) { - .error-page > .error-content > h3 { - text-align: center; - } -} -.error-page:before, -.error-page:after { - display: table; - content: " "; -} -.error-page:after { - clear: both; -} -/* - Page: Invoice -*/ -.invoice { - position: relative; - width: 90%; - margin: 10px auto; - background: #fff; - border: 1px solid #f4f4f4; -} -.invoice-title { - margin-top: 0; -} -/* Enhancement for printing */ -@media print { - .invoice { - width: 100%; - border: 0; - margin: 0; - padding: 0; - } - .invoice-col { - float: left; - width: 33.3333333%; - } - .table-responsive { - overflow: auto; - } - .table-responsive > .table tr th, - .table-responsive > .table tr td { - white-space: normal!important; - } -} -/* - Skins - ----- -*/ -/* - Skin Blue - --------- -*/ -/* skin-blue navbar */ -.skin-blue .navbar { - background-color: #3c8dbc; -} -.skin-blue .navbar .nav a { - color: rgba(255, 255, 255, 0.8); -} -.skin-blue .navbar .nav > li > a:hover, -.skin-blue .navbar .nav > li > a:active, -.skin-blue .navbar .nav > li > a:focus, -.skin-blue .navbar .nav .open > a, -.skin-blue .navbar .nav .open > a:hover, -.skin-blue .navbar .nav .open > a:focus { - background: rgba(0, 0, 0, 0.1); - color: #f6f6f6; -} -.skin-blue .navbar .navbar-right > .nav { - margin-right: 10px; -} -.skin-blue .navbar .sidebar-toggle .icon-bar { - background: rgba(255, 255, 255, 0.8); -} -.skin-blue .navbar .sidebar-toggle:hover .icon-bar { - background: #f6f6f6 !important; -} -/* skin-blue logo */ -.skin-blue .logo { - background-color: #367fa9; - color: #f9f9f9; -} -.skin-blue .logo > a { - color: #f9f9f9; -} -.skin-blue .logo:hover { - background: #357ca5; -} -/* skin-blue content header */ -.skin-blue .right-side > .content-header { - background: #fbfbfb; - box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.1); -} -/* Skin-blue user panel */ -.skin-blue .user-panel > .image > img { - border: 1px solid #dfdfdf; -} -.skin-blue .user-panel > .info, -.skin-blue .user-panel > .info > a { - color: #555555; -} -/* skin-blue sidebar */ -.skin-blue .sidebar { - border-bottom: 1px solid #fff; -} -.skin-blue .sidebar > .sidebar-menu > li { - border-top: 1px solid #fff; - border-bottom: 1px solid #dbdbdb; -} -.skin-blue .sidebar > .sidebar-menu > li:first-of-type { - border-top: 1px solid #dbdbdb; -} -.skin-blue .sidebar > .sidebar-menu > li:first-of-type > a { - border-top: 1px solid #fff; -} -.skin-blue .sidebar > .sidebar-menu > li > a { - margin-right: 1px; -} -.skin-blue .sidebar > .sidebar-menu > li > a:hover, -.skin-blue .sidebar > .sidebar-menu > li.active > a { - color: #222; - background: #f9f9f9; -} -.skin-blue .sidebar > .sidebar-menu > li > .treeview-menu { - margin: 0 1px; - background: #f9f9f9; -} -.skin-blue .left-side { - background: #f4f4f4; - -webkit-box-shadow: inset -3px 0px 8px -4px rgba(0, 0, 0, 0.1); - -moz-box-shadow: inset -3px 0px 8px -4px rgba(0, 0, 0, 0.1); - box-shadow: inset -3px 0px 8px -4px rgba(0, 0, 0, 0.07); -} -.skin-blue .sidebar a { - color: #555555; -} -.skin-blue .sidebar a:hover { - text-decoration: none; -} -.skin-blue .treeview-menu > li > a { - color: #777; -} -.skin-blue .treeview-menu > li.active > a, -.skin-blue .treeview-menu > li > a:hover { - color: #111; -} -.skin-blue .sidebar-form { - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; - border: 1px solid #dbdbdb; - margin: 10px 10px; -} -.skin-blue .sidebar-form input[type="text"], -.skin-blue .sidebar-form .btn { - box-shadow: none; - background-color: #fafafa; - border: 1px solid #fafafa; - height: 35px; -} -.skin-blue .sidebar-form input[type="text"] { - color: #666; - -webkit-border-top-left-radius: 2px !important; - -webkit-border-top-right-radius: 0 !important; - -webkit-border-bottom-right-radius: 0 !important; - -webkit-border-bottom-left-radius: 2px !important; - -moz-border-radius-topleft: 2px !important; - -moz-border-radius-topright: 0 !important; - -moz-border-radius-bottomright: 0 !important; - -moz-border-radius-bottomleft: 2px !important; - border-top-left-radius: 2px !important; - border-top-right-radius: 0 !important; - border-bottom-right-radius: 0 !important; - border-bottom-left-radius: 2px !important; -} -.skin-blue .sidebar-form input[type="text"]:focus, -.skin-blue .sidebar-form input[type="text"]:focus + .input-group-btn .btn { - background-color: #fff; - color: #666; -} -.skin-blue .sidebar-form input[type="text"]:focus + .input-group-btn .btn { - border-left-color: #fff; -} -.skin-blue .sidebar-form .btn { - color: #999; - -webkit-border-top-left-radius: 0 !important; - -webkit-border-top-right-radius: 2px !important; - -webkit-border-bottom-right-radius: 2px !important; - -webkit-border-bottom-left-radius: 0 !important; - -moz-border-radius-topleft: 0 !important; - -moz-border-radius-topright: 2px !important; - -moz-border-radius-bottomright: 2px !important; - -moz-border-radius-bottomleft: 0 !important; - border-top-left-radius: 0 !important; - border-top-right-radius: 2px !important; - border-bottom-right-radius: 2px !important; - border-bottom-left-radius: 0 !important; -} -/* - Skin Black - -------- -*/ -/* skin-black navbar */ -.skin-black .navbar { - background-color: #ffffff; - border-bottom: 1px solid #eee; -} -.skin-black .navbar .nav a { - color: #333333; -} -.skin-black .navbar .nav > li > a:hover, -.skin-black .navbar .nav > li > a:active, -.skin-black .navbar .nav > li > a:focus, -.skin-black .navbar .nav .open > a, -.skin-black .navbar .nav .open > a:hover, -.skin-black .navbar .nav .open > a:focus { - background: #ffffff; - color: #999999; -} -.skin-black .navbar .navbar-right > .nav { - margin-right: 10px; -} -.skin-black .navbar .sidebar-toggle .icon-bar { - background: #333333; -} -.skin-black .navbar .sidebar-toggle:hover .icon-bar { - background: #999999 !important; -} -/* skin-black logo */ -.skin-black .logo { - background-color: #333333; - color: #f9f9f9; -} -.skin-black .logo > a { - color: #f9f9f9; -} -.skin-black .logo:hover { - background: #303030; -} -/* skin-black content header */ -.skin-black .right-side > .content-header { - background: transparent; - box-shadow: none; -} -/* Skin-red user panel */ -.skin-black .user-panel > .image > img { - border: 1px solid #444; -} -.skin-black .user-panel > .info, -.skin-black .user-panel > .info > a { - color: #eee; -} -/* skin-black sidebar */ -.skin-black .sidebar { - border-bottom: 1px solid #333; -} -.skin-black .sidebar > .sidebar-menu > li { - border-top: 1px solid #333; - border-bottom: 0px solid #444; -} -.skin-black .sidebar > .sidebar-menu > li:first-of-type { - border-top: 1px solid #444; -} -.skin-black .sidebar > .sidebar-menu > li:first-of-type > a { - border-top: 0px solid #333; -} -.skin-black .sidebar > .sidebar-menu > li > a { - margin-right: 1px; -} -.skin-black .sidebar > .sidebar-menu > li > a:hover, -.skin-black .sidebar > .sidebar-menu > li.active > a { - color: #f6f6f6; - background: #444; -} -.skin-black .sidebar > .sidebar-menu > li > .treeview-menu { - margin: 0 1px; - background: #444; -} -.skin-black .left-side { - background: #333; -} -.skin-black .sidebar a { - color: #eee; -} -.skin-black .sidebar a:hover { - text-decoration: none; -} -.skin-black .treeview-menu > li > a { - color: #ccc; -} -.skin-black .treeview-menu > li.active > a, -.skin-black .treeview-menu > li > a:hover { - color: #fff; -} -.skin-black .sidebar-form { - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; - border: 0px solid #555; - margin: 10px 10px; -} -.skin-black .sidebar-form input[type="text"], -.skin-black .sidebar-form .btn { - box-shadow: none; - background-color: rgba(255, 255, 255, 0.1); - border: 0 solid rgba(255, 255, 255, 0.1); - height: 35px; - outline: none; -} -.skin-black .sidebar-form input[type="text"] { - color: #666; - -webkit-border-top-left-radius: 2px !important; - -webkit-border-top-right-radius: 0 !important; - -webkit-border-bottom-right-radius: 0 !important; - -webkit-border-bottom-left-radius: 2px !important; - -moz-border-radius-topleft: 2px !important; - -moz-border-radius-topright: 0 !important; - -moz-border-radius-bottomright: 0 !important; - -moz-border-radius-bottomleft: 2px !important; - border-top-left-radius: 2px !important; - border-top-right-radius: 0 !important; - border-bottom-right-radius: 0 !important; - border-bottom-left-radius: 2px !important; -} -.skin-black .sidebar-form input[type="text"]:focus, -.skin-black .sidebar-form input[type="text"]:focus + .input-group-btn .btn { - background-color: #444; - border: 0; -} -.skin-black .sidebar-form input[type="text"]:focus + .input-group-btn .btn { - border-left: 0; -} -.skin-black .sidebar-form .btn { - color: #999; - -webkit-border-top-left-radius: 0 !important; - -webkit-border-top-right-radius: 2px !important; - -webkit-border-bottom-right-radius: 2px !important; - -webkit-border-bottom-left-radius: 0 !important; - -moz-border-radius-topleft: 0 !important; - -moz-border-radius-topright: 2px !important; - -moz-border-radius-bottomright: 2px !important; - -moz-border-radius-bottomleft: 0 !important; - border-top-left-radius: 0 !important; - border-top-right-radius: 2px !important; - border-bottom-right-radius: 2px !important; - border-bottom-left-radius: 0 !important; - border-left: 0; -} -/*! - * iCheck v1.0.1, http://git.io/arlzeA - * ================================= - * Powerful jQuery and Zepto plugin for checkboxes and radio buttons customization - * - * (c) 2013 Damir Sultanov, http://fronteed.com - * MIT Licensed - */ -/* iCheck plugin Minimal skin, black ------------------------------------ */ -.icheckbox_minimal, -.iradio_minimal { - display: inline-block; - *display: inline; - vertical-align: middle; - margin: 0; - padding: 0; - width: 18px; - height: 18px; - background: rgba(255, 255, 255, 0.7) url(iCheck/minimal/minimal.png) no-repeat; - border: none; - cursor: pointer; -} -.icheckbox_minimal { - background-position: 0 0; -} -.icheckbox_minimal.hover { - background-position: -20px 0; -} -.icheckbox_minimal.checked { - background-position: -40px 0; -} -.icheckbox_minimal.disabled { - background-position: -60px 0; - cursor: default; -} -.icheckbox_minimal.checked.disabled { - background-position: -80px 0; -} -.iradio_minimal { - background-position: -100px 0; -} -.iradio_minimal.hover { - background-position: -120px 0; -} -.iradio_minimal.checked { - background-position: -140px 0; -} -.iradio_minimal.disabled { - background-position: -160px 0; - cursor: default; -} -.iradio_minimal.checked.disabled { - background-position: -180px 0; -} -/* Retina support */ -@media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (-moz-min-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (min-device-pixel-ratio: 1.5) { - .icheckbox_minimal, - .iradio_minimal { - background-image: url('iCheck/minimal/minimal@2x.png'); - -webkit-background-size: 200px 20px; - background-size: 200px 20px; - } -} -.pace .pace-progress { - background: #00c0ef; - position: fixed; - z-index: 2000; - top: 0; - left: 0; - height: 2px; - -webkit-transition: width 1s; - -moz-transition: width 1s; - -o-transition: width 1s; - transition: width 1s; -} -.pace-inactive { - display: none; -} -/* - * Social Buttons for Bootstrap - * - * Copyright 2013-2014 Panayiotis Lipiridis - * Licensed under the MIT License - * - * https://github.com/lipis/bootstrap-social - * - * Note: this file has been altered to work correctly with AdminLTE - */ -.btn-social { - position: relative; - padding-left: 44px !important; - text-align: left; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -.btn-social :first-child { - position: absolute; - left: 0; - top: 0; - bottom: 0; - width: 32px !important; - line-height: 34px !important; - font-size: 1.6em!important; - text-align: center; - border-right: 1px solid rgba(0, 0, 0, 0.2); -} -.btn-social.btn-lg { - padding-left: 60px !important; -} -.btn-social.btn-lg :first-child { - line-height: 45px; - width: 45px; - font-size: 1.8em; -} -.btn-social.btn-sm { - padding-left: 38px !important; -} -.btn-social.btn-sm :first-child { - line-height: 28px; - width: 28px; - font-size: 1.4em; -} -.btn-social.btn-xs { - padding-left: 30px !important; -} -.btn-social.btn-xs :first-child { - line-height: 20px; - width: 20px; - font-size: 1.2em; -} -.btn-social-icon { - position: relative; - padding-left: 44px !important; - text-align: left; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - height: 34px; - width: 34px; - padding: 0; -} -.btn-social-icon :first-child { - position: absolute; - left: 0; - top: 0; - bottom: 0; - width: 32px !important; - line-height: 34px !important; - font-size: 1.6em!important; - text-align: center; - border-right: 1px solid rgba(0, 0, 0, 0.2); -} -.btn-social-icon.btn-lg { - padding-left: 60px !important; -} -.btn-social-icon.btn-lg :first-child { - line-height: 45px; - width: 45px; - font-size: 1.8em; -} -.btn-social-icon.btn-sm { - padding-left: 38px !important; -} -.btn-social-icon.btn-sm :first-child { - line-height: 28px; - width: 28px; - font-size: 1.4em; -} -.btn-social-icon.btn-xs { - padding-left: 30px !important; -} -.btn-social-icon.btn-xs :first-child { - line-height: 20px; - width: 20px; - font-size: 1.2em; -} -.btn-social-icon :first-child { - border: none; - text-align: center; - width: 100%!important; -} -.btn-social-icon.btn-lg { - height: 45px; - width: 45px; - padding-left: 0; - padding-right: 0; -} -.btn-social-icon.btn-sm { - height: 30px; - width: 30px; - padding-left: 0; - padding-right: 0; -} -.btn-social-icon.btn-xs { - height: 22px; - width: 22px; - padding-left: 0; - padding-right: 0; -} -.btn-bitbucket { - color: #ffffff; - background-color: #205081; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-bitbucket:hover, -.btn-bitbucket:focus, -.btn-bitbucket:active, -.btn-bitbucket.active, -.open .dropdown-toggle.btn-bitbucket { - color: #ffffff; - background-color: #183c60; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-bitbucket:active, -.btn-bitbucket.active, -.open .dropdown-toggle.btn-bitbucket { - background-image: none; -} -.btn-bitbucket.disabled, -.btn-bitbucket[disabled], -fieldset[disabled] .btn-bitbucket, -.btn-bitbucket.disabled:hover, -.btn-bitbucket[disabled]:hover, -fieldset[disabled] .btn-bitbucket:hover, -.btn-bitbucket.disabled:focus, -.btn-bitbucket[disabled]:focus, -fieldset[disabled] .btn-bitbucket:focus, -.btn-bitbucket.disabled:active, -.btn-bitbucket[disabled]:active, -fieldset[disabled] .btn-bitbucket:active, -.btn-bitbucket.disabled.active, -.btn-bitbucket[disabled].active, -fieldset[disabled] .btn-bitbucket.active { - background-color: #205081; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-bitbucket .badge { - color: #205081; - background-color: #ffffff; -} -.btn-dropbox { - color: #ffffff; - background-color: #1087dd; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-dropbox:hover, -.btn-dropbox:focus, -.btn-dropbox:active, -.btn-dropbox.active, -.open .dropdown-toggle.btn-dropbox { - color: #ffffff; - background-color: #0d70b7; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-dropbox:active, -.btn-dropbox.active, -.open .dropdown-toggle.btn-dropbox { - background-image: none; -} -.btn-dropbox.disabled, -.btn-dropbox[disabled], -fieldset[disabled] .btn-dropbox, -.btn-dropbox.disabled:hover, -.btn-dropbox[disabled]:hover, -fieldset[disabled] .btn-dropbox:hover, -.btn-dropbox.disabled:focus, -.btn-dropbox[disabled]:focus, -fieldset[disabled] .btn-dropbox:focus, -.btn-dropbox.disabled:active, -.btn-dropbox[disabled]:active, -fieldset[disabled] .btn-dropbox:active, -.btn-dropbox.disabled.active, -.btn-dropbox[disabled].active, -fieldset[disabled] .btn-dropbox.active { - background-color: #1087dd; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-dropbox .badge { - color: #1087dd; - background-color: #ffffff; -} -.btn-facebook { - color: #ffffff; - background-color: #3b5998; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-facebook:hover, -.btn-facebook:focus, -.btn-facebook:active, -.btn-facebook.active, -.open .dropdown-toggle.btn-facebook { - color: #ffffff; - background-color: #30487b; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-facebook:active, -.btn-facebook.active, -.open .dropdown-toggle.btn-facebook { - background-image: none; -} -.btn-facebook.disabled, -.btn-facebook[disabled], -fieldset[disabled] .btn-facebook, -.btn-facebook.disabled:hover, -.btn-facebook[disabled]:hover, -fieldset[disabled] .btn-facebook:hover, -.btn-facebook.disabled:focus, -.btn-facebook[disabled]:focus, -fieldset[disabled] .btn-facebook:focus, -.btn-facebook.disabled:active, -.btn-facebook[disabled]:active, -fieldset[disabled] .btn-facebook:active, -.btn-facebook.disabled.active, -.btn-facebook[disabled].active, -fieldset[disabled] .btn-facebook.active { - background-color: #3b5998; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-facebook .badge { - color: #3b5998; - background-color: #ffffff; -} -.btn-flickr { - color: #ffffff; - background-color: #ff0084; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-flickr:hover, -.btn-flickr:focus, -.btn-flickr:active, -.btn-flickr.active, -.open .dropdown-toggle.btn-flickr { - color: #ffffff; - background-color: #d6006f; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-flickr:active, -.btn-flickr.active, -.open .dropdown-toggle.btn-flickr { - background-image: none; -} -.btn-flickr.disabled, -.btn-flickr[disabled], -fieldset[disabled] .btn-flickr, -.btn-flickr.disabled:hover, -.btn-flickr[disabled]:hover, -fieldset[disabled] .btn-flickr:hover, -.btn-flickr.disabled:focus, -.btn-flickr[disabled]:focus, -fieldset[disabled] .btn-flickr:focus, -.btn-flickr.disabled:active, -.btn-flickr[disabled]:active, -fieldset[disabled] .btn-flickr:active, -.btn-flickr.disabled.active, -.btn-flickr[disabled].active, -fieldset[disabled] .btn-flickr.active { - background-color: #ff0084; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-flickr .badge { - color: #ff0084; - background-color: #ffffff; -} -.btn-foursquare { - color: #ffffff; - background-color: #0072b1; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-foursquare:hover, -.btn-foursquare:focus, -.btn-foursquare:active, -.btn-foursquare.active, -.open .dropdown-toggle.btn-foursquare { - color: #ffffff; - background-color: #005888; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-foursquare:active, -.btn-foursquare.active, -.open .dropdown-toggle.btn-foursquare { - background-image: none; -} -.btn-foursquare.disabled, -.btn-foursquare[disabled], -fieldset[disabled] .btn-foursquare, -.btn-foursquare.disabled:hover, -.btn-foursquare[disabled]:hover, -fieldset[disabled] .btn-foursquare:hover, -.btn-foursquare.disabled:focus, -.btn-foursquare[disabled]:focus, -fieldset[disabled] .btn-foursquare:focus, -.btn-foursquare.disabled:active, -.btn-foursquare[disabled]:active, -fieldset[disabled] .btn-foursquare:active, -.btn-foursquare.disabled.active, -.btn-foursquare[disabled].active, -fieldset[disabled] .btn-foursquare.active { - background-color: #0072b1; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-foursquare .badge { - color: #0072b1; - background-color: #ffffff; -} -.btn-github { - color: #ffffff; - background-color: #444444; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-github:hover, -.btn-github:focus, -.btn-github:active, -.btn-github.active, -.open .dropdown-toggle.btn-github { - color: #ffffff; - background-color: #303030; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-github:active, -.btn-github.active, -.open .dropdown-toggle.btn-github { - background-image: none; -} -.btn-github.disabled, -.btn-github[disabled], -fieldset[disabled] .btn-github, -.btn-github.disabled:hover, -.btn-github[disabled]:hover, -fieldset[disabled] .btn-github:hover, -.btn-github.disabled:focus, -.btn-github[disabled]:focus, -fieldset[disabled] .btn-github:focus, -.btn-github.disabled:active, -.btn-github[disabled]:active, -fieldset[disabled] .btn-github:active, -.btn-github.disabled.active, -.btn-github[disabled].active, -fieldset[disabled] .btn-github.active { - background-color: #444444; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-github .badge { - color: #444444; - background-color: #ffffff; -} -.btn-google-plus { - color: #ffffff; - background-color: #dd4b39; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-google-plus:hover, -.btn-google-plus:focus, -.btn-google-plus:active, -.btn-google-plus.active, -.open .dropdown-toggle.btn-google-plus { - color: #ffffff; - background-color: #ca3523; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-google-plus:active, -.btn-google-plus.active, -.open .dropdown-toggle.btn-google-plus { - background-image: none; -} -.btn-google-plus.disabled, -.btn-google-plus[disabled], -fieldset[disabled] .btn-google-plus, -.btn-google-plus.disabled:hover, -.btn-google-plus[disabled]:hover, -fieldset[disabled] .btn-google-plus:hover, -.btn-google-plus.disabled:focus, -.btn-google-plus[disabled]:focus, -fieldset[disabled] .btn-google-plus:focus, -.btn-google-plus.disabled:active, -.btn-google-plus[disabled]:active, -fieldset[disabled] .btn-google-plus:active, -.btn-google-plus.disabled.active, -.btn-google-plus[disabled].active, -fieldset[disabled] .btn-google-plus.active { - background-color: #dd4b39; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-google-plus .badge { - color: #dd4b39; - background-color: #ffffff; -} -.btn-instagram { - color: #ffffff; - background-color: #3f729b; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-instagram:hover, -.btn-instagram:focus, -.btn-instagram:active, -.btn-instagram.active, -.open .dropdown-toggle.btn-instagram { - color: #ffffff; - background-color: #335d7e; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-instagram:active, -.btn-instagram.active, -.open .dropdown-toggle.btn-instagram { - background-image: none; -} -.btn-instagram.disabled, -.btn-instagram[disabled], -fieldset[disabled] .btn-instagram, -.btn-instagram.disabled:hover, -.btn-instagram[disabled]:hover, -fieldset[disabled] .btn-instagram:hover, -.btn-instagram.disabled:focus, -.btn-instagram[disabled]:focus, -fieldset[disabled] .btn-instagram:focus, -.btn-instagram.disabled:active, -.btn-instagram[disabled]:active, -fieldset[disabled] .btn-instagram:active, -.btn-instagram.disabled.active, -.btn-instagram[disabled].active, -fieldset[disabled] .btn-instagram.active { - background-color: #3f729b; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-instagram .badge { - color: #3f729b; - background-color: #ffffff; -} -.btn-linkedin { - color: #ffffff; - background-color: #007bb6; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-linkedin:hover, -.btn-linkedin:focus, -.btn-linkedin:active, -.btn-linkedin.active, -.open .dropdown-toggle.btn-linkedin { - color: #ffffff; - background-color: #005f8d; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-linkedin:active, -.btn-linkedin.active, -.open .dropdown-toggle.btn-linkedin { - background-image: none; -} -.btn-linkedin.disabled, -.btn-linkedin[disabled], -fieldset[disabled] .btn-linkedin, -.btn-linkedin.disabled:hover, -.btn-linkedin[disabled]:hover, -fieldset[disabled] .btn-linkedin:hover, -.btn-linkedin.disabled:focus, -.btn-linkedin[disabled]:focus, -fieldset[disabled] .btn-linkedin:focus, -.btn-linkedin.disabled:active, -.btn-linkedin[disabled]:active, -fieldset[disabled] .btn-linkedin:active, -.btn-linkedin.disabled.active, -.btn-linkedin[disabled].active, -fieldset[disabled] .btn-linkedin.active { - background-color: #007bb6; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-linkedin .badge { - color: #007bb6; - background-color: #ffffff; -} -.btn-tumblr { - color: #ffffff; - background-color: #2c4762; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-tumblr:hover, -.btn-tumblr:focus, -.btn-tumblr:active, -.btn-tumblr.active, -.open .dropdown-toggle.btn-tumblr { - color: #ffffff; - background-color: #1f3346; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-tumblr:active, -.btn-tumblr.active, -.open .dropdown-toggle.btn-tumblr { - background-image: none; -} -.btn-tumblr.disabled, -.btn-tumblr[disabled], -fieldset[disabled] .btn-tumblr, -.btn-tumblr.disabled:hover, -.btn-tumblr[disabled]:hover, -fieldset[disabled] .btn-tumblr:hover, -.btn-tumblr.disabled:focus, -.btn-tumblr[disabled]:focus, -fieldset[disabled] .btn-tumblr:focus, -.btn-tumblr.disabled:active, -.btn-tumblr[disabled]:active, -fieldset[disabled] .btn-tumblr:active, -.btn-tumblr.disabled.active, -.btn-tumblr[disabled].active, -fieldset[disabled] .btn-tumblr.active { - background-color: #2c4762; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-tumblr .badge { - color: #2c4762; - background-color: #ffffff; -} -.btn-twitter { - color: #ffffff; - background-color: #55acee; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-twitter:hover, -.btn-twitter:focus, -.btn-twitter:active, -.btn-twitter.active, -.open .dropdown-toggle.btn-twitter { - color: #ffffff; - background-color: #309aea; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-twitter:active, -.btn-twitter.active, -.open .dropdown-toggle.btn-twitter { - background-image: none; -} -.btn-twitter.disabled, -.btn-twitter[disabled], -fieldset[disabled] .btn-twitter, -.btn-twitter.disabled:hover, -.btn-twitter[disabled]:hover, -fieldset[disabled] .btn-twitter:hover, -.btn-twitter.disabled:focus, -.btn-twitter[disabled]:focus, -fieldset[disabled] .btn-twitter:focus, -.btn-twitter.disabled:active, -.btn-twitter[disabled]:active, -fieldset[disabled] .btn-twitter:active, -.btn-twitter.disabled.active, -.btn-twitter[disabled].active, -fieldset[disabled] .btn-twitter.active { - background-color: #55acee; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-twitter .badge { - color: #55acee; - background-color: #ffffff; -} -.btn-vk { - color: #ffffff; - background-color: #587ea3; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-vk:hover, -.btn-vk:focus, -.btn-vk:active, -.btn-vk.active, -.open .dropdown-toggle.btn-vk { - color: #ffffff; - background-color: #4a6a89; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-vk:active, -.btn-vk.active, -.open .dropdown-toggle.btn-vk { - background-image: none; -} -.btn-vk.disabled, -.btn-vk[disabled], -fieldset[disabled] .btn-vk, -.btn-vk.disabled:hover, -.btn-vk[disabled]:hover, -fieldset[disabled] .btn-vk:hover, -.btn-vk.disabled:focus, -.btn-vk[disabled]:focus, -fieldset[disabled] .btn-vk:focus, -.btn-vk.disabled:active, -.btn-vk[disabled]:active, -fieldset[disabled] .btn-vk:active, -.btn-vk.disabled.active, -.btn-vk[disabled].active, -fieldset[disabled] .btn-vk.active { - background-color: #587ea3; - border-color: rgba(0, 0, 0, 0.2); -} -.btn-vk .badge { - color: #587ea3; - background-color: #ffffff; -} diff --git a/public/assets/css/AdminLTE.min.css b/public/assets/css/AdminLTE.min.css new file mode 100644 index 00000000..b5ec266b --- /dev/null +++ b/public/assets/css/AdminLTE.min.css @@ -0,0 +1,7 @@ +@import url(https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic);/*! + * AdminLTE v2.3.0 + * Author: Almsaeed Studio + * Website: Almsaeed Studio + * License: Open source - MIT + * Please visit http://opensource.org/licenses/MIT for more information +!*/html,body{min-height:100%}.layout-boxed html,.layout-boxed body{height:100%}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:'Source Sans Pro','Helvetica Neue',Helvetica,Arial,sans-serif;font-weight:400;overflow-x:hidden;overflow-y:auto}.wrapper{min-height:100%;position:static;overflow:hidden}.wrapper:before,.wrapper:after{content:" ";display:table}.wrapper:after{clear:both}.layout-boxed .wrapper{max-width:1250px;margin:0 auto;min-height:100%;box-shadow:0 0 8px rgba(0,0,0,0.5);position:relative}.layout-boxed{background:url('../img/boxed-bg.jpg') repeat fixed}.content-wrapper,.right-side,.main-footer{-webkit-transition:-webkit-transform .3s ease-in-out,margin .3s ease-in-out;-moz-transition:-moz-transform .3s ease-in-out,margin .3s ease-in-out;-o-transition:-o-transform .3s ease-in-out,margin .3s ease-in-out;transition:transform .3s ease-in-out,margin .3s ease-in-out;margin-left:230px;z-index:820}.layout-top-nav .content-wrapper,.layout-top-nav .right-side,.layout-top-nav .main-footer{margin-left:0}@media (max-width:767px){.content-wrapper,.right-side,.main-footer{margin-left:0}}@media (min-width:768px){.sidebar-collapse .content-wrapper,.sidebar-collapse .right-side,.sidebar-collapse .main-footer{margin-left:0}}@media (max-width:767px){.sidebar-open .content-wrapper,.sidebar-open .right-side,.sidebar-open .main-footer{-webkit-transform:translate(230px, 0);-ms-transform:translate(230px, 0);-o-transform:translate(230px, 0);transform:translate(230px, 0)}}.content-wrapper,.right-side{min-height:100%;background-color:#ecf0f5;z-index:800}.main-footer{background:#fff;padding:15px;color:#444;border-top:1px solid #d2d6de}.fixed .main-header,.fixed .main-sidebar,.fixed .left-side{position:fixed}.fixed .main-header{top:0;right:0;left:0}.fixed .content-wrapper,.fixed .right-side{padding-top:50px}@media (max-width:767px){.fixed .content-wrapper,.fixed .right-side{padding-top:100px}}.fixed.layout-boxed .wrapper{max-width:100%}body.hold-transition .content-wrapper,body.hold-transition .right-side,body.hold-transition .main-footer,body.hold-transition .main-sidebar,body.hold-transition .left-side,body.hold-transition .main-header>.navbar,body.hold-transition .main-header .logo{-webkit-transition:none;-o-transition:none;transition:none}.content{min-height:250px;padding:15px;margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:'Source Sans Pro',sans-serif}a{color:#3c8dbc}a:hover,a:active,a:focus{outline:none;text-decoration:none;color:#72afd2}.page-header{margin:10px 0 20px 0;font-size:22px}.page-header>small{color:#666;display:block;margin-top:5px}.main-header{position:relative;max-height:100px;z-index:1030}.main-header>.navbar{-webkit-transition:margin-left .3s ease-in-out;-o-transition:margin-left .3s ease-in-out;transition:margin-left .3s ease-in-out;margin-bottom:0;margin-left:230px;border:none;min-height:50px;border-radius:0}.layout-top-nav .main-header>.navbar{margin-left:0}.main-header #navbar-search-input.form-control{background:rgba(255,255,255,0.2);border-color:transparent}.main-header #navbar-search-input.form-control:focus,.main-header #navbar-search-input.form-control:active{border-color:rgba(0,0,0,0.1);background:rgba(255,255,255,0.9)}.main-header #navbar-search-input.form-control::-moz-placeholder{color:#ccc;opacity:1}.main-header #navbar-search-input.form-control:-ms-input-placeholder{color:#ccc}.main-header #navbar-search-input.form-control::-webkit-input-placeholder{color:#ccc}.main-header .navbar-custom-menu,.main-header .navbar-right{float:right}@media (max-width:991px){.main-header .navbar-custom-menu a,.main-header .navbar-right a{color:inherit;background:transparent}}@media (max-width:767px){.main-header .navbar-right{float:none}.navbar-collapse .main-header .navbar-right{margin:7.5px -15px}.main-header .navbar-right>li{color:inherit;border:0}}.main-header .sidebar-toggle{float:left;background-color:transparent;background-image:none;padding:15px 15px;font-family:fontAwesome}.main-header .sidebar-toggle:before{content:"\f0c9"}.main-header .sidebar-toggle:hover{color:#fff}.main-header .sidebar-toggle:focus,.main-header .sidebar-toggle:active{background:transparent}.main-header .sidebar-toggle .icon-bar{display:none}.main-header .navbar .nav>li.user>a>.fa,.main-header .navbar .nav>li.user>a>.glyphicon,.main-header .navbar .nav>li.user>a>.ion{margin-right:5px}.main-header .navbar .nav>li>a>.label{position:absolute;top:9px;right:7px;text-align:center;font-size:9px;padding:2px 3px;line-height:.9}.main-header .logo{-webkit-transition:width .3s ease-in-out;-o-transition:width .3s ease-in-out;transition:width .3s ease-in-out;display:block;float:left;height:50px;font-size:20px;line-height:50px;text-align:center;width:230px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;padding:0 15px;font-weight:300;overflow:hidden}.main-header .logo .logo-lg{display:block}.main-header .logo .logo-mini{display:none}.main-header .navbar-brand{color:#fff}.content-header{position:relative;padding:15px 15px 0 15px}.content-header>h1{margin:0;font-size:24px}.content-header>h1>small{font-size:15px;display:inline-block;padding-left:4px;font-weight:300}.content-header>.breadcrumb{float:right;background:transparent;margin-top:0;margin-bottom:0;font-size:12px;padding:7px 5px;position:absolute;top:15px;right:10px;border-radius:2px}.content-header>.breadcrumb>li>a{color:#444;text-decoration:none;display:inline-block}.content-header>.breadcrumb>li>a>.fa,.content-header>.breadcrumb>li>a>.glyphicon,.content-header>.breadcrumb>li>a>.ion{margin-right:5px}.content-header>.breadcrumb>li+li:before{content:'>\00a0'}@media (max-width:991px){.content-header>.breadcrumb{position:relative;margin-top:5px;top:0;right:0;float:none;background:#d2d6de;padding-left:10px}.content-header>.breadcrumb li:before{color:#97a0b3}}.navbar-toggle{color:#fff;border:0;margin:0;padding:15px 15px}@media (max-width:991px){.navbar-custom-menu .navbar-nav>li{float:left}.navbar-custom-menu .navbar-nav{margin:0;float:left}.navbar-custom-menu .navbar-nav>li>a{padding-top:15px;padding-bottom:15px;line-height:20px}}@media (max-width:767px){.main-header{position:relative}.main-header .logo,.main-header .navbar{width:100%;float:none}.main-header .navbar{margin:0}.main-header .navbar-custom-menu{float:right}}@media (max-width:991px){.navbar-collapse.pull-left{float:none!important}.navbar-collapse.pull-left+.navbar-custom-menu{display:block;position:absolute;top:0;right:40px}}.main-sidebar,.left-side{position:absolute;top:0;left:0;padding-top:50px;min-height:100%;width:230px;z-index:810;-webkit-transition:-webkit-transform .3s ease-in-out,width .3s ease-in-out;-moz-transition:-moz-transform .3s ease-in-out,width .3s ease-in-out;-o-transition:-o-transform .3s ease-in-out,width .3s ease-in-out;transition:transform .3s ease-in-out,width .3s ease-in-out}@media (max-width:767px){.main-sidebar,.left-side{padding-top:100px}}@media (max-width:767px){.main-sidebar,.left-side{-webkit-transform:translate(-230px, 0);-ms-transform:translate(-230px, 0);-o-transform:translate(-230px, 0);transform:translate(-230px, 0)}}@media (min-width:768px){.sidebar-collapse .main-sidebar,.sidebar-collapse .left-side{-webkit-transform:translate(-230px, 0);-ms-transform:translate(-230px, 0);-o-transform:translate(-230px, 0);transform:translate(-230px, 0)}}@media (max-width:767px){.sidebar-open .main-sidebar,.sidebar-open .left-side{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0)}}.sidebar{padding-bottom:10px}.sidebar-form input:focus{border-color:transparent}.user-panel{position:relative;width:100%;padding:10px;overflow:hidden}.user-panel:before,.user-panel:after{content:" ";display:table}.user-panel:after{clear:both}.user-panel>.image>img{width:100%;max-width:45px;height:auto}.user-panel>.info{padding:5px 5px 5px 15px;line-height:1;position:absolute;left:55px}.user-panel>.info>p{font-weight:600;margin-bottom:9px}.user-panel>.info>a{text-decoration:none;padding-right:5px;margin-top:3px;font-size:11px}.user-panel>.info>a>.fa,.user-panel>.info>a>.ion,.user-panel>.info>a>.glyphicon{margin-right:3px}.sidebar-menu{list-style:none;margin:0;padding:0}.sidebar-menu>li{position:relative;margin:0;padding:0}.sidebar-menu>li>a{padding:12px 5px 12px 15px;display:block}.sidebar-menu>li>a>.fa,.sidebar-menu>li>a>.glyphicon,.sidebar-menu>li>a>.ion{width:20px}.sidebar-menu>li .label,.sidebar-menu>li .badge{margin-top:3px;margin-right:5px}.sidebar-menu li.header{padding:10px 25px 10px 15px;font-size:12px}.sidebar-menu li>a>.fa-angle-left{width:auto;height:auto;padding:0;margin-right:10px;margin-top:3px}.sidebar-menu li.active>a>.fa-angle-left{-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-o-transform:rotate(-90deg);transform:rotate(-90deg)}.sidebar-menu li.active>.treeview-menu{display:block}.sidebar-menu .treeview-menu{display:none;list-style:none;padding:0;margin:0;padding-left:5px}.sidebar-menu .treeview-menu .treeview-menu{padding-left:20px}.sidebar-menu .treeview-menu>li{margin:0}.sidebar-menu .treeview-menu>li>a{padding:5px 5px 5px 15px;display:block;font-size:14px}.sidebar-menu .treeview-menu>li>a>.fa,.sidebar-menu .treeview-menu>li>a>.glyphicon,.sidebar-menu .treeview-menu>li>a>.ion{width:20px}.sidebar-menu .treeview-menu>li>a>.fa-angle-left,.sidebar-menu .treeview-menu>li>a>.fa-angle-down{width:auto}@media (min-width:768px){.sidebar-mini.sidebar-collapse .content-wrapper,.sidebar-mini.sidebar-collapse .right-side,.sidebar-mini.sidebar-collapse .main-footer{margin-left:50px!important;z-index:840}.sidebar-mini.sidebar-collapse .main-sidebar{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0);width:50px!important;z-index:850}.sidebar-mini.sidebar-collapse .sidebar-menu>li{position:relative}.sidebar-mini.sidebar-collapse .sidebar-menu>li>a{margin-right:0}.sidebar-mini.sidebar-collapse .sidebar-menu>li>a>span{border-top-right-radius:4px}.sidebar-mini.sidebar-collapse .sidebar-menu>li:not(.treeview)>a>span{border-bottom-right-radius:4px}.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu{padding-top:5px;padding-bottom:5px;border-bottom-right-radius:4px}.sidebar-mini.sidebar-collapse .sidebar-menu>li:hover>a>span:not(.pull-right),.sidebar-mini.sidebar-collapse .sidebar-menu>li:hover>.treeview-menu{display:block!important;position:absolute;width:180px;left:50px}.sidebar-mini.sidebar-collapse .sidebar-menu>li:hover>a>span{top:0;margin-left:-3px;padding:12px 5px 12px 20px;background-color:inherit}.sidebar-mini.sidebar-collapse .sidebar-menu>li:hover>.treeview-menu{top:44px;margin-left:0}.sidebar-mini.sidebar-collapse .main-sidebar .user-panel>.info,.sidebar-mini.sidebar-collapse .sidebar-form,.sidebar-mini.sidebar-collapse .sidebar-menu>li>a>span,.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu,.sidebar-mini.sidebar-collapse .sidebar-menu>li>a>.pull-right,.sidebar-mini.sidebar-collapse .sidebar-menu li.header{display:none!important;-webkit-transform:translateZ(0)}.sidebar-mini.sidebar-collapse .main-header .logo{width:50px}.sidebar-mini.sidebar-collapse .main-header .logo>.logo-mini{display:block;margin-left:-15px;margin-right:-15px;font-size:18px}.sidebar-mini.sidebar-collapse .main-header .logo>.logo-lg{display:none}.sidebar-mini.sidebar-collapse .main-header .navbar{margin-left:50px}}.sidebar-menu,.main-sidebar .user-panel,.sidebar-menu>li.header{white-space:nowrap;overflow:hidden}.sidebar-menu:hover{overflow:visible}.sidebar-form,.sidebar-menu>li.header{overflow:hidden;text-overflow:clip}.sidebar-menu li>a{position:relative}.sidebar-menu li>a>.pull-right{position:absolute;top:50%;right:10px;margin-top:-7px}.control-sidebar-bg{position:fixed;z-index:1000;bottom:0}.control-sidebar-bg,.control-sidebar{top:0;right:-230px;width:230px;-webkit-transition:right .3s ease-in-out;-o-transition:right .3s ease-in-out;transition:right .3s ease-in-out}.control-sidebar{position:absolute;padding-top:50px;z-index:1010}@media (max-width:768px){.control-sidebar{padding-top:100px}}.control-sidebar>.tab-content{padding:10px 15px}.control-sidebar.control-sidebar-open,.control-sidebar.control-sidebar-open+.control-sidebar-bg{right:0}.control-sidebar-open .control-sidebar-bg,.control-sidebar-open .control-sidebar{right:0}@media (min-width:768px){.control-sidebar-open .content-wrapper,.control-sidebar-open .right-side,.control-sidebar-open .main-footer{margin-right:230px}}.nav-tabs.control-sidebar-tabs>li:first-of-type>a,.nav-tabs.control-sidebar-tabs>li:first-of-type>a:hover,.nav-tabs.control-sidebar-tabs>li:first-of-type>a:focus{border-left-width:0}.nav-tabs.control-sidebar-tabs>li>a{border-radius:0}.nav-tabs.control-sidebar-tabs>li>a,.nav-tabs.control-sidebar-tabs>li>a:hover{border-top:none;border-right:none;border-left:1px solid transparent;border-bottom:1px solid transparent}.nav-tabs.control-sidebar-tabs>li>a .icon{font-size:16px}.nav-tabs.control-sidebar-tabs>li.active>a,.nav-tabs.control-sidebar-tabs>li.active>a:hover,.nav-tabs.control-sidebar-tabs>li.active>a:focus,.nav-tabs.control-sidebar-tabs>li.active>a:active{border-top:none;border-right:none;border-bottom:none}@media (max-width:768px){.nav-tabs.control-sidebar-tabs{display:table}.nav-tabs.control-sidebar-tabs>li{display:table-cell}}.control-sidebar-heading{font-weight:400;font-size:16px;padding:10px 0;margin-bottom:10px}.control-sidebar-subheading{display:block;font-weight:400;font-size:14px}.control-sidebar-menu{list-style:none;padding:0;margin:0 -15px}.control-sidebar-menu>li>a{display:block;padding:10px 15px}.control-sidebar-menu>li>a:before,.control-sidebar-menu>li>a:after{content:" ";display:table}.control-sidebar-menu>li>a:after{clear:both}.control-sidebar-menu>li>a>.control-sidebar-subheading{margin-top:0}.control-sidebar-menu .menu-icon{float:left;width:35px;height:35px;border-radius:50%;text-align:center;line-height:35px}.control-sidebar-menu .menu-info{margin-left:45px;margin-top:3px}.control-sidebar-menu .menu-info>.control-sidebar-subheading{margin:0}.control-sidebar-menu .menu-info>p{margin:0;font-size:11px}.control-sidebar-menu .progress{margin:0}.control-sidebar-dark{color:#b8c7ce}.control-sidebar-dark,.control-sidebar-dark+.control-sidebar-bg{background:#222d32}.control-sidebar-dark .nav-tabs.control-sidebar-tabs{border-bottom:#1c2529}.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a{background:#181f23;color:#b8c7ce}.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:hover,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:focus{border-left-color:#141a1d;border-bottom-color:#141a1d}.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:hover,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:focus,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:active{background:#1c2529}.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:hover{color:#fff}.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li.active>a,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li.active>a:hover,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li.active>a:focus,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li.active>a:active{background:#222d32;color:#fff}.control-sidebar-dark .control-sidebar-heading,.control-sidebar-dark .control-sidebar-subheading{color:#fff}.control-sidebar-dark .control-sidebar-menu>li>a:hover{background:#1e282c}.control-sidebar-dark .control-sidebar-menu>li>a .menu-info>p{color:#b8c7ce}.control-sidebar-light{color:#5e5e5e}.control-sidebar-light,.control-sidebar-light+.control-sidebar-bg{background:#f9fafc;border-left:1px solid #d2d6de}.control-sidebar-light .nav-tabs.control-sidebar-tabs{border-bottom:#d2d6de}.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a{background:#e8ecf4;color:#444}.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a:hover,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a:focus{border-left-color:#d2d6de;border-bottom-color:#d2d6de}.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a:hover,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a:focus,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a:active{background:#eff1f7}.control-sidebar-light .nav-tabs.control-sidebar-tabs>li.active>a,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li.active>a:hover,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li.active>a:focus,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li.active>a:active{background:#f9fafc;color:#111}.control-sidebar-light .control-sidebar-heading,.control-sidebar-light .control-sidebar-subheading{color:#111}.control-sidebar-light .control-sidebar-menu{margin-left:-14px}.control-sidebar-light .control-sidebar-menu>li>a:hover{background:#f4f4f5}.control-sidebar-light .control-sidebar-menu>li>a .menu-info>p{color:#5e5e5e}.dropdown-menu{box-shadow:none;border-color:#eee}.dropdown-menu>li>a{color:#777}.dropdown-menu>li>a>.glyphicon,.dropdown-menu>li>a>.fa,.dropdown-menu>li>a>.ion{margin-right:10px}.dropdown-menu>li>a:hover{background-color:#e1e3e9;color:#333}.dropdown-menu>.divider{background-color:#eee}.navbar-nav>.notifications-menu>.dropdown-menu,.navbar-nav>.messages-menu>.dropdown-menu,.navbar-nav>.tasks-menu>.dropdown-menu{width:280px;padding:0 0 0 0;margin:0;top:100%}.navbar-nav>.notifications-menu>.dropdown-menu>li,.navbar-nav>.messages-menu>.dropdown-menu>li,.navbar-nav>.tasks-menu>.dropdown-menu>li{position:relative}.navbar-nav>.notifications-menu>.dropdown-menu>li.header,.navbar-nav>.messages-menu>.dropdown-menu>li.header,.navbar-nav>.tasks-menu>.dropdown-menu>li.header{border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0;background-color:#ffffff;padding:7px 10px;border-bottom:1px solid #f4f4f4;color:#444444;font-size:14px}.navbar-nav>.notifications-menu>.dropdown-menu>li.footer>a,.navbar-nav>.messages-menu>.dropdown-menu>li.footer>a,.navbar-nav>.tasks-menu>.dropdown-menu>li.footer>a{border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px;font-size:12px;background-color:#fff;padding:7px 10px;border-bottom:1px solid #eeeeee;color:#444!important;text-align:center}@media (max-width:991px){.navbar-nav>.notifications-menu>.dropdown-menu>li.footer>a,.navbar-nav>.messages-menu>.dropdown-menu>li.footer>a,.navbar-nav>.tasks-menu>.dropdown-menu>li.footer>a{background:#fff!important;color:#444!important}}.navbar-nav>.notifications-menu>.dropdown-menu>li.footer>a:hover,.navbar-nav>.messages-menu>.dropdown-menu>li.footer>a:hover,.navbar-nav>.tasks-menu>.dropdown-menu>li.footer>a:hover{text-decoration:none;font-weight:normal}.navbar-nav>.notifications-menu>.dropdown-menu>li .menu,.navbar-nav>.messages-menu>.dropdown-menu>li .menu,.navbar-nav>.tasks-menu>.dropdown-menu>li .menu{max-height:200px;margin:0;padding:0;list-style:none;overflow-x:hidden}.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a,.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a,.navbar-nav>.tasks-menu>.dropdown-menu>li .menu>li>a{display:block;white-space:nowrap;border-bottom:1px solid #f4f4f4}.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a:hover,.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a:hover,.navbar-nav>.tasks-menu>.dropdown-menu>li .menu>li>a:hover{background:#f4f4f4;text-decoration:none}.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a{color:#444444;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:10px}.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a>.glyphicon,.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a>.fa,.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a>.ion{width:20px}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a{margin:0;padding:10px 10px}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a>div>img{margin:auto 10px auto auto;width:40px;height:40px}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a>h4{padding:0;margin:0 0 0 45px;color:#444444;font-size:15px;position:relative}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a>h4>small{color:#999999;font-size:10px;position:absolute;top:0;right:0}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a>p{margin:0 0 0 45px;font-size:12px;color:#888888}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a:before,.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a:after{content:" ";display:table}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a:after{clear:both}.navbar-nav>.tasks-menu>.dropdown-menu>li .menu>li>a{padding:10px}.navbar-nav>.tasks-menu>.dropdown-menu>li .menu>li>a>h3{font-size:14px;padding:0;margin:0 0 10px 0;color:#666666}.navbar-nav>.tasks-menu>.dropdown-menu>li .menu>li>a>.progress{padding:0;margin:0}.navbar-nav>.user-menu>.dropdown-menu{border-top-right-radius:0;border-top-left-radius:0;padding:1px 0 0 0;border-top-width:0;width:280px}.navbar-nav>.user-menu>.dropdown-menu,.navbar-nav>.user-menu>.dropdown-menu>.user-body{border-bottom-right-radius:4px;border-bottom-left-radius:4px}.navbar-nav>.user-menu>.dropdown-menu>li.user-header{height:175px;padding:10px;text-align:center}.navbar-nav>.user-menu>.dropdown-menu>li.user-header>img{z-index:5;height:90px;width:90px;border:3px solid;border-color:transparent;border-color:rgba(255,255,255,0.2)}.navbar-nav>.user-menu>.dropdown-menu>li.user-header>p{z-index:5;color:#fff;color:rgba(255,255,255,0.8);font-size:17px;margin-top:10px}.navbar-nav>.user-menu>.dropdown-menu>li.user-header>p>small{display:block;font-size:12px}.navbar-nav>.user-menu>.dropdown-menu>.user-body{padding:15px;border-bottom:1px solid #f4f4f4;border-top:1px solid #dddddd}.navbar-nav>.user-menu>.dropdown-menu>.user-body:before,.navbar-nav>.user-menu>.dropdown-menu>.user-body:after{content:" ";display:table}.navbar-nav>.user-menu>.dropdown-menu>.user-body:after{clear:both}.navbar-nav>.user-menu>.dropdown-menu>.user-body a{color:#444 !important}@media (max-width:991px){.navbar-nav>.user-menu>.dropdown-menu>.user-body a{background:#fff !important;color:#444 !important}}.navbar-nav>.user-menu>.dropdown-menu>.user-footer{background-color:#f9f9f9;padding:10px}.navbar-nav>.user-menu>.dropdown-menu>.user-footer:before,.navbar-nav>.user-menu>.dropdown-menu>.user-footer:after{content:" ";display:table}.navbar-nav>.user-menu>.dropdown-menu>.user-footer:after{clear:both}.navbar-nav>.user-menu>.dropdown-menu>.user-footer .btn-default{color:#666666}@media (max-width:991px){.navbar-nav>.user-menu>.dropdown-menu>.user-footer .btn-default:hover{background-color:#f9f9f9}}.navbar-nav>.user-menu .user-image{float:left;width:25px;height:25px;border-radius:50%;margin-right:10px;margin-top:-2px}@media (max-width:767px){.navbar-nav>.user-menu .user-image{float:none;margin-right:0;margin-top:-8px;line-height:10px}}.open:not(.dropup)>.animated-dropdown-menu{backface-visibility:visible !important;-webkit-animation:flipInX .7s both;-o-animation:flipInX .7s both;animation:flipInX .7s both}@keyframes flipInX{0%{transform:perspective(400px) rotate3d(1, 0, 0, 90deg);transition-timing-function:ease-in;opacity:0}40%{transform:perspective(400px) rotate3d(1, 0, 0, -20deg);transition-timing-function:ease-in}60%{transform:perspective(400px) rotate3d(1, 0, 0, 10deg);opacity:1}80%{transform:perspective(400px) rotate3d(1, 0, 0, -5deg)}100%{transform:perspective(400px)}}@-webkit-keyframes flipInX{0%{-webkit-transform:perspective(400px) rotate3d(1, 0, 0, 90deg);-webkit-transition-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1, 0, 0, -20deg);-webkit-transition-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(1, 0, 0, 10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1, 0, 0, -5deg)}100%{-webkit-transform:perspective(400px)}}.navbar-custom-menu>.navbar-nav>li{position:relative}.navbar-custom-menu>.navbar-nav>li>.dropdown-menu{position:absolute;right:0;left:auto}@media (max-width:991px){.navbar-custom-menu>.navbar-nav{float:right}.navbar-custom-menu>.navbar-nav>li{position:static}.navbar-custom-menu>.navbar-nav>li>.dropdown-menu{position:absolute;right:5%;left:auto;border:1px solid #ddd;background:#fff}}.form-control{border-radius:0;box-shadow:none;border-color:#d2d6de}.form-control:focus{border-color:#3c8dbc;box-shadow:none}.form-control::-moz-placeholder,.form-control:-ms-input-placeholder,.form-control::-webkit-input-placeholder{color:#bbb;opacity:1}.form-control:not(select){-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-group.has-success label{color:#00a65a}.form-group.has-success .form-control{border-color:#00a65a;box-shadow:none}.form-group.has-warning label{color:#f39c12}.form-group.has-warning .form-control{border-color:#f39c12;box-shadow:none}.form-group.has-error label{color:#dd4b39}.form-group.has-error .form-control{border-color:#dd4b39;box-shadow:none}.input-group .input-group-addon{border-radius:0;border-color:#d2d6de;background-color:#fff}.btn-group-vertical .btn.btn-flat:first-of-type,.btn-group-vertical .btn.btn-flat:last-of-type{border-radius:0}.icheck>label{padding-left:0}.form-control-feedback.fa{line-height:34px}.input-lg+.form-control-feedback.fa,.input-group-lg+.form-control-feedback.fa,.form-group-lg .form-control+.form-control-feedback.fa{line-height:46px}.input-sm+.form-control-feedback.fa,.input-group-sm+.form-control-feedback.fa,.form-group-sm .form-control+.form-control-feedback.fa{line-height:30px}.progress,.progress>.progress-bar{-webkit-box-shadow:none;box-shadow:none}.progress,.progress>.progress-bar,.progress .progress-bar,.progress>.progress-bar .progress-bar{border-radius:1px}.progress.sm,.progress-sm{height:10px}.progress.sm,.progress-sm,.progress.sm .progress-bar,.progress-sm .progress-bar{border-radius:1px}.progress.xs,.progress-xs{height:7px}.progress.xs,.progress-xs,.progress.xs .progress-bar,.progress-xs .progress-bar{border-radius:1px}.progress.xxs,.progress-xxs{height:3px}.progress.xxs,.progress-xxs,.progress.xxs .progress-bar,.progress-xxs .progress-bar{border-radius:1px}.progress.vertical{position:relative;width:30px;height:200px;display:inline-block;margin-right:10px}.progress.vertical>.progress-bar{width:100%;position:absolute;bottom:0}.progress.vertical.sm,.progress.vertical.progress-sm{width:20px}.progress.vertical.xs,.progress.vertical.progress-xs{width:10px}.progress.vertical.xxs,.progress.vertical.progress-xxs{width:3px}.progress-group .progress-text{font-weight:600}.progress-group .progress-number{float:right}.table tr>td .progress{margin:0}.progress-bar-light-blue,.progress-bar-primary{background-color:#3c8dbc}.progress-striped .progress-bar-light-blue,.progress-striped .progress-bar-primary{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:-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-bar-green,.progress-bar-success{background-color:#00a65a}.progress-striped .progress-bar-green,.progress-striped .progress-bar-success{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:-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-bar-aqua,.progress-bar-info{background-color:#00c0ef}.progress-striped .progress-bar-aqua,.progress-striped .progress-bar-info{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:-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-bar-yellow,.progress-bar-warning{background-color:#f39c12}.progress-striped .progress-bar-yellow,.progress-striped .progress-bar-warning{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:-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-bar-red,.progress-bar-danger{background-color:#dd4b39}.progress-striped .progress-bar-red,.progress-striped .progress-bar-danger{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:-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)}.small-box{border-radius:2px;position:relative;display:block;margin-bottom:20px;box-shadow:0 1px 1px rgba(0,0,0,0.1)}.small-box>.inner{padding:10px}.small-box>.small-box-footer{position:relative;text-align:center;padding:3px 0;color:#fff;color:rgba(255,255,255,0.8);display:block;z-index:10;background:rgba(0,0,0,0.1);text-decoration:none}.small-box>.small-box-footer:hover{color:#fff;background:rgba(0,0,0,0.15)}.small-box h3{font-size:38px;font-weight:bold;margin:0 0 10px 0;white-space:nowrap;padding:0}.small-box p{font-size:15px}.small-box p>small{display:block;color:#f9f9f9;font-size:13px;margin-top:5px}.small-box h3,.small-box p{z-index:5px}.small-box .icon{-webkit-transition:all .3s linear;-o-transition:all .3s linear;transition:all .3s linear;position:absolute;top:-10px;right:10px;z-index:0;font-size:90px;color:rgba(0,0,0,0.15)}.small-box:hover{text-decoration:none;color:#f9f9f9}.small-box:hover .icon{font-size:95px}@media (max-width:767px){.small-box{text-align:center}.small-box .icon{display:none}.small-box p{font-size:12px}}.box{position:relative;border-radius:3px;background:#ffffff;border-top:3px solid #d2d6de;margin-bottom:20px;width:100%;box-shadow:0 1px 1px rgba(0,0,0,0.1)}.box.box-primary{border-top-color:#3c8dbc}.box.box-info{border-top-color:#00c0ef}.box.box-danger{border-top-color:#dd4b39}.box.box-warning{border-top-color:#f39c12}.box.box-success{border-top-color:#00a65a}.box.box-default{border-top-color:#d2d6de}.box.collapsed-box .box-body,.box.collapsed-box .box-footer{display:none}.box .nav-stacked>li{border-bottom:1px solid #f4f4f4;margin:0}.box .nav-stacked>li:last-of-type{border-bottom:none}.box.height-control .box-body{max-height:300px;overflow:auto}.box .border-right{border-right:1px solid #f4f4f4}.box .border-left{border-left:1px solid #f4f4f4}.box.box-solid{border-top:0}.box.box-solid>.box-header .btn.btn-default{background:transparent}.box.box-solid>.box-header .btn:hover,.box.box-solid>.box-header a:hover{background:rgba(0,0,0,0.1)}.box.box-solid.box-default{border:1px solid #d2d6de}.box.box-solid.box-default>.box-header{color:#444;background:#d2d6de;background-color:#d2d6de}.box.box-solid.box-default>.box-header a,.box.box-solid.box-default>.box-header .btn{color:#444}.box.box-solid.box-primary{border:1px solid #3c8dbc}.box.box-solid.box-primary>.box-header{color:#fff;background:#3c8dbc;background-color:#3c8dbc}.box.box-solid.box-primary>.box-header a,.box.box-solid.box-primary>.box-header .btn{color:#fff}.box.box-solid.box-info{border:1px solid #00c0ef}.box.box-solid.box-info>.box-header{color:#fff;background:#00c0ef;background-color:#00c0ef}.box.box-solid.box-info>.box-header a,.box.box-solid.box-info>.box-header .btn{color:#fff}.box.box-solid.box-danger{border:1px solid #dd4b39}.box.box-solid.box-danger>.box-header{color:#fff;background:#dd4b39;background-color:#dd4b39}.box.box-solid.box-danger>.box-header a,.box.box-solid.box-danger>.box-header .btn{color:#fff}.box.box-solid.box-warning{border:1px solid #f39c12}.box.box-solid.box-warning>.box-header{color:#fff;background:#f39c12;background-color:#f39c12}.box.box-solid.box-warning>.box-header a,.box.box-solid.box-warning>.box-header .btn{color:#fff}.box.box-solid.box-success{border:1px solid #00a65a}.box.box-solid.box-success>.box-header{color:#fff;background:#00a65a;background-color:#00a65a}.box.box-solid.box-success>.box-header a,.box.box-solid.box-success>.box-header .btn{color:#fff}.box.box-solid>.box-header>.box-tools .btn{border:0;box-shadow:none}.box.box-solid[class*='bg']>.box-header{color:#fff}.box .box-group>.box{margin-bottom:5px}.box .knob-label{text-align:center;color:#333;font-weight:100;font-size:12px;margin-bottom:0.3em}.box>.overlay,.overlay-wrapper>.overlay,.box>.loading-img,.overlay-wrapper>.loading-img{position:absolute;top:0;left:0;width:100%;height:100%}.box .overlay,.overlay-wrapper .overlay{z-index:50;background:rgba(255,255,255,0.7);border-radius:3px}.box .overlay>.fa,.overlay-wrapper .overlay>.fa{position:absolute;top:50%;left:50%;margin-left:-15px;margin-top:-15px;color:#000;font-size:30px}.box .overlay.dark,.overlay-wrapper .overlay.dark{background:rgba(0,0,0,0.5)}.box-header:before,.box-body:before,.box-footer:before,.box-header:after,.box-body:after,.box-footer:after{content:" ";display:table}.box-header:after,.box-body:after,.box-footer:after{clear:both}.box-header{color:#444;display:block;padding:10px;position:relative}.box-header.with-border{border-bottom:1px solid #f4f4f4}.collapsed-box .box-header.with-border{border-bottom:none}.box-header>.fa,.box-header>.glyphicon,.box-header>.ion,.box-header .box-title{display:inline-block;font-size:18px;margin:0;line-height:1}.box-header>.fa,.box-header>.glyphicon,.box-header>.ion{margin-right:5px}.box-header>.box-tools{position:absolute;right:10px;top:5px}.box-header>.box-tools [data-toggle="tooltip"]{position:relative}.box-header>.box-tools.pull-right .dropdown-menu{right:0;left:auto}.btn-box-tool{padding:5px;font-size:12px;background:transparent;color:#97a0b3}.open .btn-box-tool,.btn-box-tool:hover{color:#606c84}.btn-box-tool.btn:active{box-shadow:none}.box-body{border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px;padding:10px}.no-header .box-body{border-top-right-radius:3px;border-top-left-radius:3px}.box-body>.table{margin-bottom:0}.box-body .fc{margin-top:5px}.box-body .full-width-chart{margin:-19px}.box-body.no-padding .full-width-chart{margin:-9px}.box-body .box-pane{border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:3px}.box-body .box-pane-right{border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:3px;border-bottom-left-radius:0}.box-footer{border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px;border-top:1px solid #f4f4f4;padding:10px;background-color:#fff}.chart-legend{margin:10px 0}@media (max-width:991px){.chart-legend>li{float:left;margin-right:10px}}.box-comments{background:#f7f7f7}.box-comments .box-comment{padding:8px 0;border-bottom:1px solid #eee}.box-comments .box-comment:before,.box-comments .box-comment:after{content:" ";display:table}.box-comments .box-comment:after{clear:both}.box-comments .box-comment:last-of-type{border-bottom:0}.box-comments .box-comment:first-of-type{padding-top:0}.box-comments .box-comment img{float:left}.box-comments .comment-text{margin-left:40px;color:#555}.box-comments .username{color:#444;display:block;font-weight:600}.box-comments .text-muted{font-weight:400;font-size:12px}.todo-list{margin:0;padding:0;list-style:none;overflow:auto}.todo-list>li{border-radius:2px;padding:10px;background:#f4f4f4;margin-bottom:2px;border-left:2px solid #e6e7e8;color:#444}.todo-list>li:last-of-type{margin-bottom:0}.todo-list>li>input[type='checkbox']{margin:0 10px 0 5px}.todo-list>li .text{display:inline-block;margin-left:5px;font-weight:600}.todo-list>li .label{margin-left:10px;font-size:9px}.todo-list>li .tools{display:none;float:right;color:#dd4b39}.todo-list>li .tools>.fa,.todo-list>li .tools>.glyphicon,.todo-list>li .tools>.ion{margin-right:5px;cursor:pointer}.todo-list>li:hover .tools{display:inline-block}.todo-list>li.done{color:#999}.todo-list>li.done .text{text-decoration:line-through;font-weight:500}.todo-list>li.done .label{background:#d2d6de !important}.todo-list .danger{border-left-color:#dd4b39}.todo-list .warning{border-left-color:#f39c12}.todo-list .info{border-left-color:#00c0ef}.todo-list .success{border-left-color:#00a65a}.todo-list .primary{border-left-color:#3c8dbc}.todo-list .handle{display:inline-block;cursor:move;margin:0 5px}.chat{padding:5px 20px 5px 10px}.chat .item{margin-bottom:10px}.chat .item:before,.chat .item:after{content:" ";display:table}.chat .item:after{clear:both}.chat .item>img{width:40px;height:40px;border:2px solid transparent;border-radius:50%}.chat .item>.online{border:2px solid #00a65a}.chat .item>.offline{border:2px solid #dd4b39}.chat .item>.message{margin-left:55px;margin-top:-40px}.chat .item>.message>.name{display:block;font-weight:600}.chat .item>.attachment{border-radius:3px;background:#f4f4f4;margin-left:65px;margin-right:15px;padding:10px}.chat .item>.attachment>h4{margin:0 0 5px 0;font-weight:600;font-size:14px}.chat .item>.attachment>p,.chat .item>.attachment>.filename{font-weight:600;font-size:13px;font-style:italic;margin:0}.chat .item>.attachment:before,.chat .item>.attachment:after{content:" ";display:table}.chat .item>.attachment:after{clear:both}.box-input{max-width:200px}.modal .panel-body{color:#444}.info-box{display:block;min-height:90px;background:#fff;width:100%;box-shadow:0 1px 1px rgba(0,0,0,0.1);border-radius:2px;margin-bottom:15px}.info-box small{font-size:14px}.info-box .progress{background:rgba(0,0,0,0.2);margin:5px -10px 5px -10px;height:2px}.info-box .progress,.info-box .progress .progress-bar{border-radius:0}.info-box .progress .progress-bar{background:#fff}.info-box-icon{border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px;display:block;float:left;height:90px;width:90px;text-align:center;font-size:45px;line-height:90px;background:rgba(0,0,0,0.2)}.info-box-icon>img{max-width:100%}.info-box-content{padding:5px 10px;margin-left:90px}.info-box-number{display:block;font-weight:bold;font-size:18px}.progress-description,.info-box-text{display:block;font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.info-box-text{text-transform:uppercase}.info-box-more{display:block}.progress-description{margin:0}.timeline{position:relative;margin:0 0 30px 0;padding:0;list-style:none}.timeline:before{content:'';position:absolute;top:0;bottom:0;width:4px;background:#ddd;left:31px;margin:0;border-radius:2px}.timeline>li{position:relative;margin-right:10px;margin-bottom:15px}.timeline>li:before,.timeline>li:after{content:" ";display:table}.timeline>li:after{clear:both}.timeline>li>.timeline-item{-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.1);box-shadow:0 1px 1px rgba(0,0,0,0.1);border-radius:3px;margin-top:0;background:#fff;color:#444;margin-left:60px;margin-right:15px;padding:0;position:relative}.timeline>li>.timeline-item>.time{color:#999;float:right;padding:10px;font-size:12px}.timeline>li>.timeline-item>.timeline-header{margin:0;color:#555;border-bottom:1px solid #f4f4f4;padding:10px;font-size:16px;line-height:1.1}.timeline>li>.timeline-item>.timeline-header>a{font-weight:600}.timeline>li>.timeline-item>.timeline-body,.timeline>li>.timeline-item>.timeline-footer{padding:10px}.timeline>li>.fa,.timeline>li>.glyphicon,.timeline>li>.ion{width:30px;height:30px;font-size:15px;line-height:30px;position:absolute;color:#666;background:#d2d6de;border-radius:50%;text-align:center;left:18px;top:0}.timeline>.time-label>span{font-weight:600;padding:5px;display:inline-block;background-color:#fff;border-radius:4px}.timeline-inverse>li>.timeline-item{background:#f0f0f0;border:1px solid #ddd;-webkit-box-shadow:none;box-shadow:none}.timeline-inverse>li>.timeline-item>.timeline-header{border-bottom-color:#ddd}.btn{border-radius:3px;-webkit-box-shadow:none;box-shadow:none;border:1px solid transparent}.btn.uppercase{text-transform:uppercase}.btn.btn-flat{border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;border-width:1px}.btn:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn:focus{outline:none}.btn.btn-file{position:relative;overflow:hidden}.btn.btn-file>input[type='file']{position:absolute;top:0;right:0;min-width:100%;min-height:100%;font-size:100px;text-align:right;opacity:0;filter:alpha(opacity=0);outline:none;background:white;cursor:inherit;display:block}.btn-default{background-color:#f4f4f4;color:#444;border-color:#ddd}.btn-default:hover,.btn-default:active,.btn-default.hover{background-color:#e7e7e7}.btn-primary{background-color:#3c8dbc;border-color:#367fa9}.btn-primary:hover,.btn-primary:active,.btn-primary.hover{background-color:#367fa9}.btn-success{background-color:#00a65a;border-color:#008d4c}.btn-success:hover,.btn-success:active,.btn-success.hover{background-color:#008d4c}.btn-info{background-color:#00c0ef;border-color:#00acd6}.btn-info:hover,.btn-info:active,.btn-info.hover{background-color:#00acd6}.btn-danger{background-color:#dd4b39;border-color:#d73925}.btn-danger:hover,.btn-danger:active,.btn-danger.hover{background-color:#d73925}.btn-warning{background-color:#f39c12;border-color:#e08e0b}.btn-warning:hover,.btn-warning:active,.btn-warning.hover{background-color:#e08e0b}.btn-outline{border:1px solid #fff;background:transparent;color:#fff}.btn-outline:hover,.btn-outline:focus,.btn-outline:active{color:rgba(255,255,255,0.7);border-color:rgba(255,255,255,0.7)}.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn[class*='bg-']:hover{-webkit-box-shadow:inset 0 0 100px rgba(0,0,0,0.2);box-shadow:inset 0 0 100px rgba(0,0,0,0.2)}.btn-app{border-radius:3px;position:relative;padding:15px 5px;margin:0 0 10px 10px;min-width:80px;height:60px;text-align:center;color:#666;border:1px solid #ddd;background-color:#f4f4f4;font-size:12px}.btn-app>.fa,.btn-app>.glyphicon,.btn-app>.ion{font-size:20px;display:block}.btn-app:hover{background:#f4f4f4;color:#444;border-color:#aaa}.btn-app:active,.btn-app:focus{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn-app>.badge{position:absolute;top:-3px;right:-10px;font-size:10px;font-weight:400}.callout{border-radius:3px;margin:0 0 20px 0;padding:15px 30px 15px 15px;border-left:5px solid #eee}.callout a{color:#fff;text-decoration:underline}.callout a:hover{color:#eee}.callout h4{margin-top:0;font-weight:600}.callout p:last-child{margin-bottom:0}.callout code,.callout .highlight{background-color:#fff}.callout.callout-danger{border-color:#c23321}.callout.callout-warning{border-color:#c87f0a}.callout.callout-info{border-color:#0097bc}.callout.callout-success{border-color:#00733e}.alert{border-radius:3px}.alert h4{font-weight:600}.alert .icon{margin-right:10px}.alert .close{color:#000;opacity:.2;filter:alpha(opacity=20)}.alert .close:hover{opacity:.5;filter:alpha(opacity=50)}.alert a{color:#fff;text-decoration:underline}.alert-success{border-color:#008d4c}.alert-danger,.alert-error{border-color:#d73925}.alert-warning{border-color:#e08e0b}.alert-info{border-color:#00acd6}.nav>li>a:hover,.nav>li>a:active,.nav>li>a:focus{color:#444;background:#f7f7f7}.nav-pills>li>a{border-radius:0;border-top:3px solid transparent;color:#444}.nav-pills>li>a>.fa,.nav-pills>li>a>.glyphicon,.nav-pills>li>a>.ion{margin-right:5px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{border-top-color:#3c8dbc}.nav-pills>li.active>a{font-weight:600}.nav-stacked>li>a{border-radius:0;border-top:0;border-left:3px solid transparent;color:#444}.nav-stacked>li.active>a,.nav-stacked>li.active>a:hover{background:transparent;color:#444;border-top:0;border-left-color:#3c8dbc}.nav-stacked>li.header{border-bottom:1px solid #ddd;color:#777;margin-bottom:10px;padding:5px 10px;text-transform:uppercase}.nav-tabs-custom{margin-bottom:20px;background:#fff;box-shadow:0 1px 1px rgba(0,0,0,0.1);border-radius:3px}.nav-tabs-custom>.nav-tabs{margin:0;border-bottom-color:#f4f4f4;border-top-right-radius:3px;border-top-left-radius:3px}.nav-tabs-custom>.nav-tabs>li{border-top:3px solid transparent;margin-bottom:-2px;margin-right:5px}.nav-tabs-custom>.nav-tabs>li>a{color:#444;border-radius:0}.nav-tabs-custom>.nav-tabs>li>a.text-muted{color:#999}.nav-tabs-custom>.nav-tabs>li>a,.nav-tabs-custom>.nav-tabs>li>a:hover{background:transparent;margin:0}.nav-tabs-custom>.nav-tabs>li>a:hover{color:#999}.nav-tabs-custom>.nav-tabs>li:not(.active)>a:hover,.nav-tabs-custom>.nav-tabs>li:not(.active)>a:focus,.nav-tabs-custom>.nav-tabs>li:not(.active)>a:active{border-color:transparent}.nav-tabs-custom>.nav-tabs>li.active{border-top-color:#3c8dbc}.nav-tabs-custom>.nav-tabs>li.active>a,.nav-tabs-custom>.nav-tabs>li.active:hover>a{background-color:#fff;color:#444}.nav-tabs-custom>.nav-tabs>li.active>a{border-top-color:transparent;border-left-color:#f4f4f4;border-right-color:#f4f4f4}.nav-tabs-custom>.nav-tabs>li:first-of-type{margin-left:0}.nav-tabs-custom>.nav-tabs>li:first-of-type.active>a{border-left-color:transparent}.nav-tabs-custom>.nav-tabs.pull-right{float:none!important}.nav-tabs-custom>.nav-tabs.pull-right>li{float:right}.nav-tabs-custom>.nav-tabs.pull-right>li:first-of-type{margin-right:0}.nav-tabs-custom>.nav-tabs.pull-right>li:first-of-type>a{border-left-width:1px}.nav-tabs-custom>.nav-tabs.pull-right>li:first-of-type.active>a{border-left-color:#f4f4f4;border-right-color:transparent}.nav-tabs-custom>.nav-tabs>li.header{line-height:35px;padding:0 10px;font-size:20px;color:#444}.nav-tabs-custom>.nav-tabs>li.header>.fa,.nav-tabs-custom>.nav-tabs>li.header>.glyphicon,.nav-tabs-custom>.nav-tabs>li.header>.ion{margin-right:5px}.nav-tabs-custom>.tab-content{background:#fff;padding:10px;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.nav-tabs-custom .dropdown.open>a:active,.nav-tabs-custom .dropdown.open>a:focus{background:transparent;color:#999}.pagination>li>a{background:#fafafa;color:#666}.pagination.pagination-flat>li>a{border-radius:0 !important}.products-list{list-style:none;margin:0;padding:0}.products-list>.item{border-radius:3px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.1);box-shadow:0 1px 1px rgba(0,0,0,0.1);padding:10px 0;background:#fff}.products-list>.item:before,.products-list>.item:after{content:" ";display:table}.products-list>.item:after{clear:both}.products-list .product-img{float:left}.products-list .product-img img{width:50px;height:50px}.products-list .product-info{margin-left:60px}.products-list .product-title{font-weight:600}.products-list .product-description{display:block;color:#999;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.product-list-in-box>.item{-webkit-box-shadow:none;box-shadow:none;border-radius:0;border-bottom:1px solid #f4f4f4}.product-list-in-box>.item:last-of-type{border-bottom-width:0}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{border-top:1px solid #f4f4f4}.table>thead>tr>th{border-bottom:2px solid #f4f4f4}.table tr td .progress{margin-top:5px}.table-bordered{border:1px solid #f4f4f4}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #f4f4f4}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table.no-border,.table.no-border td,.table.no-border th{border:0}table.text-center,table.text-center td,table.text-center th{text-align:center}.table.align th{text-align:left}.table.align td{text-align:right}.label-default{background-color:#d2d6de;color:#444}.direct-chat .box-body{border-bottom-right-radius:0;border-bottom-left-radius:0;position:relative;overflow-x:hidden;padding:0}.direct-chat.chat-pane-open .direct-chat-contacts{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0)}.direct-chat-messages{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0);padding:10px;height:250px;overflow:auto}.direct-chat-msg,.direct-chat-text{display:block}.direct-chat-msg{margin-bottom:10px}.direct-chat-msg:before,.direct-chat-msg:after{content:" ";display:table}.direct-chat-msg:after{clear:both}.direct-chat-messages,.direct-chat-contacts{-webkit-transition:-webkit-transform .5s ease-in-out;-moz-transition:-moz-transform .5s ease-in-out;-o-transition:-o-transform .5s ease-in-out;transition:transform .5s ease-in-out}.direct-chat-text{border-radius:5px;position:relative;padding:5px 10px;background:#d2d6de;border:1px solid #d2d6de;margin:5px 0 0 50px;color:#444}.direct-chat-text:after,.direct-chat-text:before{position:absolute;right:100%;top:15px;border:solid transparent;border-right-color:#d2d6de;content:' ';height:0;width:0;pointer-events:none}.direct-chat-text:after{border-width:5px;margin-top:-5px}.direct-chat-text:before{border-width:6px;margin-top:-6px}.right .direct-chat-text{margin-right:50px;margin-left:0}.right .direct-chat-text:after,.right .direct-chat-text:before{right:auto;left:100%;border-right-color:transparent;border-left-color:#d2d6de}.direct-chat-img{border-radius:50%;float:left;width:40px;height:40px}.right .direct-chat-img{float:right}.direct-chat-info{display:block;margin-bottom:2px;font-size:12px}.direct-chat-name{font-weight:600}.direct-chat-timestamp{color:#999}.direct-chat-contacts-open .direct-chat-contacts{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0)}.direct-chat-contacts{-webkit-transform:translate(101%, 0);-ms-transform:translate(101%, 0);-o-transform:translate(101%, 0);transform:translate(101%, 0);position:absolute;top:0;bottom:0;height:250px;width:100%;background:#222d32;color:#fff;overflow:auto}.contacts-list>li{border-bottom:1px solid rgba(0,0,0,0.2);padding:10px;margin:0}.contacts-list>li:before,.contacts-list>li:after{content:" ";display:table}.contacts-list>li:after{clear:both}.contacts-list>li:last-of-type{border-bottom:none}.contacts-list-img{border-radius:50%;width:40px;float:left}.contacts-list-info{margin-left:45px;color:#fff}.contacts-list-name,.contacts-list-status{display:block}.contacts-list-name{font-weight:600}.contacts-list-status{font-size:12px}.contacts-list-date{color:#aaa;font-weight:normal}.contacts-list-msg{color:#999}.direct-chat-danger .right>.direct-chat-text{background:#dd4b39;border-color:#dd4b39;color:#fff}.direct-chat-danger .right>.direct-chat-text:after,.direct-chat-danger .right>.direct-chat-text:before{border-left-color:#dd4b39}.direct-chat-primary .right>.direct-chat-text{background:#3c8dbc;border-color:#3c8dbc;color:#fff}.direct-chat-primary .right>.direct-chat-text:after,.direct-chat-primary .right>.direct-chat-text:before{border-left-color:#3c8dbc}.direct-chat-warning .right>.direct-chat-text{background:#f39c12;border-color:#f39c12;color:#fff}.direct-chat-warning .right>.direct-chat-text:after,.direct-chat-warning .right>.direct-chat-text:before{border-left-color:#f39c12}.direct-chat-info .right>.direct-chat-text{background:#00c0ef;border-color:#00c0ef;color:#fff}.direct-chat-info .right>.direct-chat-text:after,.direct-chat-info .right>.direct-chat-text:before{border-left-color:#00c0ef}.direct-chat-success .right>.direct-chat-text{background:#00a65a;border-color:#00a65a;color:#fff}.direct-chat-success .right>.direct-chat-text:after,.direct-chat-success .right>.direct-chat-text:before{border-left-color:#00a65a}.users-list>li{width:25%;float:left;padding:10px;text-align:center}.users-list>li img{border-radius:50%;max-width:100%;height:auto}.users-list>li>a:hover,.users-list>li>a:hover .users-list-name{color:#999}.users-list-name,.users-list-date{display:block}.users-list-name{font-weight:600;color:#444;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.users-list-date{color:#999;font-size:12px}.carousel-control.left,.carousel-control.right{background-image:none}.carousel-control>.fa{font-size:40px;position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-20px}.modal{background:rgba(0,0,0,0.3)}.modal-content{border-radius:0;-webkit-box-shadow:0 2px 3px rgba(0,0,0,0.125);box-shadow:0 2px 3px rgba(0,0,0,0.125);border:0}@media (min-width:768px){.modal-content{-webkit-box-shadow:0 2px 3px rgba(0,0,0,0.125);box-shadow:0 2px 3px rgba(0,0,0,0.125)}}.modal-header{border-bottom-color:#f4f4f4}.modal-footer{border-top-color:#f4f4f4}.modal-primary .modal-header,.modal-primary .modal-footer{border-color:#307095}.modal-warning .modal-header,.modal-warning .modal-footer{border-color:#c87f0a}.modal-info .modal-header,.modal-info .modal-footer{border-color:#0097bc}.modal-success .modal-header,.modal-success .modal-footer{border-color:#00733e}.modal-danger .modal-header,.modal-danger .modal-footer{border-color:#c23321}.box-widget{border:none;position:relative}.widget-user .widget-user-header{padding:20px;height:120px;border-top-right-radius:3px;border-top-left-radius:3px}.widget-user .widget-user-username{margin-top:0;margin-bottom:5px;font-size:25px;font-weight:300;text-shadow:0 1px 1px rgba(0,0,0,0.2)}.widget-user .widget-user-desc{margin-top:0}.widget-user .widget-user-image{position:absolute;top:65px;left:50%;margin-left:-45px}.widget-user .widget-user-image>img{width:90px;height:auto;border:3px solid #fff}.widget-user .box-footer{padding-top:30px}.widget-user-2 .widget-user-header{padding:20px;border-top-right-radius:3px;border-top-left-radius:3px}.widget-user-2 .widget-user-username{margin-top:5px;margin-bottom:5px;font-size:25px;font-weight:300}.widget-user-2 .widget-user-desc{margin-top:0}.widget-user-2 .widget-user-username,.widget-user-2 .widget-user-desc{margin-left:75px}.widget-user-2 .widget-user-image>img{width:65px;height:auto;float:left}.mailbox-messages>.table{margin:0}.mailbox-controls{padding:5px}.mailbox-controls.with-border{border-bottom:1px solid #f4f4f4}.mailbox-read-info{border-bottom:1px solid #f4f4f4;padding:10px}.mailbox-read-info h3{font-size:20px;margin:0}.mailbox-read-info h5{margin:0;padding:5px 0 0 0}.mailbox-read-time{color:#999;font-size:13px}.mailbox-read-message{padding:10px}.mailbox-attachments li{float:left;width:200px;border:1px solid #eee;margin-bottom:10px;margin-right:10px}.mailbox-attachment-name{font-weight:bold;color:#666}.mailbox-attachment-icon,.mailbox-attachment-info,.mailbox-attachment-size{display:block}.mailbox-attachment-info{padding:10px;background:#f4f4f4}.mailbox-attachment-size{color:#999;font-size:12px}.mailbox-attachment-icon{text-align:center;font-size:65px;color:#666;padding:20px 10px}.mailbox-attachment-icon.has-img{padding:0}.mailbox-attachment-icon.has-img>img{max-width:100%;height:auto}.lockscreen{background:#d2d6de}.lockscreen-logo{font-size:35px;text-align:center;margin-bottom:25px;font-weight:300}.lockscreen-logo a{color:#444}.lockscreen-wrapper{max-width:400px;margin:0 auto;margin-top:10%}.lockscreen .lockscreen-name{text-align:center;font-weight:600}.lockscreen-item{border-radius:4px;padding:0;background:#fff;position:relative;margin:10px auto 30px auto;width:290px}.lockscreen-image{border-radius:50%;position:absolute;left:-10px;top:-25px;background:#fff;padding:5px;z-index:10}.lockscreen-image>img{border-radius:50%;width:70px;height:70px}.lockscreen-credentials{margin-left:70px}.lockscreen-credentials .form-control{border:0}.lockscreen-credentials .btn{background-color:#fff;border:0;padding:0 10px}.lockscreen-footer{margin-top:10px}.login-logo,.register-logo{font-size:35px;text-align:center;margin-bottom:25px;font-weight:300}.login-logo a,.register-logo a{color:#444}.login-page,.register-page{background:#d2d6de}.login-box,.register-box{width:360px;margin:7% auto}@media (max-width:768px){.login-box,.register-box{width:90%;margin-top:20px}}.login-box-body,.register-box-body{background:#fff;padding:20px;border-top:0;color:#666}.login-box-body .form-control-feedback,.register-box-body .form-control-feedback{color:#777}.login-box-msg,.register-box-msg{margin:0;text-align:center;padding:0 20px 20px 20px}.social-auth-links{margin:10px 0}.error-page{width:600px;margin:20px auto 0 auto}@media (max-width:991px){.error-page{width:100%}}.error-page>.headline{float:left;font-size:100px;font-weight:300}@media (max-width:991px){.error-page>.headline{float:none;text-align:center}}.error-page>.error-content{margin-left:190px;display:block}@media (max-width:991px){.error-page>.error-content{margin-left:0}}.error-page>.error-content>h3{font-weight:300;font-size:25px}@media (max-width:991px){.error-page>.error-content>h3{text-align:center}}.invoice{position:relative;background:#fff;border:1px solid #f4f4f4;padding:20px;margin:10px 25px}.invoice-title{margin-top:0}.profile-user-img{margin:0 auto;width:100px;padding:3px;border:3px solid #d2d6de}.profile-username{font-size:21px;margin-top:5px}.post{border-bottom:1px solid #d2d6de;margin-bottom:15px;padding-bottom:15px;color:#666}.post:last-of-type{border-bottom:0;margin-bottom:0;padding-bottom:0}.post .user-block{margin-bottom:15px}.btn-social{position:relative;padding-left:44px;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.btn-social>:first-child{position:absolute;left:0;top:0;bottom:0;width:32px;line-height:34px;font-size:1.6em;text-align:center;border-right:1px solid rgba(0,0,0,0.2)}.btn-social.btn-lg{padding-left:61px}.btn-social.btn-lg>:first-child{line-height:45px;width:45px;font-size:1.8em}.btn-social.btn-sm{padding-left:38px}.btn-social.btn-sm>:first-child{line-height:28px;width:28px;font-size:1.4em}.btn-social.btn-xs{padding-left:30px}.btn-social.btn-xs>:first-child{line-height:20px;width:20px;font-size:1.2em}.btn-social-icon{position:relative;padding-left:44px;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:34px;width:34px;padding:0}.btn-social-icon>:first-child{position:absolute;left:0;top:0;bottom:0;width:32px;line-height:34px;font-size:1.6em;text-align:center;border-right:1px solid rgba(0,0,0,0.2)}.btn-social-icon.btn-lg{padding-left:61px}.btn-social-icon.btn-lg>:first-child{line-height:45px;width:45px;font-size:1.8em}.btn-social-icon.btn-sm{padding-left:38px}.btn-social-icon.btn-sm>:first-child{line-height:28px;width:28px;font-size:1.4em}.btn-social-icon.btn-xs{padding-left:30px}.btn-social-icon.btn-xs>:first-child{line-height:20px;width:20px;font-size:1.2em}.btn-social-icon>:first-child{border:none;text-align:center;width:100%}.btn-social-icon.btn-lg{height:45px;width:45px;padding-left:0;padding-right:0}.btn-social-icon.btn-sm{height:30px;width:30px;padding-left:0;padding-right:0}.btn-social-icon.btn-xs{height:22px;width:22px;padding-left:0;padding-right:0}.btn-adn{color:#fff;background-color:#d87a68;border-color:rgba(0,0,0,0.2)}.btn-adn:hover,.btn-adn:focus,.btn-adn.focus,.btn-adn:active,.btn-adn.active,.open>.dropdown-toggle.btn-adn{color:#fff;background-color:#ce563f;border-color:rgba(0,0,0,0.2)}.btn-adn:active,.btn-adn.active,.open>.dropdown-toggle.btn-adn{background-image:none}.btn-adn .badge{color:#d87a68;background-color:#fff}.btn-bitbucket{color:#fff;background-color:#205081;border-color:rgba(0,0,0,0.2)}.btn-bitbucket:hover,.btn-bitbucket:focus,.btn-bitbucket.focus,.btn-bitbucket:active,.btn-bitbucket.active,.open>.dropdown-toggle.btn-bitbucket{color:#fff;background-color:#163758;border-color:rgba(0,0,0,0.2)}.btn-bitbucket:active,.btn-bitbucket.active,.open>.dropdown-toggle.btn-bitbucket{background-image:none}.btn-bitbucket .badge{color:#205081;background-color:#fff}.btn-dropbox{color:#fff;background-color:#1087dd;border-color:rgba(0,0,0,0.2)}.btn-dropbox:hover,.btn-dropbox:focus,.btn-dropbox.focus,.btn-dropbox:active,.btn-dropbox.active,.open>.dropdown-toggle.btn-dropbox{color:#fff;background-color:#0d6aad;border-color:rgba(0,0,0,0.2)}.btn-dropbox:active,.btn-dropbox.active,.open>.dropdown-toggle.btn-dropbox{background-image:none}.btn-dropbox .badge{color:#1087dd;background-color:#fff}.btn-facebook{color:#fff;background-color:#3b5998;border-color:rgba(0,0,0,0.2)}.btn-facebook:hover,.btn-facebook:focus,.btn-facebook.focus,.btn-facebook:active,.btn-facebook.active,.open>.dropdown-toggle.btn-facebook{color:#fff;background-color:#2d4373;border-color:rgba(0,0,0,0.2)}.btn-facebook:active,.btn-facebook.active,.open>.dropdown-toggle.btn-facebook{background-image:none}.btn-facebook .badge{color:#3b5998;background-color:#fff}.btn-flickr{color:#fff;background-color:#ff0084;border-color:rgba(0,0,0,0.2)}.btn-flickr:hover,.btn-flickr:focus,.btn-flickr.focus,.btn-flickr:active,.btn-flickr.active,.open>.dropdown-toggle.btn-flickr{color:#fff;background-color:#cc006a;border-color:rgba(0,0,0,0.2)}.btn-flickr:active,.btn-flickr.active,.open>.dropdown-toggle.btn-flickr{background-image:none}.btn-flickr .badge{color:#ff0084;background-color:#fff}.btn-foursquare{color:#fff;background-color:#f94877;border-color:rgba(0,0,0,0.2)}.btn-foursquare:hover,.btn-foursquare:focus,.btn-foursquare.focus,.btn-foursquare:active,.btn-foursquare.active,.open>.dropdown-toggle.btn-foursquare{color:#fff;background-color:#f71752;border-color:rgba(0,0,0,0.2)}.btn-foursquare:active,.btn-foursquare.active,.open>.dropdown-toggle.btn-foursquare{background-image:none}.btn-foursquare .badge{color:#f94877;background-color:#fff}.btn-github{color:#fff;background-color:#444;border-color:rgba(0,0,0,0.2)}.btn-github:hover,.btn-github:focus,.btn-github.focus,.btn-github:active,.btn-github.active,.open>.dropdown-toggle.btn-github{color:#fff;background-color:#2b2b2b;border-color:rgba(0,0,0,0.2)}.btn-github:active,.btn-github.active,.open>.dropdown-toggle.btn-github{background-image:none}.btn-github .badge{color:#444;background-color:#fff}.btn-google{color:#fff;background-color:#dd4b39;border-color:rgba(0,0,0,0.2)}.btn-google:hover,.btn-google:focus,.btn-google.focus,.btn-google:active,.btn-google.active,.open>.dropdown-toggle.btn-google{color:#fff;background-color:#c23321;border-color:rgba(0,0,0,0.2)}.btn-google:active,.btn-google.active,.open>.dropdown-toggle.btn-google{background-image:none}.btn-google .badge{color:#dd4b39;background-color:#fff}.btn-instagram{color:#fff;background-color:#3f729b;border-color:rgba(0,0,0,0.2)}.btn-instagram:hover,.btn-instagram:focus,.btn-instagram.focus,.btn-instagram:active,.btn-instagram.active,.open>.dropdown-toggle.btn-instagram{color:#fff;background-color:#305777;border-color:rgba(0,0,0,0.2)}.btn-instagram:active,.btn-instagram.active,.open>.dropdown-toggle.btn-instagram{background-image:none}.btn-instagram .badge{color:#3f729b;background-color:#fff}.btn-linkedin{color:#fff;background-color:#007bb6;border-color:rgba(0,0,0,0.2)}.btn-linkedin:hover,.btn-linkedin:focus,.btn-linkedin.focus,.btn-linkedin:active,.btn-linkedin.active,.open>.dropdown-toggle.btn-linkedin{color:#fff;background-color:#005983;border-color:rgba(0,0,0,0.2)}.btn-linkedin:active,.btn-linkedin.active,.open>.dropdown-toggle.btn-linkedin{background-image:none}.btn-linkedin .badge{color:#007bb6;background-color:#fff}.btn-microsoft{color:#fff;background-color:#2672ec;border-color:rgba(0,0,0,0.2)}.btn-microsoft:hover,.btn-microsoft:focus,.btn-microsoft.focus,.btn-microsoft:active,.btn-microsoft.active,.open>.dropdown-toggle.btn-microsoft{color:#fff;background-color:#125acd;border-color:rgba(0,0,0,0.2)}.btn-microsoft:active,.btn-microsoft.active,.open>.dropdown-toggle.btn-microsoft{background-image:none}.btn-microsoft .badge{color:#2672ec;background-color:#fff}.btn-openid{color:#fff;background-color:#f7931e;border-color:rgba(0,0,0,0.2)}.btn-openid:hover,.btn-openid:focus,.btn-openid.focus,.btn-openid:active,.btn-openid.active,.open>.dropdown-toggle.btn-openid{color:#fff;background-color:#da7908;border-color:rgba(0,0,0,0.2)}.btn-openid:active,.btn-openid.active,.open>.dropdown-toggle.btn-openid{background-image:none}.btn-openid .badge{color:#f7931e;background-color:#fff}.btn-pinterest{color:#fff;background-color:#cb2027;border-color:rgba(0,0,0,0.2)}.btn-pinterest:hover,.btn-pinterest:focus,.btn-pinterest.focus,.btn-pinterest:active,.btn-pinterest.active,.open>.dropdown-toggle.btn-pinterest{color:#fff;background-color:#9f191f;border-color:rgba(0,0,0,0.2)}.btn-pinterest:active,.btn-pinterest.active,.open>.dropdown-toggle.btn-pinterest{background-image:none}.btn-pinterest .badge{color:#cb2027;background-color:#fff}.btn-reddit{color:#000;background-color:#eff7ff;border-color:rgba(0,0,0,0.2)}.btn-reddit:hover,.btn-reddit:focus,.btn-reddit.focus,.btn-reddit:active,.btn-reddit.active,.open>.dropdown-toggle.btn-reddit{color:#000;background-color:#bcddff;border-color:rgba(0,0,0,0.2)}.btn-reddit:active,.btn-reddit.active,.open>.dropdown-toggle.btn-reddit{background-image:none}.btn-reddit .badge{color:#eff7ff;background-color:#000}.btn-soundcloud{color:#fff;background-color:#f50;border-color:rgba(0,0,0,0.2)}.btn-soundcloud:hover,.btn-soundcloud:focus,.btn-soundcloud.focus,.btn-soundcloud:active,.btn-soundcloud.active,.open>.dropdown-toggle.btn-soundcloud{color:#fff;background-color:#c40;border-color:rgba(0,0,0,0.2)}.btn-soundcloud:active,.btn-soundcloud.active,.open>.dropdown-toggle.btn-soundcloud{background-image:none}.btn-soundcloud .badge{color:#f50;background-color:#fff}.btn-tumblr{color:#fff;background-color:#2c4762;border-color:rgba(0,0,0,0.2)}.btn-tumblr:hover,.btn-tumblr:focus,.btn-tumblr.focus,.btn-tumblr:active,.btn-tumblr.active,.open>.dropdown-toggle.btn-tumblr{color:#fff;background-color:#1c2d3f;border-color:rgba(0,0,0,0.2)}.btn-tumblr:active,.btn-tumblr.active,.open>.dropdown-toggle.btn-tumblr{background-image:none}.btn-tumblr .badge{color:#2c4762;background-color:#fff}.btn-twitter{color:#fff;background-color:#55acee;border-color:rgba(0,0,0,0.2)}.btn-twitter:hover,.btn-twitter:focus,.btn-twitter.focus,.btn-twitter:active,.btn-twitter.active,.open>.dropdown-toggle.btn-twitter{color:#fff;background-color:#2795e9;border-color:rgba(0,0,0,0.2)}.btn-twitter:active,.btn-twitter.active,.open>.dropdown-toggle.btn-twitter{background-image:none}.btn-twitter .badge{color:#55acee;background-color:#fff}.btn-vimeo{color:#fff;background-color:#1ab7ea;border-color:rgba(0,0,0,0.2)}.btn-vimeo:hover,.btn-vimeo:focus,.btn-vimeo.focus,.btn-vimeo:active,.btn-vimeo.active,.open>.dropdown-toggle.btn-vimeo{color:#fff;background-color:#1295bf;border-color:rgba(0,0,0,0.2)}.btn-vimeo:active,.btn-vimeo.active,.open>.dropdown-toggle.btn-vimeo{background-image:none}.btn-vimeo .badge{color:#1ab7ea;background-color:#fff}.btn-vk{color:#fff;background-color:#587ea3;border-color:rgba(0,0,0,0.2)}.btn-vk:hover,.btn-vk:focus,.btn-vk.focus,.btn-vk:active,.btn-vk.active,.open>.dropdown-toggle.btn-vk{color:#fff;background-color:#466482;border-color:rgba(0,0,0,0.2)}.btn-vk:active,.btn-vk.active,.open>.dropdown-toggle.btn-vk{background-image:none}.btn-vk .badge{color:#587ea3;background-color:#fff}.btn-yahoo{color:#fff;background-color:#720e9e;border-color:rgba(0,0,0,0.2)}.btn-yahoo:hover,.btn-yahoo:focus,.btn-yahoo.focus,.btn-yahoo:active,.btn-yahoo.active,.open>.dropdown-toggle.btn-yahoo{color:#fff;background-color:#500a6f;border-color:rgba(0,0,0,0.2)}.btn-yahoo:active,.btn-yahoo.active,.open>.dropdown-toggle.btn-yahoo{background-image:none}.btn-yahoo .badge{color:#720e9e;background-color:#fff}.fc-button{background:#f4f4f4;background-image:none;color:#444;border-color:#ddd;border-bottom-color:#ddd}.fc-button:hover,.fc-button:active,.fc-button.hover{background-color:#e9e9e9}.fc-header-title h2{font-size:15px;line-height:1.6em;color:#666;margin-left:10px}.fc-header-right{padding-right:10px}.fc-header-left{padding-left:10px}.fc-widget-header{background:#fafafa}.fc-grid{width:100%;border:0}.fc-widget-header:first-of-type,.fc-widget-content:first-of-type{border-left:0;border-right:0}.fc-widget-header:last-of-type,.fc-widget-content:last-of-type{border-right:0}.fc-toolbar{padding:10px;margin:0}.fc-day-number{font-size:20px;font-weight:300;padding-right:10px}.fc-color-picker{list-style:none;margin:0;padding:0}.fc-color-picker>li{float:left;font-size:30px;margin-right:5px;line-height:30px}.fc-color-picker>li .fa{-webkit-transition:-webkit-transform linear .3s;-moz-transition:-moz-transform linear .3s;-o-transition:-o-transform linear .3s;transition:transform linear .3s}.fc-color-picker>li .fa:hover{-webkit-transform:rotate(30deg);-ms-transform:rotate(30deg);-o-transform:rotate(30deg);transform:rotate(30deg)}#add-new-event{-webkit-transition:all linear .3s;-o-transition:all linear .3s;transition:all linear .3s}.external-event{padding:5px 10px;font-weight:bold;margin-bottom:4px;box-shadow:0 1px 1px rgba(0,0,0,0.1);text-shadow:0 1px 1px rgba(0,0,0,0.1);border-radius:3px;cursor:move}.external-event:hover{box-shadow:inset 0 0 90px rgba(0,0,0,0.2)}.select2-container--default.select2-container--focus,.select2-selection.select2-container--focus,.select2-container--default:focus,.select2-selection:focus,.select2-container--default:active,.select2-selection:active{outline:none}.select2-container--default .select2-selection--single,.select2-selection .select2-selection--single{border:1px solid #d2d6de;border-radius:0;padding:6px 12px;height:34px}.select2-container--default.select2-container--open{border-color:#3c8dbc}.select2-dropdown{border:1px solid #d2d6de;border-radius:0}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#3c8dbc;color:white}.select2-results__option{padding:6px 12px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{padding-left:0;padding-right:0;height:auto;margin-top:-4px}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:6px;padding-left:20px}.select2-container--default .select2-selection--single .select2-selection__arrow{height:28px;right:3px}.select2-container--default .select2-selection--single .select2-selection__arrow b{margin-top:0}.select2-dropdown .select2-search__field,.select2-search--inline .select2-search__field{border:1px solid #d2d6de}.select2-dropdown .select2-search__field:focus,.select2-search--inline .select2-search__field:focus{outline:none;border:1px solid #3c8dbc}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option[aria-selected=true],.select2-container--default .select2-results__option[aria-selected=true]:hover{color:#444}.select2-container--default .select2-selection--multiple{border:1px solid #d2d6de;border-radius:0}.select2-container--default .select2-selection--multiple:focus{border-color:#3c8dbc}.select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#d2d6de}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#3c8dbc;border-color:#367fa9;padding:1px 10px;color:#fff}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{margin-right:5px;color:rgba(255,255,255,0.7)}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.select2-container .select2-selection--single .select2-selection__rendered{padding-right:10px}.pad{padding:10px}.margin{margin:10px}.margin-bottom{margin-bottom:20px}.margin-bottom-none{margin-bottom:0}.margin-r-5{margin-right:5px}.inline{display:inline}.description-block{display:block;margin:10px 0;text-align:center}.description-block.margin-bottom{margin-bottom:25px}.description-block>.description-header{margin:0;padding:0;font-weight:600;font-size:16px}.description-block>.description-text{text-transform:uppercase}.bg-red,.bg-yellow,.bg-aqua,.bg-blue,.bg-light-blue,.bg-green,.bg-navy,.bg-teal,.bg-olive,.bg-lime,.bg-orange,.bg-fuchsia,.bg-purple,.bg-maroon,.bg-black,.bg-red-active,.bg-yellow-active,.bg-aqua-active,.bg-blue-active,.bg-light-blue-active,.bg-green-active,.bg-navy-active,.bg-teal-active,.bg-olive-active,.bg-lime-active,.bg-orange-active,.bg-fuchsia-active,.bg-purple-active,.bg-maroon-active,.bg-black-active,.callout.callout-danger,.callout.callout-warning,.callout.callout-info,.callout.callout-success,.alert-success,.alert-danger,.alert-error,.alert-warning,.alert-info,.label-danger,.label-info,.label-warning,.label-primary,.label-success,.modal-primary .modal-body,.modal-primary .modal-header,.modal-primary .modal-footer,.modal-warning .modal-body,.modal-warning .modal-header,.modal-warning .modal-footer,.modal-info .modal-body,.modal-info .modal-header,.modal-info .modal-footer,.modal-success .modal-body,.modal-success .modal-header,.modal-success .modal-footer,.modal-danger .modal-body,.modal-danger .modal-header,.modal-danger .modal-footer{color:#fff !important}.bg-gray{color:#000;background-color:#d2d6de !important}.bg-gray-light{background-color:#f7f7f7}.bg-black{background-color:#111 !important}.bg-red,.callout.callout-danger,.alert-danger,.alert-error,.label-danger,.modal-danger .modal-body{background-color:#dd4b39 !important}.bg-yellow,.callout.callout-warning,.alert-warning,.label-warning,.modal-warning .modal-body{background-color:#f39c12 !important}.bg-aqua,.callout.callout-info,.alert-info,.label-info,.modal-info .modal-body{background-color:#00c0ef !important}.bg-blue{background-color:#0073b7 !important}.bg-light-blue,.label-primary,.modal-primary .modal-body{background-color:#3c8dbc !important}.bg-green,.callout.callout-success,.alert-success,.label-success,.modal-success .modal-body{background-color:#00a65a !important}.bg-navy{background-color:#001f3f !important}.bg-teal{background-color:#39cccc !important}.bg-olive{background-color:#3d9970 !important}.bg-lime{background-color:#01ff70 !important}.bg-orange{background-color:#ff851b !important}.bg-fuchsia{background-color:#f012be !important}.bg-purple{background-color:#605ca8 !important}.bg-maroon{background-color:#d81b60 !important}.bg-gray-active{color:#000;background-color:#b5bbc8 !important}.bg-black-active{background-color:#000 !important}.bg-red-active,.modal-danger .modal-header,.modal-danger .modal-footer{background-color:#d33724 !important}.bg-yellow-active,.modal-warning .modal-header,.modal-warning .modal-footer{background-color:#db8b0b !important}.bg-aqua-active,.modal-info .modal-header,.modal-info .modal-footer{background-color:#00a7d0 !important}.bg-blue-active{background-color:#005384 !important}.bg-light-blue-active,.modal-primary .modal-header,.modal-primary .modal-footer{background-color:#357ca5 !important}.bg-green-active,.modal-success .modal-header,.modal-success .modal-footer{background-color:#008d4c !important}.bg-navy-active{background-color:#001a35 !important}.bg-teal-active{background-color:#30bbbb !important}.bg-olive-active{background-color:#368763 !important}.bg-lime-active{background-color:#00e765 !important}.bg-orange-active{background-color:#ff7701 !important}.bg-fuchsia-active{background-color:#db0ead !important}.bg-purple-active{background-color:#555299 !important}.bg-maroon-active{background-color:#ca195a !important}[class^="bg-"].disabled{opacity:.65;filter:alpha(opacity=65)}.text-red{color:#dd4b39 !important}.text-yellow{color:#f39c12 !important}.text-aqua{color:#00c0ef !important}.text-blue{color:#0073b7 !important}.text-black{color:#111 !important}.text-light-blue{color:#3c8dbc !important}.text-green{color:#00a65a !important}.text-gray{color:#d2d6de !important}.text-navy{color:#001f3f !important}.text-teal{color:#39cccc !important}.text-olive{color:#3d9970 !important}.text-lime{color:#01ff70 !important}.text-orange{color:#ff851b !important}.text-fuchsia{color:#f012be !important}.text-purple{color:#605ca8 !important}.text-maroon{color:#d81b60 !important}.link-muted{color:#7a869d}.link-muted:hover,.link-muted:focus{color:#606c84}.link-black{color:#666}.link-black:hover,.link-black:focus{color:#999}.hide{display:none !important}.no-border{border:0 !important}.no-padding{padding:0 !important}.no-margin{margin:0 !important}.no-shadow{box-shadow:none!important}.list-unstyled,.chart-legend,.contacts-list,.users-list,.mailbox-attachments{list-style:none;margin:0;padding:0}.list-group-unbordered>.list-group-item{border-left:0;border-right:0;border-radius:0;padding-left:0;padding-right:0}.flat{border-radius:0 !important}.text-bold,.text-bold.table td,.text-bold.table th{font-weight:700}.text-sm{font-size:12px}.jqstooltip{padding:5px!important;width:auto!important;height:auto!important}.bg-teal-gradient{background:#39cccc !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #39cccc), color-stop(1, #7adddd)) !important;background:-ms-linear-gradient(bottom, #39cccc, #7adddd) !important;background:-moz-linear-gradient(center bottom, #39cccc 0, #7adddd 100%) !important;background:-o-linear-gradient(#7adddd, #39cccc) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#7adddd', endColorstr='#39cccc', GradientType=0) !important;color:#fff}.bg-light-blue-gradient{background:#3c8dbc !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #3c8dbc), color-stop(1, #67a8ce)) !important;background:-ms-linear-gradient(bottom, #3c8dbc, #67a8ce) !important;background:-moz-linear-gradient(center bottom, #3c8dbc 0, #67a8ce 100%) !important;background:-o-linear-gradient(#67a8ce, #3c8dbc) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#67a8ce', endColorstr='#3c8dbc', GradientType=0) !important;color:#fff}.bg-blue-gradient{background:#0073b7 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #0073b7), color-stop(1, #0089db)) !important;background:-ms-linear-gradient(bottom, #0073b7, #0089db) !important;background:-moz-linear-gradient(center bottom, #0073b7 0, #0089db 100%) !important;background:-o-linear-gradient(#0089db, #0073b7) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#0089db', endColorstr='#0073b7', GradientType=0) !important;color:#fff}.bg-aqua-gradient{background:#00c0ef !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #00c0ef), color-stop(1, #14d1ff)) !important;background:-ms-linear-gradient(bottom, #00c0ef, #14d1ff) !important;background:-moz-linear-gradient(center bottom, #00c0ef 0, #14d1ff 100%) !important;background:-o-linear-gradient(#14d1ff, #00c0ef) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#14d1ff', endColorstr='#00c0ef', GradientType=0) !important;color:#fff}.bg-yellow-gradient{background:#f39c12 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #f39c12), color-stop(1, #f7bc60)) !important;background:-ms-linear-gradient(bottom, #f39c12, #f7bc60) !important;background:-moz-linear-gradient(center bottom, #f39c12 0, #f7bc60 100%) !important;background:-o-linear-gradient(#f7bc60, #f39c12) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f7bc60', endColorstr='#f39c12', GradientType=0) !important;color:#fff}.bg-purple-gradient{background:#605ca8 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #605ca8), color-stop(1, #9491c4)) !important;background:-ms-linear-gradient(bottom, #605ca8, #9491c4) !important;background:-moz-linear-gradient(center bottom, #605ca8 0, #9491c4 100%) !important;background:-o-linear-gradient(#9491c4, #605ca8) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#9491c4', endColorstr='#605ca8', GradientType=0) !important;color:#fff}.bg-green-gradient{background:#00a65a !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #00a65a), color-stop(1, #00ca6d)) !important;background:-ms-linear-gradient(bottom, #00a65a, #00ca6d) !important;background:-moz-linear-gradient(center bottom, #00a65a 0, #00ca6d 100%) !important;background:-o-linear-gradient(#00ca6d, #00a65a) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ca6d', endColorstr='#00a65a', GradientType=0) !important;color:#fff}.bg-red-gradient{background:#dd4b39 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #dd4b39), color-stop(1, #e47365)) !important;background:-ms-linear-gradient(bottom, #dd4b39, #e47365) !important;background:-moz-linear-gradient(center bottom, #dd4b39 0, #e47365 100%) !important;background:-o-linear-gradient(#e47365, #dd4b39) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e47365', endColorstr='#dd4b39', GradientType=0) !important;color:#fff}.bg-black-gradient{background:#111 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #111), color-stop(1, #2b2b2b)) !important;background:-ms-linear-gradient(bottom, #111, #2b2b2b) !important;background:-moz-linear-gradient(center bottom, #111 0, #2b2b2b 100%) !important;background:-o-linear-gradient(#2b2b2b, #111) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#2b2b2b', endColorstr='#111111', GradientType=0) !important;color:#fff}.bg-maroon-gradient{background:#d81b60 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #d81b60), color-stop(1, #e73f7c)) !important;background:-ms-linear-gradient(bottom, #d81b60, #e73f7c) !important;background:-moz-linear-gradient(center bottom, #d81b60 0, #e73f7c 100%) !important;background:-o-linear-gradient(#e73f7c, #d81b60) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e73f7c', endColorstr='#d81b60', GradientType=0) !important;color:#fff}.description-block .description-icon{font-size:16px}.no-pad-top{padding-top:0}.position-static{position:static!important}.list-header{font-size:15px;padding:10px 4px;font-weight:bold;color:#666}.list-seperator{height:1px;background:#f4f4f4;margin:15px 0 9px 0}.list-link>a{padding:4px;color:#777}.list-link>a:hover{color:#222}.font-light{font-weight:300}.user-block:before,.user-block:after{content:" ";display:table}.user-block:after{clear:both}.user-block img{width:40px;height:40px;float:left}.user-block .username,.user-block .description,.user-block .comment{display:block;margin-left:50px}.user-block .username{font-size:16px;font-weight:600}.user-block .description{color:#999;font-size:13px}.user-block.user-block-sm .username,.user-block.user-block-sm .description,.user-block.user-block-sm .comment{margin-left:40px}.user-block.user-block-sm .username{font-size:14px}.img-sm,.img-md,.img-lg,.box-comments .box-comment img,.user-block.user-block-sm img{float:left}.img-sm,.box-comments .box-comment img,.user-block.user-block-sm img{width:30px!important;height:30px!important}.img-sm+.img-push{margin-left:40px}.img-md{width:60px;height:60px}.img-md+.img-push{margin-left:70px}.img-lg{width:100px;height:100px}.img-lg+.img-push{margin-left:110px}.img-bordered{border:3px solid #d2d6de;padding:3px}.img-bordered-sm{border:2px solid #d2d6de;padding:2px}.attachment-block{border:1px solid #f4f4f4;padding:5px;margin-bottom:10px;background:#f7f7f7}.attachment-block .attachment-img{max-width:100px;max-height:100px;height:auto;float:left}.attachment-block .attachment-pushed{margin-left:110px}.attachment-block .attachment-heading{margin:0}.attachment-block .attachment-text{color:#555}.connectedSortable{min-height:100px}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sort-highlight{background:#f4f4f4;border:1px dashed #ddd;margin-bottom:10px}.full-opacity-hover{opacity:.65;filter:alpha(opacity=65)}.full-opacity-hover:hover{opacity:1;filter:alpha(opacity=100)}.chart{position:relative;overflow:hidden;width:100%}.chart svg,.chart canvas{width:100%!important}@media print{.no-print,.main-sidebar,.left-side,.main-header,.content-header{display:none!important}.content-wrapper,.right-side,.main-footer{margin-left:0!important;min-height:0!important;-webkit-transform:translate(0, 0) !important;-ms-transform:translate(0, 0) !important;-o-transform:translate(0, 0) !important;transform:translate(0, 0) !important}.fixed .content-wrapper,.fixed .right-side{padding-top:0!important}.invoice{width:100%;border:0;margin:0;padding:0}.invoice-col{float:left;width:33.3333333%}.table-responsive{overflow:auto}.table-responsive>.table tr th,.table-responsive>.table tr td{white-space:normal!important}} \ No newline at end of file diff --git a/public/assets/css/ansi-colors.css b/public/assets/css/ansi-colors.css new file mode 100644 index 00000000..47a14dbf --- /dev/null +++ b/public/assets/css/ansi-colors.css @@ -0,0 +1,33 @@ +.ansi_color_bg_black { background-color: #FFF } +.ansi_color_bg_red { background-color: #900 } +.ansi_color_bg_green { background-color: #090 } +.ansi_color_bg_yellow { background-color: #990 } +.ansi_color_bg_blue { background-color: #009 } +.ansi_color_bg_magenta { background-color: #909 } +.ansi_color_bg_cyan { background-color: #099 } +.ansi_color_bg_white { background-color: #000 } +.ansi_color_bg_brblack { background-color: #FFF } +.ansi_color_bg_brred { background-color: #F00 } +.ansi_color_bg_brgreen { background-color: #0F0 } +.ansi_color_bg_bryellow { background-color: #FF0 } +.ansi_color_bg_brblue { background-color: #00F } +.ansi_color_bg_brmagenta { background-color: #F0F } +.ansi_color_bg_brcyan { background-color: #0FF } +.ansi_color_bg_brwhite { background-color: #000 } + +.ansi_color_fg_black { color: #FFF } +.ansi_color_fg_red { color: #900 } +.ansi_color_fg_green { color: #090 } +.ansi_color_fg_yellow { color: #990 } +.ansi_color_fg_blue { color: #009 } +.ansi_color_fg_magenta { color: #909 } +.ansi_color_fg_cyan { color: #099 } +.ansi_color_fg_white { color: #000 } +.ansi_color_fg_brblack { color: #FFF } +.ansi_color_fg_brred { color: #F00 } +.ansi_color_fg_brgreen { color: #0F0 } +.ansi_color_fg_bryellow { color: #FF0 } +.ansi_color_fg_brblue { color: #00F } +.ansi_color_fg_brmagenta { color: #F0F } +.ansi_color_fg_brcyan { color: #0FF } +.ansi_color_fg_brwhite { color: #000 } diff --git a/public/assets/css/bootstrap-theme.min.css b/public/assets/css/bootstrap-theme.min.css deleted file mode 100755 index 9c85321d..00000000 --- a/public/assets/css/bootstrap-theme.min.css +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * Bootstrap v3.1.1 (http://getbootstrap.com) - * Copyright 2011-2014 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */ - -.btn-default,.btn-primary,.btn-success,.btn-info,.btn-warning,.btn-danger{text-shadow:0 -1px 0 rgba(0,0,0,0.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075)}.btn-default:active,.btn-primary:active,.btn-success:active,.btn-info:active,.btn-warning:active,.btn-danger:active,.btn-default.active,.btn-primary.active,.btn-success.active,.btn-info.active,.btn-warning.active,.btn-danger.active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn:active,.btn.active{background-image:none}.btn-default{background-image:-webkit-linear-gradient(top, #fff 0, #e0e0e0 100%);background-image:linear-gradient(to bottom, #fff 0, #e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#dbdbdb;text-shadow:0 1px 0 #fff;border-color:#ccc}.btn-default:hover,.btn-default:focus{background-color:#e0e0e0;background-position:0 -15px}.btn-default:active,.btn-default.active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-primary{background-image:-webkit-linear-gradient(top, #428bca 0, #2d6ca2 100%);background-image:linear-gradient(to bottom, #428bca 0, #2d6ca2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff2d6ca2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#2b669a}.btn-primary:hover,.btn-primary:focus{background-color:#2d6ca2;background-position:0 -15px}.btn-primary:active,.btn-primary.active{background-color:#2d6ca2;border-color:#2b669a}.btn-success{background-image:-webkit-linear-gradient(top, #5cb85c 0, #419641 100%);background-image:linear-gradient(to bottom, #5cb85c 0, #419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:hover,.btn-success:focus{background-color:#419641;background-position:0 -15px}.btn-success:active,.btn-success.active{background-color:#419641;border-color:#3e8f3e}.btn-info{background-image:-webkit-linear-gradient(top, #5bc0de 0, #2aabd2 100%);background-image:linear-gradient(to bottom, #5bc0de 0, #2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:hover,.btn-info:focus{background-color:#2aabd2;background-position:0 -15px}.btn-info:active,.btn-info.active{background-color:#2aabd2;border-color:#28a4c9}.btn-warning{background-image:-webkit-linear-gradient(top, #f0ad4e 0, #eb9316 100%);background-image:linear-gradient(to bottom, #f0ad4e 0, #eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:hover,.btn-warning:focus{background-color:#eb9316;background-position:0 -15px}.btn-warning:active,.btn-warning.active{background-color:#eb9316;border-color:#e38d13}.btn-danger{background-image:-webkit-linear-gradient(top, #d9534f 0, #c12e2a 100%);background-image:linear-gradient(to bottom, #d9534f 0, #c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:hover,.btn-danger:focus{background-color:#c12e2a;background-position:0 -15px}.btn-danger:active,.btn-danger.active{background-color:#c12e2a;border-color:#b92c28}.thumbnail,.img-thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.075);box-shadow:0 1px 2px rgba(0,0,0,0.075)}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{background-image:-webkit-linear-gradient(top, #f5f5f5 0, #e8e8e8 100%);background-image:linear-gradient(to bottom, #f5f5f5 0, #e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-color:#e8e8e8}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{background-image:-webkit-linear-gradient(top, #428bca 0, #357ebd 100%);background-image:linear-gradient(to bottom, #428bca 0, #357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);background-color:#357ebd}.navbar-default{background-image:-webkit-linear-gradient(top, #fff 0, #f8f8f8 100%);background-image:linear-gradient(to bottom, #fff 0, #f8f8f8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 5px rgba(0,0,0,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 5px rgba(0,0,0,0.075)}.navbar-default .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top, #ebebeb 0, #f3f3f3 100%);background-image:linear-gradient(to bottom, #ebebeb 0, #f3f3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff3f3f3', GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,0.075);box-shadow:inset 0 3px 9px rgba(0,0,0,0.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,0.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top, #3c3c3c 0, #222 100%);background-image:linear-gradient(to bottom, #3c3c3c 0, #222 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.navbar-inverse .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top, #222 0, #282828 100%);background-image:linear-gradient(to bottom, #222 0, #282828 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff282828', GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,0.25);box-shadow:inset 0 3px 9px rgba(0,0,0,0.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-static-top,.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}.alert{text-shadow:0 1px 0 rgba(255,255,255,0.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 2px rgba(0,0,0,0.05)}.alert-success{background-image:-webkit-linear-gradient(top, #dff0d8 0, #c8e5bc 100%);background-image:linear-gradient(to bottom, #dff0d8 0, #c8e5bc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top, #d9edf7 0, #b9def0 100%);background-image:linear-gradient(to bottom, #d9edf7 0, #b9def0 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top, #fcf8e3 0, #f8efc0 100%);background-image:linear-gradient(to bottom, #fcf8e3 0, #f8efc0 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top, #f2dede 0, #e7c3c3 100%);background-image:linear-gradient(to bottom, #f2dede 0, #e7c3c3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top, #ebebeb 0, #f5f5f5 100%);background-image:linear-gradient(to bottom, #ebebeb 0, #f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0)}.progress-bar{background-image:-webkit-linear-gradient(top, #428bca 0, #3071a9 100%);background-image:linear-gradient(to bottom, #428bca 0, #3071a9 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0)}.progress-bar-success{background-image:-webkit-linear-gradient(top, #5cb85c 0, #449d44 100%);background-image:linear-gradient(to bottom, #5cb85c 0, #449d44 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0)}.progress-bar-info{background-image:-webkit-linear-gradient(top, #5bc0de 0, #31b0d5 100%);background-image:linear-gradient(to bottom, #5bc0de 0, #31b0d5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0)}.progress-bar-warning{background-image:-webkit-linear-gradient(top, #f0ad4e 0, #ec971f 100%);background-image:linear-gradient(to bottom, #f0ad4e 0, #ec971f 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0)}.progress-bar-danger{background-image:-webkit-linear-gradient(top, #d9534f 0, #c9302c 100%);background-image:linear-gradient(to bottom, #d9534f 0, #c9302c 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.075);box-shadow:0 1px 2px rgba(0,0,0,0.075)}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{text-shadow:0 -1px 0 #3071a9;background-image:-webkit-linear-gradient(top, #428bca 0, #3278b3 100%);background-image:linear-gradient(to bottom, #428bca 0, #3278b3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0);border-color:#3278b3}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.panel-default>.box-header{background-image:-webkit-linear-gradient(top, #f5f5f5 0, #e8e8e8 100%);background-image:linear-gradient(to bottom, #f5f5f5 0, #e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0)}.panel-primary>.box-header{background-image:-webkit-linear-gradient(top, #428bca 0, #357ebd 100%);background-image:linear-gradient(to bottom, #428bca 0, #357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0)}.panel-success>.box-header{background-image:-webkit-linear-gradient(top, #dff0d8 0, #d0e9c6 100%);background-image:linear-gradient(to bottom, #dff0d8 0, #d0e9c6 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0)}.panel-info>.box-header{background-image:-webkit-linear-gradient(top, #d9edf7 0, #c4e3f3 100%);background-image:linear-gradient(to bottom, #d9edf7 0, #c4e3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0)}.panel-warning>.box-header{background-image:-webkit-linear-gradient(top, #fcf8e3 0, #faf2cc 100%);background-image:linear-gradient(to bottom, #fcf8e3 0, #faf2cc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0)}.panel-danger>.box-header{background-image:-webkit-linear-gradient(top, #f2dede 0, #ebcccc 100%);background-image:linear-gradient(to bottom, #f2dede 0, #ebcccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0)}.well{background-image:-webkit-linear-gradient(top, #e8e8e8 0, #f5f5f5 100%);background-image:linear-gradient(to bottom, #e8e8e8 0, #f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,0.05),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 3px rgba(0,0,0,0.05),0 1px 0 rgba(255,255,255,0.1)} \ No newline at end of file diff --git a/public/assets/css/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css b/public/assets/css/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css deleted file mode 100755 index d8dd3c22..00000000 --- a/public/assets/css/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css +++ /dev/null @@ -1,3 +0,0 @@ -/*! bootstrap3-wysihtml5-bower 2013-11-22 */ - -ul.wysihtml5-toolbar{margin:0;padding:0;display:block}ul.wysihtml5-toolbar::after{clear:both;display:table;content:""}ul.wysihtml5-toolbar>li{float:left;display:list-item;list-style:none;margin:0 5px 10px 0}ul.wysihtml5-toolbar a[data-wysihtml5-command=bold]{font-weight:700}ul.wysihtml5-toolbar a[data-wysihtml5-command=italic]{font-style:italic}ul.wysihtml5-toolbar a[data-wysihtml5-command=underline]{text-decoration:underline}ul.wysihtml5-toolbar a.btn.wysihtml5-command-active{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05);background-color:#E6E6E6;background-color:#D9D9D9;outline:0}ul.wysihtml5-commands-disabled .dropdown-menu{display:none!important}ul.wysihtml5-toolbar div.wysihtml5-colors{display:block;width:50px;height:20px;margin-top:2px;margin-left:5px;position:absolute;pointer-events:none}ul.wysihtml5-toolbar a.wysihtml5-colors-title{padding-left:70px}ul.wysihtml5-toolbar div[data-wysihtml5-command-value=black]{background:#000!important}ul.wysihtml5-toolbar div[data-wysihtml5-command-value=silver]{background:silver!important}ul.wysihtml5-toolbar div[data-wysihtml5-command-value=gray]{background:gray!important}ul.wysihtml5-toolbar div[data-wysihtml5-command-value=maroon]{background:maroon!important}ul.wysihtml5-toolbar div[data-wysihtml5-command-value=red]{background:red!important}ul.wysihtml5-toolbar div[data-wysihtml5-command-value=purple]{background:purple!important}ul.wysihtml5-toolbar div[data-wysihtml5-command-value=green]{background:green!important}ul.wysihtml5-toolbar div[data-wysihtml5-command-value=olive]{background:olive!important}ul.wysihtml5-toolbar div[data-wysihtml5-command-value=navy]{background:navy!important}ul.wysihtml5-toolbar div[data-wysihtml5-command-value=blue]{background:#00f!important}ul.wysihtml5-toolbar div[data-wysihtml5-command-value=orange]{background:orange!important} \ No newline at end of file diff --git a/public/assets/css/bootstrap.min.css b/public/assets/css/bootstrap.min.css deleted file mode 100755 index 7af7ea7c..00000000 --- a/public/assets/css/bootstrap.min.css +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * Bootstrap v3.1.1 (http://getbootstrap.com) - * Copyright 2011-2014 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */ - -/*! normalize.css v3.0.0 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}@media print{*{text-shadow:none !important;color:#000 !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) ")"}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}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff !important}.navbar{display:none}.table td,.table th{background-color:#fff !important}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000 !important}.label{border:1px solid #000}.table{border-collapse:collapse !important}.table-bordered th,.table-bordered td{border:1px solid #ddd !important}}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:62.5%;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#428bca;text-decoration:none}a:hover,a:focus{color:#2a6496;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:normal;line-height:1;color:#999}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:200;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}small,.small{font-size:85%}cite{font-style:normal}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-muted{color:#999}.text-primary{color:#428bca}a.text-primary:hover{color:#3071a9}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#428bca}a.bg-primary:hover{background-color:#3071a9}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:bold}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#999}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0;text-align:right}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}blockquote:before,blockquote:after{content:""}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;white-space:nowrap;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25)}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;word-break:break-all;word-wrap:break-word;color:#333;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-15px}.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:0}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:0}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:0}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:0}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:0}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:0}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:0}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:0}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{max-width:100%;background-color:transparent}th{text-align:left}.table{width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-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 col[class*="col-"]{position:static;float:none;display:table-column}table td[class*="col-"],table th[class*="col-"]{position:static;float:none;display:table-cell}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}@media (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;overflow-x:scroll;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd;-webkit-overflow-scrolling:touch}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;margin-bottom:5px;font-weight:bold}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type="file"]{display:block}input[type="range"]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}textarea.form-control{height:auto}input[type="search"]{-webkit-appearance:none}input[type="date"]{line-height:34px}.form-group{margin-bottom:15px}.radio,.checkbox{display:block;min-height:20px;margin-top:10px;margin-bottom:10px;padding-left:20px}.radio label,.checkbox label{display:inline;font-weight:normal;cursor:pointer}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{float:left;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:normal;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type="radio"][disabled],input[type="checkbox"][disabled],.radio[disabled],.radio-inline[disabled],.checkbox[disabled],.checkbox-inline[disabled],fieldset[disabled] input[type="radio"],fieldset[disabled] input[type="checkbox"],fieldset[disabled] .radio,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm,select[multiple].input-sm{height:auto}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg{height:46px;line-height:46px}textarea.input-lg,select[multiple].input-lg{height:auto}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.has-feedback .form-control-feedback{position:absolute;top:25px;right:0;display:block;width:34px;height:34px;line-height:34px;text-align:center}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;border-color:#3c763d;background-color:#dff0d8}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;border-color:#8a6d3b;background-color:#fcf8e3}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;border-color:#a94442;background-color:#f2dede}.has-error .form-control-feedback{color:#a94442}.form-control-static{margin-bottom:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;padding-left:0;vertical-align:middle}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:none;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .control-label,.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{margin-top:0;margin-bottom:0;padding-top:7px}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}.form-horizontal .form-control-static{padding-top:7px}@media (min-width:768px){.form-horizontal .control-label{text-align:right}}.form-horizontal .has-feedback .form-control-feedback{top:0;right:15px}.btn{display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn:active:focus,.btn.active:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus{color:#333;text-decoration:none}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;pointer-events:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:hover,.btn-default:focus,.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{color:#333;background-color:#ebebeb;border-color:#adadad}.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#428bca;border-color:#357ebd}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{color:#fff;background-color:#3276b1;border-color:#285e8e}.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#428bca;border-color:#357ebd}.btn-primary .badge{color:#428bca;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{color:#fff;background-color:#47a447;border-color:#398439}.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{color:#fff;background-color:#39b3d7;border-color:#269abc}.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{color:#fff;background-color:#ed9c28;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{color:#fff;background-color:#d2322d;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{color:#428bca;font-weight:normal;cursor:pointer;border-radius:0}.btn-link,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#2a6496;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#999;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%;padding-left:0;padding-right:0}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;transition:height .35s ease}@font-face{font-family:'Glyphicons Halflings';src:url('../fonts/glyphicons-halflings-regular.eot');src:url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),url('../fonts/glyphicons-halflings-regular.woff') format('woff'),url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'),url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:14px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{text-decoration:none;color:#262626;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;outline:0;background-color:#428bca}.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;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#999}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu-left{left:0;right:auto}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group>.btn:focus,.btn-group-vertical>.btn:focus{outline:none}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-left:12px;padding-right:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-bottom-left-radius:4px;border-top-right-radius:0;border-top-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{float:none;display:table-cell;width:1%}.btn-group-justified>.btn-group .btn{width:100%}[data-toggle="buttons"]>.btn>input[type="radio"],[data-toggle="buttons"]>.btn>input[type="checkbox"]{display:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*="col-"]{float:none;padding-left:0;padding-right:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:normal;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type="radio"],.input-group-addon input[type="checkbox"]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-top-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{margin-bottom:0;padding-left:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#999}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#999;text-decoration:none;background-color:transparent;cursor:not-allowed}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#428bca}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#428bca}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{max-height:340px;overflow-x:visible;padding-right:15px;padding-left:15px;border-top:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);-webkit-overflow-scrolling:touch}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;box-shadow:none}.navbar-collapse.collapse{display:block !important;height:auto !important;padding-bottom:0;overflow:visible !important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-left:0;padding-right:0}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;padding:15px 15px;font-size:18px;line-height:20px;height:50px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;margin-right:15px;padding:9px 10px;margin-top:8px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:none}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}.navbar-nav.navbar-right:last-child{margin-right:-15px}}@media (min-width:768px){.navbar-left{float:left !important}.navbar-right{float:right !important}}.navbar-form{margin-left:-15px;margin-right:-15px;padding:10px 15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-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);margin-top:8px;margin-bottom:8px}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;padding-left:0;vertical-align:middle}.navbar-form .radio input[type="radio"],.navbar-form .checkbox input[type="checkbox"]{float:none;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}}@media (min-width:768px){.navbar-form{width:auto;border:0;margin-left:0;margin-right:0;padding-top:0;padding-bottom:0;-webkit-box-shadow:none;box-shadow:none}.navbar-form.navbar-right:last-child{margin-right:-15px}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-left:15px;margin-right:15px}.navbar-text.navbar-right:last-child{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{background-color:#e7e7e7;color:#555}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#999}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .navbar-nav>li>a{color:#999}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{background-color:#080808;color:#fff}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#999}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover{color:#fff}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;line-height:1.42857143;text-decoration:none;color:#428bca;background-color:#fff;border:1px solid #ddd;margin-left:-1px}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:4px;border-top-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{color:#2a6496;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca;cursor:default}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#999;background-color:#fff;border-color:#ddd;cursor:not-allowed}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:6px;border-top-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pager{padding-left:0;margin:20px 0;list-style:none;text-align:center}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;background-color:#fff;cursor:not-allowed}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}.label[href]:hover,.label[href]:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#999}.label-default[href]:hover,.label-default[href]:focus{background-color:#808080}.label-primary{background-color:#428bca}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#3071a9}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:bold;color:#fff;line-height:1;vertical-align:baseline;white-space:nowrap;text-align:center;background-color:#999;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}a.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#428bca;background-color:#fff}.nav-pills>li>a>.badge{margin-left:3px}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:bold}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable{padding-right:35px}.alert-dismissable .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#3c763d}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#31708f}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{background-color:#fcf8e3;border-color:#faebcc;color:#8a6d3b}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{background-color:#f2dede;border-color:#ebccd1;color:#a94442}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}.list-group{margin-bottom:20px;padding-left:0}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-right-radius:4px;border-top-left-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,a.list-group-item:focus{text-decoration:none;background-color:#f5f5f5}a.list-group-item.active,a.list-group-item.active:hover,a.list-group-item.active:focus{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca}a.list-group-item.active .list-group-item-heading,a.list-group-item.active:hover .list-group-item-heading,a.list-group-item.active:focus .list-group-item-heading{color:inherit}a.list-group-item.active .list-group-item-text,a.list-group-item.active:hover .list-group-item-text,a.list-group-item.active:focus .list-group-item-text{color:#e1edf7}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,a.list-group-item-success:focus{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:hover,a.list-group-item-success.active:focus{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,a.list-group-item-info:focus{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:hover,a.list-group-item-info.active:focus{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,a.list-group-item-warning:focus{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,a.list-group-item-danger:focus{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.box-body{padding:15px}.box-header{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:3px;border-top-left-radius:3px}.box-header>.dropdown .dropdown-toggle{color:inherit}.box-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.box-title>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group{margin-bottom:0}.panel>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-right-radius:3px;border-top-left-radius:3px}.panel>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.box-header+.list-group .list-group-item:first-child{border-top-width:0}.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-right-radius:3px;border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.box-body+.table,.panel>.box-body+.table-responsive{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{border:0;margin-bottom:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px;overflow:hidden}.panel-group .panel+.panel{margin-top:5px}.panel-group .box-header{border-bottom:0}.panel-group .box-header+.panel-collapse .box-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .box-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.box-header{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.box-header+.panel-collapse .box-body{border-top-color:#ddd}.panel-default>.panel-footer+.panel-collapse .box-body{border-bottom-color:#ddd}.panel-primary{border-color:#428bca}.panel-primary>.box-header{color:#fff;background-color:#428bca;border-color:#428bca}.panel-primary>.box-header+.panel-collapse .box-body{border-top-color:#428bca}.panel-primary>.panel-footer+.panel-collapse .box-body{border-bottom-color:#428bca}.panel-success{border-color:#d6e9c6}.panel-success>.box-header{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.box-header+.panel-collapse .box-body{border-top-color:#d6e9c6}.panel-success>.panel-footer+.panel-collapse .box-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.box-header{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.box-header+.panel-collapse .box-body{border-top-color:#bce8f1}.panel-info>.panel-footer+.panel-collapse .box-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.box-header{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.box-header+.panel-collapse .box-body{border-top-color:#faebcc}.panel-warning>.panel-footer+.panel-collapse .box-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.box-header{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.box-header+.panel-collapse .box-body{border-top-color:#ebccd1}.panel-danger>.panel-footer+.panel-collapse .box-body{border-bottom-color:#ebccd1}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,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-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:bold;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{display:none;overflow:auto;overflow-y:scroll;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0, -25%);-ms-transform:translate(0, -25%);transform:translate(0, -25%);-webkit-transition:-webkit-transform 0.3s ease-out;-moz-transition:-moz-transform 0.3s ease-out;-o-transition:-o-transform 0.3s ease-out;transition:transform 0.3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);transform:translate(0, 0)}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.2);border-radius:6px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,0.5);box-shadow:0 3px 9px rgba(0,0,0,0.5);background-clip:padding-box;outline:none}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5;min-height:16.42857143px}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:20px}.modal-footer{margin-top:15px;padding:19px 20px 20px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,0.5);box-shadow:0 5px 15px rgba(0,0,0,0.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.clearfix:before,.clearfix:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.box-body:before,.box-body:after,.modal-footer:before,.modal-footer:after{content:" ";display:table}.clearfix:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.box-body:after,.modal-footer:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right !important}.pull-left{float:left !important}.hide{display:none !important}.show{display:block !important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none !important;visibility:hidden !important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none !important}@media (max-width:767px){.visible-xs{display:block !important}table.visible-xs{display:table}tr.visible-xs{display:table-row !important}th.visible-xs,td.visible-xs{display:table-cell !important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block !important}table.visible-sm{display:table}tr.visible-sm{display:table-row !important}th.visible-sm,td.visible-sm{display:table-cell !important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block !important}table.visible-md{display:table}tr.visible-md{display:table-row !important}th.visible-md,td.visible-md{display:table-cell !important}}@media (min-width:1200px){.visible-lg{display:block !important}table.visible-lg{display:table}tr.visible-lg{display:table-row !important}th.visible-lg,td.visible-lg{display:table-cell !important}}@media (max-width:767px){.hidden-xs{display:none !important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none !important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none !important}}@media (min-width:1200px){.hidden-lg{display:none !important}}.visible-print{display:none !important}@media print{.visible-print{display:block !important}table.visible-print{display:table}tr.visible-print{display:table-row !important}th.visible-print,td.visible-print{display:table-cell !important}}@media print{.hidden-print{display:none !important}} \ No newline at end of file diff --git a/public/assets/css/colorpicker/bootstrap-colorpicker.min.css b/public/assets/css/colorpicker/bootstrap-colorpicker.min.css deleted file mode 100755 index 5f315042..00000000 --- a/public/assets/css/colorpicker/bootstrap-colorpicker.min.css +++ /dev/null @@ -1,9 +0,0 @@ -/*! - * Bootstrap Colorpicker - * http://mjolnic.github.io/bootstrap-colorpicker/ - * - * Originally written by (c) 2012 Stefan Petre - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0.txt - * - */.colorpicker-saturation{float:left;width:100px;height:100px;cursor:crosshair;background-image:url("../../img/bootstrap-colorpicker/saturation.png")}.colorpicker-saturation i{position:absolute;top:0;left:0;display:block;width:5px;height:5px;margin:-4px 0 0 -4px;border:1px solid #000;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.colorpicker-saturation i b{display:block;width:5px;height:5px;border:1px solid #fff;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.colorpicker-hue,.colorpicker-alpha{float:left;width:15px;height:100px;margin-bottom:4px;margin-left:4px;cursor:row-resize}.colorpicker-hue i,.colorpicker-alpha i{position:absolute;top:0;left:0;display:block;width:100%;height:1px;margin-top:-1px;background:#000;border-top:1px solid #fff}.colorpicker-hue{background-image:url("../../img/bootstrap-colorpicker/hue.png")}.colorpicker-alpha{display:none;background-image:url("../../img/bootstrap-colorpicker/alpha.png")}.colorpicker{top:0;left:0;z-index:2500;min-width:130px;padding:4px;margin-top:1px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*zoom:1}.colorpicker:before,.colorpicker:after{display:table;line-height:0;content:""}.colorpicker:after{clear:both}.colorpicker:before{position:absolute;top:-7px;left:6px;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:''}.colorpicker:after{position:absolute;top:-6px;left:7px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''}.colorpicker div{position:relative}.colorpicker.colorpicker-with-alpha{min-width:140px}.colorpicker.colorpicker-with-alpha .colorpicker-alpha{display:block}.colorpicker-color{height:10px;margin-top:5px;clear:both;background-image:url("../../img/bootstrap-colorpicker/alpha.png");background-position:0 100%}.colorpicker-color div{height:10px}.colorpicker-element .input-group-addon i{display:block;width:16px;height:16px;cursor:pointer}.colorpicker.colorpicker-inline{position:relative;display:inline-block;float:none}.colorpicker.colorpicker-horizontal{width:110px;height:auto;min-width:110px}.colorpicker.colorpicker-horizontal .colorpicker-saturation{margin-bottom:4px}.colorpicker.colorpicker-horizontal .colorpicker-color{width:100px}.colorpicker.colorpicker-horizontal .colorpicker-hue,.colorpicker.colorpicker-horizontal .colorpicker-alpha{float:left;width:100px;height:15px;margin-bottom:4px;margin-left:0;cursor:col-resize}.colorpicker.colorpicker-horizontal .colorpicker-hue i,.colorpicker.colorpicker-horizontal .colorpicker-alpha i{position:absolute;top:0;left:0;display:block;width:1px;height:15px;margin-top:0;background:#fff;border:0}.colorpicker.colorpicker-horizontal .colorpicker-hue{background-image:url("../../img/bootstrap-colorpicker/hue-horizontal.png")}.colorpicker.colorpicker-horizontal .colorpicker-alpha{background-image:url("../../img/bootstrap-colorpicker/alpha-horizontal.png")}.colorpicker.colorpicker-hidden{display:none}.colorpicker.colorpicker-visible{display:block}.colorpicker-inline.colorpicker-visible{display:inline-block} \ No newline at end of file diff --git a/public/assets/css/datatables/dataTables.bootstrap.css b/public/assets/css/datatables/dataTables.bootstrap.css deleted file mode 100755 index 27036b0e..00000000 --- a/public/assets/css/datatables/dataTables.bootstrap.css +++ /dev/null @@ -1,223 +0,0 @@ -div.dataTables_length label { - font-weight: normal; - float: left; - text-align: left; -} - -div.dataTables_length select { - width: 75px; -} - -div.dataTables_filter label { - font-weight: normal; - float: right; -} - -div.dataTables_filter input { - width: 16em; -} - -div.dataTables_info { - padding-top: 8px; -} - -div.dataTables_paginate { - float: right; - margin: 0; -} - -div.dataTables_paginate ul.pagination { - margin: 2px 0; - white-space: nowrap; -} - -table.dataTable, -table.dataTable td, -table.dataTable th { - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; -} - - -table.dataTable { - clear: both; - margin-top: 6px !important; - margin-bottom: 6px !important; - max-width: none !important; -} - -table.dataTable thead .sorting, -table.dataTable thead .sorting_asc, -table.dataTable thead .sorting_desc, -table.dataTable thead .sorting_asc_disabled, -table.dataTable thead .sorting_desc_disabled { - cursor: pointer; -} - -table.dataTable thead .sorting { background: url('images/sort_both.png') no-repeat center right; } -table.dataTable thead .sorting_asc { background: url('images/sort_asc.png') no-repeat center right; } -table.dataTable thead .sorting_desc { background: url('images/sort_desc.png') no-repeat center right; } - -table.dataTable thead .sorting_asc_disabled { background: url('images/sort_asc_disabled.png') no-repeat center right; } -table.dataTable thead .sorting_desc_disabled { background: url('images/sort_desc_disabled.png') no-repeat center right; } - -table.dataTable th:active { - outline: none; -} - -/* Scrolling */ -div.dataTables_scrollHead table { - margin-bottom: 0 !important; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; -} - -div.dataTables_scrollHead table thead tr:last-child th:first-child, -div.dataTables_scrollHead table thead tr:last-child td:first-child { - border-bottom-left-radius: 0 !important; - border-bottom-right-radius: 0 !important; -} - -div.dataTables_scrollBody table { - border-top: none; - margin-top: 0 !important; - margin-bottom: 0 !important; -} - -div.dataTables_scrollBody tbody tr:first-child th, -div.dataTables_scrollBody tbody tr:first-child td { - border-top: none; -} - -div.dataTables_scrollFoot table { - margin-top: 0 !important; - border-top: none; -} - - - - -/* - * TableTools styles - */ -.table tbody tr.active td, -.table tbody tr.active th { - background-color: #08C; - color: white; -} - -.table tbody tr.active:hover td, -.table tbody tr.active:hover th { - background-color: #0075b0 !important; -} - -.table tbody tr.active a { - color: white; -} - -.table-striped tbody tr.active:nth-child(odd) td, -.table-striped tbody tr.active:nth-child(odd) th { - background-color: #017ebc; -} - -table.DTTT_selectable tbody tr { - cursor: pointer; -} - -div.DTTT .btn { - color: #333 !important; - font-size: 12px; -} - -div.DTTT .btn:hover { - text-decoration: none !important; -} - -ul.DTTT_dropdown.dropdown-menu { - z-index: 2003; -} - -ul.DTTT_dropdown.dropdown-menu a { - color: #333 !important; /* needed only when demo_page.css is included */ -} - -ul.DTTT_dropdown.dropdown-menu li { - position: relative; -} - -ul.DTTT_dropdown.dropdown-menu li:hover a { - background-color: #0088cc; - color: white !important; -} - -div.DTTT_collection_background { - z-index: 2002; -} - -/* TableTools information display */ -div.DTTT_print_info.modal { - height: 150px; - margin-top: -75px; - text-align: center; -} - -div.DTTT_print_info h6 { - font-weight: normal; - font-size: 28px; - line-height: 28px; - margin: 1em; -} - -div.DTTT_print_info p { - font-size: 14px; - line-height: 20px; -} - - - -/* - * FixedColumns styles - */ -div.DTFC_LeftHeadWrapper table, -div.DTFC_LeftFootWrapper table, -div.DTFC_RightHeadWrapper table, -div.DTFC_RightFootWrapper table, -table.DTFC_Cloned tr.even { - background-color: white; -} - -div.DTFC_RightHeadWrapper table , -div.DTFC_LeftHeadWrapper table { - margin-bottom: 0 !important; - border-top-right-radius: 0 !important; - border-bottom-left-radius: 0 !important; - border-bottom-right-radius: 0 !important; -} - -div.DTFC_RightHeadWrapper table thead tr:last-child th:first-child, -div.DTFC_RightHeadWrapper table thead tr:last-child td:first-child, -div.DTFC_LeftHeadWrapper table thead tr:last-child th:first-child, -div.DTFC_LeftHeadWrapper table thead tr:last-child td:first-child { - border-bottom-left-radius: 0 !important; - border-bottom-right-radius: 0 !important; -} - -div.DTFC_RightBodyWrapper table, -div.DTFC_LeftBodyWrapper table { - border-top: none; - margin-bottom: 0 !important; -} - -div.DTFC_RightBodyWrapper tbody tr:first-child th, -div.DTFC_RightBodyWrapper tbody tr:first-child td, -div.DTFC_LeftBodyWrapper tbody tr:first-child th, -div.DTFC_LeftBodyWrapper tbody tr:first-child td { - border-top: none; -} - -div.DTFC_RightFootWrapper table, -div.DTFC_LeftFootWrapper table { - border-top: none; -} - diff --git a/public/assets/css/datatables/images/sort_asc.png b/public/assets/css/datatables/images/sort_asc.png deleted file mode 100755 index a88d7975..00000000 Binary files a/public/assets/css/datatables/images/sort_asc.png and /dev/null differ diff --git a/public/assets/css/datatables/images/sort_asc_disabled.png b/public/assets/css/datatables/images/sort_asc_disabled.png deleted file mode 100755 index 4e144cf0..00000000 Binary files a/public/assets/css/datatables/images/sort_asc_disabled.png and /dev/null differ diff --git a/public/assets/css/datatables/images/sort_both.png b/public/assets/css/datatables/images/sort_both.png deleted file mode 100755 index 18670406..00000000 Binary files a/public/assets/css/datatables/images/sort_both.png and /dev/null differ diff --git a/public/assets/css/datatables/images/sort_desc.png b/public/assets/css/datatables/images/sort_desc.png deleted file mode 100755 index def071ed..00000000 Binary files a/public/assets/css/datatables/images/sort_desc.png and /dev/null differ diff --git a/public/assets/css/datatables/images/sort_desc_disabled.png b/public/assets/css/datatables/images/sort_desc_disabled.png deleted file mode 100755 index 7824973c..00000000 Binary files a/public/assets/css/datatables/images/sort_desc_disabled.png and /dev/null differ diff --git a/public/assets/css/images/animated-overlay.gif b/public/assets/css/images/animated-overlay.gif deleted file mode 100755 index d441f75e..00000000 Binary files a/public/assets/css/images/animated-overlay.gif and /dev/null differ diff --git a/public/assets/css/images/ui-bg_flat_0_aaaaaa_40x100.png b/public/assets/css/images/ui-bg_flat_0_aaaaaa_40x100.png deleted file mode 100755 index c09235f6..00000000 Binary files a/public/assets/css/images/ui-bg_flat_0_aaaaaa_40x100.png and /dev/null differ diff --git a/public/assets/css/images/ui-bg_flat_55_fbec88_40x100.png b/public/assets/css/images/ui-bg_flat_55_fbec88_40x100.png deleted file mode 100755 index d48c482d..00000000 Binary files a/public/assets/css/images/ui-bg_flat_55_fbec88_40x100.png and /dev/null differ diff --git a/public/assets/css/images/ui-bg_glass_75_d0e5f5_1x400.png b/public/assets/css/images/ui-bg_glass_75_d0e5f5_1x400.png deleted file mode 100755 index c621bd68..00000000 Binary files a/public/assets/css/images/ui-bg_glass_75_d0e5f5_1x400.png and /dev/null differ diff --git a/public/assets/css/images/ui-bg_glass_85_dfeffc_1x400.png b/public/assets/css/images/ui-bg_glass_85_dfeffc_1x400.png deleted file mode 100755 index f042e76a..00000000 Binary files a/public/assets/css/images/ui-bg_glass_85_dfeffc_1x400.png and /dev/null differ diff --git a/public/assets/css/images/ui-bg_glass_95_fef1ec_1x400.png b/public/assets/css/images/ui-bg_glass_95_fef1ec_1x400.png deleted file mode 100755 index 398c56a9..00000000 Binary files a/public/assets/css/images/ui-bg_glass_95_fef1ec_1x400.png and /dev/null differ diff --git a/public/assets/css/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png b/public/assets/css/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png deleted file mode 100755 index 1025df02..00000000 Binary files a/public/assets/css/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png and /dev/null differ diff --git a/public/assets/css/images/ui-bg_inset-hard_100_f5f8f9_1x100.png b/public/assets/css/images/ui-bg_inset-hard_100_f5f8f9_1x100.png deleted file mode 100755 index e29b0ca3..00000000 Binary files a/public/assets/css/images/ui-bg_inset-hard_100_f5f8f9_1x100.png and /dev/null differ diff --git a/public/assets/css/images/ui-bg_inset-hard_100_fcfdfd_1x100.png b/public/assets/css/images/ui-bg_inset-hard_100_fcfdfd_1x100.png deleted file mode 100755 index 5888e51e..00000000 Binary files a/public/assets/css/images/ui-bg_inset-hard_100_fcfdfd_1x100.png and /dev/null differ diff --git a/public/assets/css/images/ui-icons_217bc0_256x240.png b/public/assets/css/images/ui-icons_217bc0_256x240.png deleted file mode 100755 index 8d2b7e57..00000000 Binary files a/public/assets/css/images/ui-icons_217bc0_256x240.png and /dev/null differ diff --git a/public/assets/css/images/ui-icons_2e83ff_256x240.png b/public/assets/css/images/ui-icons_2e83ff_256x240.png deleted file mode 100755 index 84b601bf..00000000 Binary files a/public/assets/css/images/ui-icons_2e83ff_256x240.png and /dev/null differ diff --git a/public/assets/css/images/ui-icons_469bdd_256x240.png b/public/assets/css/images/ui-icons_469bdd_256x240.png deleted file mode 100755 index 5dff3f96..00000000 Binary files a/public/assets/css/images/ui-icons_469bdd_256x240.png and /dev/null differ diff --git a/public/assets/css/images/ui-icons_6da8d5_256x240.png b/public/assets/css/images/ui-icons_6da8d5_256x240.png deleted file mode 100755 index f7809f85..00000000 Binary files a/public/assets/css/images/ui-icons_6da8d5_256x240.png and /dev/null differ diff --git a/public/assets/css/images/ui-icons_cd0a0a_256x240.png b/public/assets/css/images/ui-icons_cd0a0a_256x240.png deleted file mode 100755 index ed5b6b09..00000000 Binary files a/public/assets/css/images/ui-icons_cd0a0a_256x240.png and /dev/null differ diff --git a/public/assets/css/images/ui-icons_d8e7f3_256x240.png b/public/assets/css/images/ui-icons_d8e7f3_256x240.png deleted file mode 100755 index 9b46228f..00000000 Binary files a/public/assets/css/images/ui-icons_d8e7f3_256x240.png and /dev/null differ diff --git a/public/assets/css/images/ui-icons_f9bd01_256x240.png b/public/assets/css/images/ui-icons_f9bd01_256x240.png deleted file mode 100755 index f1f0531a..00000000 Binary files a/public/assets/css/images/ui-icons_f9bd01_256x240.png and /dev/null differ diff --git a/public/assets/css/phpci.css b/public/assets/css/phpci.css deleted file mode 100644 index 06aa9163..00000000 --- a/public/assets/css/phpci.css +++ /dev/null @@ -1,77 +0,0 @@ -body { - background: #f9f9f9; - font-family: Arial, Sans-Serif; - font-style: normal; - font-weight: 300; - padding-top: 70px; -} - -.navbar { - background-color: #eee; -} - - .navbar-brand { - padding: 10px 15px; - } - -#latest-builds td, -#project-overview td, -#users td { - vertical-align: middle; -} - -.table th { - background-color: #efefef; - background-image: -webkit-gradient(linear, 0 0%, 0 100%, from(#fdfdfd), to(#eaeaea)); - background-image: -webkit-linear-gradient(top, #fdfdfd 0%, #eaeaea 100%); - background-image: -moz-linear-gradient(top, #fdfdfd 0%, #eaeaea 100%); - background-image: -ms-linear-gradient(top, #fdfdfd 0%, #eaeaea 100%); - background-image: -o-linear-gradient(top, #fdfdfd 0%, #eaeaea 100%); - background-image: -linear-gradient(top, #fdfdfd 0%, #eaeaea 100%); - border-bottom: 1px solid #CDCDCD; -} - - -h1 { - border-bottom: 1px solid #ddd; - font-size: 2em; - padding: 10px 0; -} - - h1 i { - font-size: 23px; - margin-right: 10px; - } - - - - -#loading { - background: #246; - bottom: 25px; - color: #fff; - display: none; - font-size: 1.5em; - padding: 20px 40px; - position: absolute; - right: 25px; - width: 200px; -} - -.word-wrap { - word-wrap: break-word; -} - -ul.pagination { - -} - - ul.pagination > li > span { - color: #333; - } - - ul.pagination > li > span:hover, - ul.pagination > li > span:focus { - color: #333; - background-color: #fff; - } diff --git a/public/assets/img/ajax-loader.gif b/public/assets/img/ajax-loader.gif index b8d06f66..e65dcffc 100755 Binary files a/public/assets/img/ajax-loader.gif and b/public/assets/img/ajax-loader.gif differ diff --git a/public/assets/img/ajax-loader1.gif b/public/assets/img/ajax-loader1.gif index cc70a7a8..ff412c92 100755 Binary files a/public/assets/img/ajax-loader1.gif and b/public/assets/img/ajax-loader1.gif differ diff --git a/public/assets/img/avatar.png b/public/assets/img/avatar.png index 0ef6233d..ae1cb7b5 100755 Binary files a/public/assets/img/avatar.png and b/public/assets/img/avatar.png differ diff --git a/public/assets/img/avatar04.png b/public/assets/img/avatar04.png index 63fa709b..10d44d44 100755 Binary files a/public/assets/img/avatar04.png and b/public/assets/img/avatar04.png differ diff --git a/public/assets/img/avatar2.png b/public/assets/img/avatar2.png index 5330c223..65fa3552 100755 Binary files a/public/assets/img/avatar2.png and b/public/assets/img/avatar2.png differ diff --git a/public/assets/img/avatar3.png b/public/assets/img/avatar3.png index b1afb21b..4d65e2c6 100755 Binary files a/public/assets/img/avatar3.png and b/public/assets/img/avatar3.png differ diff --git a/public/assets/img/avatar5.png b/public/assets/img/avatar5.png index 29ce6343..670e6d95 100755 Binary files a/public/assets/img/avatar5.png and b/public/assets/img/avatar5.png differ diff --git a/public/assets/img/blur-background04.jpg b/public/assets/img/blur-background04.jpg index c2ad9ea1..e208d771 100755 Binary files a/public/assets/img/blur-background04.jpg and b/public/assets/img/blur-background04.jpg differ diff --git a/public/assets/img/blur-background08.jpg b/public/assets/img/blur-background08.jpg index de91f6cc..3632e07d 100755 Binary files a/public/assets/img/blur-background08.jpg and b/public/assets/img/blur-background08.jpg differ diff --git a/public/assets/img/blur-background09.jpg b/public/assets/img/blur-background09.jpg index 0da84072..5ee3c17a 100755 Binary files a/public/assets/img/blur-background09.jpg and b/public/assets/img/blur-background09.jpg differ diff --git a/public/assets/img/bootstrap-colorpicker/alpha-horizontal.png b/public/assets/img/bootstrap-colorpicker/alpha-horizontal.png index d0a65c08..7789694f 100755 Binary files a/public/assets/img/bootstrap-colorpicker/alpha-horizontal.png and b/public/assets/img/bootstrap-colorpicker/alpha-horizontal.png differ diff --git a/public/assets/img/bootstrap-colorpicker/alpha.png b/public/assets/img/bootstrap-colorpicker/alpha.png index 38043f1c..a4129735 100755 Binary files a/public/assets/img/bootstrap-colorpicker/alpha.png and b/public/assets/img/bootstrap-colorpicker/alpha.png differ diff --git a/public/assets/img/bootstrap-colorpicker/hue-horizontal.png b/public/assets/img/bootstrap-colorpicker/hue-horizontal.png index a0d9add8..4ad05e78 100755 Binary files a/public/assets/img/bootstrap-colorpicker/hue-horizontal.png and b/public/assets/img/bootstrap-colorpicker/hue-horizontal.png differ diff --git a/public/assets/img/bootstrap-colorpicker/hue.png b/public/assets/img/bootstrap-colorpicker/hue.png index d89560e9..7f5f4749 100755 Binary files a/public/assets/img/bootstrap-colorpicker/hue.png and b/public/assets/img/bootstrap-colorpicker/hue.png differ diff --git a/public/assets/img/bootstrap-colorpicker/saturation.png b/public/assets/img/bootstrap-colorpicker/saturation.png index 594ae50e..a1598af6 100755 Binary files a/public/assets/img/bootstrap-colorpicker/saturation.png and b/public/assets/img/bootstrap-colorpicker/saturation.png differ diff --git a/public/assets/img/credit/american-express.png b/public/assets/img/credit/american-express.png index fbe9ce2c..bd7fcfbe 100755 Binary files a/public/assets/img/credit/american-express.png and b/public/assets/img/credit/american-express.png differ diff --git a/public/assets/img/credit/cirrus.png b/public/assets/img/credit/cirrus.png index 03d2bd6a..18236bef 100755 Binary files a/public/assets/img/credit/cirrus.png and b/public/assets/img/credit/cirrus.png differ diff --git a/public/assets/img/credit/mastercard.png b/public/assets/img/credit/mastercard.png index f709adba..2d7addcf 100755 Binary files a/public/assets/img/credit/mastercard.png and b/public/assets/img/credit/mastercard.png differ diff --git a/public/assets/img/credit/mestro.png b/public/assets/img/credit/mestro.png index c22ddeaf..9b5153a9 100755 Binary files a/public/assets/img/credit/mestro.png and b/public/assets/img/credit/mestro.png differ diff --git a/public/assets/img/credit/paypal.png b/public/assets/img/credit/paypal.png index a7e1458f..1d8e8a24 100755 Binary files a/public/assets/img/credit/paypal.png and b/public/assets/img/credit/paypal.png differ diff --git a/public/assets/img/credit/paypal2.png b/public/assets/img/credit/paypal2.png index b0ca241b..7c2fda42 100755 Binary files a/public/assets/img/credit/paypal2.png and b/public/assets/img/credit/paypal2.png differ diff --git a/public/assets/img/credit/visa.png b/public/assets/img/credit/visa.png index 7099cdf4..9a378542 100755 Binary files a/public/assets/img/credit/visa.png and b/public/assets/img/credit/visa.png differ diff --git a/public/assets/img/favicon.png b/public/assets/img/favicon.png index 1e33cffa..0b6f60ec 100644 Binary files a/public/assets/img/favicon.png and b/public/assets/img/favicon.png differ diff --git a/public/assets/img/glyphicons-halflings-white.png b/public/assets/img/glyphicons-halflings-white.png index 3bf6484a..c1ab5815 100644 Binary files a/public/assets/img/glyphicons-halflings-white.png and b/public/assets/img/glyphicons-halflings-white.png differ diff --git a/public/assets/img/glyphicons-halflings.png b/public/assets/img/glyphicons-halflings.png index a9969993..f241c76f 100644 Binary files a/public/assets/img/glyphicons-halflings.png and b/public/assets/img/glyphicons-halflings.png differ diff --git a/public/assets/img/icon-build-failed.png b/public/assets/img/icon-build-failed.png index 9dde31bd..8ddd4b14 100644 Binary files a/public/assets/img/icon-build-failed.png and b/public/assets/img/icon-build-failed.png differ diff --git a/public/assets/img/icon-build-ok.png b/public/assets/img/icon-build-ok.png index 650e5f1f..90e5f35e 100644 Binary files a/public/assets/img/icon-build-ok.png and b/public/assets/img/icon-build-ok.png differ diff --git a/public/assets/img/icon-build-pending.png b/public/assets/img/icon-build-pending.png index f23051c7..2c8d1196 100644 Binary files a/public/assets/img/icon-build-pending.png and b/public/assets/img/icon-build-pending.png differ diff --git a/public/assets/img/icon-build-running.png b/public/assets/img/icon-build-running.png index 593f00b5..3e9b4f71 100644 Binary files a/public/assets/img/icon-build-running.png and b/public/assets/img/icon-build-running.png differ diff --git a/public/assets/img/icons.png b/public/assets/img/icons.png index 1663a0bd..96c1afd3 100755 Binary files a/public/assets/img/icons.png and b/public/assets/img/icons.png differ diff --git a/public/assets/img/logo-icon.png b/public/assets/img/logo-icon.png new file mode 100644 index 00000000..c3cb1143 Binary files /dev/null and b/public/assets/img/logo-icon.png differ diff --git a/public/assets/img/logo-icon.svg b/public/assets/img/logo-icon.svg new file mode 100644 index 00000000..1c44f696 --- /dev/null +++ b/public/assets/img/logo-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/img/logo-large.png b/public/assets/img/logo-large.png index dd3e1d34..08bb5604 100644 Binary files a/public/assets/img/logo-large.png and b/public/assets/img/logo-large.png differ diff --git a/public/assets/img/logo.png b/public/assets/img/logo.png index 4c56e4a7..61fbbebd 100644 Binary files a/public/assets/img/logo.png and b/public/assets/img/logo.png differ diff --git a/public/assets/img/sprite-skin-flat.png b/public/assets/img/sprite-skin-flat.png index 3055db77..84a36653 100755 Binary files a/public/assets/img/sprite-skin-flat.png and b/public/assets/img/sprite-skin-flat.png differ diff --git a/public/assets/img/sprite-skin-nice.png b/public/assets/img/sprite-skin-nice.png index d62f8188..25e4d509 100755 Binary files a/public/assets/img/sprite-skin-nice.png and b/public/assets/img/sprite-skin-nice.png differ diff --git a/public/assets/img/user-bg.png b/public/assets/img/user-bg.png index 75e1b46c..a491bc0d 100755 Binary files a/public/assets/img/user-bg.png and b/public/assets/img/user-bg.png differ diff --git a/public/assets/img/user.jpg b/public/assets/img/user.jpg index b4f104f2..6eab19ae 100755 Binary files a/public/assets/img/user.jpg and b/public/assets/img/user.jpg differ diff --git a/public/assets/img/user2.jpg b/public/assets/img/user2.jpg index cb2d3639..ce9e457a 100755 Binary files a/public/assets/img/user2.jpg and b/public/assets/img/user2.jpg differ diff --git a/public/assets/js/AdminLTE/app.js b/public/assets/js/AdminLTE/app.js deleted file mode 100755 index a2154e7e..00000000 --- a/public/assets/js/AdminLTE/app.js +++ /dev/null @@ -1,1054 +0,0 @@ -/*! - * Author: Abdullah A Almsaeed - * Date: 4 Jan 2014 - * Description: - * This file should be included in all pages - !**/ - -/* - * Global variables. If you change any of these vars, don't forget - * to change the values in the less files! - */ -var left_side_width = 220; //Sidebar width in pixels - -$(function() { - "use strict"; - - //Enable sidebar toggle - $("[data-toggle='offcanvas']").click(function(e) { - e.preventDefault(); - - //If window is small enough, enable sidebar push menu - if ($(window).width() <= 992) { - $('.row-offcanvas').toggleClass('active'); - $('.left-side').removeClass("collapse-left"); - $(".right-side").removeClass("strech"); - $('.row-offcanvas').toggleClass("relative"); - } else { - //Else, enable content streching - $('.left-side').toggleClass("collapse-left"); - $(".right-side").toggleClass("strech"); - } - }); - - //Add hover support for touch devices - $('.btn').bind('touchstart', function() { - $(this).addClass('hover'); - }).bind('touchend', function() { - $(this).removeClass('hover'); - }); - - //Activate tooltips - $("[data-toggle='tooltip']").tooltip(); - - /* - * Add collapse and remove events to boxes - */ - $("[data-widget='collapse']").click(function() { - //Find the box parent - var box = $(this).parents(".box").first(); - //Find the body and the footer - var bf = box.find(".box-body, .box-footer"); - if (!box.hasClass("collapsed-box")) { - box.addClass("collapsed-box"); - //Convert minus into plus - $(this).children(".fa-minus").removeClass("fa-minus").addClass("fa-plus"); - bf.slideUp(); - } else { - box.removeClass("collapsed-box"); - //Convert plus into minus - $(this).children(".fa-plus").removeClass("fa-plus").addClass("fa-minus"); - bf.slideDown(); - } - }); - - /* - * ADD SLIMSCROLL TO THE TOP NAV DROPDOWNS - * --------------------------------------- - */ - $(".navbar .menu").slimscroll({ - height: "200px", - alwaysVisible: false, - size: "3px" - }).css("width", "100%"); - - /* - * INITIALIZE BUTTON TOGGLE - * ------------------------ - */ - $('.btn-group[data-toggle="btn-toggle"]').each(function() { - var group = $(this); - $(this).find(".btn").click(function(e) { - group.find(".btn.active").removeClass("active"); - $(this).addClass("active"); - e.preventDefault(); - }); - - }); - - $("[data-widget='remove']").click(function() { - //Find the box parent - var box = $(this).parents(".box").first(); - box.slideUp(); - }); - - /* Sidebar tree view */ - $(".sidebar .treeview").tree(); - - /* - * Make sure that the sidebar is streched full height - * --------------------------------------------- - * We are gonna assign a min-height value every time the - * wrapper gets resized and upon page load. We will use - * Ben Alman's method for detecting the resize event. - * - **/ - function _fix() { - //Get window height and the wrapper height - var height = $(window).height() - $("body > .header").height() - ($("body > .footer").outerHeight() || 0); - $(".wrapper").css("min-height", height + "px"); - var content = $(".wrapper").height(); - //If the wrapper height is greater than the window - if (content > height) - //then set sidebar height to the wrapper - $(".left-side, html, body").css("min-height", content + "px"); - else { - //Otherwise, set the sidebar to the height of the window - $(".left-side, html, body").css("min-height", height + "px"); - } - } - //Fire upon load - _fix(); - //Fire when wrapper is resized - $(".wrapper").resize(function() { - _fix(); - fix_sidebar(); - }); - - //Fix the fixed layout sidebar scroll bug - fix_sidebar(); - - /* - * We are gonna initialize all checkbox and radio inputs to - * iCheck plugin in. - * You can find the documentation at http://fronteed.com/iCheck/ - */ - $("input[type='checkbox']:not(.simple), input[type='radio']:not(.simple)").iCheck({ - checkboxClass: 'icheckbox_minimal', - radioClass: 'iradio_minimal' - }); - -}); -function fix_sidebar() { - //Make sure the body tag has the .fixed class - if (!$("body").hasClass("fixed")) { - return; - } - - //Add slimscroll - $(".sidebar").slimscroll({ - height: ($(window).height() - $(".header").height()) + "px", - color: "rgba(0,0,0,0.2)" - }); -} - -/*END DEMO*/ -$(window).load(function() { - /*! pace 0.4.17 */ - (function() { - var a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V = [].slice, W = {}.hasOwnProperty, X = function(a, b) { - function c() { - this.constructor = a - } - for (var d in b) - W.call(b, d) && (a[d] = b[d]); - return c.prototype = b.prototype, a.prototype = new c, a.__super__ = b.prototype, a - }, Y = [].indexOf || function(a) { - for (var b = 0, c = this.length; c > b; b++) - if (b in this && this[b] === a) - return b; - return-1 - }; - for (t = {catchupTime:500, initialRate:.03, minTime:500, ghostTime:500, maxProgressPerFrame:10, easeFactor:1.25, startOnPageLoad:!0, restartOnPushState:!0, restartOnRequestAfter:500, target:"body", elements:{checkInterval:100, selectors:["body"]}, eventLag:{minSamples:10, sampleCount:3, lagThreshold:3}, ajax:{trackMethods:["GET"], trackWebSockets:!1}}, B = function() { - var a; - return null != (a = "undefined" != typeof performance && null !== performance ? "function" == typeof performance.now ? performance.now() : void 0 : void 0) ? a : +new Date - }, D = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame, s = window.cancelAnimationFrame || window.mozCancelAnimationFrame, null == D && (D = function(a) { - return setTimeout(a, 50) - }, s = function(a) { - return clearTimeout(a) - }), F = function(a) { - var b, c; - return b = B(), (c = function() { - var d; - return d = B() - b, d >= 33 ? (b = B(), a(d, function() { - return D(c) - })) : setTimeout(c, 33 - d) - })() - }, E = function() { - var a, b, c; - return c = arguments[0], b = arguments[1], a = 3 <= arguments.length ? V.call(arguments, 2) : [], "function" == typeof c[b] ? c[b].apply(c, a) : c[b] - }, u = function() { - var a, b, c, d, e, f, g; - for (b = arguments[0], d = 2 <= arguments.length?V.call(arguments, 1):[], f = 0, g = d.length; g > f; f++) - if (c = d[f]) - for (a in c) - W.call(c, a) && (e = c[a], null != b[a] && "object" == typeof b[a] && null != e && "object" == typeof e ? u(b[a], e) : b[a] = e); - return b - }, p = function(a) { - var b, c, d, e, f; - for (c = b = 0, e = 0, f = a.length; f > e; e++) - d = a[e], c += Math.abs(d), b++; - return c / b - }, w = function(a, b) { - var c, d, e; - if (null == a && (a = "options"), null == b && (b = !0), e = document.querySelector("[data-pace-" + a + "]")) { - if (c = e.getAttribute("data-pace-" + a), !b) - return c; - try { - return JSON.parse(c) - } catch (f) { - return d = f, "undefined" != typeof console && null !== console ? console.error("Error parsing inline pace options", d) : void 0 - } - } - }, g = function() { - function a() { - } - return a.prototype.on = function(a, b, c, d) { - var e; - return null == d && (d = !1), null == this.bindings && (this.bindings = {}), null == (e = this.bindings)[a] && (e[a] = []), this.bindings[a].push({handler: b, ctx: c, once: d}) - }, a.prototype.once = function(a, b, c) { - return this.on(a, b, c, !0) - }, a.prototype.off = function(a, b) { - var c, d, e; - if (null != (null != (d = this.bindings) ? d[a] : void 0)) { - if (null == b) - return delete this.bindings[a]; - for (c = 0, e = []; c < this.bindings[a].length; ) - this.bindings[a][c].handler === b ? e.push(this.bindings[a].splice(c, 1)) : e.push(c++); - return e - } - }, a.prototype.trigger = function() { - var a, b, c, d, e, f, g, h, i; - if (c = arguments[0], a = 2 <= arguments.length ? V.call(arguments, 1) : [], null != (g = this.bindings) ? g[c] : void 0) { - for (e = 0, i = []; e < this.bindings[c].length; ) - h = this.bindings[c][e], d = h.handler, b = h.ctx, f = h.once, d.apply(null != b ? b : this, a), f ? i.push(this.bindings[c].splice(e, 1)) : i.push(e++); - return i - } - }, a - }(), null == window.Pace && (window.Pace = {}), u(Pace, g.prototype), C = Pace.options = u({}, t, window.paceOptions, w()), S = ["ajax", "document", "eventLag", "elements"], O = 0, Q = S.length; Q > O; O++) - I = S[O], C[I] === !0 && (C[I] = t[I]); - i = function(a) { - function b() { - return T = b.__super__.constructor.apply(this, arguments) - } - return X(b, a), b - }(Error), b = function() { - function a() { - this.progress = 0 - } - return a.prototype.getElement = function() { - var a; - if (null == this.el) { - if (a = document.querySelector(C.target), !a) - throw new i; - this.el = document.createElement("div"), this.el.className = "pace pace-active", document.body.className = document.body.className.replace("pace-done", ""), document.body.className += " pace-running", this.el.innerHTML = '
    \n
    \n
    \n
    ', null != a.firstChild ? a.insertBefore(this.el, a.firstChild) : a.appendChild(this.el) - } - return this.el - }, a.prototype.finish = function() { - var a; - return a = this.getElement(), a.className = a.className.replace("pace-active", ""), a.className += " pace-inactive", document.body.className = document.body.className.replace("pace-running", ""), document.body.className += " pace-done" - }, a.prototype.update = function(a) { - return this.progress = a, this.render() - }, a.prototype.destroy = function() { - try { - this.getElement().parentNode.removeChild(this.getElement()) - } catch (a) { - i = a - } - return this.el = void 0 - }, a.prototype.render = function() { - var a, b; - return null == document.querySelector(C.target) ? !1 : (a = this.getElement(), a.children[0].style.width = "" + this.progress + "%", (!this.lastRenderedProgress || this.lastRenderedProgress | 0 !== this.progress | 0) && (a.children[0].setAttribute("data-progress-text", "" + (0 | this.progress) + "%"), this.progress >= 100 ? b = "99" : (b = this.progress < 10 ? "0" : "", b += 0 | this.progress), a.children[0].setAttribute("data-progress", "" + b)), this.lastRenderedProgress = this.progress) - }, a.prototype.done = function() { - return this.progress >= 100 - }, a - }(), h = function() { - function a() { - this.bindings = {} - } - return a.prototype.trigger = function(a, b) { - var c, d, e, f, g; - if (null != this.bindings[a]) { - for (f = this.bindings[a], g = [], d = 0, e = f.length; e > d; d++) - c = f[d], g.push(c.call(this, b)); - return g - } - }, a.prototype.on = function(a, b) { - var c; - return null == (c = this.bindings)[a] && (c[a] = []), this.bindings[a].push(b) - }, a - }(), N = window.XMLHttpRequest, M = window.XDomainRequest, L = window.WebSocket, v = function(a, b) { - var c, d, e, f; - f = []; - for (d in b.prototype) - try { - e = b.prototype[d], null == a[d] && "function" != typeof e ? f.push(a[d] = e) : f.push(void 0) - } catch (g) { - c = g - } - return f - }, z = [], Pace.ignore = function() { - var a, b, c; - return b = arguments[0], a = 2 <= arguments.length ? V.call(arguments, 1) : [], z.unshift("ignore"), c = b.apply(null, a), z.shift(), c - }, Pace.track = function() { - var a, b, c; - return b = arguments[0], a = 2 <= arguments.length ? V.call(arguments, 1) : [], z.unshift("track"), c = b.apply(null, a), z.shift(), c - }, H = function(a) { - var b; - if (null == a && (a = "GET"), "track" === z[0]) - return"force"; - if (!z.length && C.ajax) { - if ("socket" === a && C.ajax.trackWebSockets) - return!0; - if (b = a.toUpperCase(), Y.call(C.ajax.trackMethods, b) >= 0) - return!0 - } - return!1 - }, j = function(a) { - function b() { - var a, c = this; - b.__super__.constructor.apply(this, arguments), a = function(a) { - var b; - return b = a.open, a.open = function(d, e) { - return H(d) && c.trigger("request", {type: d, url: e, request: a}), b.apply(a, arguments) - } - }, window.XMLHttpRequest = function(b) { - var c; - return c = new N(b), a(c), c - }, v(window.XMLHttpRequest, N), null != M && (window.XDomainRequest = function() { - var b; - return b = new M, a(b), b - }, v(window.XDomainRequest, M)), null != L && C.ajax.trackWebSockets && (window.WebSocket = function(a, b) { - var d; - return d = new L(a, b), H("socket") && c.trigger("request", {type: "socket", url: a, protocols: b, request: d}), d - }, v(window.WebSocket, L)) - } - return X(b, a), b - }(h), P = null, x = function() { - return null == P && (P = new j), P - }, x().on("request", function(b) { - var c, d, e, f; - return f = b.type, e = b.request, Pace.running || C.restartOnRequestAfter === !1 && "force" !== H(f) ? void 0 : (d = arguments, c = C.restartOnRequestAfter || 0, "boolean" == typeof c && (c = 0), setTimeout(function() { - var b, c, g, h, i, j; - if (b = "socket" === f ? e.readyState < 2 : 0 < (h = e.readyState) && 4 > h) { - for (Pace.restart(), i = Pace.sources, j = [], c = 0, g = i.length; g > c; c++) { - if (I = i[c], I instanceof a) { - I.watch.apply(I, d); - break - } - j.push(void 0) - } - return j - } - }, c)) - }), a = function() { - function a() { - var a = this; - this.elements = [], x().on("request", function() { - return a.watch.apply(a, arguments) - }) - } - return a.prototype.watch = function(a) { - var b, c, d; - return d = a.type, b = a.request, c = "socket" === d ? new m(b) : new n(b), this.elements.push(c) - }, a - }(), n = function() { - function a(a) { - var b, c, d, e, f, g, h = this; - if (this.progress = 0, null != window.ProgressEvent) - for (c = null, a.addEventListener("progress", function(a) { - return h.progress = a.lengthComputable ? 100 * a.loaded / a.total : h.progress + (100 - h.progress) / 2 - }), g = ["load", "abort", "timeout", "error"], d = 0, e = g.length; e > d; d++) - b = g[d], a.addEventListener(b, function() { - return h.progress = 100 - }); - else - f = a.onreadystatechange, a.onreadystatechange = function() { - var b; - return 0 === (b = a.readyState) || 4 === b ? h.progress = 100 : 3 === a.readyState && (h.progress = 50), "function" == typeof f ? f.apply(null, arguments) : void 0 - } - } - return a - }(), m = function() { - function a(a) { - var b, c, d, e, f = this; - for (this.progress = 0, e = ["error", "open"], c = 0, d = e.length; d > c; c++) - b = e[c], a.addEventListener(b, function() { - return f.progress = 100 - }) - } - return a - }(), d = function() { - function a(a) { - var b, c, d, f; - for (null == a && (a = {}), this.elements = [], null == a.selectors && (a.selectors = []), f = a.selectors, c = 0, d = f.length; d > c; c++) - b = f[c], this.elements.push(new e(b)) - } - return a - }(), e = function() { - function a(a) { - this.selector = a, this.progress = 0, this.check() - } - return a.prototype.check = function() { - var a = this; - return document.querySelector(this.selector) ? this.done() : setTimeout(function() { - return a.check() - }, C.elements.checkInterval) - }, a.prototype.done = function() { - return this.progress = 100 - }, a - }(), c = function() { - function a() { - var a, b, c = this; - this.progress = null != (b = this.states[document.readyState]) ? b : 100, a = document.onreadystatechange, document.onreadystatechange = function() { - return null != c.states[document.readyState] && (c.progress = c.states[document.readyState]), "function" == typeof a ? a.apply(null, arguments) : void 0 - } - } - return a.prototype.states = {loading: 0, interactive: 50, complete: 100}, a - }(), f = function() { - function a() { - var a, b, c, d, e, f = this; - this.progress = 0, a = 0, e = [], d = 0, c = B(), b = setInterval(function() { - var g; - return g = B() - c - 50, c = B(), e.push(g), e.length > C.eventLag.sampleCount && e.shift(), a = p(e), ++d >= C.eventLag.minSamples && a < C.eventLag.lagThreshold ? (f.progress = 100, clearInterval(b)) : f.progress = 100 * (3 / (a + 3)) - }, 50) - } - return a - }(), l = function() { - function a(a) { - this.source = a, this.last = this.sinceLastUpdate = 0, this.rate = C.initialRate, this.catchup = 0, this.progress = this.lastProgress = 0, null != this.source && (this.progress = E(this.source, "progress")) - } - return a.prototype.tick = function(a, b) { - var c; - return null == b && (b = E(this.source, "progress")), b >= 100 && (this.done = !0), b === this.last ? this.sinceLastUpdate += a : (this.sinceLastUpdate && (this.rate = (b - this.last) / this.sinceLastUpdate), this.catchup = (b - this.progress) / C.catchupTime, this.sinceLastUpdate = 0, this.last = b), b > this.progress && (this.progress += this.catchup * a), c = 1 - Math.pow(this.progress / 100, C.easeFactor), this.progress += c * this.rate * a, this.progress = Math.min(this.lastProgress + C.maxProgressPerFrame, this.progress), this.progress = Math.max(0, this.progress), this.progress = Math.min(100, this.progress), this.lastProgress = this.progress, this.progress - }, a - }(), J = null, G = null, q = null, K = null, o = null, r = null, Pace.running = !1, y = function() { - return C.restartOnPushState ? Pace.restart() : void 0 - }, null != window.history.pushState && (R = window.history.pushState, window.history.pushState = function() { - return y(), R.apply(window.history, arguments) - }), null != window.history.replaceState && (U = window.history.replaceState, window.history.replaceState = function() { - return y(), U.apply(window.history, arguments) - }), k = {ajax: a, elements: d, document: c, eventLag: f}, (A = function() { - var a, c, d, e, f, g, h, i; - for (Pace.sources = J = [], g = ["ajax", "elements", "document", "eventLag"], c = 0, e = g.length; e > c; c++) - a = g[c], C[a] !== !1 && J.push(new k[a](C[a])); - for (i = null != (h = C.extraSources)?h:[], d = 0, f = i.length; f > d; d++) - I = i[d], J.push(new I(C)); - return Pace.bar = q = new b, G = [], K = new l - })(), Pace.stop = function() { - return Pace.trigger("stop"), Pace.running = !1, q.destroy(), r = !0, null != o && ("function" == typeof s && s(o), o = null), A() - }, Pace.restart = function() { - return Pace.trigger("restart"), Pace.stop(), Pace.start() - }, Pace.go = function() { - return Pace.running = !0, q.render(), r = !1, o = F(function(a, b) { - var c, d, e, f, g, h, i, j, k, m, n, o, p, s, t, u, v; - for (j = 100 - q.progress, d = o = 0, e = !0, h = p = 0, t = J.length; t > p; h = ++p) - for (I = J[h], m = null != G[h]?G[h]:G[h] = [], g = null != (v = I.elements)?v:[I], i = s = 0, u = g.length; u > s; i = ++s) - f = g[i], k = null != m[i] ? m[i] : m[i] = new l(f), e &= k.done, k.done || (d++, o += k.tick(a)); - return c = o / d, q.update(K.tick(a, c)), n = B(), q.done() || e || r ? (q.update(100), Pace.trigger("done"), setTimeout(function() { - return q.finish(), Pace.running = !1, Pace.trigger("hide") - }, Math.max(C.ghostTime, Math.min(C.minTime, B() - n)))) : b() - }) - }, Pace.start = function(a) { - u(C, a), Pace.running = !0; - try { - q.render() - } catch (b) { - i = b - } - return document.querySelector(".pace") ? (Pace.trigger("start"), Pace.go()) : setTimeout(Pace.start, 50) - }, "function" == typeof define && define.amd ? define('theme-app', [], function() { - return Pace - }) : "object" == typeof exports ? module.exports = Pace : C.startOnPageLoad && Pace.start() - }).call(this); -}); - -/* - * BOX REFRESH BUTTON - * ------------------ - * This is a custom plugin to use with the compenet BOX. It allows you to add - * a refresh button to the box. It converts the box's state to a loading state. - * - * USAGE: - * $("#box-widget").boxRefresh( options ); - * */ -(function($) { - "use strict"; - - $.fn.boxRefresh = function(options) { - - // Render options - var settings = $.extend({ - //Refressh button selector - trigger: ".refresh-btn", - //File source to be loaded (e.g: ajax/src.php) - source: "", - //Callbacks - onLoadStart: function(box) { - }, //Right after the button has been clicked - onLoadDone: function(box) { - } //When the source has been loaded - - }, options); - - //The overlay - var overlay = $('
    '); - - return this.each(function() { - //if a source is specified - if (settings.source === "") { - if (console) { - console.log("Please specify a source first - boxRefresh()"); - } - return; - } - //the box - var box = $(this); - //the button - var rBtn = box.find(settings.trigger).first(); - - //On trigger click - rBtn.click(function(e) { - e.preventDefault(); - //Add loading overlay - start(box); - - //Perform ajax call - box.find(".box-body").load(settings.source, function() { - done(box); - }); - - - }); - - }); - - function start(box) { - //Add overlay and loading img - box.append(overlay); - - settings.onLoadStart.call(box); - } - - function done(box) { - //Remove overlay and loading img - box.find(overlay).remove(); - - settings.onLoadDone.call(box); - } - - }; - -})(jQuery); - -/* - * SIDEBAR MENU - * ------------ - * This is a custom plugin for the sidebar menu. It provides a tree view. - * - * Usage: - * $(".sidebar).tree(); - * - * Note: This plugin does not accept any options. Instead, it only requires a class - * added to the element that contains a sub-menu. - * - * When used with the sidebar, for example, it would look something like this: - *
    ' + + '' + + '' + + '' + + '' + + '
    '+Lang.get('codeception_suite')+''+Lang.get('codeception_feature')+''+Lang.get('codeception_time')+'
    '); + }, + + onUpdateData: function(e) { + if (!e.queryData) { + $('#build-codeception-errors').hide(); + return; + } + + this.rendered = true; + this.lastData = e.queryData; + + var tests = this.lastData[0].meta_value; + var tbody = $('#codeception-data tbody'); + tbody.empty(); + + if (tests.length == 0) { + $('#build-codeception-errors').hide(); + return; + } + + for (var i in tests) { + + var rows = $('' + + ''+tests[i].suite+'' + + ''+tests[i].feature+'' + + ''+tests[i].time+''+ + '' + + '' + + '' + + ''+Lang.get('name')+': '+tests[i].name+'
    ' + + ''+Lang.get('file')+': '+tests[i].file+'
    ' + + (tests[i].message + ? ''+Lang.get('message')+': '+tests[i].message+'' + : '') + + '' + + ''); + + if (!tests[i].pass) { + rows.first().addClass('danger'); + } else { + rows.first().addClass('success'); + } + + tbody.append(rows); + } + + $('#build-codeception-errors').show(); + }, + + onUpdateMeta: function(e) { + if (!e.queryData) { + return; + } + + $('#build-codeception-errors').show(); + $('#build-codeception-errors td').tooltip(); + + this.lastMeta = e.queryData; + + var data = this.lastMeta[0].meta_value; + var tfoot = $('#codeception-data tfoot'); + tfoot.empty(); + + var row = $('' + + '' + + Lang.get('codeception_synopsis', data.tests, data.timetaken, data.failures) + + '' + + ''); + + tfoot.append(row); + } +}); + +ActiveBuild.registerPlugin(new codeceptionPlugin()); diff --git a/public/assets/js/build-plugins/loc.js b/public/assets/js/build-plugins/loc.js index b74058bb..89e703b8 100644 --- a/public/assets/js/build-plugins/loc.js +++ b/public/assets/js/build-plugins/loc.js @@ -1,10 +1,11 @@ var locPlugin = ActiveBuild.UiPlugin.extend({ id: 'build-lines-chart', - css: 'col-lg-6 col-md-6 col-sm-12 col-xs-12', + css: 'col-xs-12', title: Lang.get('lines_of_code'), lastData: null, displayOnUpdate: false, rendered: false, + chartData: null, register: function() { var self = this; @@ -19,12 +20,19 @@ var locPlugin = ActiveBuild.UiPlugin.extend({ query(); } }); - - google.load("visualization", "1", {packages:["corechart"]}); }, render: function() { - return $('
    ').text(Lang.get('chart_display')); + var self = this; + var container = $('
    '); + container.append(''); + + $(document).on('shown.bs.tab', function () { + $('#build-lines-chart').hide(); + self.drawChart(); + }); + + return container; }, onUpdate: function(e) { @@ -33,34 +41,65 @@ var locPlugin = ActiveBuild.UiPlugin.extend({ }, displayChart: function() { + var self = this; var builds = this.lastData; + self.rendered = true; - if (!builds || !builds.length) { - $('#build-lines-chart').hide(); - return; - } - - this.rendered = true; - - $('#phploc-lines').empty().animate({height: '275px'}); - - var titles = [Lang.get('build'), Lang.get('lines'), Lang.get('comment_lines'), Lang.get('noncomment_lines'), Lang.get('logical_lines')]; - var data = [titles]; - for (var i in builds) { - data.push(['#' + builds[i].build_id, parseInt(builds[i].meta_value.LOC), parseInt(builds[i].meta_value.CLOC), parseInt(builds[i].meta_value.NCLOC), parseInt(builds[i].meta_value.LLOC)]); - } - - var data = google.visualization.arrayToDataTable(data); - var options = { - hAxis: {title: Lang.get('builds')}, - vAxis: {title: Lang.get('lines')}, - backgroundColor: { fill: 'transparent' }, - height: 275 + self.chartData = { + labels: [], + datasets: [ + { + label: Lang.get('lines'), + strokeColor: "rgba(60,141,188,1)", + pointColor: "rgba(60,141,188,1)", + data: [] + }, + { + label: Lang.get('logical_lines'), + strokeColor: "rgba(245,105,84,1)", + pointColor: "rgba(245,105,84,1)", + data: [] + }, + { + label: Lang.get('comment_lines'), + strokeColor: "rgba(0,166,90,1)", + pointColor: "rgba(0,166,90,1)", + data: [] + }, + { + label: Lang.get('noncomment_lines'), + strokeColor: "rgba(0,192,239,1)", + pointColor: "rgba(0,192,239,1)", + data: [] + } + ] }; - $('#build-lines-chart').show(); - var chart = new google.visualization.LineChart(document.getElementById('phploc-lines')); - chart.draw(data, options); + for (var i in builds) { + self.chartData.labels.push('Build ' + builds[i].build_id); + self.chartData.datasets[0].data.push(builds[i].meta_value.LOC); + self.chartData.datasets[1].data.push(builds[i].meta_value.LLOC); + self.chartData.datasets[2].data.push(builds[i].meta_value.CLOC); + self.chartData.datasets[3].data.push(builds[i].meta_value.NCLOC); + } + + self.drawChart(); + }, + + drawChart: function () { + var self = this; + + if ($('#information').hasClass('active') && self.chartData && self.lastData) { + $('#build-lines-chart').show(); + + var ctx = $("#phploc-lines-chart").get(0).getContext("2d"); + var phpLocChart = new Chart(ctx); + + phpLocChart.Line(self.chartData, { + datasetFill: false, + multiTooltipTemplate: "<%=datasetLabel%>: <%= value %>" + }); + } } }); diff --git a/public/assets/js/build-plugins/log.js b/public/assets/js/build-plugins/log.js deleted file mode 100644 index 8798e23c..00000000 --- a/public/assets/js/build-plugins/log.js +++ /dev/null @@ -1,29 +0,0 @@ -var logPlugin = ActiveBuild.UiPlugin.extend({ - id: 'build-log', - css: 'col-lg-6 col-md-12 col-sm-12 col-xs-12', - title: Lang.get('build_log'), - - init: function(){ - this._super(); - }, - - render: function() { - var container = $('
    ');
    -        container.css({height: '300px', 'overflow-y': 'auto'});
    -        container.html(ActiveBuild.buildData.log);
    -
    -        return container;
    -    },
    -
    -    onUpdate: function(e) {
    -        if (!e.queryData || e.queryData == '') {
    -            $('#build-log').hide();
    -            return;
    -        }
    -
    -        $('#build-log pre').html(e.queryData.log);
    -        $('#build-log').show();
    -    }
    -});
    -
    -ActiveBuild.registerPlugin(new logPlugin());
    \ No newline at end of file
    diff --git a/public/assets/js/build-plugins/phpcpd.js b/public/assets/js/build-plugins/phpcpd.js
    deleted file mode 100644
    index c9733678..00000000
    --- a/public/assets/js/build-plugins/phpcpd.js
    +++ /dev/null
    @@ -1,90 +0,0 @@
    -var phpcpdPlugin = ActiveBuild.UiPlugin.extend({
    -    id: 'build-phpcpd',
    -    css: 'col-lg-6 col-md-12 col-sm-12 col-xs-12',
    -    title: Lang.get('phpcpd'),
    -    lastData: null,
    -    box: true,
    -    rendered: false,
    -
    -    register: function() {
    -        var self = this;
    -        var query = ActiveBuild.registerQuery('phpcpd-data', -1, {key: 'phpcpd-data'})
    -
    -        $(window).on('phpcpd-data', function(data) {
    -            self.onUpdate(data);
    -        });
    -
    -        $(window).on('build-updated', function() {
    -            if (!self.rendered) {
    -                query();
    -            }
    -        });
    -    },
    -
    -    render: function() {
    -
    -        return $('' +
    -            '' +
    -            '' +
    -            '   ' +
    -            '   ' +
    -            '   ' +
    -            '' +
    -            '
    '+Lang.get('file')+''+Lang.get('start')+''+Lang.get('end')+'
    '); - - }, - - onUpdate: function(e) { - if (!e.queryData) { - $('#build-phpcpd').hide(); - return; - } - - this.rendered = true; - this.lastData = e.queryData; - - var errors = this.lastData[0].meta_value; - var tbody = $('#phpcpd-data tbody'); - tbody.empty(); - - var rowClass = 'danger'; - - if (errors.length == 0) { - $('#build-phpcpd').hide(); - return; - } - - for (var i in errors) { - var file = errors[i].file; - - if (ActiveBuild.fileLinkTemplate) { - var fileLink = ActiveBuild.fileLinkTemplate.replace('{FILE}', file); - fileLink = fileLink.replace('{LINE}', errors[i].line_start); - - file = '
    ' + file + ''; - } - - var label = Lang.get('from'); - - if (i % 2 > 0) { - label = Lang.get('to'); - } - else { - rowClass = (rowClass == 'warning' ? 'danger' : 'warning'); - } - - var row = $('' + - '' + label + ': '+file+'' + - ''+errors[i].line_start+'' + - ''+errors[i].line_end+''); - - row.addClass(rowClass); - - tbody.append(row); - } - - $('#build-phpcpd').show(); - } -}); - -ActiveBuild.registerPlugin(new phpcpdPlugin()); diff --git a/public/assets/js/build-plugins/phpcs.js b/public/assets/js/build-plugins/phpcs.js deleted file mode 100644 index f3b1fe67..00000000 --- a/public/assets/js/build-plugins/phpcs.js +++ /dev/null @@ -1,79 +0,0 @@ -var phpcsPlugin = ActiveBuild.UiPlugin.extend({ - id: 'build-phpcs', - css: 'col-lg-6 col-md-12 col-sm-12 col-xs-12', - title: Lang.get('phpcs'), - lastData: null, - box: true, - rendered: false, - - register: function() { - var self = this; - var query = ActiveBuild.registerQuery('phpcs-data', -1, {key: 'phpcs-data'}) - - $(window).on('phpcs-data', function(data) { - self.onUpdate(data); - }); - - $(window).on('build-updated', function() { - if (!self.rendered) { - query(); - } - }); - }, - - render: function() { - return $('' + - '' + - '' + - ' ' + - ' ' + - ' ' + - '' + - '
    '+Lang.get('file')+''+Lang.get('line')+''+Lang.get('message')+'
    '); - }, - - onUpdate: function(e) { - if (!e.queryData) { - $('#build-phpcs').hide(); - return; - } - - this.rendered = true; - this.lastData = e.queryData; - - var errors = this.lastData[0].meta_value; - var tbody = $('#phpcs-data tbody'); - tbody.empty(); - - if (errors.length == 0) { - $('#build-phpcs').hide(); - return; - } - - for (var i in errors) { - var file = errors[i].file; - - if (ActiveBuild.fileLinkTemplate) { - var fileLink = ActiveBuild.fileLinkTemplate.replace('{FILE}', file); - fileLink = fileLink.replace('{LINE}', errors[i].line); - - file = '' + file + ''; - } - - var row = $('' + - ''+file+'' + - ''+errors[i].line+'' + - ''+errors[i].message+''); - - if (errors[i].type == 'ERROR') { - row.addClass('danger'); - } - - tbody.append(row); - } - - $('#build-phpcs').show(); - } -}); - -ActiveBuild.registerPlugin(new phpcsPlugin()); diff --git a/public/assets/js/build-plugins/phpdoccheck.js b/public/assets/js/build-plugins/phpdoccheck.js deleted file mode 100644 index 7d284617..00000000 --- a/public/assets/js/build-plugins/phpdoccheck.js +++ /dev/null @@ -1,85 +0,0 @@ -var phpdoccheckPlugin = ActiveBuild.UiPlugin.extend({ - id: 'build-phpdoccheck-warnings', - css: 'col-lg-6 col-md-12 col-sm-12 col-xs-12', - title: Lang.get('phpdoccheck'), - lastData: null, - displayOnUpdate: false, - box: true, - rendered: false, - - register: function() { - var self = this; - var query = ActiveBuild.registerQuery('phpdoccheck-data', -1, {key: 'phpdoccheck-data'}) - - $(window).on('phpdoccheck-data', function(data) { - self.onUpdate(data); - }); - - $(window).on('build-updated', function() { - if (!self.rendered) { - self.displayOnUpdate = true; - query(); - } - }); - }, - - render: function() { - return $('' + - '' + - '' + - ' ' + - ' ' + - ' ' + - ' ' + - '' + - '
    '+Lang.get('file')+''+Lang.get('line')+''+Lang.get('class')+''+Lang.get('method')+'
    '); - }, - - onUpdate: function(e) { - if (!e.queryData) { - $('#build-phpdoccheck-warnings').hide(); - return; - } - - this.rendered = true; - this.lastData = e.queryData; - - var errors = this.lastData[0].meta_value; - var tbody = $('#phpdoccheck-data tbody'); - tbody.empty(); - - if (errors.length == 0) { - $('#build-phpdoccheck-warnings').hide(); - return; - } - - for (var i in errors) { - var file = errors[i].file; - - if (ActiveBuild.fileLinkTemplate) { - var fileLink = ActiveBuild.fileLinkTemplate.replace('{FILE}', file); - fileLink = fileLink.replace('{LINE}', errors[i].line); - - file = '' + file + ''; - } - - var row = $('' + - ''+file+'' + - ''+errors[i].line+'' + - ''+errors[i].class+'' + - ''+(errors[i].method ? errors[i].method : '')+''); - - if (errors[i].type == 'method') { - row.addClass('danger'); - } else { - row.addClass('warning'); - } - - tbody.append(row); - } - - $('#build-phpdoccheck-warnings').show(); - } -}); - -ActiveBuild.registerPlugin(new phpdoccheckPlugin()); diff --git a/public/assets/js/build-plugins/phpmd.js b/public/assets/js/build-plugins/phpmd.js deleted file mode 100644 index 57723ba9..00000000 --- a/public/assets/js/build-plugins/phpmd.js +++ /dev/null @@ -1,80 +0,0 @@ -var phpmdPlugin = ActiveBuild.UiPlugin.extend({ - id: 'build-phpmd-warnings', - css: 'col-lg-6 col-md-12 col-sm-12 col-xs-12', - title: Lang.get('phpmd'), - lastData: null, - displayOnUpdate: false, - box: true, - rendered: false, - - register: function() { - var self = this; - var query = ActiveBuild.registerQuery('phpmd-data', -1, {key: 'phpmd-data'}) - - $(window).on('phpmd-data', function(data) { - self.onUpdate(data); - }); - - $(window).on('build-updated', function() { - if (!self.rendered) { - self.displayOnUpdate = true; - query(); - } - }); - }, - - render: function() { - - return $('' + - '' + - '' + - ' ' + - ' ' + - ' ' + - ' ' + - '' + - '
    '+Lang.get('file')+''+Lang.get('start')+''+Lang.get('end')+''+Lang.get('message')+'
    '); - }, - - onUpdate: function(e) { - if (!e.queryData) { - $('#build-phpmd-warnings').hide(); - return; - } - - this.rendered = true; - this.lastData = e.queryData; - - var errors = this.lastData[0].meta_value; - var tbody = $('#phpmd-data tbody'); - tbody.empty(); - - if (errors.length == 0) { - $('#build-phpmd-warnings').hide(); - return; - } - - for (var i in errors) { - var file = errors[i].file; - - if (ActiveBuild.fileLinkTemplate) { - var fileLink = ActiveBuild.fileLinkTemplate.replace('{FILE}', file); - fileLink = fileLink.replace('{LINE}', errors[i].line_start); - - file = '' + file + ''; - } - - var row = $('' + - ''+file+'' + - ''+errors[i].line_start+'' + - ''+errors[i].line_end+'' + - ''+errors[i].message+''); - - tbody.append(row); - } - - $('#build-phpmd-warnings').show(); - } -}); - -ActiveBuild.registerPlugin(new phpmdPlugin()); diff --git a/public/assets/js/build-plugins/phptallint.js b/public/assets/js/build-plugins/phptallint.js index 9d981c53..fe549b99 100644 --- a/public/assets/js/build-plugins/phptallint.js +++ b/public/assets/js/build-plugins/phptallint.js @@ -22,14 +22,14 @@ var phptalPlugin = ActiveBuild.UiPlugin.extend({ }, render: function() { - return $('' + + return $('
    ' + '' + '' + ' ' + ' ' + ' ' + '' + - '
    FileLineMessage
    '); + '
    '); }, onUpdate: function(e) { diff --git a/public/assets/js/build-plugins/phpunit.js b/public/assets/js/build-plugins/phpunit.js index 0e648e9d..71495603 100644 --- a/public/assets/js/build-plugins/phpunit.js +++ b/public/assets/js/build-plugins/phpunit.js @@ -6,6 +6,13 @@ var phpunitPlugin = ActiveBuild.UiPlugin.extend({ displayOnUpdate: false, box: true, rendered: false, + statusMap: { + success : 'ok', + fail: 'remove', + error: 'warning-sign', + todo: 'info-sign', + skipped: 'exclamation-sign' + }, register: function() { var self = this; @@ -21,16 +28,21 @@ var phpunitPlugin = ActiveBuild.UiPlugin.extend({ query(); } }); + + $(document).on('click', '#phpunit-data .test-toggle', function(ev) { + var input = $(ev.target); + $('#phpunit-data tbody ' + input.data('target')).toggle(input.prop('checked')); + }); }, render: function() { - return $('' + + return $('
    ' + '' + '' + - ' ' + + ' ' + '' + - '
    '+Lang.get('test')+''+Lang.get('test_message')+'
    '); + '
    '); }, onUpdate: function(e) { @@ -43,7 +55,9 @@ var phpunitPlugin = ActiveBuild.UiPlugin.extend({ this.lastData = e.queryData; var tests = this.lastData[0].meta_value; + var thead = $('#phpunit-data thead tr'); var tbody = $('#phpunit-data tbody'); + thead.empty().append(''+Lang.get('test_message')+''); tbody.empty(); if (tests.length == 0) { @@ -51,24 +65,82 @@ var phpunitPlugin = ActiveBuild.UiPlugin.extend({ return; } + var counts = { success: 0, fail: 0, error: 0, skipped: 0, todo: 0 }, total = 0; + for (var i in tests) { + var content = $(''), + message = $('
    ').appendTo(content), + severity = tests[i].severity || (tests[i].pass ? 'success' : 'failed'); - var row = $('' + - ''+tests[i].suite+'' + - '::'+tests[i].test+'
    ' + - ''+(tests[i].message || '')+'' + - ''); - - if (!tests[i].pass) { - row.addClass('danger'); + if (tests[i].message) { + message.text(tests[i].message); + } else if (tests[i].test && tests[i].suite) { + message.text(tests[i].suite + '::' + tests[i].test); } else { - row.addClass('success'); + message.html('' + Lang.get('test_no_message') + ''); } - tbody.append(row); + if (tests[i].data) { + content.append('
    ' + this.repr(tests[i].data) + '
    '); + } + + $('').append(content).appendTo(tbody); + + counts[severity]++; + total++; } + var checkboxes = $(''); + thead.append(checkboxes).append('' + Lang.get('test_total', total) + ''); + + for (var key in counts) { + var count = counts[key]; + if(count > 0) { + checkboxes.append( + '
     ' + + Lang.get('test_'+key, count)+ '
    ' + ); + } + } + + tbody.find('.success').hide(); + $('#build-phpunit-errors').show(); + }, + + repr: function(data) + { + switch(typeof(data)) { + case 'boolean': + return '' + (data ? 'true' : 'false') + ''; + case 'string': + return '"' + data + '"'; + case 'undefined': case null: + return 'null'; + case 'object': + var rows = []; + if(data instanceof Array) { + for(var i in data) { + rows.push('' + this.repr(data[i]) + ','); + } + } else { + for(var key in data) { + rows.push( + '' + + '' + this.repr(key) + '' + + '=>' + + '' + this.repr(data[key]) + ',' + + ''); + } + } + return '' + + '' + + rows.join('') + + '' + + '
    array(
    )
    '; + } + return '???'; } }); diff --git a/public/assets/js/build-plugins/summary.js b/public/assets/js/build-plugins/summary.js new file mode 100644 index 00000000..7ccea67b --- /dev/null +++ b/public/assets/js/build-plugins/summary.js @@ -0,0 +1,67 @@ +var SummaryPlugin = ActiveBuild.UiPlugin.extend({ + id: 'build-summary', + css: 'col-xs-12', + title: Lang.get('build-summary'), + box: true, + statusIcons: [ 'fa-clock-o', 'fa-cogs', 'fa-check', 'fa-remove' ], + statusLabels: [ Lang.get('pending'), Lang.get('running'), Lang.get('successful'), Lang.get('failed') ], + statusClasses: ['text-blue', 'text-yellow', 'text-green', 'text-red'], + + register: function() { + var self = this; + var query = ActiveBuild.registerQuery('plugin-summary', 5, {key: 'plugin-summary'}) + + $(window).on('plugin-summary', function(data) { + self.onUpdate(data); + }); + + $(window).on('build-updated', function() { + query(); + }); + }, + + render: function() { + return $( + '
    ' + + '' + + '' + + '' + + '' + + '' + + '
    '+Lang.get('stage')+''+Lang.get('plugin')+''+Lang.get('status')+''+Lang.get('duration')+' (s)
    ' + ); + }, + + onUpdate: function(e) { + if (!e.queryData) { + $('#build-summary').hide(); + return; + } + + var tbody = $('#plugin-summary tbody'), + summary = e.queryData[0].meta_value; + tbody.empty(); + + for(var stage in summary) { + for(var plugin in summary[stage]) { + var data = summary[stage][plugin], + duration = data.started ? ((data.ended || Math.floor(Date.now()/1000)) - data.started) : '-'; + tbody.append( + '' + + '' + Lang.get('stage_'+stage) + '' + + '' + plugin + '' + + '' + + ' ' + + this.statusLabels[data.status] + + '' + + '' + duration + '' + + '' + ); + } + } + + $('#build-summary').show(); + } +}); + +ActiveBuild.registerPlugin(new SummaryPlugin()); diff --git a/public/assets/js/build-plugins/time.js b/public/assets/js/build-plugins/time.js deleted file mode 100644 index de21b2f5..00000000 --- a/public/assets/js/build-plugins/time.js +++ /dev/null @@ -1,71 +0,0 @@ -var timePlugin = ActiveBuild.UiPlugin.extend({ - id: 'build-time', - css: 'col-lg-12 col-md-12 col-sm-12 col-xs-12', - title: null, - box: true, - - init: function(){ - this._super(); - }, - - render: function() { - var created = ''; - var started = ''; - var finished = ''; - - if (ActiveBuild.buildData.created) { - created = moment(ActiveBuild.buildData.created).format('ll LT'); - } - - if (ActiveBuild.buildData.started) { - started = moment(ActiveBuild.buildData.started).format('ll LT'); - } - - if (ActiveBuild.buildData.finished) { - finished = moment(ActiveBuild.buildData.finished).format('ll LT'); - } - - return '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '
    '+Lang.get('build_created')+''+Lang.get('build_started')+''+Lang.get('build_finished')+'
    ' + created + '' + started + '' + finished + '
    '; - }, - - onUpdate: function(e) { - var build = e.queryData; - - var created = ''; - var started = ''; - var finished = ''; - - if (build.created) { - created = moment(build.created).format('ll LT'); - } - - if (build.started) { - started = moment(build.started).format('ll LT'); - } - - if (build.finished) { - finished = moment(build.finished).format('ll LT'); - } - - $('#created').text(created); - $('#started').text(started); - $('#finished').text(finished); - } -}); - -ActiveBuild.registerPlugin(new timePlugin()); \ No newline at end of file diff --git a/public/assets/js/build-plugins/warnings.js b/public/assets/js/build-plugins/warnings.js index 3e8a5208..046fb9c6 100644 --- a/public/assets/js/build-plugins/warnings.js +++ b/public/assets/js/build-plugins/warnings.js @@ -1,20 +1,18 @@ var warningsPlugin = ActiveBuild.UiPlugin.extend({ id: 'build-warnings-chart', - css: 'col-lg-6 col-md-6 col-sm-12 col-xs-12', + css: 'col-xs-12', title: Lang.get('quality_trend'), keys: { - 'phpmd-warnings': Lang.get('phpmd_warnings'), - 'phpcs-warnings': Lang.get('phpcs_warnings'), - 'phpcs-errors': Lang.get('phpcs_errors'), + 'codeception-errors': Lang.get('codeception_errors'), 'phplint-errors': Lang.get('phplint_errors'), 'phpunit-errors': Lang.get('phpunit_errors'), - 'phpdoccheck-warnings': Lang.get('phpdoccheck'), 'phptallint-errors': Lang.get('phptal_errors'), 'phptallint-warnings': Lang.get('phptal_warnings') }, data: {}, displayOnUpdate: false, rendered: false, + chartData: null, register: function() { var self = this; @@ -24,7 +22,7 @@ var warningsPlugin = ActiveBuild.UiPlugin.extend({ queries.push(ActiveBuild.registerQuery(key, -1, {num_builds: 10, key: key})); } - $(window).on('phpmd-warnings phpcs-warnings phptallint-warnings phptallint-errors phpcs-errors phplint-errors phpunit-errors phpdoccheck-warnings', function(data) { + $(window).on('codeception-errors phptallint-warnings phptallint-errors phplint-errors phpunit-errors', function(data) { self.onUpdate(data); }); @@ -36,12 +34,19 @@ var warningsPlugin = ActiveBuild.UiPlugin.extend({ } } }); - - google.load("visualization", "1", {packages:["corechart"]}); }, render: function() { - return $('
    ').text(Lang.get('chart_display')); + var self = this; + var container = $('
    '); + container.append(''); + + $(document).on('shown.bs.tab', function () { + $('#build-warnings-chart').hide(); + self.drawChart(); + }); + + return container; }, onUpdate: function(e) { @@ -73,37 +78,52 @@ var warningsPlugin = ActiveBuild.UiPlugin.extend({ var self = this; self.rendered = true; - $('#build-warnings').empty().animate({height: '275px'}); + var colors = ['#4D4D4D', '#5DA5DA', '#FAA43A', '#60BD68', '#F17CB0', '#B2912F', '#B276B2', '#DECF3F', '#F15854']; - var titles = ['Build']; - for (var key in self.keys) { - titles.push(self.keys[key]); - } - - var data = [titles]; - for (var build in self.data) { - var thisBuild = ['#' + build]; - - for (var key in self.keys) { - thisBuild.push(parseInt(self.data[build][key])); - } - - data.push(thisBuild); - } - - var data = google.visualization.arrayToDataTable(data); - var options = { - hAxis: {title: Lang.get('builds')}, - vAxis: {title: Lang.get('issues'), logScale:true}, - backgroundColor: { fill: 'transparent' }, - height: 275, - pointSize: 3 + self.chartData = { + labels: [], + datasets: [] }; - $('#build-warnings-chart').show(); + for (var key in self.keys) { + var color = colors.shift(); - var chart = new google.visualization.LineChart(document.getElementById('build-warnings')); - chart.draw(data, options); + self.chartData.datasets.push({ + label: self.keys[key], + strokeColor: color, + pointColor: color, + data: [] + }); + } + + for (var build in self.data) { + self.chartData.labels.push('Build ' + build); + + var i = 0; + for (var key in self.keys) { + + self.chartData.datasets[i].data.push(parseInt(self.data[build][key])); + i++; + } + } + + self.drawChart(); + }, + + drawChart: function () { + var self = this; + + if ($('#information').hasClass('active') && self.chartData) { + $('#build-warnings-chart').show(); + + var ctx = $("#build-warnings-linechart").get(0).getContext("2d"); + var buildWarningsChart = new Chart(ctx); + + buildWarningsChart.Line(self.chartData, { + datasetFill: false, + multiTooltipTemplate: "<%=datasetLabel%>: <%= value %>" + }); + } } }); diff --git a/public/assets/js/build.js b/public/assets/js/build.js index 0b1d95dc..4b9c10a1 100644 --- a/public/assets/js/build.js +++ b/public/assets/js/build.js @@ -8,17 +8,63 @@ var Build = Class.extend({ init: function(build) { var self = this; - this.buildId = build; - this.registerQuery('build-updated', 10); + self.buildId = build; + }, + + setupBuild: function (buildData, linkTemplate) { + var self = this; + self.buildData = buildData; + self.fileLinkTemplate = linkTemplate; + + self.registerQuery('build-updated', 10); $(window).on('build-updated', function(data) { + self.buildData = data.queryData; + // If the build has finished, stop updating every 10 seconds: - if (data.queryData.status > 1) { + if (self.buildData.status > 1) { self.cancelQuery('build-updated'); $(window).trigger({type: 'build-complete'}); } + $('.build-duration').data('duration', self.buildData.duration ? self.buildData.duration : ''); + $('.build-started').data('date', self.buildData.started ? self.buildData.started : ''); + $('.build-finished').data('date', self.buildData.finished ? self.buildData.finished : ''); + $('#log pre').html(self.buildData.log); + $('.errors-table tbody').append(self.buildData.error_html); + + if (self.buildData.errors == 0) { + $('.errors-label').hide(); + } else { + $('.errors-label').text(self.buildData.errors); + $('.errors-label').show(); + } + + switch (self.buildData.status) { + case 0: + $('body').removeClass('skin-red skin-green skin-yellow'); + $('body').addClass('skin-blue'); + break; + + case 1: + $('body').removeClass('skin-red skin-green skin-blue'); + $('body').addClass('skin-yellow'); + break; + + case 2: + $('body').removeClass('skin-red skin-blue skin-yellow'); + $('body').addClass('skin-green'); + break; + + case 3: + $('body').removeClass('skin-blue skin-green skin-yellow'); + $('body').addClass('skin-red'); + break; + + } + + PHPCI.uiUpdated(); }); }, @@ -27,14 +73,16 @@ var Build = Class.extend({ var uri = 'build/meta/' + self.buildId; var query = query || {}; - if (name == 'build-updated') { - uri = 'build/data/' + self.buildId; - } - var cb = function() { + var fullUri = window.PHPCI_URL + uri; + + if (name == 'build-updated') { + fullUri = window.PHPCI_URL + 'build/data/' + self.buildId + '?since=' + self.buildData.since; + } + $.ajax({ dataType: "json", - url: window.PHPCI_URL + uri, + url: fullUri, data: query, success: function(data) { $(window).trigger({type: name, queryData: data}); @@ -77,11 +125,17 @@ var Build = Class.extend({ if (renderOrder) { renderOrder = JSON.parse(renderOrder); } else { - renderOrder = ['build-time', 'build-lines-chart', 'build-warnings-chart', 'build-log']; + renderOrder = ['build-lines-chart', 'build-warnings-chart']; } for (var idx in renderOrder) { var key = renderOrder[idx]; + + // Plugins have changed, clear the order. + if (typeof self.plugins[key] == 'undefined') { + localStorage.setItem('phpci-plugin-order', []); + } + self.renderPlugin(self.plugins[key]); rendered.push(key); } @@ -108,8 +162,8 @@ var Build = Class.extend({ output = $('
    ').append(output); } - var container = $('
    ').addClass('ui-plugin ' + plugin.css); - var content = $('
    ').attr('id', plugin.id).append(output); + var container = $('
    ').addClass('ui-plugin ' + plugin.css).attr('id', plugin.id); + var content = $('
    ').append(output); content.addClass('box box-default'); if (plugin.title) { @@ -145,4 +199,4 @@ var Build = Class.extend({ } }) -}); \ No newline at end of file +}); diff --git a/public/assets/js/phpci.js b/public/assets/js/phpci.js index f98ea959..4a55b459 100644 --- a/public/assets/js/phpci.js +++ b/public/assets/js/phpci.js @@ -3,7 +3,17 @@ var PHPCI = { intervals: {}, init: function () { + // Setup the date locale + moment.locale(PHPCI_LANGUAGE); + $(document).ready(function () { + // Format datetimes + $('time[datetime]').each(function() { + var thisDate = $(this).attr('datetime'); + var formattedDate = moment(thisDate).format($(this).data('format') || 'lll'); + $(this).text(formattedDate); + }); + // Update latest builds every 5 seconds: PHPCI.getBuilds(); PHPCI.intervals.getBuilds = setInterval(PHPCI.getBuilds, 5000); @@ -12,6 +22,8 @@ var PHPCI = { if (typeof PHPCI_PROJECT_ID != 'undefined') { PHPCI.intervals.getProjectBuilds = setInterval(PHPCI.getProjectBuilds, 10000); } + + PHPCI.uiUpdated(); }); $(window).on('builds-updated', function (e, data) { @@ -24,7 +36,7 @@ var PHPCI = { url: PHPCI_URL + 'build/latest', success: function (data) { - $(window).trigger('builds-updated', [JSON.parse(data)]); + $(window).trigger('builds-updated', [data]); }, error: PHPCI.handleFailedAjax @@ -69,16 +81,55 @@ var PHPCI = { }); } + }, + + get: function (uri, success) { + + $.ajax({ + url: window.PHPCI_URL + uri, + + success: function (data) { + success(); + PHPCI.uiUpdated(); + }, + + error: PHPCI.handleFailedAjax + }); + }, + + handleFailedAjax: function (xhr) { + if (xhr.status == 401) { + window.location.href = window.PHPCI_URL + 'session/login'; + } + }, + + uiUpdated: function () { + $('.duration').each(function () { + var seconds = $(this).data('duration'); + + if (seconds == 0) { + return; + } + + $(this).text(moment.duration(seconds, 'seconds').humanize()); + }); + + $('.datetime').each(function () { + var dateString = $(this).data('date'); + + if (!dateString) { + return; + } + + $(this).text(moment(dateString).format('lll')); + }); } }; PHPCI.init(); -function handleFailedAjax(xhr) -{ - if (xhr.status == 401) { - window.location.href = window.PHPCI_URL + 'session/login'; - } +function handleFailedAjax(xhr) { + PHPCI.handleFailedAjax(xhr); } /** diff --git a/public/assets/js/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js b/public/assets/js/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js deleted file mode 100755 index 7d6426c5..00000000 --- a/public/assets/js/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/*! bootstrap3-wysihtml5-bower 2013-11-22 */ -var wysihtml5={version:"0.3.0",commands:{},dom:{},quirks:{},toolbar:{},lang:{},selection:{},views:{},INVISIBLE_SPACE:"",EMPTY_FUNCTION:function(){},ELEMENT_NODE:1,TEXT_NODE:3,BACKSPACE_KEY:8,ENTER_KEY:13,ESCAPE_KEY:27,SPACE_KEY:32,DELETE_KEY:46};window.rangy=function(){function a(a,b){var c=typeof a[b];return c==j||!(c!=i||!a[b])||"unknown"==c}function b(a,b){return!(typeof a[b]!=i||!a[b])}function c(a,b){return typeof a[b]!=k}function d(a){return function(b,c){for(var d=c.length;d--;)if(!a(b,c[d]))return!1;return!0}}function e(a){return a&&p(a,o)&&r(a,n)}function f(a){window.alert("Rangy not supported in your browser. Reason: "+a),s.initialized=!0,s.supported=!1}function g(){if(!s.initialized){var c,d=!1,g=!1;for(a(document,"createRange")&&(c=document.createRange(),p(c,m)&&r(c,l)&&(d=!0),c.detach()),(c=b(document,"body")?document.body:document.getElementsByTagName("body")[0])&&a(c,"createTextRange")&&(c=c.createTextRange(),e(c)&&(g=!0)),!d&&!g&&f("Neither Range nor TextRange are implemented"),s.initialized=!0,s.features={implementsDomRange:d,implementsTextRange:g},d=u.concat(t),g=0,c=d.length;c>g;++g)try{d[g](s)}catch(h){b(window,"console")&&a(window.console,"log")&&window.console.log("Init listener threw an exception. Continuing.",h)}}}function h(a){this.name=a,this.supported=this.initialized=!1}var i="object",j="function",k="undefined",l="startContainer startOffset endContainer endOffset collapsed commonAncestorContainer START_TO_START START_TO_END END_TO_START END_TO_END".split(" "),m="setStart setStartBefore setStartAfter setEnd setEndBefore setEndAfter collapse selectNode selectNodeContents compareBoundaryPoints deleteContents extractContents cloneContents insertNode surroundContents cloneRange toString detach".split(" "),n="boundingHeight boundingLeft boundingTop boundingWidth htmlText text".split(" "),o="collapse compareEndPoints duplicate getBookmark moveToBookmark moveToElementText parentElement pasteHTML select setEndPoint getBoundingClientRect".split(" "),p=d(a),q=d(b),r=d(c),s={version:"1.2.2",initialized:!1,supported:!0,util:{isHostMethod:a,isHostObject:b,isHostProperty:c,areHostMethods:p,areHostObjects:q,areHostProperties:r,isTextRange:e},features:{},modules:{},config:{alertOnWarn:!1,preferTextRange:!1}};s.fail=f,s.warn=function(a){a="Rangy warning: "+a,s.config.alertOnWarn?window.alert(a):typeof window.console!=k&&typeof window.console.log!=k&&window.console.log(a)},{}.hasOwnProperty?s.util.extend=function(a,b){for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c])}:f("hasOwnProperty not supported");var t=[],u=[];s.init=g,s.addInitListener=function(a){s.initialized?a(s):t.push(a)};var v=[];s.addCreateMissingNativeApiListener=function(a){v.push(a)},s.createMissingNativeApi=function(a){a=a||window,g();for(var b=0,c=v.length;c>b;++b)v[b](a)},h.prototype.fail=function(a){throw this.initialized=!0,this.supported=!1,Error("Module '"+this.name+"' failed to load: "+a)},h.prototype.warn=function(a){s.warn("Module "+this.name+": "+a)},h.prototype.createError=function(a){return Error("Error in Rangy "+this.name+" module: "+a)},s.createModule=function(a,b){var c=new h(a);s.modules[a]=c,u.push(function(a){b(a,c),c.initialized=!0,c.supported=!0})},s.requireModules=function(a){for(var b,c,d=0,e=a.length;e>d;++d){if(c=a[d],b=s.modules[c],!(b&&b instanceof h))throw Error("Module '"+c+"' not found");if(!b.supported)throw Error("Module '"+c+"' not supported")}};var w=!1,q=function(){w||(w=!0,s.initialized||g())};if(typeof window==k)f("No window found");else{if(typeof document!=k)return a(document,"addEventListener")&&document.addEventListener("DOMContentLoaded",q,!1),a(window,"addEventListener")?window.addEventListener("load",q,!1):a(window,"attachEvent")?window.attachEvent("onload",q):f("Window does not have required addEventListener or attachEvent method"),s;f("No document found")}}(),rangy.createModule("DomUtil",function(a,b){function c(a){for(var b=0;a=a.previousSibling;)b++;return b}function d(a,b){var c,d=[];for(c=a;c;c=c.parentNode)d.push(c);for(c=b;c;c=c.parentNode)if(p(d,c))return c;return null}function e(a,b,c){for(c=c?a:a.parentNode;c;){if(a=c.parentNode,a===b)return c;c=a}return null}function f(a){return a=a.nodeType,3==a||4==a||8==a}function g(a,b){var c=b.nextSibling,d=b.parentNode;return c?d.insertBefore(a,c):d.appendChild(a),a}function h(a){if(9==a.nodeType)return a;if(typeof a.ownerDocument!=m)return a.ownerDocument;if(typeof a.document!=m)return a.document;if(a.parentNode)return h(a.parentNode);throw Error("getDocument: no document found for node")}function i(a){return a?f(a)?'"'+a.data+'"':1==a.nodeType?"<"+a.nodeName+(a.id?' id="'+a.id+'"':"")+">["+a.childNodes.length+"]":a.nodeName:"[No node]"}function j(a){this._next=this.root=a}function k(a,b){this.node=a,this.offset=b}function l(a){this.code=this[a],this.codeName=a,this.message="DOMException: "+this.codeName}var m="undefined",n=a.util;n.areHostMethods(document,["createDocumentFragment","createElement","createTextNode"])||b.fail("document missing a Node creation method"),n.isHostMethod(document,"getElementsByTagName")||b.fail("document missing getElementsByTagName method");var o=document.createElement("div");n.areHostMethods(o,["insertBefore","appendChild","cloneNode"])||b.fail("Incomplete Element implementation"),n.isHostProperty(o,"innerHTML")||b.fail("Element is missing innerHTML property"),o=document.createTextNode("test"),n.areHostMethods(o,["splitText","deleteData","insertData","appendData","cloneNode"])||b.fail("Incomplete Text Node implementation");var p=function(a,b){for(var c=a.length;c--;)if(a[c]===b)return!0;return!1};j.prototype={_current:null,hasNext:function(){return!!this._next},next:function(){var a,b=this._current=this._next;if(this._current){if(a=b.firstChild,!a)for(a=null;b!==this.root&&!(a=b.nextSibling);)b=b.parentNode;this._next=a}return this._current},detach:function(){this._current=this._next=this.root=null}},k.prototype={equals:function(a){return this.node===a.node&this.offset==a.offset},inspect:function(){return"[DomPosition("+i(this.node)+":"+this.offset+")]"}},l.prototype={INDEX_SIZE_ERR:1,HIERARCHY_REQUEST_ERR:3,WRONG_DOCUMENT_ERR:4,NO_MODIFICATION_ALLOWED_ERR:7,NOT_FOUND_ERR:8,NOT_SUPPORTED_ERR:9,INVALID_STATE_ERR:11},l.prototype.toString=function(){return this.message},a.dom={arrayContains:p,isHtmlNamespace:function(a){var b;return typeof a.namespaceURI==m||null===(b=a.namespaceURI)||"http://www.w3.org/1999/xhtml"==b},parentElement:function(a){return a=a.parentNode,1==a.nodeType?a:null},getNodeIndex:c,getNodeLength:function(a){var b;return f(a)?a.length:(b=a.childNodes)?b.length:0},getCommonAncestor:d,isAncestorOf:function(a,b,c){for(b=c?b:b.parentNode;b;){if(b===a)return!0;b=b.parentNode}return!1},getClosestAncestorIn:e,isCharacterDataNode:f,insertAfter:g,splitDataNode:function(a,b){var c=a.cloneNode(!1);return c.deleteData(0,b),a.deleteData(b,a.length-b),g(c,a),c},getDocument:h,getWindow:function(a){if(a=h(a),typeof a.defaultView!=m)return a.defaultView;if(typeof a.parentWindow!=m)return a.parentWindow;throw Error("Cannot get a window object for node")},getIframeWindow:function(a){if(typeof a.contentWindow!=m)return a.contentWindow;if(typeof a.contentDocument!=m)return a.contentDocument.defaultView;throw Error("getIframeWindow: No Window object found for iframe element")},getIframeDocument:function(a){if(typeof a.contentDocument!=m)return a.contentDocument;if(typeof a.contentWindow!=m)return a.contentWindow.document;throw Error("getIframeWindow: No Document object found for iframe element")},getBody:function(a){return n.isHostObject(a,"body")?a.body:a.getElementsByTagName("body")[0]},getRootContainer:function(a){for(var b;b=a.parentNode;)a=b;return a},comparePoints:function(a,b,f,g){var h;if(a==f)return b===g?0:g>b?-1:1;if(h=e(f,a,!0))return b<=c(h)?-1:1;if(h=e(a,f,!0))return c(h)d;++d)b[d].call(a,{target:a,args:c})}function e(a){return new I(a.parentNode,H.getNodeIndex(a))}function f(a){return new I(a.parentNode,H.getNodeIndex(a)+1)}function g(a,b,c){var d=11==a.nodeType?a.firstChild:a;return H.isCharacterDataNode(b)?c==b.length?H.insertAfter(a,b):b.parentNode.insertBefore(a,0==c?b:H.splitDataNode(b,c)):c>=b.childNodes.length?b.appendChild(a):b.insertBefore(a,b.childNodes[c]),d}function h(a){for(var b,d,e=c(a.range).createDocumentFragment();d=a.next();){if(b=a.isPartiallySelectedSubtree(),d=d.cloneNode(!b),b&&(b=a.getSubtreeIterator(),d.appendChild(h(b)),b.detach(!0)),10==d.nodeType)throw new J("HIERARCHY_REQUEST_ERR");e.appendChild(d)}return e}function i(a,b,c){for(var d,e,c=c||{stop:!1};d=a.next();)if(a.isPartiallySelectedSubtree()){if(!1===b(d)){c.stop=!0;break}if(d=a.getSubtreeIterator(),i(d,b,c),d.detach(!0),c.stop)break}else for(d=H.createIterator(d);e=d.next();)if(!1===b(e))return c.stop=!0,void 0}function j(a){for(var b;a.next();)a.isPartiallySelectedSubtree()?(b=a.getSubtreeIterator(),j(b),b.detach(!0)):a.remove()}function k(a){for(var b,d,e=c(a.range).createDocumentFragment();b=a.next();){if(a.isPartiallySelectedSubtree()?(b=b.cloneNode(!1),d=a.getSubtreeIterator(),b.appendChild(k(d)),d.detach(!0)):a.remove(),10==b.nodeType)throw new J("HIERARCHY_REQUEST_ERR");e.appendChild(b)}return e}function l(a,b,c){var d,e=!(!b||!b.length),f=!!c;e&&(d=RegExp("^("+b.join("|")+")$"));var g=[];return i(new n(a,!1),function(a){(!e||d.test(a.nodeType))&&(!f||c(a))&&g.push(a)}),g}function m(a){return"["+("undefined"==typeof a.getName?"Range":a.getName())+"("+H.inspectNode(a.startContainer)+":"+a.startOffset+", "+H.inspectNode(a.endContainer)+":"+a.endOffset+")]"}function n(a,b){if(this.range=a,this.clonePartiallySelectedTextNodes=b,!a.collapsed){this.sc=a.startContainer,this.so=a.startOffset,this.ec=a.endContainer,this.eo=a.endOffset;var c=a.commonAncestorContainer;this.sc===this.ec&&H.isCharacterDataNode(this.sc)?(this.isSingleCharacterDataNode=!0,this._first=this._last=this._next=this.sc):(this._first=this._next=this.sc!==c||H.isCharacterDataNode(this.sc)?H.getClosestAncestorIn(this.sc,c,!0):this.sc.childNodes[this.so],this._last=this.ec!==c||H.isCharacterDataNode(this.ec)?H.getClosestAncestorIn(this.ec,c,!0):this.ec.childNodes[this.eo-1])}}function o(a){this.code=this[a],this.codeName=a,this.message="RangeException: "+this.codeName}function p(a,b,c){this.nodes=l(a,b,c),this._next=this.nodes[0],this._position=0}function q(a){return function(b,c){for(var d,e=c?b:b.parentNode;e;){if(d=e.nodeType,H.arrayContains(a,d))return e;e=e.parentNode}return null}}function r(a,b){if(R(a,b))throw new o("INVALID_NODE_TYPE_ERR")}function s(a){if(!a.startContainer)throw new J("INVALID_STATE_ERR")}function t(a,b){if(!H.arrayContains(b,a.nodeType))throw new o("INVALID_NODE_TYPE_ERR")}function u(a,b){if(0>b||b>(H.isCharacterDataNode(a)?a.length:a.childNodes.length))throw new J("INDEX_SIZE_ERR")}function v(a,b){if(P(a,!0)!==P(b,!0))throw new J("WRONG_DOCUMENT_ERR")}function w(a){if(Q(a,!0))throw new J("NO_MODIFICATION_ALLOWED_ERR")}function x(a,b){if(!a)throw new J(b)}function y(a){if(s(a),!((H.arrayContains(L,a.startContainer.nodeType)||P(a.startContainer,!0))&&(H.arrayContains(L,a.endContainer.nodeType)||P(a.endContainer,!0))&&a.startOffset<=(H.isCharacterDataNode(a.startContainer)?a.startContainer.length:a.startContainer.childNodes.length)&&a.endOffset<=(H.isCharacterDataNode(a.endContainer)?a.endContainer.length:a.endContainer.childNodes.length)))throw Error("Range error: Range is no longer valid after DOM mutation ("+a.inspect()+")")}function z(){}function A(a){a.START_TO_START=W,a.START_TO_END=X,a.END_TO_END=Y,a.END_TO_START=Z,a.NODE_BEFORE=$,a.NODE_AFTER=_,a.NODE_BEFORE_AND_AFTER=ab,a.NODE_INSIDE=bb}function B(a){A(a),A(a.prototype)}function C(a,b){return function(){y(this);var c=this.startContainer,d=this.startOffset,e=this.commonAncestorContainer,g=new n(this,!0);return c!==e&&(c=H.getClosestAncestorIn(c,e,!0),d=f(c),c=d.node,d=d.offset),i(g,w),g.reset(),e=a(g),g.detach(),b(this,c,d,c,d),e}}function D(c,d,g){function h(a,b){return function(c){s(this),t(c,K),t(O(c),L),c=(a?e:f)(c),(b?i:l)(this,c.node,c.offset)}}function i(a,b,c){var e=a.endContainer,f=a.endOffset;(b!==a.startContainer||c!==a.startOffset)&&((O(b)!=O(e)||1==H.comparePoints(b,c,e,f))&&(e=b,f=c),d(a,b,c,e,f))}function l(a,b,c){var e=a.startContainer,f=a.startOffset;(b!==a.endContainer||c!==a.endOffset)&&((O(b)!=O(e)||-1==H.comparePoints(b,c,e,f))&&(e=b,f=c),d(a,e,f,b,c))}c.prototype=new z,a.util.extend(c.prototype,{setStart:function(a,b){s(this),r(a,!0),u(a,b),i(this,a,b)},setEnd:function(a,b){s(this),r(a,!0),u(a,b),l(this,a,b)},setStartBefore:h(!0,!0),setStartAfter:h(!1,!0),setEndBefore:h(!0,!1),setEndAfter:h(!1,!1),collapse:function(a){y(this),a?d(this,this.startContainer,this.startOffset,this.startContainer,this.startOffset):d(this,this.endContainer,this.endOffset,this.endContainer,this.endOffset)},selectNodeContents:function(a){s(this),r(a,!0),d(this,a,0,a,H.getNodeLength(a))},selectNode:function(a){s(this),r(a,!1),t(a,K);var b=e(a),a=f(a);d(this,b.node,b.offset,a.node,a.offset)},extractContents:C(k,d),deleteContents:C(j,d),canSurroundContents:function(){y(this),w(this.startContainer),w(this.endContainer);var a=new n(this,!0),c=a._first&&b(a._first,this)||a._last&&b(a._last,this);return a.detach(),!c},detach:function(){g(this)},splitBoundaries:function(){y(this);var a=this.startContainer,b=this.startOffset,c=this.endContainer,e=this.endOffset,f=a===c;H.isCharacterDataNode(c)&&e>0&&e0&&b=H.getNodeIndex(a)&&e++,b=0),d(this,a,b,c,e)},normalizeBoundaries:function(){y(this);var a=this.startContainer,b=this.startOffset,c=this.endContainer,e=this.endOffset,f=function(a){var b=a.nextSibling;b&&b.nodeType==a.nodeType&&(c=a,e=a.length,a.appendData(b.data),b.parentNode.removeChild(b))},g=function(d){var f=d.previousSibling;if(f&&f.nodeType==d.nodeType){a=d;var g=d.length;b=f.length,d.insertData(0,f.data),f.parentNode.removeChild(f),a==c?(e+=b,c=a):c==d.parentNode&&(f=H.getNodeIndex(d),e==f?(c=d,e=g):e>f&&e--)}},h=!0;H.isCharacterDataNode(c)?c.length==e&&f(c):(e>0&&(h=c.childNodes[e-1])&&H.isCharacterDataNode(h)&&f(h),h=!this.collapsed),h?H.isCharacterDataNode(a)?0==b&&g(a):bx",T=3==S.firstChild.nodeType}catch(U){}a.features.htmlParsingConforms=T;var V="startContainer startOffset endContainer endOffset collapsed commonAncestorContainer".split(" "),W=0,X=1,Y=2,Z=3,$=0,_=1,ab=2,bb=3;z.prototype={attachListener:function(a,b){this._listeners[a].push(b)},compareBoundaryPoints:function(a,b){y(this),v(this.startContainer,b.startContainer);var c=a==Z||a==W?"start":"end",d=a==X||a==W?"start":"end";return H.comparePoints(this[c+"Container"],this[c+"Offset"],b[d+"Container"],b[d+"Offset"])},insertNode:function(a){if(y(this),t(a,M),w(this.startContainer),H.isAncestorOf(a,this.startContainer,!0))throw new J("HIERARCHY_REQUEST_ERR");this.setStartBefore(g(a,this.startContainer,this.startOffset))},cloneContents:function(){y(this);var a,b;return this.collapsed?c(this).createDocumentFragment():this.startContainer===this.endContainer&&H.isCharacterDataNode(this.startContainer)?(a=this.startContainer.cloneNode(!0),a.data=a.data.slice(this.startOffset,this.endOffset),b=c(this).createDocumentFragment(),b.appendChild(a),b):(b=new n(this,!0),a=h(b),b.detach(),a)},canSurroundContents:function(){y(this),w(this.startContainer),w(this.endContainer);var a=new n(this,!0),c=a._first&&b(a._first,this)||a._last&&b(a._last,this);return a.detach(),!c},surroundContents:function(a){if(t(a,N),!this.canSurroundContents())throw new o("BAD_BOUNDARYPOINTS_ERR");var b=this.extractContents();if(a.hasChildNodes())for(;a.lastChild;)a.removeChild(a.lastChild);g(a,this.startContainer,this.startOffset),a.appendChild(b),this.selectNode(a)},cloneRange:function(){y(this);for(var a,b=new G(c(this)),d=V.length;d--;)a=V[d],b[a]=this[a];return b},toString:function(){y(this);var a=this.startContainer;if(a===this.endContainer&&H.isCharacterDataNode(a))return 3==a.nodeType||4==a.nodeType?a.data.slice(this.startOffset,this.endOffset):"";var b=[],a=new n(this,!0);return i(a,function(a){(3==a.nodeType||4==a.nodeType)&&b.push(a.data)}),a.detach(),b.join("")},compareNode:function(a){y(this);var b=a.parentNode,c=H.getNodeIndex(a);if(!b)throw new J("NOT_FOUND_ERR");return a=this.comparePoint(b,c),b=this.comparePoint(b,c+1),0>a?b>0?ab:$:b>0?_:bb},comparePoint:function(a,b){return y(this),x(a,"HIERARCHY_REQUEST_ERR"),v(a,this.startContainer),0>H.comparePoints(a,b,this.startContainer,this.startOffset)?-1:0=f&&d>=0:0>f&&d>0},isPointInRange:function(a,b){return y(this),x(a,"HIERARCHY_REQUEST_ERR"),v(a,this.startContainer),0<=H.comparePoints(a,b,this.startContainer,this.startOffset)&&0>=H.comparePoints(a,b,this.endContainer,this.endOffset)},intersectsRange:function(a,b){if(y(this),c(a)!=c(this))throw new J("WRONG_DOCUMENT_ERR");var d=H.comparePoints(this.startContainer,this.startOffset,a.endContainer,a.endOffset),e=H.comparePoints(this.endContainer,this.endOffset,a.startContainer,a.startOffset);return b?0>=d&&e>=0:0>d&&e>0},intersection:function(a){if(this.intersectsRange(a)){var b=H.comparePoints(this.startContainer,this.startOffset,a.startContainer,a.startOffset),c=H.comparePoints(this.endContainer,this.endOffset,a.endContainer,a.endOffset),d=this.cloneRange();return-1==b&&d.setStart(a.startContainer,a.startOffset),1==c&&d.setEnd(a.endContainer,a.endOffset),d}return null},union:function(a){if(this.intersectsRange(a,!0)){var b=this.cloneRange();return-1==H.comparePoints(a.startContainer,a.startOffset,this.startContainer,this.startOffset)&&b.setStart(a.startContainer,a.startOffset),1==H.comparePoints(a.endContainer,a.endOffset,this.endContainer,this.endOffset)&&b.setEnd(a.endContainer,a.endOffset),b}throw new o("Ranges do not intersect")},containsNode:function(a,b){return b?this.intersectsNode(a,!1):this.compareNode(a)==bb},containsNodeContents:function(a){return 0<=this.comparePoint(a,0)&&0>=this.comparePoint(a,H.getNodeLength(a))},containsRange:function(a){return this.intersection(a).equals(a)},containsNodeText:function(a){var b=this.cloneRange();b.selectNode(a);var c=b.getNodes([3]);return 0b;++b)if(!r.isAncestorOf(c[0],c[b])){b=!1;break a}b=!0}else b=!1;if(!b)throw Error("getSingleElementFromRange: range "+a.inspect()+" did not consist of a single element");return c[0]}function i(a,b){var c=new u(b);a._ranges=[c],e(a,c,!1),a.rangeCount=1,a.isCollapsed=c.collapsed}function j(b){if(b._ranges.length=0,"None"==b.docSelection.type)f(b);else{var c=b.docSelection.createRange();if(c&&"undefined"!=typeof c.text)i(b,c);else{b.rangeCount=c.length;for(var d,g=r.getDocument(c.item(0)),h=0;hf;++f)e.add(c.item(f));try{e.add(d)}catch(i){throw Error("addRange(): Element within the specified Range could not be added to control selection (does it have layout?)")}e.select(),j(a)}function l(a,b,c){this.nativeSelection=a,this.docSelection=b,this._ranges=[],this.win=c,this.refresh()}function m(a,b){for(var c,d=r.getDocument(b[0].startContainer),d=r.getBody(d).createControlRange(),e=0;rangeCount>e;++e){c=h(b[e]); -try{d.add(c)}catch(f){throw Error("setRanges(): Element within the one of the specified Ranges could not be added to control selection (does it have layout?)")}}d.select(),j(a)}function n(a,b){if(a.anchorNode&&r.getDocument(a.anchorNode)!==r.getDocument(b))throw new v("WRONG_DOCUMENT_ERR")}function o(a){var b=[],c=new w(a.anchorNode,a.anchorOffset),d=new w(a.focusNode,a.focusOffset),e="function"==typeof a.getName?a.getName():"Selection";if("undefined"!=typeof a.rangeCount)for(var f=0,g=a.rangeCount;g>f;++f)b[f]=t.inspect(a.getRangeAt(f));return"["+e+"(Ranges: "+b.join(", ")+")(anchor: "+c.inspect()+", focus: "+d.inspect()+"]"}a.requireModules(["DomUtil","DomRange","WrappedRange"]),a.config.checkSelectionRanges=!0;var p,q,r=a.dom,s=a.util,t=a.DomRange,u=a.WrappedRange,v=a.DOMException,w=r.DomPosition,x=a.util.isHostMethod(window,"getSelection"),y=a.util.isHostObject(document,"selection"),z=y&&(!x||a.config.preferTextRange);z?(p=d,a.isSelectionValid=function(a){var a=(a||window).document,b=a.selection;return"None"!=b.type||r.getDocument(b.createRange().parentElement())==a}):x?(p=c,a.isSelectionValid=function(){return!0}):b.fail("Neither document.selection or window.getSelection() detected."),a.getNativeSelection=p;var x=p(),A=a.createNativeRange(document),B=r.getBody(document),C=s.areHostObjects(x,s.areHostProperties(x,["anchorOffset","focusOffset"]));a.features.selectionHasAnchorAndFocus=C;var D=s.isHostMethod(x,"extend");a.features.selectionHasExtend=D;var E="number"==typeof x.rangeCount;a.features.selectionHasRangeCount=E;var F=!1,G=!0;s.areHostMethods(x,["addRange","getRangeAt","removeAllRanges"])&&"number"==typeof x.rangeCount&&a.features.implementsDomRange&&function(){var a=document.createElement("iframe");B.appendChild(a);var b=r.getIframeDocument(a);b.open(),b.write("12"),b.close();var c=r.getIframeWindow(a).getSelection(),d=b.documentElement.lastChild.firstChild,b=b.createRange();b.setStart(d,1),b.collapse(!0),c.addRange(b),G=1==c.rangeCount,c.removeAllRanges();var e=b.cloneRange();b.setStart(d,0),e.setEnd(d,2),c.addRange(b),c.addRange(e),F=2==c.rangeCount,b.detach(),e.detach(),B.removeChild(a)}(),a.features.selectionSupportsMultipleRanges=F,a.features.collapsedNonEditableSelectionsSupported=G;var H,I=!1;B&&s.isHostMethod(B,"createControlRange")&&(H=B.createControlRange(),s.areHostProperties(H,["item","add"])&&(I=!0)),a.features.implementsControlRange=I,q=C?function(a){return a.anchorNode===a.focusNode&&a.anchorOffset===a.focusOffset}:function(a){return a.rangeCount?a.getRangeAt(a.rangeCount-1).collapsed:!1};var J;if(s.isHostMethod(x,"getRangeAt")?J=function(a,b){try{return a.getRangeAt(b)}catch(c){return null}}:C&&(J=function(b){var c=r.getDocument(b.anchorNode),c=a.createRange(c);return c.setStart(b.anchorNode,b.anchorOffset),c.setEnd(b.focusNode,b.focusOffset),c.collapsed!==this.isCollapsed&&(c.setStart(b.focusNode,b.focusOffset),c.setEnd(b.anchorNode,b.anchorOffset)),c}),a.getSelection=function(a){var a=a||window,b=a._rangySelection,c=p(a),e=y?d(a):null;return b?(b.nativeSelection=c,b.docSelection=e,b.refresh(a)):(b=new l(c,e,a),a._rangySelection=b),b},a.getIframeSelection=function(b){return a.getSelection(r.getIframeWindow(b))},H=l.prototype,!z&&C&&s.areHostMethods(x,["removeAllRanges","addRange"])){H.removeAllRanges=function(){this.nativeSelection.removeAllRanges(),f(this)};var K=function(b,c){var d=t.getRangeDocument(c),d=a.createRange(d);d.collapseToPoint(c.endContainer,c.endOffset),b.nativeSelection.addRange(g(d)),b.nativeSelection.extend(c.startContainer,c.startOffset),b.refresh()};H.addRange=E?function(b,c){if(I&&y&&"Control"==this.docSelection.type)k(this,b);else if(c&&D)K(this,b);else{var d;F?d=this.rangeCount:(this.removeAllRanges(),d=0),this.nativeSelection.addRange(g(b)),this.rangeCount=this.nativeSelection.rangeCount,this.rangeCount==d+1?(a.config.checkSelectionRanges&&(d=J(this.nativeSelection,this.rangeCount-1))&&!t.rangesEqual(d,b)&&(b=new u(d)),this._ranges[this.rangeCount-1]=b,e(this,b,N(this.nativeSelection)),this.isCollapsed=q(this)):this.refresh()}}:function(a,b){b&&D?K(this,a):(this.nativeSelection.addRange(g(a)),this.refresh())},H.setRanges=function(a){if(I&&a.length>1)m(this,a);else{this.removeAllRanges();for(var b=0,c=a.length;c>b;++b)this.addRange(a[b])}}}else{if(!(s.isHostMethod(x,"empty")&&s.isHostMethod(A,"select")&&I&&z))return b.fail("No means of selecting a Range or TextRange was found"),!1;H.removeAllRanges=function(){try{if(this.docSelection.empty(),"None"!=this.docSelection.type){var a;if(this.anchorNode)a=r.getDocument(this.anchorNode);else if("Control"==this.docSelection.type){var b=this.docSelection.createRange();b.length&&(a=r.getDocument(b.item(0)).body.createTextRange())}a&&(a.body.createTextRange().select(),this.docSelection.empty())}}catch(c){}f(this)},H.addRange=function(a){"Control"==this.docSelection.type?k(this,a):(u.rangeToTextRange(a).select(),this._ranges[0]=a,this.rangeCount=1,this.isCollapsed=this._ranges[0].collapsed,e(this,a,!1))},H.setRanges=function(a){this.removeAllRanges();var b=a.length;b>1?m(this,a):b&&this.addRange(a[0])}}H.getRangeAt=function(a){if(0>a||a>=this.rangeCount)throw new v("INDEX_SIZE_ERR");return this._ranges[a]};var L;if(z)L=function(b){var c;a.isSelectionValid(b.win)?c=b.docSelection.createRange():(c=r.getBody(b.win.document).createTextRange(),c.collapse(!0)),"Control"==b.docSelection.type?j(b):c&&"undefined"!=typeof c.text?i(b,c):f(b)};else if(s.isHostMethod(x,"getRangeAt")&&"number"==typeof x.rangeCount)L=function(b){if(I&&y&&"Control"==b.docSelection.type)j(b);else if(b._ranges.length=b.rangeCount=b.nativeSelection.rangeCount,b.rangeCount){for(var c=0,d=b.rangeCount;d>c;++c)b._ranges[c]=new a.WrappedRange(b.nativeSelection.getRangeAt(c));e(b,b._ranges[b.rangeCount-1],N(b.nativeSelection)),b.isCollapsed=q(b)}else f(b)};else{if(!C||"boolean"!=typeof x.isCollapsed||"boolean"!=typeof A.collapsed||!a.features.implementsDomRange)return b.fail("No means of obtaining a Range or TextRange from the user's selection was found"),!1;L=function(a){var b;b=a.nativeSelection,b.anchorNode?(b=J(b,0),a._ranges=[b],a.rangeCount=1,b=a.nativeSelection,a.anchorNode=b.anchorNode,a.anchorOffset=b.anchorOffset,a.focusNode=b.focusNode,a.focusOffset=b.focusOffset,a.isCollapsed=q(a)):f(a)}}H.refresh=function(a){var b=a?this._ranges.slice(0):null;if(L(this),a){if(a=b.length,a!=this._ranges.length)return!1;for(;a--;)if(!t.rangesEqual(b[a],this._ranges[a]))return!1;return!0}};var M=function(a,b){var c=a.getAllRanges(),d=!1;a.removeAllRanges();for(var e=0,g=c.length;g>e;++e)d||b!==c[e]?a.addRange(c[e]):d=!0;a.rangeCount||f(a)};H.removeRange=I?function(a){if("Control"==this.docSelection.type){for(var b,c=this.docSelection.createRange(),a=h(a),d=r.getDocument(c.item(0)),d=r.getBody(d).createControlRange(),e=!1,f=0,g=c.length;g>f;++f)b=c.item(f),b!==a||e?d.add(c.item(f)):e=!0;d.select(),j(this)}else M(this,a)}:function(a){M(this,a)};var N;!z&&C&&a.features.implementsDomRange?(N=function(a){var b=!1;return a.anchorNode&&(b=1==r.comparePoints(a.anchorNode,a.anchorOffset,a.focusNode,a.focusOffset)),b},H.isBackwards=function(){return N(this)}):N=H.isBackwards=function(){return!1},H.toString=function(){for(var a=[],b=0,c=this.rangeCount;c>b;++b)a[b]=""+this._ranges[b];return a.join("")},H.collapse=function(b,c){n(this,b);var d=a.createRange(r.getDocument(b));d.collapseToPoint(b,c),this.removeAllRanges(),this.addRange(d),this.isCollapsed=!0},H.collapseToStart=function(){if(!this.rangeCount)throw new v("INVALID_STATE_ERR");var a=this._ranges[0];this.collapse(a.startContainer,a.startOffset)},H.collapseToEnd=function(){if(!this.rangeCount)throw new v("INVALID_STATE_ERR");var a=this._ranges[this.rangeCount-1];this.collapse(a.endContainer,a.endOffset)},H.selectAllChildren=function(b){n(this,b);var c=a.createRange(r.getDocument(b));c.selectNodeContents(b),this.removeAllRanges(),this.addRange(c)},H.deleteFromDocument=function(){if(I&&y&&"Control"==this.docSelection.type){for(var a,b=this.docSelection.createRange();b.length;)a=b.item(0),b.remove(a),a.parentNode.removeChild(a);this.refresh()}else if(this.rangeCount){b=this.getAllRanges(),this.removeAllRanges(),a=0;for(var c=b.length;c>a;++a)b[a].deleteContents();this.addRange(b[c-1])}},H.getAllRanges=function(){return this._ranges.slice(0)},H.setSingleRange=function(a){this.setRanges([a])},H.containsNode=function(a,b){for(var c=0,d=this._ranges.length;d>c;++c)if(this._ranges[c].containsNode(a,b))return!0;return!1},H.toHtml=function(){var a="";if(this.rangeCount){for(var a=t.getRangeDocument(this._ranges[0]).createElement("div"),b=0,c=this._ranges.length;c>b;++b)a.appendChild(this._ranges[b].cloneContents());a=a.innerHTML}return a},H.getName=function(){return"WrappedSelection"},H.inspect=function(){return o(this)},H.detach=function(){this.win=this.anchorNode=this.focusNode=this.win._rangySelection=null},l.inspect=o,a.Selection=l,a.selectionPrototype=H,a.addCreateMissingNativeApiListener(function(b){"undefined"==typeof b.getSelection&&(b.getSelection=function(){return a.getSelection(this)}),b=null})});var Base=function(){};Base.extend=function(a,b){var c=Base.prototype.extend;Base._prototyping=!0;var d=new this;c.call(d,a),d.base=function(){},delete Base._prototyping;var e=d.constructor,f=d.constructor=function(){if(!Base._prototyping)if(this._constructing||this.constructor==f)this._constructing=!0,e.apply(this,arguments),delete this._constructing;else if(null!=arguments[0])return(arguments[0].extend||c).call(arguments[0],d)};return f.ancestor=this,f.extend=this.extend,f.forEach=this.forEach,f.implement=this.implement,f.prototype=d,f.toString=this.toString,f.valueOf=function(a){return"object"==a?f:e.valueOf()},c.call(f,b),"function"==typeof f.init&&f.init(),f},Base.prototype={extend:function(a,b){if(1(/ipad|iphone|ipod/.test(a)&&a.match(/ os (\d+).+? like mac os x/)||[,0])[1]||-1!==a.indexOf("opera mobi")||-1!==a.indexOf("hpwos/");return c&&d&&e&&!a},isTouchDevice:function(){return this.supportsEvent("touchmove")},isIos:function(){var a=this.USER_AGENT.toLowerCase();return-1!==a.indexOf("webkit")&&-1!==a.indexOf("mobile")},supportsSandboxedIframes:function(){return c},throwsMixedContentWarningWhenIframeSrcIsEmpty:function(){return!("querySelector"in document)},displaysCaretInEmptyContentEditableCorrectly:function(){return!d},hasCurrentStyleProperty:function(){return"currentStyle"in b},insertsLineBreaksOnReturn:function(){return d},supportsPlaceholderAttributeOn:function(a){return"placeholder"in a},supportsEvent:function(a){var c;return(c="on"+a in b)||(b.setAttribute("on"+a,"return;"),c="function"==typeof b["on"+a]),c},supportsEventsInIframeCorrectly:function(){return!g},firesOnDropOnlyWhenOnDragOverIsCancelled:function(){return e||d},supportsDataTransfer:function(){try{return e&&(window.Clipboard||window.DataTransfer).prototype.getData}catch(a){return!1}},supportsHTML5Tags:function(a){return a=a.createElement("div"),a.innerHTML="
    foo
    ","
    foo
    "===a.innerHTML.toLowerCase()},supportsCommand:function(){var a={formatBlock:c,insertUnorderedList:c||g||e,insertOrderedList:c||g||e},b={insertHTML:d};return function(c,d){if(!a[d]){try{return c.queryCommandSupported(d)}catch(e){}try{return c.queryCommandEnabled(d)}catch(f){return!!b[d]}}return!1}}(),doesAutoLinkingInContentEditable:function(){return c},canDisableAutoLinking:function(){return this.supportsCommand(document,"AutoUrlDetect")},clearsContentEditableCorrectly:function(){return d||g||e},supportsGetAttributeCorrectly:function(){return"1"!=document.createElement("td").getAttribute("rowspan")},canSelectImagesInContentEditable:function(){return d||c||g},clearsListsInContentEditableCorrectly:function(){return d||c||e},autoScrollsToCaret:function(){return!e},autoClosesUnclosedTags:function(){var a,c=b.cloneNode(!1);return c.innerHTML="

    ",c=c.innerHTML.toLowerCase(),a="

    "===c||"

    "===c,this.autoClosesUnclosedTags=function(){return a},a},supportsNativeGetElementsByClassName:function(){return-1!==(""+document.getElementsByClassName).indexOf("[native code]")},supportsSelectionModify:function(){return"getSelection"in window&&"modify"in window.getSelection()},supportsClassList:function(){return"classList"in b},needsSpaceAfterLineBreak:function(){return g},supportsSpeechApiOn:function(b){return 11<=(a.match(/Chrome\/(\d+)/)||[,0])[1]&&("onwebkitspeechchange"in b||"speech"in b)},crashesWhenDefineProperty:function(a){return c&&("XMLHttpRequest"===a||"XDomainRequest"===a)},doesAsyncFocus:function(){return c},hasProblemsSettingCaretAfterImg:function(){return c},hasUndoInContextMenu:function(){return d||f||g}}}(),wysihtml5.lang.array=function(a){return{contains:function(b){if(a.indexOf)return-1!==a.indexOf(b);for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return!0;return!1},without:function(b){for(var b=wysihtml5.lang.array(b),c=[],d=0,e=a.length;e>d;d++)b.contains(a[d])||c.push(a[d]);return c},get:function(){for(var b=0,c=a.length,d=[];c>b;b++)d.push(a[b]);return d}}},wysihtml5.lang.Dispatcher=Base.extend({observe:function(a,b){return this.events=this.events||{},this.events[a]=this.events[a]||[],this.events[a].push(b),this},on:function(){return this.observe.apply(this,wysihtml5.lang.array(arguments).get())},fire:function(a,b){this.events=this.events||{};for(var c=this.events[a]||[],d=0;db.split(c).length&&(b+=c,c="");var e=d=b;return b.length>g&&(e=e.substr(0,g)+"..."),"www."===d.substr(0,4)&&(d="http://"+d),''+e+""+c})}function c(f){if(!d.contains(f.nodeName)){if(f.nodeType!==a.TEXT_NODE||!f.data.match(e)){for(h=a.lang.array(f.childNodes).get(),g=h.length,i=0;g>i;i++)c(h[i]);return f}var g,h=f.parentNode;g=h.ownerDocument;var i=g._wysihtml5_tempElement;for(i||(i=g._wysihtml5_tempElement=g.createElement("div")),g=i,g.innerHTML=""+b(f.data),g.removeChild(g.firstChild);g.firstChild;)h.insertBefore(g.firstChild,f);h.removeChild(f)}}var d=a.lang.array("CODE PRE A SCRIPT HEAD TITLE STYLE".split(" ")),e=/((https?:\/\/|www\.)[^\s<]{3,})/gi,f=/([^\w\/\-](,?))$/i,g=100,h={")":"(","]":"[","}":"{"};a.dom.autoLink=function(a){var b;a:{b=a;for(var e;b.parentNode;){if(b=b.parentNode,e=b.nodeName,d.contains(e)){b=!0;break a}if("body"===e)break}b=!1}return b?a:(a===a.ownerDocument.documentElement&&(a=a.ownerDocument.body),c(a))},a.dom.autoLink.URL_REG_EXP=e}(wysihtml5),function(a){var b=a.browser.supportsClassList(),c=a.dom;c.addClass=function(a,d){return b?a.classList.add(d):(c.hasClass(a,d)||(a.className+=" "+d),void 0)},c.removeClass=function(a,c){return b?a.classList.remove(c):(a.className=a.className.replace(RegExp("(^|\\s+)"+c+"(\\s+|$)")," "),void 0)},c.hasClass=function(a,c){if(b)return a.classList.contains(c);var d=a.className;return 0h;h++)for(d=k[h];(e=d.parentNode)&&e!==b&&e.lastChild===d;){if("block"===wysihtml5.dom.getStyle("display").from(e)){e.removeChild(d);break}wysihtml5.dom.insert(d).after(d.parentNode)}for(k=wysihtml5.lang.array(b.childNodes).get(),l=k.length,h=0;l>h;h++)g=g||a(i,j),d=k[h],e="block"===wysihtml5.dom.getStyle("display").from(d),f="BR"===d.nodeName,e?(g=g.firstChild?a(i,j):g,g.appendChild(d),g=null):f?g=g.firstChild?null:g:g.appendChild(d);return b.parentNode.replaceChild(j,b),j}}(),wysihtml5.dom.copyAttributes=function(a){return{from:function(b){return{to:function(c){for(var d,e=0,f=a.length;f>e;e++)d=a[e],"undefined"!=typeof b[d]&&""!==b[d]&&(c[d]=b[d]);return{andTo:arguments.callee}}}}}},function(a){var b=["-webkit-box-sizing","-moz-box-sizing","-ms-box-sizing","box-sizing"],c=function(c){var d;a:for(var e=0,f=b.length;f>e;e++)if("border-box"===a.getStyle(b[e]).from(c)){d=b[e];break a}return d?parseInt(a.getStyle("width").from(c),10)i;i++)f=d[i],g+=f+":"+a.getStyle(f).from(e)+";";return{to:function(b){return a.setStyles(g).on(b),{andTo:arguments.callee}}}}}}}(wysihtml5.dom),function(a){a.dom.delegate=function(b,c,d,e){return a.dom.observe(b,d,function(d){for(var f=d.target,g=a.lang.array(b.querySelectorAll(c));f&&f!==b;){if(g.contains(f)){e.call(f,d);break}f=f.parentNode}})}}(wysihtml5),wysihtml5.dom.getAsDom=function(){var a="abbr article aside audio bdi canvas command datalist details figcaption figure footer header hgroup keygen mark meter nav output progress rp rt ruby svg section source summary time track video wbr".split(" ");return function(b,c){var d,c=c||document;if("object"==typeof b&&b.nodeType)d=c.createElement("div"),d.appendChild(b);else if(wysihtml5.browser.supportsHTML5Tags(c))d=c.createElement("div"),d.innerHTML=b;else{if(d=c,!d._wysihtml5_supportsHTML5Tags){for(var e=0,f=a.length;f>e;e++)d.createElement(a[e]);d._wysihtml5_supportsHTML5Tags=!0}d=c,e=d.createElement("div"),e.style.display="none",d.body.appendChild(e);try{e.innerHTML=b}catch(g){}d.body.removeChild(e),d=e}return d}}(),wysihtml5.dom.getParentElement=function(){function a(a,b){return b&&b.length?"string"==typeof b?a===b:wysihtml5.lang.array(b).contains(a):!0}return function(b,c,d){if(d=d||50,c.className||c.classRegExp){a:{for(var e=c.nodeName,f=c.className,c=c.classRegExp;d--&&b&&"BODY"!==b.nodeName;){var g;if((g=b.nodeType===wysihtml5.ELEMENT_NODE)&&(g=a(b.nodeName,e))){g=f;var h=(b.className||"").match(c)||[];g=g?h[h.length-1]===g:!!h.length}if(g)break a;b=b.parentNode}b=null}return b}a:{for(e=c.nodeName,f=d;f--&&b&&"BODY"!==b.nodeName;){if(a(b.nodeName,e))break a;b=b.parentNode}b=null}return b}}(),wysihtml5.dom.getStyle=function(){function a(a){return a.replace(c,function(a){return a.charAt(1).toUpperCase()})}var b={"float":"styleFloat"in document.createElement("div").style?"styleFloat":"cssFloat"},c=/\-[a-z]/g;return function(c){return{from:function(d){if(d.nodeType===wysihtml5.ELEMENT_NODE){var e=d.ownerDocument,f=b[c]||a(c),g=d.style,h=d.currentStyle,i=g[f];if(i)return i;if(h)try{return h[f]}catch(j){}var k,f=e.defaultView||e.parentWindow,e=("height"===c||"width"===c)&&"TEXTAREA"===d.nodeName;if(f.getComputedStyle)return e&&(k=g.overflow,g.overflow="hidden"),d=f.getComputedStyle(d,null).getPropertyValue(c),e&&(g.overflow=k||""),d}}}}}(),wysihtml5.dom.hasElementWithTagName=function(){var a={},b=1;return function(c,d){var e=(c._wysihtml5_identifier||(c._wysihtml5_identifier=b++))+":"+d,f=a[e];return f||(f=a[e]=c.getElementsByTagName(d)),0f;f++)e=b[f],a.addEventListener?a.addEventListener(e,c,!1):(d=function(b){"target"in b||(b.target=b.srcElement),b.preventDefault=b.preventDefault||function(){this.returnValue=!1},b.stopPropagation=b.stopPropagation||function(){this.cancelBubble=!0},c.call(a,b)},a.attachEvent("on"+e,d));return{stop:function(){for(var e,f=0,g=b.length;g>f;f++)e=b[f],a.removeEventListener?a.removeEventListener(e,c,!1):a.detachEvent("on"+e,d)}}},wysihtml5.dom.parse=function(){function a(b,e){var f,g=b.childNodes,h=g.length;f=c[b.nodeType];var i=0;if(f=f&&f(b),!f)return null;for(i=0;h>i;i++)(newChild=a(g[i],e))&&f.appendChild(newChild);return e&&1>=f.childNodes.length&&f.nodeName.toLowerCase()===d&&!f.attributes.length?f.firstChild:f}function b(a,b){var c,b=b.toLowerCase();if((c="IMG"==a.nodeName)&&(c="src"==b)){var d;try{d=a.complete&&!a.mozMatchesSelector(":-moz-broken")}catch(e){a.complete&&"complete"===a.readyState&&(d=!0)}c=!0===d}return c?a.src:h&&"outerHTML"in a?-1!=a.outerHTML.toLowerCase().indexOf(" "+b+"=")?a.getAttribute(b):null:a.getAttribute(b)}var c={1:function(a){var c,f,h=g.tags;if(f=a.nodeName.toLowerCase(),c=a.scopeName,a._wysihtml5)return null;if(a._wysihtml5=1,"wysihtml5-temp"===a.className)return null;if(c&&"HTML"!=c&&(f=c+":"+f),"outerHTML"in a&&!wysihtml5.browser.autoClosesUnclosedTags()&&"P"===a.nodeName&&"

    "!==a.outerHTML.slice(-4).toLowerCase()&&(f="div"),f in h){if(c=h[f],!c||c.remove)return null;c="string"==typeof c?{rename_tag:c}:c}else{if(!a.firstChild)return null;c={rename_tag:d}}f=a.ownerDocument.createElement(c.rename_tag||f);var h={},k=c.set_class,l=c.add_class,m=c.set_attributes,n=c.check_attributes,o=g.classes,p=0,q=[];c=[];var r,s=[],t=[];if(m&&(h=wysihtml5.lang.object(m).clone()),n)for(r in n)(m=i[n[r]])&&(m=m(b(a,r)),"string"==typeof m&&(h[r]=m));if(k&&q.push(k),l)for(r in l)(m=j[l[r]])&&(k=m(b(a,r)),"string"==typeof k&&q.push(k));for(o["_wysihtml5-temp-placeholder"]=1,(t=a.getAttribute("class"))&&(q=q.concat(t.split(e))),l=q.length;l>p;p++)a=q[p],o[a]&&c.push(a);for(o=c.length;o--;)a=c[o],wysihtml5.lang.array(s).contains(a)||s.unshift(a);s.length&&(h["class"]=s.join(" "));for(r in h)try{f.setAttribute(r,h[r])}catch(u){}return h.src&&("undefined"!=typeof h.width&&f.setAttribute("width",h.width),"undefined"!=typeof h.height&&f.setAttribute("height",h.height)),f},3:function(a){return a.ownerDocument.createTextNode(a.data)}},d="span",e=/\s+/,f={tags:{},classes:{}},g={},h=!wysihtml5.browser.supportsGetAttributeCorrectly(),i={url:function(){var a=/^https?:\/\//i;return function(b){return b&&b.match(a)?b.replace(a,function(a){return a.toLowerCase()}):null}}(),alt:function(){var a=/[^ a-z0-9_\-]/gi;return function(b){return b?b.replace(a,""):""}}(),numbers:function(){var a=/\D/g;return function(b){return(b=(b||"").replace(a,""))||null}}()},j={align_img:function(){var a={left:"wysiwyg-float-left",right:"wysiwyg-float-right"};return function(b){return a[(""+b).toLowerCase()]}}(),align_text:function(){var a={left:"wysiwyg-text-align-left",right:"wysiwyg-text-align-right",center:"wysiwyg-text-align-center",justify:"wysiwyg-text-align-justify"};return function(b){return a[(""+b).toLowerCase()]}}(),clear_br:function(){var a={left:"wysiwyg-clear-left",right:"wysiwyg-clear-right",both:"wysiwyg-clear-both",all:"wysiwyg-clear-both"};return function(b){return a[(""+b).toLowerCase()]}}(),size_font:function(){var a={1:"wysiwyg-font-size-xx-small",2:"wysiwyg-font-size-small",3:"wysiwyg-font-size-medium",4:"wysiwyg-font-size-large",5:"wysiwyg-font-size-x-large",6:"wysiwyg-font-size-xx-large",7:"wysiwyg-font-size-xx-large","-":"wysiwyg-font-size-smaller","+":"wysiwyg-font-size-larger"};return function(b){return a[(""+b).charAt(0)]}}()};return function(b,c,d,e){wysihtml5.lang.object(g).merge(f).merge(c).get();for(var d=d||b.ownerDocument||document,c=d.createDocumentFragment(),h="string"==typeof b,b=h?wysihtml5.dom.getAsDom(b,d):b;b.firstChild;)d=b.firstChild,b.removeChild(d),(d=a(d,e))&&c.appendChild(d);return b.innerHTML="",b.appendChild(c),h?wysihtml5.quirks.getCorrectInnerHTML(b):b}}(),wysihtml5.dom.removeEmptyTextNodes=function(a){for(var b=wysihtml5.lang.array(a.childNodes).get(),c=b.length,d=0;c>d;d++)a=b[d],a.nodeType===wysihtml5.TEXT_NODE&&""===a.data&&a.parentNode.removeChild(a)},wysihtml5.dom.renameElement=function(a,b){for(var c,d=a.ownerDocument.createElement(b);c=a.firstChild;)d.appendChild(c);return wysihtml5.dom.copyAttributes(["align","className"]).from(a).to(d),a.parentNode.replaceChild(d,a),d},wysihtml5.dom.replaceWithChildNodes=function(a){if(a.parentNode)if(a.firstChild){for(var b=a.ownerDocument.createDocumentFragment();a.firstChild;)b.appendChild(a.firstChild);a.parentNode.replaceChild(b,a)}else a.parentNode.removeChild(a)},function(a){function b(a){var b=a.ownerDocument.createElement("br");a.appendChild(b)}a.resolveList=function(c){if("MENU"===c.nodeName||"UL"===c.nodeName||"OL"===c.nodeName){var d,e,f,g=c.ownerDocument.createDocumentFragment(),h=c.previousElementSibling||c.previousSibling;for(h&&"block"!==a.getStyle("display").from(h)&&b(g);f=c.firstChild;){for(d=f.lastChild;h=f.firstChild;)e=(e=h===d)&&"block"!==a.getStyle("display").from(h)&&"BR"!==h.nodeName,g.appendChild(h),e&&b(g);f.parentNode.removeChild(f)}c.parentNode.replaceChild(g,c)}}}(wysihtml5.dom),function(a){var b=document,c="parent top opener frameElement frames localStorage globalStorage sessionStorage indexedDB".split(" "),d="open close openDialog showModalDialog alert confirm prompt openDatabase postMessage XMLHttpRequest XDomainRequest".split(" "),e=["referrer","write","open","close"];a.dom.Sandbox=Base.extend({constructor:function(b,c){this.callback=b||a.EMPTY_FUNCTION,this.config=a.lang.object({}).merge(c).get(),this.iframe=this._createIframe()},insertInto:function(a){"string"==typeof a&&(a=b.getElementById(a)),a.appendChild(this.iframe)},getIframe:function(){return this.iframe},getWindow:function(){this._readyError()},getDocument:function(){this._readyError()},destroy:function(){var a=this.getIframe();a.parentNode.removeChild(a)},_readyError:function(){throw Error("wysihtml5.Sandbox: Sandbox iframe isn't loaded yet")},_createIframe:function(){var c=this,d=b.createElement("iframe");return d.className="wysihtml5-sandbox",a.dom.setAttributes({security:"restricted",allowtransparency:"true",frameborder:0,width:0,height:0,marginwidth:0,marginheight:0}).on(d),a.browser.throwsMixedContentWarningWhenIframeSrcIsEmpty()&&(d.src="javascript:''"),d.onload=function(){d.onreadystatechange=d.onload=null,c._onLoadIframe(d)},d.onreadystatechange=function(){/loaded|complete/.test(d.readyState)&&(d.onreadystatechange=d.onload=null,c._onLoadIframe(d))},d},_onLoadIframe:function(f){if(a.dom.contains(b.documentElement,f)){var g=this,h=f.contentWindow,i=f.contentWindow.document,j=this._getHtml({charset:b.characterSet||b.charset||"utf-8",stylesheets:this.config.stylesheets});if(i.open("text/html","replace"),i.write(j),i.close(),this.getWindow=function(){return f.contentWindow},this.getDocument=function(){return f.contentWindow.document},h.onerror=function(a,b,c){throw Error("wysihtml5.Sandbox: "+a,b,c)},!a.browser.supportsSandboxedIframes()){var k,j=0;for(k=c.length;k>j;j++)this._unset(h,c[j]);for(j=0,k=d.length;k>j;j++)this._unset(h,d[j],a.EMPTY_FUNCTION);for(j=0,k=e.length;k>j;j++)this._unset(i,e[j]);this._unset(i,"cookie","",!0)}this.loaded=!0,setTimeout(function(){g.callback(g)},0)}},_getHtml:function(b){var c,d=b.stylesheets,e="",f=0;if(d="string"==typeof d?[d]:d)for(c=d.length;c>f;f++)e+='';return b.stylesheets=e,a.lang.string('#{stylesheets}').interpolate(b)},_unset:function(b,c,d,e){try{b[c]=d}catch(f){}try{b.__defineGetter__(c,function(){return d})}catch(g){}if(e)try{b.__defineSetter__(c,function(){})}catch(h){}if(!a.browser.crashesWhenDefineProperty(c))try{var i={get:function(){return d}};e&&(i.set=function(){}),Object.defineProperty(b,c,i)}catch(j){}}})}(wysihtml5),function(){var a={className:"class"};wysihtml5.dom.setAttributes=function(b){return{on:function(c){for(var d in b)c.setAttribute(a[d]||d,b[d])}}}}(),wysihtml5.dom.setStyles=function(a){return{on:function(b){if(b=b.style,"string"==typeof a)b.cssText+=";"+a;else for(var c in a)"float"===c?(b.cssFloat=a[c],b.styleFloat=a[c]):b[c]=a[c]}}},function(a){a.simulatePlaceholder=function(b,c,d){var e=function(){c.hasPlaceholderSet()&&c.clear(),a.removeClass(c.element,"placeholder")},f=function(){c.isEmpty()&&(c.setValue(d),a.addClass(c.element,"placeholder"))};b.observe("set_placeholder",f).observe("unset_placeholder",e).observe("focus:composer",e).observe("paste:composer",e).observe("blur:composer",f),f()}}(wysihtml5.dom),function(a){var b=document.documentElement;"textContent"in b?(a.setTextContent=function(a,b){a.textContent=b},a.getTextContent=function(a){return a.textContent}):"innerText"in b?(a.setTextContent=function(a,b){a.innerText=b},a.getTextContent=function(a){return a.innerText}):(a.setTextContent=function(a,b){a.nodeValue=b},a.getTextContent=function(a){return a.nodeValue})}(wysihtml5.dom),wysihtml5.quirks.cleanPastedHTML=function(){var a={"a u":wysihtml5.dom.replaceWithChildNodes};return function(b,c,d){var e,f,g,c=c||a,d=d||b.ownerDocument||document,h="string"==typeof b,i=0,b=h?wysihtml5.dom.getAsDom(b,d):b;for(g in c)for(e=b.querySelectorAll(g),d=c[g],f=e.length;f>i;i++)d(e[i]);return h?b.innerHTML:b}}(),function(a){var b=a.dom;a.quirks.ensureProperClearing=function(){var a=function(){var a=this;setTimeout(function(){var b=a.innerHTML.toLowerCase();("

     

    "==b||"

     

     

    "==b)&&(a.innerHTML="") -},0)};return function(c){b.observe(c.element,["cut","keydown"],a)}}(),a.quirks.ensureProperClearingOfLists=function(){var c=["OL","UL","MENU"];return function(d){b.observe(d.element,"keydown",function(e){if(e.keyCode===a.BACKSPACE_KEY){var f=d.selection.getSelectedNode(),e=d.element;e.firstChild&&a.lang.array(c).contains(e.firstChild.nodeName)&&(f=b.getParentElement(f,{nodeName:c}))&&f==e.firstChild&&1>=f.childNodes.length&&(f.firstChild?""===f.firstChild.innerHTML:1)&&f.parentNode.removeChild(f)}})}}()}(wysihtml5),function(a){a.quirks.getCorrectInnerHTML=function(b){var c=b.innerHTML;if(-1===c.indexOf("%7E"))return c;var d,e,f,g,b=b.querySelectorAll("[href*='~'], [src*='~']");for(g=0,f=b.length;f>g;g++)d=b[g].href||b[g].src,e=a.lang.string(d).replace("~").by("%7E"),c=a.lang.string(c).replace(e).by(d);return c}}(wysihtml5),function(a){var b=a.dom,c="LI P H1 H2 H3 H4 H5 H6".split(" "),d=["UL","OL","MENU"];a.quirks.insertLineBreakOnReturn=function(e){function f(c){if(c=b.getParentElement(c,{nodeName:["P","DIV"]},2)){var d=document.createTextNode(a.INVISIBLE_SPACE);b.insert(d).before(c),b.replaceWithChildNodes(c),e.selection.selectNode(d)}}b.observe(e.element.ownerDocument,"keydown",function(g){var h=g.keyCode;if(!(g.shiftKey||h!==a.ENTER_KEY&&h!==a.BACKSPACE_KEY)){var i=e.selection.getSelectedNode();(i=b.getParentElement(i,{nodeName:c},4))?"LI"!==i.nodeName||h!==a.ENTER_KEY&&h!==a.BACKSPACE_KEY?i.nodeName.match(/H[1-6]/)&&h===a.ENTER_KEY&&setTimeout(function(){f(e.selection.getSelectedNode())},0):setTimeout(function(){var a,c=e.selection.getSelectedNode();c&&((a=b.getParentElement(c,{nodeName:d},2))||f(c))},0):h===a.ENTER_KEY&&!a.browser.insertsLineBreaksOnReturn()&&(e.commands.exec("insertLineBreak"),g.preventDefault())}})}}(wysihtml5),function(a){a.quirks.redraw=function(b){a.dom.addClass(b,"wysihtml5-quirks-redraw"),a.dom.removeClass(b,"wysihtml5-quirks-redraw");try{var c=b.ownerDocument;c.execCommand("italic",!1,null),c.execCommand("italic",!1,null)}catch(d){}}}(wysihtml5),function(a){var b=a.dom;a.Selection=Base.extend({constructor:function(a){window.rangy.init(),this.editor=a,this.composer=a.composer,this.doc=this.composer.doc},getBookmark:function(){var a=this.getRange();return a&&a.cloneRange()},setBookmark:function(a){a&&this.setSelection(a)},setBefore:function(a){var b=rangy.createRange(this.doc);return b.setStartBefore(a),b.setEndBefore(a),this.setSelection(b)},setAfter:function(a){var b=rangy.createRange(this.doc);return b.setStartAfter(a),b.setEndAfter(a),this.setSelection(b)},selectNode:function(c){var d=rangy.createRange(this.doc),e=c.nodeType===a.ELEMENT_NODE,f="canHaveHTML"in c?c.canHaveHTML:"IMG"!==c.nodeName,g=e?c.innerHTML:c.data,g=""===g||g===a.INVISIBLE_SPACE,h=b.getStyle("display").from(c),h="block"===h||"list-item"===h;if(g&&e&&f)try{c.innerHTML=a.INVISIBLE_SPACE}catch(i){}f?d.selectNodeContents(c):d.selectNode(c),f&&g&&e?d.collapse(h):f&&g&&(d.setStartAfter(c),d.setEndAfter(c)),this.setSelection(d)},getSelectedNode:function(a){return a&&this.doc.selection&&"Control"===this.doc.selection.type&&(a=this.doc.selection.createRange())&&a.length?a.item(0):(a=this.getSelection(this.doc),a.focusNode===a.anchorNode?a.focusNode:(a=this.getRange(this.doc))?a.commonAncestorContainer:this.doc.body)},executeAndRestore:function(b,c){var d=this.doc.body,e=c&&d.scrollTop,f=c&&d.scrollLeft,g=''+a.INVISIBLE_SPACE+"",h=this.getRange(this.doc);if(h){g=h.createContextualFragment(g),h.insertNode(g);try{b(h.startContainer,h.endContainer)}catch(i){setTimeout(function(){throw i},0)}(caretPlaceholder=this.doc.querySelector("._wysihtml5-temp-placeholder"))?(h=rangy.createRange(this.doc),h.selectNode(caretPlaceholder),h.deleteContents(),this.setSelection(h)):d.focus(),c&&(d.scrollTop=e,d.scrollLeft=f);try{caretPlaceholder.parentNode.removeChild(caretPlaceholder)}catch(j){}}else b(d,d)},executeAndRestoreSimple:function(a){var b,c,d,e=this.getRange(),f=this.doc.body;if(e){b=e.getNodes([3]),f=b[0]||e.startContainer,d=b[b.length-1]||e.endContainer,b=f===e.startContainer?e.startOffset:0,c=d===e.endContainer?e.endOffset:d.length;try{a(e.startContainer,e.endContainer)}catch(g){setTimeout(function(){throw g},0)}a=rangy.createRange(this.doc);try{a.setStart(f,b)}catch(h){}try{a.setEnd(d,c)}catch(i){}try{this.setSelection(a)}catch(j){}}else a(f,f)},insertHTML:function(a){var a=rangy.createRange(this.doc).createContextualFragment(a),b=a.lastChild;this.insertNode(a),b&&this.setAfter(b)},insertNode:function(a){var b=this.getRange();b&&b.insertNode(a)},surround:function(a){var b=this.getRange();if(b)try{b.surroundContents(a),this.selectNode(a)}catch(c){a.appendChild(b.extractContents()),b.insertNode(a)}},scrollIntoView:function(){var b,c=this.doc,d=c.documentElement.scrollHeight>c.documentElement.offsetHeight;if((b=c._wysihtml5ScrollIntoViewElement)||(b=c.createElement("span"),b.innerHTML=a.INVISIBLE_SPACE),b=c._wysihtml5ScrollIntoViewElement=b,d){this.insertNode(b);var d=b,e=0;if(d.parentNode)do e+=d.offsetTop||0,d=d.offsetParent;while(d);d=e,b.parentNode.removeChild(b),d>c.body.scrollTop&&(c.body.scrollTop=d)}},selectLine:function(){a.browser.supportsSelectionModify()?this._selectLine_W3C():this.doc.selection&&this._selectLine_MSIE()},_selectLine_W3C:function(){var a=this.doc.defaultView.getSelection();a.modify("extend","left","lineboundary"),a.modify("extend","right","lineboundary")},_selectLine_MSIE:function(){var a,b=this.doc.selection.createRange(),c=b.boundingTop,d=this.doc.body.scrollWidth;if(b.moveToPoint){for(0===c&&(a=this.doc.createElement("span"),this.insertNode(a),c=a.offsetTop,a.parentNode.removeChild(a)),c+=1,a=-10;d>a;a+=2)try{b.moveToPoint(a,c);break}catch(e){}for(a=this.doc.selection.createRange();d>=0;d--)try{a.moveToPoint(d,c);break}catch(f){}b.setEndPoint("EndToEnd",a),b.select()}},getText:function(){var a=this.getSelection();return a?a.toString():""},getNodes:function(a,b){var c=this.getRange();return c?c.getNodes([a],b):[]},getRange:function(){var a=this.getSelection();return a&&a.rangeCount&&a.getRangeAt(0)},getSelection:function(){return rangy.getSelection(this.doc.defaultView||this.doc.parentWindow)},setSelection:function(a){return rangy.getSelection(this.doc.defaultView||this.doc.parentWindow).setSingleRange(a)}})}(wysihtml5),function(a,b){function c(a,c){return b.dom.isCharacterDataNode(a)?0==c?!!a.previousSibling:c==a.length?!!a.nextSibling:!0:c>0&&cd;++d)a=this.textNodes[d],b=a.parentNode,c[d]=a.data,d&&(b.removeChild(a),b.hasChildNodes()||b.parentNode.removeChild(b));return this.firstTextNode.data=c=c.join("")},getLength:function(){for(var a=this.textNodes.length,b=0;a--;)b+=this.textNodes[a].length;return b},toString:function(){for(var a=[],b=0,c=this.textNodes.length;c>b;++b)a[b]="'"+this.textNodes[b].data+"'";return"[Merge("+a.join(",")+")]"}},f.prototype={getAncestorWithClass:function(c){for(var d;c;){if(this.cssClass)if(d=this.cssClass,c.className){var e=c.className.match(this.similarClassRegExp)||[];d=e[e.length-1]===d}else d=!1;else d=!0;if(c.nodeType==a.ELEMENT_NODE&&b.dom.arrayContains(this.tagNames,c.tagName.toLowerCase())&&d)return c;c=c.parentNode}return!1},postApply:function(a,b){for(var c,d,f,g=a[0],h=a[a.length-1],i=[],j=g,k=h,l=0,m=h.length,n=0,o=a.length;o>n;++n)d=a[n],(f=this.getAdjacentMergeableTextNode(d.parentNode,!1))?(c||(c=new e(f),i.push(c)),c.textNodes.push(d),d===g&&(j=c.firstTextNode,l=j.length),d===h&&(k=c.firstTextNode,m=c.getLength())):c=null;if((g=this.getAdjacentMergeableTextNode(h.parentNode,!0))&&(c||(c=new e(h),i.push(c)),c.textNodes.push(g)),i.length){for(n=0,o=i.length;o>n;++n)i[n].doMerge();b.setStart(j,l),b.setEnd(k,m)}},getAdjacentMergeableTextNode:function(b,c){var d=b.nodeType==a.TEXT_NODE,e=d?b.parentNode:b,f=c?"nextSibling":"previousSibling";if(d){if((d=b[f])&&d.nodeType==a.TEXT_NODE)return d}else if((d=e[f])&&this.areElementsMergeable(b,d))return d[c?"firstChild":"lastChild"];return null},areElementsMergeable:function(a,c){var d;if((d=b.dom.arrayContains(this.tagNames,(a.tagName||"").toLowerCase()))&&(d=b.dom.arrayContains(this.tagNames,(c.tagName||"").toLowerCase()))&&(d=a.className.replace(h," ")==c.className.replace(h," ")))a:if(a.attributes.length!=c.attributes.length)d=!1;else{d=0;for(var e,f,g=a.attributes.length;g>d;++d)if(e=a.attributes[d],f=e.name,"class"!=f&&(f=c.attributes.getNamedItem(f),e.specified!=f.specified||e.specified&&e.nodeValue!==f.nodeValue)){d=!1;break a}d=!0}return d},createContainer:function(a){return a=a.createElement(this.tagNames[0]),this.cssClass&&(a.className=this.cssClass),a},applyToTextNode:function(a){var c=a.parentNode;1==c.childNodes.length&&b.dom.arrayContains(this.tagNames,c.tagName.toLowerCase())?this.cssClass&&(a=this.cssClass,c.className?(c.className&&(c.className=c.className.replace(this.similarClassRegExp,"")),c.className+=" "+a):c.className=a):(c=this.createContainer(b.dom.getDocument(a)),a.parentNode.insertBefore(c,a),c.appendChild(a))},isRemovable:function(c){return b.dom.arrayContains(this.tagNames,c.tagName.toLowerCase())&&a.lang.string(c.className).trim()==this.cssClass},undoToTextNode:function(a,b,e){if(b.containsNode(e)||(a=b.cloneRange(),a.selectNode(e),a.isPointInRange(b.endContainer,b.endOffset)&&c(b.endContainer,b.endOffset)&&(d(e,b.endContainer,b.endOffset),b.setEndAfter(e)),a.isPointInRange(b.startContainer,b.startOffset)&&c(b.startContainer,b.startOffset)&&(e=d(e,b.startContainer,b.startOffset))),this.similarClassRegExp&&e.className&&(e.className=e.className.replace(this.similarClassRegExp,"")),this.isRemovable(e)){for(b=e,e=b.parentNode;b.firstChild;)e.insertBefore(b.firstChild,b);e.removeChild(b)}},applyToRange:function(b){var c=b.getNodes([a.TEXT_NODE]);if(!c.length)try{var d=this.createContainer(b.endContainer.ownerDocument);return b.surroundContents(d),this.selectNode(b,d),void 0}catch(e){}if(b.splitBoundaries(),c=b.getNodes([a.TEXT_NODE]),c.length){for(var f=0,g=c.length;g>f;++f)d=c[f],this.getAncestorWithClass(d)||this.applyToTextNode(d);b.setStart(c[0],0),d=c[c.length-1],b.setEnd(d,d.length),this.normalize&&this.postApply(c,b)}},undoToRange:function(b){var c,d,e=b.getNodes([a.TEXT_NODE]);e.length?(b.splitBoundaries(),e=b.getNodes([a.TEXT_NODE])):(e=b.endContainer.ownerDocument.createTextNode(a.INVISIBLE_SPACE),b.insertNode(e),b.selectNode(e),e=[e]);for(var f=0,g=e.length;g>f;++f)c=e[f],(d=this.getAncestorWithClass(c))&&this.undoToTextNode(c,b,d);1==g?this.selectNode(b,e[0]):(b.setStart(e[0],0),c=e[e.length-1],b.setEnd(c,c.length),this.normalize&&this.postApply(e,b))},selectNode:function(b,c){var d=c.nodeType===a.ELEMENT_NODE,e="canHaveHTML"in c?c.canHaveHTML:!0,f=d?c.innerHTML:c.data;if((f=""===f||f===a.INVISIBLE_SPACE)&&d&&e)try{c.innerHTML=a.INVISIBLE_SPACE}catch(g){}b.selectNodeContents(c),f&&d?b.collapse(!1):f&&(b.setStartAfter(c),b.setEndAfter(c))},getTextSelectedByRange:function(a,b){var c=b.cloneRange();c.selectNodeContents(a);var d=c.intersection(b),d=d?d.toString():"";return c.detach(),d},isAppliedToRange:function(b){var c,d=[],e=b.getNodes([a.TEXT_NODE]);if(!e.length)return(c=this.getAncestorWithClass(b.startContainer))?[c]:!1;for(var f,g=0,h=e.length;h>g;++g){if(f=this.getTextSelectedByRange(e[g],b),c=this.getAncestorWithClass(e[g]),""!=f&&!c)return!1;d.push(c)}return d},toggleRange:function(a){this.isAppliedToRange(a)?this.undoToRange(a):this.applyToRange(a)}},a.selection.HTMLApplier=f}(wysihtml5,rangy),wysihtml5.Commands=Base.extend({constructor:function(a){this.editor=a,this.composer=a.composer,this.doc=this.composer.doc},support:function(a){return wysihtml5.browser.supportsCommand(this.doc,a)},exec:function(a,b){var c=wysihtml5.commands[a],d=wysihtml5.lang.array(arguments).get(),e=c&&c.exec,f=null;if(this.editor.fire("beforecommand:composer"),e)d.unshift(this.composer),f=e.apply(c,d);else try{f=this.doc.execCommand(a,!1,b)}catch(g){}return this.editor.fire("aftercommand:composer"),f},state:function(a){var b=wysihtml5.commands[a],c=wysihtml5.lang.array(arguments).get(),d=b&&b.state;if(d)return c.unshift(this.composer),d.apply(b,c);try{return this.doc.queryCommandState(a)}catch(e){return!1}},value:function(a){var b=wysihtml5.commands[a],c=b&&b.value;if(c)return c.call(b,this.composer,a);try{return this.doc.queryCommandValue(a)}catch(d){return null}}}),function(a){a.commands.bold={exec:function(b,c){return a.commands.formatInline.exec(b,c,"b")},state:function(b,c){return a.commands.formatInline.state(b,c,"b")},value:function(){}}}(wysihtml5),function(a){function b(b,f){var g,h,i,j=b.doc,k="_wysihtml5-temp-"+ +new Date,l=0;for(a.commands.formatInline.exec(b,c,d,k,/non-matching-class/g),g=j.querySelectorAll(d+"."+k),k=g.length;k>l;l++)for(i in h=g[l],h.removeAttribute("class"),f)h.setAttribute(i,f[i]);l=h,1===k&&(i=e.getTextContent(h),k=!!h.querySelector("*"),i=""===i||i===a.INVISIBLE_SPACE,!k&&i&&(e.setTextContent(h,f.text||h.href),j=j.createTextNode(" "),b.selection.setAfter(h),b.selection.insertNode(j),l=j)),b.selection.setAfter(l)}var c,d="A",e=a.dom;a.commands.createLink={exec:function(a,c,d){var f=this.state(a,c);f?a.selection.executeAndRestore(function(){for(var a,b,c,d=f.length,g=0;d>g;g++)a=f[g],b=e.getParentElement(a,{nodeName:"code"}),c=e.getTextContent(a),c.match(e.autoLink.URL_REG_EXP)&&!b?e.renameElement(a,"code"):e.replaceWithChildNodes(a)}):(d="object"==typeof d?d:{href:d},b(a,d))},state:function(b,c){return a.commands.formatInline.state(b,c,"A")},value:function(){return c}}}(wysihtml5),function(a){var b=/wysiwyg-font-size-[a-z\-]+/g;a.commands.fontSize={exec:function(c,d,e){return a.commands.formatInline.exec(c,d,"span","wysiwyg-font-size-"+e,b)},state:function(c,d,e){return a.commands.formatInline.state(c,d,"span","wysiwyg-font-size-"+e,b)},value:function(){}}}(wysihtml5),function(a){var b=/wysiwyg-color-[a-z]+/g;a.commands.foreColor={exec:function(c,d,e){return a.commands.formatInline.exec(c,d,"span","wysiwyg-color-"+e,b)},state:function(c,d,e){return a.commands.formatInline.state(c,d,"span","wysiwyg-color-"+e,b)},value:function(){}}}(wysihtml5),function(a){function b(b){for(b=b.previousSibling;b&&b.nodeType===a.TEXT_NODE&&!a.lang.string(b.data).trim();)b=b.previousSibling;return b}function c(b){for(b=b.nextSibling;b&&b.nodeType===a.TEXT_NODE&&!a.lang.string(b.data).trim();)b=b.nextSibling;return b}function d(a){return"BR"===a.nodeName||"block"===g.getStyle("display").from(a)?!0:!1}function e(b,c,d,e){if(e)var f=g.observe(b,"DOMNodeInserted",function(b){var c,b=b.target;b.nodeType===a.ELEMENT_NODE&&(c=g.getStyle("display").from(b),"inline"!==c.substr(0,6)&&(b.className+=" "+e))});b.execCommand(c,!1,d),f&&f.stop()}function f(a,d){a.selection.selectLine(),a.selection.surround(d);var e=c(d),f=b(d);e&&"BR"===e.nodeName&&e.parentNode.removeChild(e),f&&"BR"===f.nodeName&&f.parentNode.removeChild(f),(e=d.lastChild)&&"BR"===e.nodeName&&e.parentNode.removeChild(e),a.selection.selectNode(d)}var g=a.dom,h="H1 H2 H3 H4 H5 H6 P BLOCKQUOTE DIV".split(" ");a.commands.formatBlock={exec:function(i,j,k,l,m){var n,o=i.doc,p=this.state(i,j,k,l,m),k="string"==typeof k?k.toUpperCase():k;if(p)i.selection.executeAndRestoreSimple(function(){m&&(p.className=p.className.replace(m,""));var e=!!a.lang.string(p.className).trim();if(e||p.nodeName!==(k||"DIV"))e&&g.renameElement(p,"DIV");else{var e=p,f=e.ownerDocument,h=c(e),i=b(e);h&&!d(h)&&e.parentNode.insertBefore(f.createElement("br"),h),i&&!d(i)&&e.parentNode.insertBefore(f.createElement("br"),e),g.replaceWithChildNodes(p)}});else{if((null===k||a.lang.array(h).contains(k))&&(n=i.selection.getSelectedNode(),p=g.getParentElement(n,{nodeName:h})))return i.selection.executeAndRestoreSimple(function(){if(k&&(p=g.renameElement(p,k)),l){var a=p;a.className?(a.className=a.className.replace(m,""),a.className+=" "+l):a.className=l}}),void 0;i.commands.support(j)?e(o,j,k||"DIV",l):(p=o.createElement(k||"DIV"),l&&(p.className=l),f(i,p))}},state:function(a,b,c,d,e){return c="string"==typeof c?c.toUpperCase():c,a=a.selection.getSelectedNode(),g.getParentElement(a,{nodeName:c,className:d,classRegExp:e})},value:function(){}}}(wysihtml5),function(a){function b(b,e,f){var g=b+":"+e;if(!d[g]){var h=d,i=a.selection.HTMLApplier,j=c[b],b=j?[b.toLowerCase(),j.toLowerCase()]:[b.toLowerCase()];h[g]=new i(b,e,f,!0)}return d[g]}var c={strong:"b",em:"i",b:"strong",i:"em"},d={};a.commands.formatInline={exec:function(a,c,d,e,f){return(c=a.selection.getRange())?(b(d,e,f).toggleRange(c),a.selection.setSelection(c),void 0):!1},state:function(d,e,f,g,h){var e=d.doc,i=c[f]||f;return!a.dom.hasElementWithTagName(e,f)&&!a.dom.hasElementWithTagName(e,i)||g&&!a.dom.hasElementWithClassName(e,g)?!1:(d=d.selection.getRange(),d?b(f,g,h).isAppliedToRange(d):!1)},value:function(){}}}(wysihtml5),function(a){a.commands.insertHTML={exec:function(a,b,c){a.commands.support(b)?a.doc.execCommand(b,!1,c):a.selection.insertHTML(c)},state:function(){return!1},value:function(){}}}(wysihtml5),function(a){a.commands.insertImage={exec:function(b,c,d){var e,d="object"==typeof d?d:{src:d},f=b.doc,c=this.state(b);if(c)b.selection.setBefore(c),d=c.parentNode,d.removeChild(c),a.dom.removeEmptyTextNodes(d),"A"===d.nodeName&&!d.firstChild&&(b.selection.setAfter(d),d.parentNode.removeChild(d)),a.quirks.redraw(b.element);else{c=f.createElement("IMG");for(e in d)c[e]=d[e];b.selection.insertNode(c),a.browser.hasProblemsSettingCaretAfterImg()?(d=f.createTextNode(a.INVISIBLE_SPACE),b.selection.insertNode(d),b.selection.setAfter(d)):b.selection.setAfter(c)}},state:function(b){var c;return a.dom.hasElementWithTagName(b.doc,"IMG")?(c=b.selection.getSelectedNode())?"IMG"===c.nodeName?c:c.nodeType!==a.ELEMENT_NODE?!1:(c=b.selection.getText(),(c=a.lang.string(c).trim())?!1:(b=b.selection.getNodes(a.ELEMENT_NODE,function(a){return"IMG"===a.nodeName}),1!==b.length?!1:b[0])):!1:!1},value:function(a){return(a=this.state(a))&&a.src}}}(wysihtml5),function(a){var b="
    "+(a.browser.needsSpaceAfterLineBreak()?" ":"");a.commands.insertLineBreak={exec:function(c,d){c.commands.support(d)?(c.doc.execCommand(d,!1,null),a.browser.autoScrollsToCaret()||c.selection.scrollIntoView()):c.commands.exec("insertHTML",b)},state:function(){return!1},value:function(){}}}(wysihtml5),function(a){a.commands.insertOrderedList={exec:function(b,c){var d,e=b.doc,f=b.selection.getSelectedNode(),g=a.dom.getParentElement(f,{nodeName:"OL"}),h=a.dom.getParentElement(f,{nodeName:"UL"}),f="_wysihtml5-temp-"+(new Date).getTime();b.commands.support(c)?e.execCommand(c,!1,null):g?b.selection.executeAndRestoreSimple(function(){a.dom.resolveList(g)}):h?b.selection.executeAndRestoreSimple(function(){a.dom.renameElement(h,"ol")}):(b.commands.exec("formatBlock","div",f),d=e.querySelector("."+f),e=""===d.innerHTML||d.innerHTML===a.INVISIBLE_SPACE,b.selection.executeAndRestoreSimple(function(){g=a.dom.convertToList(d,"ol")}),e&&b.selection.selectNode(g.querySelector("li")))},state:function(b){return b=b.selection.getSelectedNode(),a.dom.getParentElement(b,{nodeName:"OL"})},value:function(){}}}(wysihtml5),function(a){a.commands.insertUnorderedList={exec:function(b,c){var d,e=b.doc,f=b.selection.getSelectedNode(),g=a.dom.getParentElement(f,{nodeName:"UL"}),h=a.dom.getParentElement(f,{nodeName:"OL"}),f="_wysihtml5-temp-"+(new Date).getTime();b.commands.support(c)?e.execCommand(c,!1,null):g?b.selection.executeAndRestoreSimple(function(){a.dom.resolveList(g)}):h?b.selection.executeAndRestoreSimple(function(){a.dom.renameElement(h,"ul")}):(b.commands.exec("formatBlock","div",f),d=e.querySelector("."+f),e=""===d.innerHTML||d.innerHTML===a.INVISIBLE_SPACE,b.selection.executeAndRestoreSimple(function(){g=a.dom.convertToList(d,"ul")}),e&&b.selection.selectNode(g.querySelector("li")))},state:function(b){return b=b.selection.getSelectedNode(),a.dom.getParentElement(b,{nodeName:"UL"})},value:function(){}}}(wysihtml5),function(a){a.commands.italic={exec:function(b,c){return a.commands.formatInline.exec(b,c,"i")},state:function(b,c){return a.commands.formatInline.state(b,c,"i")},value:function(){}}}(wysihtml5),function(a){var b=/wysiwyg-text-align-[a-z]+/g;a.commands.justifyCenter={exec:function(c){return a.commands.formatBlock.exec(c,"formatBlock",null,"wysiwyg-text-align-center",b)},state:function(c){return a.commands.formatBlock.state(c,"formatBlock",null,"wysiwyg-text-align-center",b)},value:function(){}}}(wysihtml5),function(a){var b=/wysiwyg-text-align-[a-z]+/g;a.commands.justifyLeft={exec:function(c){return a.commands.formatBlock.exec(c,"formatBlock",null,"wysiwyg-text-align-left",b)},state:function(c){return a.commands.formatBlock.state(c,"formatBlock",null,"wysiwyg-text-align-left",b)},value:function(){}}}(wysihtml5),function(a){var b=/wysiwyg-text-align-[a-z]+/g;a.commands.justifyRight={exec:function(c){return a.commands.formatBlock.exec(c,"formatBlock",null,"wysiwyg-text-align-right",b)},state:function(c){return a.commands.formatBlock.state(c,"formatBlock",null,"wysiwyg-text-align-right",b)},value:function(){}}}(wysihtml5),function(a){a.commands.underline={exec:function(b,c){return a.commands.formatInline.exec(b,c,"u")},state:function(b,c){return a.commands.formatInline.state(b,c,"u")},value:function(){}}}(wysihtml5),function(a){var b=''+a.INVISIBLE_SPACE+"",c=''+a.INVISIBLE_SPACE+"",d=a.dom;a.UndoManager=a.lang.Dispatcher.extend({constructor:function(a){this.editor=a,this.composer=a.composer,this.element=this.composer.element,this.history=[this.composer.getValue()],this.position=1,this.composer.commands.support("insertHTML")&&this._observe()},_observe:function(){var e,f=this,g=this.composer.sandbox.getDocument();if(d.observe(this.element,"keydown",function(a){if(!a.altKey&&(a.ctrlKey||a.metaKey)){var b=a.keyCode,c=90===b&&a.shiftKey||89===b;90!==b||a.shiftKey?c&&(f.redo(),a.preventDefault()):(f.undo(),a.preventDefault())}}),d.observe(this.element,"keydown",function(a){a=a.keyCode,a!==e&&(e=a,(8===a||46===a)&&f.transact())}),a.browser.hasUndoInContextMenu()){var h,i,j=function(){for(var a;a=g.querySelector("._wysihtml5-temp");)a.parentNode.removeChild(a);clearInterval(h)};d.observe(this.element,"contextmenu",function(){j(),f.composer.selection.executeAndRestoreSimple(function(){f.element.lastChild&&f.composer.selection.setAfter(f.element.lastChild),g.execCommand("insertHTML",!1,b),g.execCommand("insertHTML",!1,c),g.execCommand("undo",!1,null)}),h=setInterval(function(){g.getElementById("_wysihtml5-redo")?(j(),f.redo()):g.getElementById("_wysihtml5-undo")||(j(),f.undo())},400),i||(i=!0,d.observe(document,"mousedown",j),d.observe(g,["mousedown","paste","cut","copy"],j))})}this.editor.observe("newword:composer",function(){f.transact()}).observe("beforecommand:composer",function(){f.transact()})},transact:function(){var a=this.history[this.position-1],b=this.composer.getValue();b!=a&&(40<(this.history.length=this.position)&&(this.history.shift(),this.position--),this.position++,this.history.push(b))},undo:function(){this.transact(),1>=this.position||(this.set(this.history[--this.position-1]),this.editor.fire("undo:composer"))},redo:function(){this.position>=this.history.length||(this.set(this.history[++this.position-1]),this.editor.fire("redo:composer"))},set:function(a){this.composer.setValue(a),this.editor.focus(!0)}})}(wysihtml5),wysihtml5.views.View=Base.extend({constructor:function(a,b,c){this.parent=a,this.element=b,this.config=c,this._observeViewChange()},_observeViewChange:function(){var a=this;this.parent.observe("beforeload",function(){a.parent.observe("change_view",function(b){b===a.name?(a.parent.currentView=a,a.show(),setTimeout(function(){a.focus()},0)):a.hide()})})},focus:function(){if(this.element.ownerDocument.querySelector(":focus")!==this.element)try{this.element.focus()}catch(a){}},hide:function(){this.element.style.display="none"},show:function(){this.element.style.display=""},disable:function(){this.element.setAttribute("disabled","disabled")},enable:function(){this.element.removeAttribute("disabled")}}),function(a){var b=a.dom,c=a.browser;a.views.Composer=a.views.View.extend({name:"composer",CARET_HACK:"
    ",constructor:function(a,b,c){this.base(a,b,c),this.textarea=this.parent.textarea,this._initSandbox()},clear:function(){this.element.innerHTML=c.displaysCaretInEmptyContentEditableCorrectly()?"":this.CARET_HACK},getValue:function(b){var c=this.isEmpty()?"":a.quirks.getCorrectInnerHTML(this.element);return b&&(c=this.parent.parse(c)),c=a.lang.string(c).replace(a.INVISIBLE_SPACE).by("")},setValue:function(a,b){b&&(a=this.parent.parse(a)),this.element.innerHTML=a},show:function(){this.iframe.style.display=this._displayStyle||"",this.disable(),this.enable()},hide:function(){this._displayStyle=b.getStyle("display").from(this.iframe),"none"===this._displayStyle&&(this._displayStyle=null),this.iframe.style.display="none"},disable:function(){this.element.removeAttribute("contentEditable"),this.base()},enable:function(){this.element.setAttribute("contentEditable","true"),this.base()},focus:function(b){a.browser.doesAsyncFocus()&&this.hasPlaceholderSet()&&this.clear(),this.base();var c=this.element.lastChild;b&&c&&("BR"===c.nodeName?this.selection.setBefore(this.element.lastChild):this.selection.setAfter(this.element.lastChild))},getTextContent:function(){return b.getTextContent(this.element)},hasPlaceholderSet:function(){return this.getTextContent()==this.textarea.element.getAttribute("placeholder")},isEmpty:function(){var a=this.element.innerHTML;return""===a||a===this.CARET_HACK||this.hasPlaceholderSet()||""===this.getTextContent()&&!this.element.querySelector("blockquote, ul, ol, img, embed, object, table, iframe, svg, video, audio, button, input, select, textarea")},_initSandbox:function(){var a=this;this.sandbox=new b.Sandbox(function(){a._create()},{stylesheets:this.config.stylesheets}),this.iframe=this.sandbox.getIframe();var c=document.createElement("input");c.type="hidden",c.name="_wysihtml5_mode",c.value=1;var d=this.textarea.element;b.insert(this.iframe).after(d),b.insert(c).after(d)},_create:function(){var d=this;this.doc=this.sandbox.getDocument(),this.element=this.doc.body,this.textarea=this.parent.textarea,this.element.innerHTML=this.textarea.getValue(!0),this.enable(),this.selection=new a.Selection(this.parent),this.commands=new a.Commands(this.parent),b.copyAttributes("className spellcheck title lang dir accessKey".split(" ")).from(this.textarea.element).to(this.element),b.addClass(this.element,this.config.composerClassName),this.config.style&&this.style(),this.observe();var e=this.config.name;e&&(b.addClass(this.element,e),b.addClass(this.iframe,e)),(e="string"==typeof this.config.placeholder?this.config.placeholder:this.textarea.element.getAttribute("placeholder"))&&b.simulatePlaceholder(this.parent,this,e),this.commands.exec("styleWithCSS",!1),this._initAutoLinking(),this._initObjectResizing(),this._initUndoManager(),(this.textarea.element.hasAttribute("autofocus")||document.querySelector(":focus")==this.textarea.element)&&setTimeout(function(){d.focus()},100),a.quirks.insertLineBreakOnReturn(this),c.clearsContentEditableCorrectly()||a.quirks.ensureProperClearing(this),c.clearsListsInContentEditableCorrectly()||a.quirks.ensureProperClearingOfLists(this),this.initSync&&this.config.sync&&this.initSync(),this.textarea.hide(),this.parent.fire("beforeload").fire("load")},_initAutoLinking:function(){var d=this,e=c.canDisableAutoLinking(),f=c.doesAutoLinkingInContentEditable();if(e&&this.commands.exec("autoUrlDetect",!1),this.config.autoLink){(!f||f&&e)&&this.parent.observe("newword:composer",function(){d.selection.executeAndRestore(function(a,c){b.autoLink(c.parentNode)})});var g=this.sandbox.getDocument().getElementsByTagName("a"),h=b.autoLink.URL_REG_EXP,i=function(c){return c=a.lang.string(b.getTextContent(c)).trim(),"www."===c.substr(0,4)&&(c="http://"+c),c};b.observe(this.element,"keydown",function(a){if(g.length){var c,a=d.selection.getSelectedNode(a.target.ownerDocument),e=b.getParentElement(a,{nodeName:"A"},4);e&&(c=i(e),setTimeout(function(){var a=i(e);a!==c&&a.match(h)&&e.setAttribute("href",a)},0))}})}},_initObjectResizing:function(){var d=["width","height"],e=d.length,f=this.element;this.commands.exec("enableObjectResizing",this.config.allowObjectResizing),this.config.allowObjectResizing?c.supportsEvent("resizeend")&&b.observe(f,"resizeend",function(b){for(var c,b=b.target||b.srcElement,g=b.style,h=0;e>h;h++)c=d[h],g[c]&&(b.setAttribute(c,parseInt(g[c],10)),g[c]="");a.quirks.redraw(f)}):c.supportsEvent("resizestart")&&b.observe(f,"resizestart",function(a){a.preventDefault()})},_initUndoManager:function(){new a.UndoManager(this.parent)}})}(wysihtml5),function(a){var b=a.dom,c=document,d=window,e=c.createElement("div"),f="background-color color cursor font-family font-size font-style font-variant font-weight line-height letter-spacing text-align text-decoration text-indent text-rendering word-break word-wrap word-spacing".split(" "),g="background-color border-collapse border-bottom-color border-bottom-style border-bottom-width border-left-color border-left-style border-left-width border-right-color border-right-style border-right-width border-top-color border-top-style border-top-width clear display float margin-bottom margin-left margin-right margin-top outline-color outline-offset outline-width outline-style padding-left padding-right padding-top padding-bottom position top left right bottom z-index vertical-align text-align -webkit-box-sizing -moz-box-sizing -ms-box-sizing box-sizing -webkit-box-shadow -moz-box-shadow -ms-box-shadow box-shadow -webkit-border-top-right-radius -moz-border-radius-topright border-top-right-radius -webkit-border-bottom-right-radius -moz-border-radius-bottomright border-bottom-right-radius -webkit-border-bottom-left-radius -moz-border-radius-bottomleft border-bottom-left-radius -webkit-border-top-left-radius -moz-border-radius-topleft border-top-left-radius width height".split(" "),h="width height top left right bottom".split(" "),i=["html { height: 100%; }","body { min-height: 100%; padding: 0; margin: 0; margin-top: -1px; padding-top: 1px; }","._wysihtml5-temp { display: none; }",a.browser.isGecko?"body.placeholder { color: graytext !important; }":"body.placeholder { color: #a9a9a9 !important; }","body[disabled] { background-color: #eee !important; color: #999 !important; cursor: default !important; }","img:-moz-broken { -moz-force-broken-image-icon: 1; height: 24px; width: 24px; }"],j=function(a){if(a.setActive)try{a.setActive()}catch(e){}else{var f=a.style,g=c.documentElement.scrollTop||c.body.scrollTop,h=c.documentElement.scrollLeft||c.body.scrollLeft,f={position:f.position,top:f.top,left:f.left,WebkitUserSelect:f.WebkitUserSelect};b.setStyles({position:"absolute",top:"-99999px",left:"-99999px",WebkitUserSelect:"none"}).on(a),a.focus(),b.setStyles(f).on(a),d.scrollTo&&d.scrollTo(h,g)}};a.views.Composer.prototype.style=function(){var k=this,l=c.querySelector(":focus"),m=this.textarea.element,n=m.hasAttribute("placeholder"),o=n&&m.getAttribute("placeholder");this.focusStylesHost=this.focusStylesHost||e.cloneNode(!1),this.blurStylesHost=this.blurStylesHost||e.cloneNode(!1),n&&m.removeAttribute("placeholder"),m===l&&m.blur(),b.copyStyles(g).from(m).to(this.iframe).andTo(this.blurStylesHost),b.copyStyles(f).from(m).to(this.element).andTo(this.blurStylesHost),b.insertCSS(i).into(this.element.ownerDocument),j(m),b.copyStyles(g).from(m).to(this.focusStylesHost),b.copyStyles(f).from(m).to(this.focusStylesHost); -var p=a.lang.array(g).without(["display"]);if(l?l.focus():m.blur(),n&&m.setAttribute("placeholder",o),!a.browser.hasCurrentStyleProperty())var q=b.observe(d,"resize",function(){if(b.contains(document.documentElement,k.iframe)){var a=b.getStyle("display").from(m),c=b.getStyle("display").from(k.iframe);m.style.display="",k.iframe.style.display="none",b.copyStyles(h).from(m).to(k.iframe).andTo(k.focusStylesHost).andTo(k.blurStylesHost),k.iframe.style.display=c,m.style.display=a}else q.stop()});return this.parent.observe("focus:composer",function(){b.copyStyles(p).from(k.focusStylesHost).to(k.iframe),b.copyStyles(f).from(k.focusStylesHost).to(k.element)}),this.parent.observe("blur:composer",function(){b.copyStyles(p).from(k.blurStylesHost).to(k.iframe),b.copyStyles(f).from(k.blurStylesHost).to(k.element)}),this}}(wysihtml5),function(a){var b=a.dom,c=a.browser,d={66:"bold",73:"italic",85:"underline"};a.views.Composer.prototype.observe=function(){var e=this,f=this.getValue(),g=this.sandbox.getIframe(),h=this.element,i=c.supportsEventsInIframeCorrectly()?h:this.sandbox.getWindow(),j=c.supportsEvent("drop")?["drop","paste"]:["dragdrop","paste"];b.observe(g,"DOMNodeRemoved",function(){clearInterval(k),e.parent.fire("destroy:composer")});var k=setInterval(function(){b.contains(document.documentElement,g)||(clearInterval(k),e.parent.fire("destroy:composer"))},250);b.observe(i,"focus",function(){e.parent.fire("focus").fire("focus:composer"),setTimeout(function(){f=e.getValue()},0)}),b.observe(i,"blur",function(){f!==e.getValue()&&e.parent.fire("change").fire("change:composer"),e.parent.fire("blur").fire("blur:composer")}),a.browser.isIos()&&b.observe(h,"blur",function(){var a=h.ownerDocument.createElement("input"),b=document.documentElement.scrollTop||document.body.scrollTop,c=document.documentElement.scrollLeft||document.body.scrollLeft;try{e.selection.insertNode(a)}catch(d){h.appendChild(a)}a.focus(),a.parentNode.removeChild(a),window.scrollTo(c,b)}),b.observe(h,"dragenter",function(){e.parent.fire("unset_placeholder")}),c.firesOnDropOnlyWhenOnDragOverIsCancelled()&&b.observe(h,["dragover","dragenter"],function(a){a.preventDefault()}),b.observe(h,j,function(a){var b,d=a.dataTransfer;d&&c.supportsDataTransfer()&&(b=d.getData("text/html")||d.getData("text/plain")),b?(h.focus(),e.commands.exec("insertHTML",b),e.parent.fire("paste").fire("paste:composer"),a.stopPropagation(),a.preventDefault()):setTimeout(function(){e.parent.fire("paste").fire("paste:composer")},0)}),b.observe(h,"keyup",function(b){b=b.keyCode,(b===a.SPACE_KEY||b===a.ENTER_KEY)&&e.parent.fire("newword:composer")}),this.parent.observe("paste:composer",function(){setTimeout(function(){e.parent.fire("newword:composer")},0)}),c.canSelectImagesInContentEditable()||b.observe(h,"mousedown",function(a){var b=a.target;"IMG"===b.nodeName&&(e.selection.selectNode(b),a.preventDefault())}),b.observe(h,"keydown",function(a){var b=d[a.keyCode];(a.ctrlKey||a.metaKey)&&!a.altKey&&b&&(e.commands.exec(b),a.preventDefault())}),b.observe(h,"keydown",function(b){var c=e.selection.getSelectedNode(!0),d=b.keyCode;!c||"IMG"!==c.nodeName||d!==a.BACKSPACE_KEY&&d!==a.DELETE_KEY||(d=c.parentNode,d.removeChild(c),"A"===d.nodeName&&!d.firstChild&&d.parentNode.removeChild(d),setTimeout(function(){a.quirks.redraw(h)},0),b.preventDefault())});var l={IMG:"Image: ",A:"Link: "};b.observe(h,"mouseover",function(a){var a=a.target,b=a.nodeName;!("A"!==b&&"IMG"!==b)&&!a.hasAttribute("title")&&(b=l[b]+(a.getAttribute("href")||a.getAttribute("src")),a.setAttribute("title",b))})}}(wysihtml5),function(a){a.views.Synchronizer=Base.extend({constructor:function(a,b,c){this.editor=a,this.textarea=b,this.composer=c,this._observe()},fromComposerToTextarea:function(b){this.textarea.setValue(a.lang.string(this.composer.getValue()).trim(),b)},fromTextareaToComposer:function(a){var b=this.textarea.getValue();b?this.composer.setValue(b,a):(this.composer.clear(),this.editor.fire("set_placeholder"))},sync:function(a){"textarea"===this.editor.currentView.name?this.fromTextareaToComposer(a):this.fromComposerToTextarea(a)},_observe:function(){var b,c=this,d=this.textarea.element.form,e=function(){b=setInterval(function(){c.fromComposerToTextarea()},400)},f=function(){clearInterval(b),b=null};e(),d&&(a.dom.observe(d,"submit",function(){c.sync(!0)}),a.dom.observe(d,"reset",function(){setTimeout(function(){c.fromTextareaToComposer()},0)})),this.editor.observe("change_view",function(a){"composer"!==a||b?"textarea"===a&&(c.fromComposerToTextarea(!0),f()):(c.fromTextareaToComposer(!0),e())}),this.editor.observe("destroy:composer",f)}})}(wysihtml5),wysihtml5.views.Textarea=wysihtml5.views.View.extend({name:"textarea",constructor:function(a,b,c){this.base(a,b,c),this._observe()},clear:function(){this.element.value=""},getValue:function(a){var b=this.isEmpty()?"":this.element.value;return a&&(b=this.parent.parse(b)),b},setValue:function(a,b){b&&(a=this.parent.parse(a)),this.element.value=a},hasPlaceholderSet:function(){var a=wysihtml5.browser.supportsPlaceholderAttributeOn(this.element),b=this.element.getAttribute("placeholder")||null,c=this.element.value;return a&&!c||c===b},isEmpty:function(){return!wysihtml5.lang.string(this.element.value).trim()||this.hasPlaceholderSet()},_observe:function(){var a=this.element,b=this.parent,c={focusin:"focus",focusout:"blur"},d=wysihtml5.browser.supportsEvent("focusin")?["focusin","focusout","change"]:["focus","blur","change"];b.observe("beforeload",function(){wysihtml5.dom.observe(a,d,function(a){a=c[a.type]||a.type,b.fire(a).fire(a+":textarea")}),wysihtml5.dom.observe(a,["paste","drop"],function(){setTimeout(function(){b.fire("paste").fire("paste:textarea")},0)})})}}),function(a){var b=a.dom;a.toolbar.Dialog=a.lang.Dispatcher.extend({constructor:function(a,b){this.link=a,this.container=b},_observe:function(){if(!this._observed){var c=this,d=function(a){var b=c._serialize();b==c.elementToChange?c.fire("edit",b):c.fire("save",b),c.hide(),a.preventDefault(),a.stopPropagation()};b.observe(c.link,"click",function(){b.hasClass(c.link,"wysihtml5-command-dialog-opened")&&setTimeout(function(){c.hide()},0)}),b.observe(this.container,"keydown",function(b){var e=b.keyCode;e===a.ENTER_KEY&&d(b),e===a.ESCAPE_KEY&&c.hide()}),b.delegate(this.container,"[data-wysihtml5-dialog-action=save]","click",d),b.delegate(this.container,"[data-wysihtml5-dialog-action=cancel]","click",function(a){c.fire("cancel"),c.hide(),a.preventDefault(),a.stopPropagation()});for(var e=this.container.querySelectorAll("input, select, textarea"),f=0,g=e.length,h=function(){clearInterval(c.interval)};g>f;f++)b.observe(e[f],"change",h);this._observed=!0}},_serialize:function(){for(var a=this.elementToChange||{},b=this.container.querySelectorAll("[data-wysihtml5-dialog-field]"),c=b.length,d=0;c>d;d++)a[b[d].getAttribute("data-wysihtml5-dialog-field")]=b[d].value;return a},_interpolate:function(a){for(var b,c,d=document.querySelector(":focus"),e=this.container.querySelectorAll("[data-wysihtml5-dialog-field]"),f=e.length,g=0;f>g;g++)b=e[g],b!==d&&!(a&&"hidden"===b.type)&&(c=b.getAttribute("data-wysihtml5-dialog-field"),c=this.elementToChange?this.elementToChange[c]||"":b.defaultValue,b.value=c)},show:function(a){var c=this,d=this.container.querySelector("input, select, textarea");if(this.elementToChange=a,this._observe(),this._interpolate(),a&&(this.interval=setInterval(function(){c._interpolate(!0)},500)),b.addClass(this.link,"wysihtml5-command-dialog-opened"),this.container.style.display="",this.fire("show"),d&&!a)try{d.focus()}catch(e){}},hide:function(){clearInterval(this.interval),this.elementToChange=null,b.removeClass(this.link,"wysihtml5-command-dialog-opened"),this.container.style.display="none",this.fire("hide")}})}(wysihtml5),function(a){var b=a.dom,c={position:"relative"},d={left:0,margin:0,opacity:0,overflow:"hidden",padding:0,position:"absolute",top:0,zIndex:1},e={cursor:"inherit",fontSize:"50px",height:"50px",marginTop:"-25px",outline:0,padding:0,position:"absolute",right:"-4px",top:"50%"},f={"x-webkit-speech":"",speech:""};a.toolbar.Speech=function(g,h){var i=document.createElement("input");if(a.browser.supportsSpeechApiOn(i)){var j=document.createElement("div");a.lang.object(d).merge({width:h.offsetWidth+"px",height:h.offsetHeight+"px"}),b.insert(i).into(j),b.insert(j).into(h),b.setStyles(e).on(i),b.setAttributes(f).on(i),b.setStyles(d).on(j),b.setStyles(c).on(h),b.observe(i,"onwebkitspeechchange"in i?"webkitspeechchange":"speechchange",function(){g.execCommand("insertText",i.value),i.value=""}),b.observe(i,"click",function(a){b.hasClass(h,"wysihtml5-command-disabled")&&a.preventDefault(),a.stopPropagation()})}else h.style.display="none"}}(wysihtml5),function(a){var b=a.dom;a.toolbar.Toolbar=Base.extend({constructor:function(b,c){this.editor=b,this.container="string"==typeof c?document.getElementById(c):c,this.composer=b.composer,this._getLinks("command"),this._getLinks("action"),this._observe(),this.show();for(var d=this.container.querySelectorAll("[data-wysihtml5-command=insertSpeech]"),e=d.length,f=0;e>f;f++)new a.toolbar.Speech(this,d[f])},_getLinks:function(b){for(var c,d,e,f,g,h=this[b+"Links"]=a.lang.array(this.container.querySelectorAll("[data-wysihtml5-"+b+"]")).get(),i=h.length,j=0,k=this[b+"Mapping"]={};i>j;j++)c=h[j],e=c.getAttribute("data-wysihtml5-"+b),f=c.getAttribute("data-wysihtml5-"+b+"-value"),d=this.container.querySelector("[data-wysihtml5-"+b+"-group='"+e+"']"),g=this._getDialog(c,e),k[e+":"+f]={link:c,group:d,name:e,value:f,dialog:g,state:!1}},_getDialog:function(b,c){var d,e,f=this,g=this.container.querySelector("[data-wysihtml5-dialog='"+c+"']");return g&&(d=new a.toolbar.Dialog(b,g),d.observe("show",function(){e=f.composer.selection.getBookmark(),f.editor.fire("show:dialog",{command:c,dialogContainer:g,commandLink:b})}),d.observe("save",function(a){e&&f.composer.selection.setBookmark(e),f._execCommand(c,a),f.editor.fire("save:dialog",{command:c,dialogContainer:g,commandLink:b})}),d.observe("cancel",function(){f.editor.focus(!1),f.editor.fire("cancel:dialog",{command:c,dialogContainer:g,commandLink:b})})),d},execCommand:function(a,b){if(!this.commandsDisabled){var c=this.commandMapping[a+":"+b];c&&c.dialog&&!c.state?c.dialog.show():this._execCommand(a,b)}},_execCommand:function(a,b){this.editor.focus(!1),this.composer.commands.exec(a,b),this._updateLinkStates()},execAction:function(a){var b=this.editor;switch(a){case"change_view":b.currentView===b.textarea?b.fire("change_view","composer"):b.fire("change_view","textarea")}},_observe:function(){for(var a=this,c=this.editor,d=this.container,e=this.commandLinks.concat(this.actionLinks),f=e.length,g=0;f>g;g++)b.setAttributes({href:"javascript:;",unselectable:"on"}).on(e[g]);b.delegate(d,"[data-wysihtml5-command]","mousedown",function(a){a.preventDefault()}),b.delegate(d,"[data-wysihtml5-command]","click",function(b){var c=this.getAttribute("data-wysihtml5-command"),d=this.getAttribute("data-wysihtml5-command-value");a.execCommand(c,d),b.preventDefault()}),b.delegate(d,"[data-wysihtml5-action]","click",function(b){var c=this.getAttribute("data-wysihtml5-action");a.execAction(c),b.preventDefault()}),c.observe("focus:composer",function(){a.bookmark=null,clearInterval(a.interval),a.interval=setInterval(function(){a._updateLinkStates()},500)}),c.observe("blur:composer",function(){clearInterval(a.interval)}),c.observe("destroy:composer",function(){clearInterval(a.interval)}),c.observe("change_view",function(c){setTimeout(function(){a.commandsDisabled="composer"!==c,a._updateLinkStates(),a.commandsDisabled?b.addClass(d,"wysihtml5-commands-disabled"):b.removeClass(d,"wysihtml5-commands-disabled")},0)})},_updateLinkStates:function(){var c,d,e,f=this.commandMapping,g=this.actionMapping;for(c in f)e=f[c],this.commandsDisabled?(d=!1,b.removeClass(e.link,"wysihtml5-command-active"),e.group&&b.removeClass(e.group,"wysihtml5-command-active"),e.dialog&&e.dialog.hide()):(d=this.composer.commands.state(e.name,e.value),a.lang.object(d).isArray()&&(d=1===d.length?d[0]:!0),b.removeClass(e.link,"wysihtml5-command-disabled"),e.group&&b.removeClass(e.group,"wysihtml5-command-disabled")),e.state!==d&&((e.state=d)?(b.addClass(e.link,"wysihtml5-command-active"),e.group&&b.addClass(e.group,"wysihtml5-command-active"),e.dialog&&("object"==typeof d?e.dialog.show(d):e.dialog.hide())):(b.removeClass(e.link,"wysihtml5-command-active"),e.group&&b.removeClass(e.group,"wysihtml5-command-active"),e.dialog&&e.dialog.hide()));for(c in g)f=g[c],"change_view"===f.name&&(f.state=this.editor.currentView===this.editor.textarea,f.state?b.addClass(f.link,"wysihtml5-action-active"):b.removeClass(f.link,"wysihtml5-action-active"))},show:function(){this.container.style.display=""},hide:function(){this.container.style.display="none"}})}(wysihtml5),function(a){var b={name:void 0,style:!0,toolbar:void 0,autoLink:!0,parserRules:{tags:{br:{},span:{},div:{},p:{}},classes:{}},parser:a.dom.parse,composerClassName:"wysihtml5-editor",bodyClassName:"wysihtml5-supported",stylesheets:[],placeholderText:void 0,allowObjectResizing:!0,supportTouchDevices:!0};a.Editor=a.lang.Dispatcher.extend({constructor:function(c,d){if(this.textareaElement="string"==typeof c?document.getElementById(c):c,this.config=a.lang.object({}).merge(b).merge(d).get(),this.currentView=this.textarea=new a.views.Textarea(this,this.textareaElement,this.config),this._isCompatible=a.browser.supported(),!this._isCompatible||!this.config.supportTouchDevices&&a.browser.isTouchDevice()){var e=this;setTimeout(function(){e.fire("beforeload").fire("load")},0)}else{a.dom.addClass(document.body,this.config.bodyClassName),this.currentView=this.composer=new a.views.Composer(this,this.textareaElement,this.config),"function"==typeof this.config.parser&&this._initParser(),this.observe("beforeload",function(){this.synchronizer=new a.views.Synchronizer(this,this.textarea,this.composer),this.config.toolbar&&(this.toolbar=new a.toolbar.Toolbar(this,this.config.toolbar))});try{console.log("Heya! This page is using wysihtml5 for rich text editing. Check out https://github.com/xing/wysihtml5")}catch(f){}}},isCompatible:function(){return this._isCompatible},clear:function(){return this.currentView.clear(),this},getValue:function(a){return this.currentView.getValue(a)},setValue:function(a,b){return a?(this.currentView.setValue(a,b),this):this.clear()},focus:function(a){return this.currentView.focus(a),this},disable:function(){return this.currentView.disable(),this},enable:function(){return this.currentView.enable(),this},isEmpty:function(){return this.currentView.isEmpty()},hasPlaceholderSet:function(){return this.currentView.hasPlaceholderSet()},parse:function(b){var c=this.config.parser(b,this.config.parserRules,this.composer.sandbox.getDocument(),!0);return"object"==typeof b&&a.quirks.redraw(b),c},_initParser:function(){this.observe("paste:composer",function(){var b=this;b.composer.selection.executeAndRestore(function(){a.quirks.cleanPastedHTML(b.composer.element),b.parse(b.composer.element)},!0)}),this.observe("paste:textarea",function(){this.textarea.setValue(this.parse(this.textarea.getValue()))})}})}(wysihtml5);var Handlebars=function(){var a=function(){"use strict";function a(a){this.string=a}var b;return a.prototype.toString=function(){return""+this.string},b=a}(),b=function(a){"use strict";function b(a){return h[a]||"&"}function c(a,b){for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c])}function d(a){return a instanceof g?a.toString():a||0===a?(a=""+a,j.test(a)?a.replace(i,b):a):""}function e(a){return a||0===a?m(a)&&0===a.length?!0:!1:!0}var f={},g=a,h={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},i=/[&<>"'`]/g,j=/[&<>"'`]/;f.extend=c;var k=Object.prototype.toString;f.toString=k;var l=function(a){return"function"==typeof a};l(/x/)&&(l=function(a){return"function"==typeof a&&"[object Function]"===k.call(a)});var l;f.isFunction=l;var m=Array.isArray||function(a){return a&&"object"==typeof a?"[object Array]"===k.call(a):!1};return f.isArray=m,f.escapeExpression=d,f.isEmpty=e,f}(a),c=function(){"use strict";function a(){for(var a=Error.prototype.constructor.apply(this,arguments),b=0;b0?a.helpers.each(b,c):d(this):e(b)}),a.registerHelper("each",function(a,b){var c,d=b.fn,e=b.inverse,f=0,g="";if(m(a)&&(a=a.call(this)),b.data&&(c=q(b.data)),a&&"object"==typeof a)if(l(a))for(var h=a.length;h>f;f++)c&&(c.index=f,c.first=0===f,c.last=f===a.length-1),g+=d(a[f],{data:c});else for(var i in a)a.hasOwnProperty(i)&&(c&&(c.key=i),g+=d(a[i],{data:c}),f++);return 0===f&&(g=e(this)),g}),a.registerHelper("if",function(a,b){return m(a)&&(a=a.call(this)),!b.hash.includeZero&&!a||g.isEmpty(a)?b.inverse(this):b.fn(this)}),a.registerHelper("unless",function(b,c){return a.helpers["if"].call(this,b,{fn:c.inverse,inverse:c.fn,hash:c.hash})}),a.registerHelper("with",function(a,b){return m(a)&&(a=a.call(this)),g.isEmpty(a)?void 0:b.fn(a)}),a.registerHelper("log",function(b,c){var d=c.data&&null!=c.data.level?parseInt(c.data.level,10):1;a.log(d,b)})}function e(a,b){p.log(a,b)}var f={},g=a,h=b,i="1.1.2";f.VERSION=i;var j=4;f.COMPILER_REVISION=j;var k={1:"<= 1.0.rc.2",2:"== 1.0.0-rc.3",3:"== 1.0.0-rc.4",4:">= 1.0.0"};f.REVISION_CHANGES=k;var l=g.isArray,m=g.isFunction,n=g.toString,o="[object Object]";f.HandlebarsEnvironment=c,c.prototype={constructor:c,logger:p,log:e,registerHelper:function(a,b,c){if(n.call(a)===o){if(c||b)throw new h("Arg not supported with multiple helpers");g.extend(this.helpers,a)}else c&&(b.not=c),this.helpers[a]=b},registerPartial:function(a,b){n.call(a)===o?g.extend(this.partials,a):this.partials[a]=b}};var p={methodMap:{0:"debug",1:"info",2:"warn",3:"error"},DEBUG:0,INFO:1,WARN:2,ERROR:3,level:3,log:function(a,b){if(p.level<=a){var c=p.methodMap[a];"undefined"!=typeof console&&console[c]&&console[c].call(console,b)}}};f.logger=p,f.log=e;var q=function(a){var b={};return g.extend(b,a),b};return f.createFrame=q,f}(b,c),e=function(a,b,c){"use strict";function d(a){var b=a&&a[0]||1,c=m;if(b!==c){if(c>b){var d=n[c],e=n[b];throw new Error("Template was precompiled with an older version of Handlebars than the current runtime. Please update your precompiler to a newer version ("+d+") or downgrade your runtime to an older version ("+e+").")}throw new Error("Template was precompiled with a newer version of Handlebars than the current runtime. Please update your runtime to a newer version ("+a[1]+").")}}function e(a,b){if(!b)throw new Error("No environment passed to template");var c;c=b.compile?function(a,c,d,e,f,g){var i=h.apply(this,arguments);if(i)return i;var j={helpers:e,partials:f,data:g};return f[c]=b.compile(a,{data:void 0!==g},b),f[c](d,j)}:function(a,b){var c=h.apply(this,arguments);if(c)return c;throw new l("The partial "+b+" could not be compiled when running in runtime-only mode")};var e={escapeExpression:k.escapeExpression,invokePartial:c,programs:[],program:function(a,b,c){var d=this.programs[a];return c?d=g(a,b,c):d||(d=this.programs[a]=g(a,b)),d},merge:function(a,b){var c=a||b;return a&&b&&a!==b&&(c={},k.extend(c,b),k.extend(c,a)),c},programWithDepth:f,noop:i,compilerInfo:null};return function(c,f){f=f||{};var g,h,i=f.partial?f:b;f.partial||(g=f.helpers,h=f.partials);var j=a.call(e,i,c,g,h,f.data);return f.partial||d(e.compilerInfo),j}}function f(a,b,c){var d=Array.prototype.slice.call(arguments,3),e=function(a,e){return e=e||{},b.apply(this,[a,e.data||c].concat(d))};return e.program=a,e.depth=d.length,e}function g(a,b,c){var d=function(a,d){return d=d||{},b(a,d.data||c)};return d.program=a,d.depth=0,d}function h(a,b,c,d,e,f){var g={partial:!0,helpers:d,partials:e,data:f};if(void 0===a)throw new l("The partial "+b+" could not be found");return a instanceof Function?a(c,g):void 0}function i(){return""}var j={},k=a,l=b,m=c.COMPILER_REVISION,n=c.REVISION_CHANGES;return j.template=e,j.programWithDepth=f,j.program=g,j.invokePartial=h,j.noop=i,j}(b,c,d),f=function(a,b,c,d,e){"use strict";var f,g=a,h=b,i=c,j=d,k=e,l=function(){var a=new g.HandlebarsEnvironment;return j.extend(a,g),a.SafeString=h,a.Exception=i,a.Utils=j,a.VM=k,a.template=function(b){return k.template(b,a)},a},m=l();return m.create=l,f=m}(d,a,c,b,e);return f}(),glob="undefined"==typeof window?global:window,Handlebars=glob.Handlebars||require("handlebars");this.wysihtml5=this.wysihtml5||{},this.wysihtml5.tpl=this.wysihtml5.tpl||{},this.wysihtml5.tpl.color=Handlebars.template(function(a,b,c,d,e){function f(a){var b,c="";return c+="btn-"+k((b=a&&a.options,b=null==b||b===!1?b:b.size,typeof b===j?b.apply(a):b))}this.compilerInfo=[4,">= 1.0.0"],c=this.merge(c,a.helpers),e=e||{};var g,h,i="",j="function",k=this.escapeExpression,l=this;return i+='\n"}),this.wysihtml5.tpl.emphasis=Handlebars.template(function(a,b,c,d,e){function f(a){var b,c="";return c+="btn-"+k((b=a&&a.options,b=null==b||b===!1?b:b.size,typeof b===j?b.apply(a):b))}this.compilerInfo=[4,">= 1.0.0"],c=this.merge(c,a.helpers),e=e||{};var g,h,i="",j="function",k=this.escapeExpression,l=this;return i+='
  • \n \n
  • \n"}),this.wysihtml5.tpl["font-styles"]=Handlebars.template(function(a,b,c,d,e){function f(a){var b,c="";return c+="btn-"+k((b=a&&a.options,b=null==b||b===!1?b:b.size,typeof b===j?b.apply(a):b))}this.compilerInfo=[4,">= 1.0.0"],c=this.merge(c,a.helpers),e=e||{};var g,h,i="",j="function",k=this.escapeExpression,l=this;return i+='\n"}),this.wysihtml5.tpl.html=Handlebars.template(function(a,b,c,d,e){function f(a){var b,c="";return c+="btn-"+k((b=a&&a.options,b=null==b||b===!1?b:b.size,typeof b===j?b.apply(a):b))}this.compilerInfo=[4,">= 1.0.0"],c=this.merge(c,a.helpers),e=e||{};var g,h,i="",j="function",k=this.escapeExpression,l=this;return i+='
  • \n
    \n \n \n \n
    \n
  • \n'}),this.wysihtml5.tpl.image=Handlebars.template(function(a,b,c,d,e){function f(a){var b,c="";return c+="btn-"+k((b=a&&a.options,b=null==b||b===!1?b:b.size,typeof b===j?b.apply(a):b))}this.compilerInfo=[4,">= 1.0.0"],c=this.merge(c,a.helpers),e=e||{};var g,h,i="",j="function",k=this.escapeExpression,l=this;return i+='
  • \n \n \n \n \n
  • \n'}),this.wysihtml5.tpl.link=Handlebars.template(function(a,b,c,d,e){function f(a){var b,c="";return c+="btn-"+k((b=a&&a.options,b=null==b||b===!1?b:b.size,typeof b===j?b.apply(a):b))}this.compilerInfo=[4,">= 1.0.0"],c=this.merge(c,a.helpers),e=e||{};var g,h,i="",j="function",k=this.escapeExpression,l=this;return i+='
  • \n \n \n \n \n
  • \n' -}),this.wysihtml5.tpl.lists=Handlebars.template(function(a,b,c,d,e){function f(a){var b,c="";return c+="btn-"+k((b=a&&a.options,b=null==b||b===!1?b:b.size,typeof b===j?b.apply(a):b))}this.compilerInfo=[4,">= 1.0.0"],c=this.merge(c,a.helpers),e=e||{};var g,h,i="",j="function",k=this.escapeExpression,l=this;return i+='
  • \n
    \n \n \n \n \n
    \n
  • \n'}),"object"==typeof exports&&exports&&(module.exports=this.wysihtml5.tpl),!function(a,b){"use strict";var c=function(a,c,d){return b.tpl[a]({locale:c,options:d})},d=function(c,d){this.el=c;var e=d||f;for(var g in e.customTemplates)b.tpl[g]=e.customTemplates[g];this.toolbar=this.createToolbar(c,e),this.editor=this.createEditor(d),window.editor=this.editor,a("iframe.wysihtml5-sandbox").each(function(b,c){a(c.contentWindow).off("focus.wysihtml5").on({"focus.wysihtml5":function(){a("li.dropdown").removeClass("open")}})})};d.prototype={constructor:d,createEditor:function(c){c=c||{},c=a.extend(!0,{},c),c.toolbar=this.toolbar[0];var d=new b.Editor(this.el[0],c);if(c&&c.events)for(var e in c.events)d.on(e,c.events[e]);return d},createToolbar:function(b,d){var e=this,h=a("
      ",{"class":"wysihtml5-toolbar",style:"display:none"}),i=d.locale||f.locale||"en";for(var j in f){var k=!1;void 0!==d[j]?d[j]===!0&&(k=!0):k=f[j],k===!0&&(h.append(c(j,g[i],d)),"html"===j&&this.initHtml(h),"link"===j&&this.initInsertLink(h),"image"===j&&this.initInsertImage(h))}if(d.toolbar)for(j in d.toolbar)h.append(d.toolbar[j]);return h.find('a[data-wysihtml5-command="formatBlock"]').click(function(b){var c=b.target||b.srcElement,d=a(c);e.toolbar.find(".current-font").text(d.html())}),h.find('a[data-wysihtml5-command="foreColor"]').click(function(b){var c=b.target||b.srcElement,d=a(c);e.toolbar.find(".current-color").text(d.html())}),this.el.before(h),h},initHtml:function(a){var b='a[data-wysihtml5-action="change_view"]';a.find(b).click(function(){a.find("a.btn").not(b).toggleClass("disabled")})},initInsertImage:function(b){var c,d=this,e=b.find(".bootstrap-wysihtml5-insert-image-modal"),f=e.find(".bootstrap-wysihtml5-insert-image-url"),g=e.find("a.btn-primary"),h=f.val(),i=function(){var a=f.val();f.val(h),d.editor.currentView.element.focus(),c&&(d.editor.composer.selection.setBookmark(c),c=null),d.editor.composer.commands.exec("insertImage",a)};f.keypress(function(a){13==a.which&&(i(),e.modal("hide"))}),g.click(i),e.on("shown",function(){f.focus()}),e.on("hide",function(){d.editor.currentView.element.focus()}),b.find("a[data-wysihtml5-command=insertImage]").click(function(){var b=a(this).hasClass("wysihtml5-command-active");return b?!0:(d.editor.currentView.element.focus(!1),c=d.editor.composer.selection.getBookmark(),e.appendTo("body").modal("show"),e.on("click.dismiss.modal",'[data-dismiss="modal"]',function(a){a.stopPropagation()}),!1)})},initInsertLink:function(b){var c,d=this,e=b.find(".bootstrap-wysihtml5-insert-link-modal"),f=e.find(".bootstrap-wysihtml5-insert-link-url"),g=e.find(".bootstrap-wysihtml5-insert-link-target"),h=e.find("a.btn-primary"),i=f.val(),j=function(){var a=f.val();f.val(i),d.editor.currentView.element.focus(),c&&(d.editor.composer.selection.setBookmark(c),c=null);var b=g.prop("checked");d.editor.composer.commands.exec("createLink",{href:a,target:b?"_blank":"_self",rel:b?"nofollow":""})};f.keypress(function(a){13==a.which&&(j(),e.modal("hide"))}),h.click(j),e.on("shown",function(){f.focus()}),e.on("hide",function(){d.editor.currentView.element.focus()}),b.find("a[data-wysihtml5-command=createLink]").click(function(){var b=a(this).hasClass("wysihtml5-command-active");return b?!0:(d.editor.currentView.element.focus(!1),c=d.editor.composer.selection.getBookmark(),e.appendTo("body").modal("show"),e.on("click.dismiss.modal",'[data-dismiss="modal"]',function(a){a.stopPropagation()}),!1)})}};var e={resetDefaults:function(){a.fn.wysihtml5.defaultOptions=a.extend(!0,{},a.fn.wysihtml5.defaultOptionsCache)},bypassDefaults:function(b){return this.each(function(){var c=a(this);c.data("wysihtml5",new d(c,b))})},shallowExtend:function(b){var c=a.extend({},a.fn.wysihtml5.defaultOptions,b||{},a(this).data()),d=this;return e.bypassDefaults.apply(d,[c])},deepExtend:function(b){var c=a.extend(!0,{},a.fn.wysihtml5.defaultOptions,b||{}),d=this;return e.bypassDefaults.apply(d,[c])},init:function(a){var b=this;return e.shallowExtend.apply(b,[a])}};a.fn.wysihtml5=function(b){return e[b]?e[b].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof b&&b?(a.error("Method "+b+" does not exist on jQuery.wysihtml5"),void 0):e.init.apply(this,arguments)},a.fn.wysihtml5.Constructor=d;var f=a.fn.wysihtml5.defaultOptions={"font-styles":!0,color:!1,emphasis:!0,lists:!0,html:!1,link:!0,image:!0,events:{},parserRules:{classes:{"wysiwyg-color-silver":1,"wysiwyg-color-gray":1,"wysiwyg-color-white":1,"wysiwyg-color-maroon":1,"wysiwyg-color-red":1,"wysiwyg-color-purple":1,"wysiwyg-color-fuchsia":1,"wysiwyg-color-green":1,"wysiwyg-color-lime":1,"wysiwyg-color-olive":1,"wysiwyg-color-yellow":1,"wysiwyg-color-navy":1,"wysiwyg-color-blue":1,"wysiwyg-color-teal":1,"wysiwyg-color-aqua":1,"wysiwyg-color-orange":1},tags:{b:{},i:{},strong:{},em:{},p:{},br:{},ol:{},ul:{},li:{},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},blockquote:{},u:1,img:{check_attributes:{width:"numbers",alt:"alt",src:"url",height:"numbers"}},a:{check_attributes:{href:"url"},set_attributes:{target:"_blank",rel:"nofollow"}},span:1,div:1,code:1,pre:1}},locale:"en"};"undefined"==typeof a.fn.wysihtml5.defaultOptionsCache&&(a.fn.wysihtml5.defaultOptionsCache=a.extend(!0,{},a.fn.wysihtml5.defaultOptions));var g=a.fn.wysihtml5.locale={}}(window.jQuery,window.wysihtml5),function(a){a.fn.wysihtml5.locale.en=a.fn.wysihtml5.locale["en-US"]={font_styles:{normal:"Normal text",h1:"Heading 1",h2:"Heading 2",h3:"Heading 3",h4:"Heading 4",h5:"Heading 5",h6:"Heading 6"},emphasis:{bold:"Bold",italic:"Italic",underline:"Underline"},lists:{unordered:"Unordered list",ordered:"Ordered list",outdent:"Outdent",indent:"Indent"},link:{insert:"Insert link",cancel:"Cancel",target:"Open link in new window"},image:{insert:"Insert image",cancel:"Cancel"},html:{edit:"Edit HTML"},colours:{black:"Black",silver:"Silver",gray:"Grey",maroon:"Maroon",red:"Red",purple:"Purple",green:"Green",olive:"Olive",navy:"Navy",blue:"Blue",orange:"Orange"}}}(jQuery); \ No newline at end of file diff --git a/public/assets/js/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.js b/public/assets/js/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.js deleted file mode 100755 index 4fbbf663..00000000 --- a/public/assets/js/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.js +++ /dev/null @@ -1,350 +0,0 @@ -/* jshint expr: true */ -!(function($, wysi) { - 'use strict'; - - var templates = function(key, locale, options) { - return wysi.tpl[key]({locale: locale, options: options}); - }; - - var Wysihtml5 = function(el, options) { - this.el = el; - var toolbarOpts = options || defaultOptions; - for(var t in toolbarOpts.customTemplates) { - wysi.tpl[t] = toolbarOpts.customTemplates[t]; - } - this.toolbar = this.createToolbar(el, toolbarOpts); - this.editor = this.createEditor(options); - - window.editor = this.editor; - - $('iframe.wysihtml5-sandbox').each(function(i, el){ - $(el.contentWindow).off('focus.wysihtml5').on({ - 'focus.wysihtml5' : function(){ - $('li.dropdown').removeClass('open'); - } - }); - }); - }; - - Wysihtml5.prototype = { - - constructor: Wysihtml5, - - createEditor: function(options) { - options = options || {}; - - // Add the toolbar to a clone of the options object so multiple instances - // of the WYISYWG don't break because 'toolbar' is already defined - options = $.extend(true, {}, options); - options.toolbar = this.toolbar[0]; - - var editor = new wysi.Editor(this.el[0], options); - - if(options && options.events) { - for(var eventName in options.events) { - editor.on(eventName, options.events[eventName]); - } - } - return editor; - }, - - createToolbar: function(el, options) { - var self = this; - var toolbar = $('
        ', { - 'class' : 'wysihtml5-toolbar', - 'style': 'display:none' - }); - var culture = options.locale || defaultOptions.locale || 'en'; - for(var key in defaultOptions) { - var value = false; - - if(options[key] !== undefined) { - if(options[key] === true) { - value = true; - } - } else { - value = defaultOptions[key]; - } - - if(value === true) { - toolbar.append(templates(key, locale[culture], options)); - - if(key === 'html') { - this.initHtml(toolbar); - } - - if(key === 'link') { - this.initInsertLink(toolbar); - } - - if(key === 'image') { - this.initInsertImage(toolbar); - } - } - } - - if(options.toolbar) { - for(key in options.toolbar) { - toolbar.append(options.toolbar[key]); - } - } - - toolbar.find('a[data-wysihtml5-command="formatBlock"]').click(function(e) { - var target = e.target || e.srcElement; - var el = $(target); - self.toolbar.find('.current-font').text(el.html()); - }); - - toolbar.find('a[data-wysihtml5-command="foreColor"]').click(function(e) { - var target = e.target || e.srcElement; - var el = $(target); - self.toolbar.find('.current-color').text(el.html()); - }); - - this.el.before(toolbar); - - return toolbar; - }, - - initHtml: function(toolbar) { - var changeViewSelector = 'a[data-wysihtml5-action="change_view"]'; - toolbar.find(changeViewSelector).click(function(e) { - toolbar.find('a.btn').not(changeViewSelector).toggleClass('disabled'); - }); - }, - - initInsertImage: function(toolbar) { - var self = this; - var insertImageModal = toolbar.find('.bootstrap-wysihtml5-insert-image-modal'); - var urlInput = insertImageModal.find('.bootstrap-wysihtml5-insert-image-url'); - var insertButton = insertImageModal.find('a.btn-primary'); - var initialValue = urlInput.val(); - var caretBookmark; - - var insertImage = function() { - var url = urlInput.val(); - urlInput.val(initialValue); - self.editor.currentView.element.focus(); - if (caretBookmark) { - self.editor.composer.selection.setBookmark(caretBookmark); - caretBookmark = null; - } - self.editor.composer.commands.exec('insertImage', url); - }; - - urlInput.keypress(function(e) { - if(e.which == 13) { - insertImage(); - insertImageModal.modal('hide'); - } - }); - - insertButton.click(insertImage); - - insertImageModal.on('shown', function() { - urlInput.focus(); - }); - - insertImageModal.on('hide', function() { - self.editor.currentView.element.focus(); - }); - - toolbar.find('a[data-wysihtml5-command=insertImage]').click(function() { - var activeButton = $(this).hasClass('wysihtml5-command-active'); - - if (!activeButton) { - self.editor.currentView.element.focus(false); - caretBookmark = self.editor.composer.selection.getBookmark(); - insertImageModal.appendTo('body').modal('show'); - insertImageModal.on('click.dismiss.modal', '[data-dismiss="modal"]', function(e) { - e.stopPropagation(); - }); - return false; - } - else { - return true; - } - }); - }, - - initInsertLink: function(toolbar) { - var self = this; - var insertLinkModal = toolbar.find('.bootstrap-wysihtml5-insert-link-modal'); - var urlInput = insertLinkModal.find('.bootstrap-wysihtml5-insert-link-url'); - var targetInput = insertLinkModal.find('.bootstrap-wysihtml5-insert-link-target'); - var insertButton = insertLinkModal.find('a.btn-primary'); - var initialValue = urlInput.val(); - var caretBookmark; - - var insertLink = function() { - var url = urlInput.val(); - urlInput.val(initialValue); - self.editor.currentView.element.focus(); - if (caretBookmark) { - self.editor.composer.selection.setBookmark(caretBookmark); - caretBookmark = null; - } - - var newWindow = targetInput.prop('checked'); - self.editor.composer.commands.exec('createLink', { - 'href' : url, - 'target' : (newWindow ? '_blank' : '_self'), - 'rel' : (newWindow ? 'nofollow' : '') - }); - }; - var pressedEnter = false; - - urlInput.keypress(function(e) { - if(e.which == 13) { - insertLink(); - insertLinkModal.modal('hide'); - } - }); - - insertButton.click(insertLink); - - insertLinkModal.on('shown', function() { - urlInput.focus(); - }); - - insertLinkModal.on('hide', function() { - self.editor.currentView.element.focus(); - }); - - toolbar.find('a[data-wysihtml5-command=createLink]').click(function() { - var activeButton = $(this).hasClass('wysihtml5-command-active'); - - if (!activeButton) { - self.editor.currentView.element.focus(false); - caretBookmark = self.editor.composer.selection.getBookmark(); - insertLinkModal.appendTo('body').modal('show'); - insertLinkModal.on('click.dismiss.modal', '[data-dismiss="modal"]', function(e) { - e.stopPropagation(); - }); - return false; - } - else { - return true; - } - }); - } - }; - - // these define our public api - var methods = { - resetDefaults: function() { - $.fn.wysihtml5.defaultOptions = $.extend(true, {}, $.fn.wysihtml5.defaultOptionsCache); - }, - bypassDefaults: function(options) { - return this.each(function () { - var $this = $(this); - $this.data('wysihtml5', new Wysihtml5($this, options)); - }); - }, - shallowExtend: function (options) { - var settings = $.extend({}, $.fn.wysihtml5.defaultOptions, options || {}, $(this).data()); - var that = this; - return methods.bypassDefaults.apply(that, [settings]); - }, - deepExtend: function(options) { - var settings = $.extend(true, {}, $.fn.wysihtml5.defaultOptions, options || {}); - var that = this; - return methods.bypassDefaults.apply(that, [settings]); - }, - init: function(options) { - var that = this; - return methods.shallowExtend.apply(that, [options]); - } - }; - - $.fn.wysihtml5 = function ( method ) { - if ( methods[method] ) { - return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 )); - } else if ( typeof method === 'object' || ! method ) { - return methods.init.apply( this, arguments ); - } else { - $.error( 'Method ' + method + ' does not exist on jQuery.wysihtml5' ); - } - }; - - $.fn.wysihtml5.Constructor = Wysihtml5; - - var defaultOptions = $.fn.wysihtml5.defaultOptions = { - 'font-styles': true, - 'color': false, - 'emphasis': true, - 'lists': true, - 'html': false, - 'link': true, - 'image': true, - events: {}, - parserRules: { - classes: { - 'wysiwyg-color-silver' : 1, - 'wysiwyg-color-gray' : 1, - 'wysiwyg-color-white' : 1, - 'wysiwyg-color-maroon' : 1, - 'wysiwyg-color-red' : 1, - 'wysiwyg-color-purple' : 1, - 'wysiwyg-color-fuchsia' : 1, - 'wysiwyg-color-green' : 1, - 'wysiwyg-color-lime' : 1, - 'wysiwyg-color-olive' : 1, - 'wysiwyg-color-yellow' : 1, - 'wysiwyg-color-navy' : 1, - 'wysiwyg-color-blue' : 1, - 'wysiwyg-color-teal' : 1, - 'wysiwyg-color-aqua' : 1, - 'wysiwyg-color-orange' : 1 - }, - tags: { - 'b': {}, - 'i': {}, - 'strong': {}, - 'em': {}, - 'p': {}, - 'br': {}, - 'ol': {}, - 'ul': {}, - 'li': {}, - 'h1': {}, - 'h2': {}, - 'h3': {}, - 'h4': {}, - 'h5': {}, - 'h6': {}, - 'blockquote': {}, - 'u': 1, - 'img': { - 'check_attributes': { - 'width': 'numbers', - 'alt': 'alt', - 'src': 'url', - 'height': 'numbers' - } - }, - 'a': { - check_attributes: { - 'href': 'url' // important to avoid XSS - }, - 'set_attributes': { - 'target': '_blank', - 'rel': 'nofollow' - } - }, - 'span': 1, - 'div': 1, - // to allow save and edit files with code tag hacks - 'code': 1, - 'pre': 1 - } - }, - locale: 'en' - }; - - if (typeof $.fn.wysihtml5.defaultOptionsCache === 'undefined') { - $.fn.wysihtml5.defaultOptionsCache = $.extend(true, {}, $.fn.wysihtml5.defaultOptions); - } - - var locale = $.fn.wysihtml5.locale = {}; -})(window.jQuery, window.wysihtml5); diff --git a/public/assets/js/plugins/datatables/dataTables.bootstrap.js b/public/assets/js/plugins/datatables/dataTables.bootstrap.js deleted file mode 100755 index 87b317c7..00000000 --- a/public/assets/js/plugins/datatables/dataTables.bootstrap.js +++ /dev/null @@ -1,250 +0,0 @@ -/* Set the defaults for DataTables initialisation */ -$.extend( true, $.fn.dataTable.defaults, { - "sDom": - "<'row'<'col-xs-6'l><'col-xs-6'f>r>"+ - "t"+ - "<'row'<'col-xs-6'i><'col-xs-6'p>>", - "oLanguage": { - "sLengthMenu": "_MENU_ records per page" - } -} ); - - -/* Default class modification */ -$.extend( $.fn.dataTableExt.oStdClasses, { - "sWrapper": "dataTables_wrapper form-inline", - "sFilterInput": "form-control input-sm", - "sLengthSelect": "form-control input-sm" -} ); - -// In 1.10 we use the pagination renderers to draw the Bootstrap paging, -// rather than custom plug-in -if ( $.fn.dataTable.Api ) { - $.fn.dataTable.defaults.renderer = 'bootstrap'; - $.fn.dataTable.ext.renderer.pageButton.bootstrap = function ( settings, host, idx, buttons, page, pages ) { - var api = new $.fn.dataTable.Api( settings ); - var classes = settings.oClasses; - var lang = settings.oLanguage.oPaginate; - var btnDisplay, btnClass; - - var attach = function( container, buttons ) { - var i, ien, node, button; - var clickHandler = function ( e ) { - e.preventDefault(); - if ( e.data.action !== 'ellipsis' ) { - api.page( e.data.action ).draw( false ); - } - }; - - for ( i=0, ien=buttons.length ; i 0 ? - '' : ' disabled'); - break; - - case 'previous': - btnDisplay = lang.sPrevious; - btnClass = button + (page > 0 ? - '' : ' disabled'); - break; - - case 'next': - btnDisplay = lang.sNext; - btnClass = button + (page < pages-1 ? - '' : ' disabled'); - break; - - case 'last': - btnDisplay = lang.sLast; - btnClass = button + (page < pages-1 ? - '' : ' disabled'); - break; - - default: - btnDisplay = button + 1; - btnClass = page === button ? - 'active' : ''; - break; - } - - if ( btnDisplay ) { - node = $('
      • ', { - 'class': classes.sPageButton+' '+btnClass, - 'aria-controls': settings.sTableId, - 'tabindex': settings.iTabIndex, - 'id': idx === 0 && typeof button === 'string' ? - settings.sTableId +'_'+ button : - null - } ) - .append( $('', { - 'href': '#' - } ) - .html( btnDisplay ) - ) - .appendTo( container ); - - settings.oApi._fnBindAction( - node, {action: button}, clickHandler - ); - } - } - } - }; - - attach( - $(host).empty().html('
          ').children('ul'), - buttons - ); - } -} -else { - // Integration for 1.9- - $.fn.dataTable.defaults.sPaginationType = 'bootstrap'; - - /* API method to get paging information */ - $.fn.dataTableExt.oApi.fnPagingInfo = function ( oSettings ) - { - return { - "iStart": oSettings._iDisplayStart, - "iEnd": oSettings.fnDisplayEnd(), - "iLength": oSettings._iDisplayLength, - "iTotal": oSettings.fnRecordsTotal(), - "iFilteredTotal": oSettings.fnRecordsDisplay(), - "iPage": oSettings._iDisplayLength === -1 ? - 0 : Math.ceil( oSettings._iDisplayStart / oSettings._iDisplayLength ), - "iTotalPages": oSettings._iDisplayLength === -1 ? - 0 : Math.ceil( oSettings.fnRecordsDisplay() / oSettings._iDisplayLength ) - }; - }; - - /* Bootstrap style pagination control */ - $.extend( $.fn.dataTableExt.oPagination, { - "bootstrap": { - "fnInit": function( oSettings, nPaging, fnDraw ) { - var oLang = oSettings.oLanguage.oPaginate; - var fnClickHandler = function ( e ) { - e.preventDefault(); - if ( oSettings.oApi._fnPageChange(oSettings, e.data.action) ) { - fnDraw( oSettings ); - } - }; - - $(nPaging).append( - '' - ); - var els = $('a', nPaging); - $(els[0]).bind( 'click.DT', { action: "previous" }, fnClickHandler ); - $(els[1]).bind( 'click.DT', { action: "next" }, fnClickHandler ); - }, - - "fnUpdate": function ( oSettings, fnDraw ) { - var iListLength = 5; - var oPaging = oSettings.oInstance.fnPagingInfo(); - var an = oSettings.aanFeatures.p; - var i, ien, j, sClass, iStart, iEnd, iHalf=Math.floor(iListLength/2); - - if ( oPaging.iTotalPages < iListLength) { - iStart = 1; - iEnd = oPaging.iTotalPages; - } - else if ( oPaging.iPage <= iHalf ) { - iStart = 1; - iEnd = iListLength; - } else if ( oPaging.iPage >= (oPaging.iTotalPages-iHalf) ) { - iStart = oPaging.iTotalPages - iListLength + 1; - iEnd = oPaging.iTotalPages; - } else { - iStart = oPaging.iPage - iHalf + 1; - iEnd = iStart + iListLength - 1; - } - - for ( i=0, ien=an.length ; i'+j+'') - .insertBefore( $('li:last', an[i])[0] ) - .bind('click', function (e) { - e.preventDefault(); - oSettings._iDisplayStart = (parseInt($('a', this).text(),10)-1) * oPaging.iLength; - fnDraw( oSettings ); - } ); - } - - // Add / remove disabled classes from the static elements - if ( oPaging.iPage === 0 ) { - $('li:first', an[i]).addClass('disabled'); - } else { - $('li:first', an[i]).removeClass('disabled'); - } - - if ( oPaging.iPage === oPaging.iTotalPages-1 || oPaging.iTotalPages === 0 ) { - $('li:last', an[i]).addClass('disabled'); - } else { - $('li:last', an[i]).removeClass('disabled'); - } - } - } - } - } ); -} - - -/* - * TableTools Bootstrap compatibility - * Required TableTools 2.1+ - */ -if ( $.fn.DataTable.TableTools ) { - // Set the classes that TableTools uses to something suitable for Bootstrap - $.extend( true, $.fn.DataTable.TableTools.classes, { - "container": "DTTT btn-group", - "buttons": { - "normal": "btn btn-default", - "disabled": "disabled" - }, - "collection": { - "container": "DTTT_dropdown dropdown-menu", - "buttons": { - "normal": "", - "disabled": "disabled" - } - }, - "print": { - "info": "DTTT_print_info modal" - }, - "select": { - "row": "active" - } - } ); - - // Have the collection use a bootstrap compatible dropdown - $.extend( true, $.fn.DataTable.TableTools.DEFAULTS.oTags, { - "collection": { - "container": "ul", - "button": "li", - "liner": "a" - } - } ); -} \ No newline at end of file diff --git a/public/assets/js/plugins/datatables/jquery.dataTables.js b/public/assets/js/plugins/datatables/jquery.dataTables.js deleted file mode 100755 index 1d8a220b..00000000 --- a/public/assets/js/plugins/datatables/jquery.dataTables.js +++ /dev/null @@ -1,12099 +0,0 @@ -/** - * @summary DataTables - * @description Paginate, search and sort HTML tables - * @version 1.9.4 - * @file jquery.dataTables.js - * @author Allan Jardine (www.sprymedia.co.uk) - * @contact www.sprymedia.co.uk/contact - * - * @copyright Copyright 2008-2012 Allan Jardine, all rights reserved. - * - * This source file is free software, under either the GPL v2 license or a - * BSD style license, available at: - * http://datatables.net/license_gpl2 - * http://datatables.net/license_bsd - * - * This source file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. - * - * For details please refer to: http://www.datatables.net - */ - -/*jslint evil: true, undef: true, browser: true */ -/*globals $, jQuery,define,_fnExternApiFunc,_fnInitialise,_fnInitComplete,_fnLanguageCompat,_fnAddColumn,_fnColumnOptions,_fnAddData,_fnCreateTr,_fnGatherData,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnServerParams,_fnAddOptionsHtml,_fnFeatureHtmlTable,_fnScrollDraw,_fnAdjustColumnSizing,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnBuildSearchArray,_fnBuildSearchRow,_fnFilterCreateSearch,_fnDataToSearch,_fnSort,_fnSortAttachListener,_fnSortingClasses,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnFeatureHtmlLength,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnNodeToDataIndex,_fnVisbleColumns,_fnCalculateEnd,_fnConvertToWidth,_fnCalculateColumnWidths,_fnScrollingWidthAdjust,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnDetectType,_fnSettingsFromNode,_fnGetDataMaster,_fnGetTrNodes,_fnGetTdNodes,_fnEscapeRegex,_fnDeleteIndex,_fnReOrderIndex,_fnColumnOrdering,_fnLog,_fnClearTable,_fnSaveState,_fnLoadState,_fnCreateCookie,_fnReadCookie,_fnDetectHeader,_fnGetUniqueThs,_fnScrollBarWidth,_fnApplyToChildren,_fnMap,_fnGetRowData,_fnGetCellData,_fnSetCellData,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnApplyColumnDefs,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnJsonString,_fnRender,_fnNodeToColumnIndex,_fnInfoMacros,_fnBrowserDetect,_fnGetColumns*/ - -(/** @lends */function( window, document, undefined ) { - -(function( factory ) { - "use strict"; - - // Define as an AMD module if possible - if ( typeof define === 'function' && define.amd ) - { - define( ['jquery'], factory ); - } - /* Define using browser globals otherwise - * Prevent multiple instantiations if the script is loaded twice - */ - else if ( jQuery && !jQuery.fn.dataTable ) - { - factory( jQuery ); - } -} -(/** @lends */function( $ ) { - "use strict"; - /** - * DataTables is a plug-in for the jQuery Javascript library. It is a - * highly flexible tool, based upon the foundations of progressive - * enhancement, which will add advanced interaction controls to any - * HTML table. For a full list of features please refer to - * DataTables.net. - * - * Note that the DataTable object is not a global variable but is - * aliased to jQuery.fn.DataTable and jQuery.fn.dataTable through which - * it may be accessed. - * - * @class - * @param {object} [oInit={}] Configuration object for DataTables. Options - * are defined by {@link DataTable.defaults} - * @requires jQuery 1.3+ - * - * @example - * // Basic initialisation - * $(document).ready( function { - * $('#example').dataTable(); - * } ); - * - * @example - * // Initialisation with configuration options - in this case, disable - * // pagination and sorting. - * $(document).ready( function { - * $('#example').dataTable( { - * "bPaginate": false, - * "bSort": false - * } ); - * } ); - */ - var DataTable = function( oInit ) - { - - - /** - * Add a column to the list used for the table with default values - * @param {object} oSettings dataTables settings object - * @param {node} nTh The th element for this column - * @memberof DataTable#oApi - */ - function _fnAddColumn( oSettings, nTh ) - { - var oDefaults = DataTable.defaults.columns; - var iCol = oSettings.aoColumns.length; - var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, { - "sSortingClass": oSettings.oClasses.sSortable, - "sSortingClassJUI": oSettings.oClasses.sSortJUI, - "nTh": nTh ? nTh : document.createElement('th'), - "sTitle": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '', - "aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol], - "mData": oDefaults.mData ? oDefaults.oDefaults : iCol - } ); - oSettings.aoColumns.push( oCol ); - - /* Add a column specific filter */ - if ( oSettings.aoPreSearchCols[ iCol ] === undefined || oSettings.aoPreSearchCols[ iCol ] === null ) - { - oSettings.aoPreSearchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch ); - } - else - { - var oPre = oSettings.aoPreSearchCols[ iCol ]; - - /* Don't require that the user must specify bRegex, bSmart or bCaseInsensitive */ - if ( oPre.bRegex === undefined ) - { - oPre.bRegex = true; - } - - if ( oPre.bSmart === undefined ) - { - oPre.bSmart = true; - } - - if ( oPre.bCaseInsensitive === undefined ) - { - oPre.bCaseInsensitive = true; - } - } - - /* Use the column options function to initialise classes etc */ - _fnColumnOptions( oSettings, iCol, null ); - } - - - /** - * Apply options for a column - * @param {object} oSettings dataTables settings object - * @param {int} iCol column index to consider - * @param {object} oOptions object with sType, bVisible and bSearchable etc - * @memberof DataTable#oApi - */ - function _fnColumnOptions( oSettings, iCol, oOptions ) - { - var oCol = oSettings.aoColumns[ iCol ]; - - /* User specified column options */ - if ( oOptions !== undefined && oOptions !== null ) - { - /* Backwards compatibility for mDataProp */ - if ( oOptions.mDataProp && !oOptions.mData ) - { - oOptions.mData = oOptions.mDataProp; - } - - if ( oOptions.sType !== undefined ) - { - oCol.sType = oOptions.sType; - oCol._bAutoType = false; - } - - $.extend( oCol, oOptions ); - _fnMap( oCol, oOptions, "sWidth", "sWidthOrig" ); - - /* iDataSort to be applied (backwards compatibility), but aDataSort will take - * priority if defined - */ - if ( oOptions.iDataSort !== undefined ) - { - oCol.aDataSort = [ oOptions.iDataSort ]; - } - _fnMap( oCol, oOptions, "aDataSort" ); - } - - /* Cache the data get and set functions for speed */ - var mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null; - var mData = _fnGetObjectDataFn( oCol.mData ); - - oCol.fnGetData = function (oData, sSpecific) { - var innerData = mData( oData, sSpecific ); - - if ( oCol.mRender && (sSpecific && sSpecific !== '') ) - { - return mRender( innerData, sSpecific, oData ); - } - return innerData; - }; - oCol.fnSetData = _fnSetObjectDataFn( oCol.mData ); - - /* Feature sorting overrides column specific when off */ - if ( !oSettings.oFeatures.bSort ) - { - oCol.bSortable = false; - } - - /* Check that the class assignment is correct for sorting */ - if ( !oCol.bSortable || - ($.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) == -1) ) - { - oCol.sSortingClass = oSettings.oClasses.sSortableNone; - oCol.sSortingClassJUI = ""; - } - else if ( $.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) == -1 ) - { - oCol.sSortingClass = oSettings.oClasses.sSortable; - oCol.sSortingClassJUI = oSettings.oClasses.sSortJUI; - } - else if ( $.inArray('asc', oCol.asSorting) != -1 && $.inArray('desc', oCol.asSorting) == -1 ) - { - oCol.sSortingClass = oSettings.oClasses.sSortableAsc; - oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIAscAllowed; - } - else if ( $.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) != -1 ) - { - oCol.sSortingClass = oSettings.oClasses.sSortableDesc; - oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIDescAllowed; - } - } - - - /** - * Adjust the table column widths for new data. Note: you would probably want to - * do a redraw after calling this function! - * @param {object} oSettings dataTables settings object - * @memberof DataTable#oApi - */ - function _fnAdjustColumnSizing ( oSettings ) - { - /* Not interested in doing column width calculation if auto-width is disabled */ - if ( oSettings.oFeatures.bAutoWidth === false ) - { - return false; - } - - _fnCalculateColumnWidths( oSettings ); - for ( var i=0 , iLen=oSettings.aoColumns.length ; i
    ')[0]; - oSettings.nTable.parentNode.insertBefore( nHolding, oSettings.nTable ); - - /* - * All DataTables are wrapped in a div - */ - oSettings.nTableWrapper = $('
    ')[0]; - oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling; - - /* Track where we want to insert the option */ - var nInsertNode = oSettings.nTableWrapper; - - /* Loop over the user set positioning and place the elements as needed */ - var aDom = oSettings.sDom.split(''); - var nTmp, iPushFeature, cOption, nNewNode, cNext, sAttr, j; - for ( var i=0 ; i
    ')[0]; - - /* Check to see if we should append an id and/or a class name to the container */ - cNext = aDom[i+1]; - if ( cNext == "'" || cNext == '"' ) - { - sAttr = ""; - j = 2; - while ( aDom[i+j] != cNext ) - { - sAttr += aDom[i+j]; - j++; - } - - /* Replace jQuery UI constants */ - if ( sAttr == "H" ) - { - sAttr = oSettings.oClasses.sJUIHeader; - } - else if ( sAttr == "F" ) - { - sAttr = oSettings.oClasses.sJUIFooter; - } - - /* The attribute can be in the format of "#id.class", "#id" or "class" This logic - * breaks the string into parts and applies them as needed - */ - if ( sAttr.indexOf('.') != -1 ) - { - var aSplit = sAttr.split('.'); - nNewNode.id = aSplit[0].substr(1, aSplit[0].length-1); - nNewNode.className = aSplit[1]; - } - else if ( sAttr.charAt(0) == "#" ) - { - nNewNode.id = sAttr.substr(1, sAttr.length-1); - } - else - { - nNewNode.className = sAttr; - } - - i += j; /* Move along the position array */ - } - - nInsertNode.appendChild( nNewNode ); - nInsertNode = nNewNode; - } - else if ( cOption == '>' ) - { - /* End container div */ - nInsertNode = nInsertNode.parentNode; - } - else if ( cOption == 'l' && oSettings.oFeatures.bPaginate && oSettings.oFeatures.bLengthChange ) - { - /* Length */ - nTmp = _fnFeatureHtmlLength( oSettings ); - iPushFeature = 1; - } - else if ( cOption == 'f' && oSettings.oFeatures.bFilter ) - { - /* Filter */ - nTmp = _fnFeatureHtmlFilter( oSettings ); - iPushFeature = 1; - } - else if ( cOption == 'r' && oSettings.oFeatures.bProcessing ) - { - /* pRocessing */ - nTmp = _fnFeatureHtmlProcessing( oSettings ); - iPushFeature = 1; - } - else if ( cOption == 't' ) - { - /* Table */ - nTmp = _fnFeatureHtmlTable( oSettings ); - iPushFeature = 1; - } - else if ( cOption == 'i' && oSettings.oFeatures.bInfo ) - { - /* Info */ - nTmp = _fnFeatureHtmlInfo( oSettings ); - iPushFeature = 1; - } - else if ( cOption == 'p' && oSettings.oFeatures.bPaginate ) - { - /* Pagination */ - nTmp = _fnFeatureHtmlPaginate( oSettings ); - iPushFeature = 1; - } - else if ( DataTable.ext.aoFeatures.length !== 0 ) - { - /* Plug-in features */ - var aoFeatures = DataTable.ext.aoFeatures; - for ( var k=0, kLen=aoFeatures.length ; k') : - sSearchStr==="" ? '' : sSearchStr+' '; - - var nFilter = document.createElement( 'div' ); - nFilter.className = oSettings.oClasses.sFilter; - nFilter.innerHTML = ''; - if ( !oSettings.aanFeatures.f ) - { - nFilter.id = oSettings.sTableId+'_filter'; - } - - var jqFilter = $('input[type="text"]', nFilter); - - // Store a reference to the input element, so other input elements could be - // added to the filter wrapper if needed (submit button for example) - nFilter._DT_Input = jqFilter[0]; - - jqFilter.val( oPreviousSearch.sSearch.replace('"','"') ); - jqFilter.bind( 'keyup.DT', function(e) { - /* Update all other filter input elements for the new display */ - var n = oSettings.aanFeatures.f; - var val = this.value==="" ? "" : this.value; // mental IE8 fix :-( - - for ( var i=0, iLen=n.length ; i=0 ; i-- ) - { - var sData = _fnDataToSearch( _fnGetCellData( oSettings, oSettings.aiDisplay[i], iColumn, 'filter' ), - oSettings.aoColumns[iColumn].sType ); - if ( ! rpSearch.test( sData ) ) - { - oSettings.aiDisplay.splice( i, 1 ); - iIndexCorrector++; - } - } - } - - - /** - * Filter the data table based on user input and draw the table - * @param {object} oSettings dataTables settings object - * @param {string} sInput string to filter on - * @param {int} iForce optional - force a research of the master array (1) or not (undefined or 0) - * @param {bool} bRegex treat as a regular expression or not - * @param {bool} bSmart perform smart filtering or not - * @param {bool} bCaseInsensitive Do case insenstive matching or not - * @memberof DataTable#oApi - */ - function _fnFilter( oSettings, sInput, iForce, bRegex, bSmart, bCaseInsensitive ) - { - var i; - var rpSearch = _fnFilterCreateSearch( sInput, bRegex, bSmart, bCaseInsensitive ); - var oPrevSearch = oSettings.oPreviousSearch; - - /* Check if we are forcing or not - optional parameter */ - if ( !iForce ) - { - iForce = 0; - } - - /* Need to take account of custom filtering functions - always filter */ - if ( DataTable.ext.afnFiltering.length !== 0 ) - { - iForce = 1; - } - - /* - * If the input is blank - we want the full data set - */ - if ( sInput.length <= 0 ) - { - oSettings.aiDisplay.splice( 0, oSettings.aiDisplay.length); - oSettings.aiDisplay = oSettings.aiDisplayMaster.slice(); - } - else - { - /* - * We are starting a new search or the new search string is smaller - * then the old one (i.e. delete). Search from the master array - */ - if ( oSettings.aiDisplay.length == oSettings.aiDisplayMaster.length || - oPrevSearch.sSearch.length > sInput.length || iForce == 1 || - sInput.indexOf(oPrevSearch.sSearch) !== 0 ) - { - /* Nuke the old display array - we are going to rebuild it */ - oSettings.aiDisplay.splice( 0, oSettings.aiDisplay.length); - - /* Force a rebuild of the search array */ - _fnBuildSearchArray( oSettings, 1 ); - - /* Search through all records to populate the search array - * The the oSettings.aiDisplayMaster and asDataSearch arrays have 1 to 1 - * mapping - */ - for ( i=0 ; i').html(sSearch).text(); - } - - // Strip newline characters - return sSearch.replace( /[\n\r]/g, " " ); - } - - /** - * Build a regular expression object suitable for searching a table - * @param {string} sSearch string to search for - * @param {bool} bRegex treat as a regular expression or not - * @param {bool} bSmart perform smart filtering or not - * @param {bool} bCaseInsensitive Do case insensitive matching or not - * @returns {RegExp} constructed object - * @memberof DataTable#oApi - */ - function _fnFilterCreateSearch( sSearch, bRegex, bSmart, bCaseInsensitive ) - { - var asSearch, sRegExpString; - - if ( bSmart ) - { - /* Generate the regular expression to use. Something along the lines of: - * ^(?=.*?\bone\b)(?=.*?\btwo\b)(?=.*?\bthree\b).*$ - */ - asSearch = bRegex ? sSearch.split( ' ' ) : _fnEscapeRegex( sSearch ).split( ' ' ); - sRegExpString = '^(?=.*?'+asSearch.join( ')(?=.*?' )+').*$'; - return new RegExp( sRegExpString, bCaseInsensitive ? "i" : "" ); - } - else - { - sSearch = bRegex ? sSearch : _fnEscapeRegex( sSearch ); - return new RegExp( sSearch, bCaseInsensitive ? "i" : "" ); - } - } - - - /** - * Convert raw data into something that the user can search on - * @param {string} sData data to be modified - * @param {string} sType data type - * @returns {string} search string - * @memberof DataTable#oApi - */ - function _fnDataToSearch ( sData, sType ) - { - if ( typeof DataTable.ext.ofnSearch[sType] === "function" ) - { - return DataTable.ext.ofnSearch[sType]( sData ); - } - else if ( sData === null ) - { - return ''; - } - else if ( sType == "html" ) - { - return sData.replace(/[\r\n]/g," ").replace( /<.*?>/g, "" ); - } - else if ( typeof sData === "string" ) - { - return sData.replace(/[\r\n]/g," "); - } - return sData; - } - - - /** - * scape a string such that it can be used in a regular expression - * @param {string} sVal string to escape - * @returns {string} escaped string - * @memberof DataTable#oApi - */ - function _fnEscapeRegex ( sVal ) - { - var acEscape = [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-' ]; - var reReplace = new RegExp( '(\\' + acEscape.join('|\\') + ')', 'g' ); - return sVal.replace(reReplace, '\\$1'); - } - - - /** - * Generate the node required for the info display - * @param {object} oSettings dataTables settings object - * @returns {node} Information element - * @memberof DataTable#oApi - */ - function _fnFeatureHtmlInfo ( oSettings ) - { - var nInfo = document.createElement( 'div' ); - nInfo.className = oSettings.oClasses.sInfo; - - /* Actions that are to be taken once only for this feature */ - if ( !oSettings.aanFeatures.i ) - { - /* Add draw callback */ - oSettings.aoDrawCallback.push( { - "fn": _fnUpdateInfo, - "sName": "information" - } ); - - /* Add id */ - nInfo.id = oSettings.sTableId+'_info'; - } - oSettings.nTable.setAttribute( 'aria-describedby', oSettings.sTableId+'_info' ); - - return nInfo; - } - - - /** - * Update the information elements in the display - * @param {object} oSettings dataTables settings object - * @memberof DataTable#oApi - */ - function _fnUpdateInfo ( oSettings ) - { - /* Show information about the table */ - if ( !oSettings.oFeatures.bInfo || oSettings.aanFeatures.i.length === 0 ) - { - return; - } - - var - oLang = oSettings.oLanguage, - iStart = oSettings._iDisplayStart+1, - iEnd = oSettings.fnDisplayEnd(), - iMax = oSettings.fnRecordsTotal(), - iTotal = oSettings.fnRecordsDisplay(), - sOut; - - if ( iTotal === 0 ) - { - /* Empty record set */ - sOut = oLang.sInfoEmpty; - } - else { - /* Normal record set */ - sOut = oLang.sInfo; - } - - if ( iTotal != iMax ) - { - /* Record set after filtering */ - sOut += ' ' + oLang.sInfoFiltered; - } - - // Convert the macros - sOut += oLang.sInfoPostFix; - sOut = _fnInfoMacros( oSettings, sOut ); - - if ( oLang.fnInfoCallback !== null ) - { - sOut = oLang.fnInfoCallback.call( oSettings.oInstance, - oSettings, iStart, iEnd, iMax, iTotal, sOut ); - } - - var n = oSettings.aanFeatures.i; - for ( var i=0, iLen=n.length ; i'; - var i, iLen; - var aLengthMenu = oSettings.aLengthMenu; - - if ( aLengthMenu.length == 2 && typeof aLengthMenu[0] === 'object' && - typeof aLengthMenu[1] === 'object' ) - { - for ( i=0, iLen=aLengthMenu[0].length ; i'+aLengthMenu[1][i]+''; - } - } - else - { - for ( i=0, iLen=aLengthMenu.length ; i'+aLengthMenu[i]+''; - } - } - sStdMenu += ''; - - var nLength = document.createElement( 'div' ); - if ( !oSettings.aanFeatures.l ) - { - nLength.id = oSettings.sTableId+'_length'; - } - nLength.className = oSettings.oClasses.sLength; - nLength.innerHTML = ''; - - /* - * Set the length to the current display length - thanks to Andrea Pavlovic for this fix, - * and Stefan Skopnik for fixing the fix! - */ - $('select option[value="'+oSettings._iDisplayLength+'"]', nLength).attr("selected", true); - - $('select', nLength).bind( 'change.DT', function(e) { - var iVal = $(this).val(); - - /* Update all other length options for the new display */ - var n = oSettings.aanFeatures.l; - for ( i=0, iLen=n.length ; i oSettings.aiDisplay.length || - oSettings._iDisplayLength == -1 ) - { - oSettings._iDisplayEnd = oSettings.aiDisplay.length; - } - else - { - oSettings._iDisplayEnd = oSettings._iDisplayStart + oSettings._iDisplayLength; - } - } - } - - - - /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Note that most of the paging logic is done in - * DataTable.ext.oPagination - */ - - /** - * Generate the node required for default pagination - * @param {object} oSettings dataTables settings object - * @returns {node} Pagination feature node - * @memberof DataTable#oApi - */ - function _fnFeatureHtmlPaginate ( oSettings ) - { - if ( oSettings.oScroll.bInfinite ) - { - return null; - } - - var nPaginate = document.createElement( 'div' ); - nPaginate.className = oSettings.oClasses.sPaging+oSettings.sPaginationType; - - DataTable.ext.oPagination[ oSettings.sPaginationType ].fnInit( oSettings, nPaginate, - function( oSettings ) { - _fnCalculateEnd( oSettings ); - _fnDraw( oSettings ); - } - ); - - /* Add a draw callback for the pagination on first instance, to update the paging display */ - if ( !oSettings.aanFeatures.p ) - { - oSettings.aoDrawCallback.push( { - "fn": function( oSettings ) { - DataTable.ext.oPagination[ oSettings.sPaginationType ].fnUpdate( oSettings, function( oSettings ) { - _fnCalculateEnd( oSettings ); - _fnDraw( oSettings ); - } ); - }, - "sName": "pagination" - } ); - } - return nPaginate; - } - - - /** - * Alter the display settings to change the page - * @param {object} oSettings dataTables settings object - * @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last" - * or page number to jump to (integer) - * @returns {bool} true page has changed, false - no change (no effect) eg 'first' on page 1 - * @memberof DataTable#oApi - */ - function _fnPageChange ( oSettings, mAction ) - { - var iOldStart = oSettings._iDisplayStart; - - if ( typeof mAction === "number" ) - { - oSettings._iDisplayStart = mAction * oSettings._iDisplayLength; - if ( oSettings._iDisplayStart > oSettings.fnRecordsDisplay() ) - { - oSettings._iDisplayStart = 0; - } - } - else if ( mAction == "first" ) - { - oSettings._iDisplayStart = 0; - } - else if ( mAction == "previous" ) - { - oSettings._iDisplayStart = oSettings._iDisplayLength>=0 ? - oSettings._iDisplayStart - oSettings._iDisplayLength : - 0; - - /* Correct for under-run */ - if ( oSettings._iDisplayStart < 0 ) - { - oSettings._iDisplayStart = 0; - } - } - else if ( mAction == "next" ) - { - if ( oSettings._iDisplayLength >= 0 ) - { - /* Make sure we are not over running the display array */ - if ( oSettings._iDisplayStart + oSettings._iDisplayLength < oSettings.fnRecordsDisplay() ) - { - oSettings._iDisplayStart += oSettings._iDisplayLength; - } - } - else - { - oSettings._iDisplayStart = 0; - } - } - else if ( mAction == "last" ) - { - if ( oSettings._iDisplayLength >= 0 ) - { - var iPages = parseInt( (oSettings.fnRecordsDisplay()-1) / oSettings._iDisplayLength, 10 ) + 1; - oSettings._iDisplayStart = (iPages-1) * oSettings._iDisplayLength; - } - else - { - oSettings._iDisplayStart = 0; - } - } - else - { - _fnLog( oSettings, 0, "Unknown paging action: "+mAction ); - } - $(oSettings.oInstance).trigger('page', oSettings); - - return iOldStart != oSettings._iDisplayStart; - } - - - - /** - * Generate the node required for the processing node - * @param {object} oSettings dataTables settings object - * @returns {node} Processing element - * @memberof DataTable#oApi - */ - function _fnFeatureHtmlProcessing ( oSettings ) - { - var nProcessing = document.createElement( 'div' ); - - if ( !oSettings.aanFeatures.r ) - { - nProcessing.id = oSettings.sTableId+'_processing'; - } - nProcessing.innerHTML = oSettings.oLanguage.sProcessing; - nProcessing.className = oSettings.oClasses.sProcessing; - oSettings.nTable.parentNode.insertBefore( nProcessing, oSettings.nTable ); - - return nProcessing; - } - - - /** - * Display or hide the processing indicator - * @param {object} oSettings dataTables settings object - * @param {bool} bShow Show the processing indicator (true) or not (false) - * @memberof DataTable#oApi - */ - function _fnProcessingDisplay ( oSettings, bShow ) - { - if ( oSettings.oFeatures.bProcessing ) - { - var an = oSettings.aanFeatures.r; - for ( var i=0, iLen=an.length ; i 0 ) - { - nCaption = nCaption[0]; - if ( nCaption._captionSide === "top" ) - { - nScrollHeadTable.appendChild( nCaption ); - } - else if ( nCaption._captionSide === "bottom" && nTfoot ) - { - nScrollFootTable.appendChild( nCaption ); - } - } - - /* - * Sizing - */ - /* When x-scrolling add the width and a scroller to move the header with the body */ - if ( oSettings.oScroll.sX !== "" ) - { - nScrollHead.style.width = _fnStringToCss( oSettings.oScroll.sX ); - nScrollBody.style.width = _fnStringToCss( oSettings.oScroll.sX ); - - if ( nTfoot !== null ) - { - nScrollFoot.style.width = _fnStringToCss( oSettings.oScroll.sX ); - } - - /* When the body is scrolled, then we also want to scroll the headers */ - $(nScrollBody).scroll( function (e) { - nScrollHead.scrollLeft = this.scrollLeft; - - if ( nTfoot !== null ) - { - nScrollFoot.scrollLeft = this.scrollLeft; - } - } ); - } - - /* When yscrolling, add the height */ - if ( oSettings.oScroll.sY !== "" ) - { - nScrollBody.style.height = _fnStringToCss( oSettings.oScroll.sY ); - } - - /* Redraw - align columns across the tables */ - oSettings.aoDrawCallback.push( { - "fn": _fnScrollDraw, - "sName": "scrolling" - } ); - - /* Infinite scrolling event handlers */ - if ( oSettings.oScroll.bInfinite ) - { - $(nScrollBody).scroll( function() { - /* Use a blocker to stop scrolling from loading more data while other data is still loading */ - if ( !oSettings.bDrawing && $(this).scrollTop() !== 0 ) - { - /* Check if we should load the next data set */ - if ( $(this).scrollTop() + $(this).height() > - $(oSettings.nTable).height() - oSettings.oScroll.iLoadGap ) - { - /* Only do the redraw if we have to - we might be at the end of the data */ - if ( oSettings.fnDisplayEnd() < oSettings.fnRecordsDisplay() ) - { - _fnPageChange( oSettings, 'next' ); - _fnCalculateEnd( oSettings ); - _fnDraw( oSettings ); - } - } - } - } ); - } - - oSettings.nScrollHead = nScrollHead; - oSettings.nScrollFoot = nScrollFoot; - - return nScroller; - } - - - /** - * Update the various tables for resizing. It's a bit of a pig this function, but - * basically the idea to: - * 1. Re-create the table inside the scrolling div - * 2. Take live measurements from the DOM - * 3. Apply the measurements - * 4. Clean up - * @param {object} o dataTables settings object - * @returns {node} Node to add to the DOM - * @memberof DataTable#oApi - */ - function _fnScrollDraw ( o ) - { - var - nScrollHeadInner = o.nScrollHead.getElementsByTagName('div')[0], - nScrollHeadTable = nScrollHeadInner.getElementsByTagName('table')[0], - nScrollBody = o.nTable.parentNode, - i, iLen, j, jLen, anHeadToSize, anHeadSizers, anFootSizers, anFootToSize, oStyle, iVis, - nTheadSize, nTfootSize, - iWidth, aApplied=[], aAppliedFooter=[], iSanityWidth, - nScrollFootInner = (o.nTFoot !== null) ? o.nScrollFoot.getElementsByTagName('div')[0] : null, - nScrollFootTable = (o.nTFoot !== null) ? nScrollFootInner.getElementsByTagName('table')[0] : null, - ie67 = o.oBrowser.bScrollOversize, - zeroOut = function(nSizer) { - oStyle = nSizer.style; - oStyle.paddingTop = "0"; - oStyle.paddingBottom = "0"; - oStyle.borderTopWidth = "0"; - oStyle.borderBottomWidth = "0"; - oStyle.height = 0; - }; - - /* - * 1. Re-create the table inside the scrolling div - */ - - /* Remove the old minimised thead and tfoot elements in the inner table */ - $(o.nTable).children('thead, tfoot').remove(); - - /* Clone the current header and footer elements and then place it into the inner table */ - nTheadSize = $(o.nTHead).clone()[0]; - o.nTable.insertBefore( nTheadSize, o.nTable.childNodes[0] ); - anHeadToSize = o.nTHead.getElementsByTagName('tr'); - anHeadSizers = nTheadSize.getElementsByTagName('tr'); - - if ( o.nTFoot !== null ) - { - nTfootSize = $(o.nTFoot).clone()[0]; - o.nTable.insertBefore( nTfootSize, o.nTable.childNodes[1] ); - anFootToSize = o.nTFoot.getElementsByTagName('tr'); - anFootSizers = nTfootSize.getElementsByTagName('tr'); - } - - /* - * 2. Take live measurements from the DOM - do not alter the DOM itself! - */ - - /* Remove old sizing and apply the calculated column widths - * Get the unique column headers in the newly created (cloned) header. We want to apply the - * calculated sizes to this header - */ - if ( o.oScroll.sX === "" ) - { - nScrollBody.style.width = '100%'; - nScrollHeadInner.parentNode.style.width = '100%'; - } - - var nThs = _fnGetUniqueThs( o, nTheadSize ); - for ( i=0, iLen=nThs.length ; i nScrollBody.offsetHeight || - $(nScrollBody).css('overflow-y') == "scroll") ) - { - o.nTable.style.width = _fnStringToCss( $(o.nTable).outerWidth() - o.oScroll.iBarWidth); - } - } - else - { - if ( o.oScroll.sXInner !== "" ) - { - /* x scroll inner has been given - use it */ - o.nTable.style.width = _fnStringToCss(o.oScroll.sXInner); - } - else if ( iSanityWidth == $(nScrollBody).width() && - $(nScrollBody).height() < $(o.nTable).height() ) - { - /* There is y-scrolling - try to take account of the y scroll bar */ - o.nTable.style.width = _fnStringToCss( iSanityWidth-o.oScroll.iBarWidth ); - if ( $(o.nTable).outerWidth() > iSanityWidth-o.oScroll.iBarWidth ) - { - /* Not possible to take account of it */ - o.nTable.style.width = _fnStringToCss( iSanityWidth ); - } - } - else - { - /* All else fails */ - o.nTable.style.width = _fnStringToCss( iSanityWidth ); - } - } - - /* Recalculate the sanity width - now that we've applied the required width, before it was - * a temporary variable. This is required because the column width calculation is done - * before this table DOM is created. - */ - iSanityWidth = $(o.nTable).outerWidth(); - - /* We want the hidden header to have zero height, so remove padding and borders. Then - * set the width based on the real headers - */ - - // Apply all styles in one pass. Invalidates layout only once because we don't read any - // DOM properties. - _fnApplyToChildren( zeroOut, anHeadSizers ); - - // Read all widths in next pass. Forces layout only once because we do not change - // any DOM properties. - _fnApplyToChildren( function(nSizer) { - aApplied.push( _fnStringToCss( $(nSizer).width() ) ); - }, anHeadSizers ); - - // Apply all widths in final pass. Invalidates layout only once because we do not - // read any DOM properties. - _fnApplyToChildren( function(nToSize, i) { - nToSize.style.width = aApplied[i]; - }, anHeadToSize ); - - $(anHeadSizers).height(0); - - /* Same again with the footer if we have one */ - if ( o.nTFoot !== null ) - { - _fnApplyToChildren( zeroOut, anFootSizers ); - - _fnApplyToChildren( function(nSizer) { - aAppliedFooter.push( _fnStringToCss( $(nSizer).width() ) ); - }, anFootSizers ); - - _fnApplyToChildren( function(nToSize, i) { - nToSize.style.width = aAppliedFooter[i]; - }, anFootToSize ); - - $(anFootSizers).height(0); - } - - /* - * 3. Apply the measurements - */ - - /* "Hide" the header and footer that we used for the sizing. We want to also fix their width - * to what they currently are - */ - _fnApplyToChildren( function(nSizer, i) { - nSizer.innerHTML = ""; - nSizer.style.width = aApplied[i]; - }, anHeadSizers ); - - if ( o.nTFoot !== null ) - { - _fnApplyToChildren( function(nSizer, i) { - nSizer.innerHTML = ""; - nSizer.style.width = aAppliedFooter[i]; - }, anFootSizers ); - } - - /* Sanity check that the table is of a sensible width. If not then we are going to get - * misalignment - try to prevent this by not allowing the table to shrink below its min width - */ - if ( $(o.nTable).outerWidth() < iSanityWidth ) - { - /* The min width depends upon if we have a vertical scrollbar visible or not */ - var iCorrection = ((nScrollBody.scrollHeight > nScrollBody.offsetHeight || - $(nScrollBody).css('overflow-y') == "scroll")) ? - iSanityWidth+o.oScroll.iBarWidth : iSanityWidth; - - /* IE6/7 are a law unto themselves... */ - if ( ie67 && (nScrollBody.scrollHeight > - nScrollBody.offsetHeight || $(nScrollBody).css('overflow-y') == "scroll") ) - { - o.nTable.style.width = _fnStringToCss( iCorrection-o.oScroll.iBarWidth ); - } - - /* Apply the calculated minimum width to the table wrappers */ - nScrollBody.style.width = _fnStringToCss( iCorrection ); - o.nScrollHead.style.width = _fnStringToCss( iCorrection ); - - if ( o.nTFoot !== null ) - { - o.nScrollFoot.style.width = _fnStringToCss( iCorrection ); - } - - /* And give the user a warning that we've stopped the table getting too small */ - if ( o.oScroll.sX === "" ) - { - _fnLog( o, 1, "The table cannot fit into the current element which will cause column"+ - " misalignment. The table has been drawn at its minimum possible width." ); - } - else if ( o.oScroll.sXInner !== "" ) - { - _fnLog( o, 1, "The table cannot fit into the current element which will cause column"+ - " misalignment. Increase the sScrollXInner value or remove it to allow automatic"+ - " calculation" ); - } - } - else - { - nScrollBody.style.width = _fnStringToCss( '100%' ); - o.nScrollHead.style.width = _fnStringToCss( '100%' ); - - if ( o.nTFoot !== null ) - { - o.nScrollFoot.style.width = _fnStringToCss( '100%' ); - } - } - - - /* - * 4. Clean up - */ - if ( o.oScroll.sY === "" ) - { - /* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting - * the scrollbar height from the visible display, rather than adding it on. We need to - * set the height in order to sort this. Don't want to do it in any other browsers. - */ - if ( ie67 ) - { - nScrollBody.style.height = _fnStringToCss( o.nTable.offsetHeight+o.oScroll.iBarWidth ); - } - } - - if ( o.oScroll.sY !== "" && o.oScroll.bCollapse ) - { - nScrollBody.style.height = _fnStringToCss( o.oScroll.sY ); - - var iExtra = (o.oScroll.sX !== "" && o.nTable.offsetWidth > nScrollBody.offsetWidth) ? - o.oScroll.iBarWidth : 0; - if ( o.nTable.offsetHeight < nScrollBody.offsetHeight ) - { - nScrollBody.style.height = _fnStringToCss( o.nTable.offsetHeight+iExtra ); - } - } - - /* Finally set the width's of the header and footer tables */ - var iOuterWidth = $(o.nTable).outerWidth(); - nScrollHeadTable.style.width = _fnStringToCss( iOuterWidth ); - nScrollHeadInner.style.width = _fnStringToCss( iOuterWidth ); - - // Figure out if there are scrollbar present - if so then we need a the header and footer to - // provide a bit more space to allow "overflow" scrolling (i.e. past the scrollbar) - var bScrolling = $(o.nTable).height() > nScrollBody.clientHeight || $(nScrollBody).css('overflow-y') == "scroll"; - nScrollHeadInner.style.paddingRight = bScrolling ? o.oScroll.iBarWidth+"px" : "0px"; - - if ( o.nTFoot !== null ) - { - nScrollFootTable.style.width = _fnStringToCss( iOuterWidth ); - nScrollFootInner.style.width = _fnStringToCss( iOuterWidth ); - nScrollFootInner.style.paddingRight = bScrolling ? o.oScroll.iBarWidth+"px" : "0px"; - } - - /* Adjust the position of the header in case we loose the y-scrollbar */ - $(nScrollBody).scroll(); - - /* If sorting or filtering has occurred, jump the scrolling back to the top */ - if ( o.bSorted || o.bFiltered ) - { - nScrollBody.scrollTop = 0; - } - } - - - /** - * Apply a given function to the display child nodes of an element array (typically - * TD children of TR rows - * @param {function} fn Method to apply to the objects - * @param array {nodes} an1 List of elements to look through for display children - * @param array {nodes} an2 Another list (identical structure to the first) - optional - * @memberof DataTable#oApi - */ - function _fnApplyToChildren( fn, an1, an2 ) - { - var index=0, i=0, iLen=an1.length; - var nNode1, nNode2; - - while ( i < iLen ) - { - nNode1 = an1[i].firstChild; - nNode2 = an2 ? an2[i].firstChild : null; - while ( nNode1 ) - { - if ( nNode1.nodeType === 1 ) - { - if ( an2 ) - { - fn( nNode1, nNode2, index ); - } - else - { - fn( nNode1, index ); - } - index++; - } - nNode1 = nNode1.nextSibling; - nNode2 = an2 ? nNode2.nextSibling : null; - } - i++; - } - } - - /** - * Convert a CSS unit width to pixels (e.g. 2em) - * @param {string} sWidth width to be converted - * @param {node} nParent parent to get the with for (required for relative widths) - optional - * @returns {int} iWidth width in pixels - * @memberof DataTable#oApi - */ - function _fnConvertToWidth ( sWidth, nParent ) - { - if ( !sWidth || sWidth === null || sWidth === '' ) - { - return 0; - } - - if ( !nParent ) - { - nParent = document.body; - } - - var iWidth; - var nTmp = document.createElement( "div" ); - nTmp.style.width = _fnStringToCss( sWidth ); - - nParent.appendChild( nTmp ); - iWidth = nTmp.offsetWidth; - nParent.removeChild( nTmp ); - - return ( iWidth ); - } - - - /** - * Calculate the width of columns for the table - * @param {object} oSettings dataTables settings object - * @memberof DataTable#oApi - */ - function _fnCalculateColumnWidths ( oSettings ) - { - var iTableWidth = oSettings.nTable.offsetWidth; - var iUserInputs = 0; - var iTmpWidth; - var iVisibleColumns = 0; - var iColums = oSettings.aoColumns.length; - var i, iIndex, iCorrector, iWidth; - var oHeaders = $('th', oSettings.nTHead); - var widthAttr = oSettings.nTable.getAttribute('width'); - var nWrapper = oSettings.nTable.parentNode; - - /* Convert any user input sizes into pixel sizes */ - for ( i=0 ; itd', nCalcTmp); - } - - /* Apply custom sizing to the cloned header */ - var nThs = _fnGetUniqueThs( oSettings, nTheadClone ); - iCorrector = 0; - for ( i=0 ; i 0 ) - { - oSettings.aoColumns[i].sWidth = _fnStringToCss( iWidth ); - } - iCorrector++; - } - } - - var cssWidth = $(nCalcTmp).css('width'); - oSettings.nTable.style.width = (cssWidth.indexOf('%') !== -1) ? - cssWidth : _fnStringToCss( $(nCalcTmp).outerWidth() ); - nCalcTmp.parentNode.removeChild( nCalcTmp ); - } - - if ( widthAttr ) - { - oSettings.nTable.style.width = _fnStringToCss( widthAttr ); - } - } - - - /** - * Adjust a table's width to take account of scrolling - * @param {object} oSettings dataTables settings object - * @param {node} n table node - * @memberof DataTable#oApi - */ - function _fnScrollingWidthAdjust ( oSettings, n ) - { - if ( oSettings.oScroll.sX === "" && oSettings.oScroll.sY !== "" ) - { - /* When y-scrolling only, we want to remove the width of the scroll bar so the table - * + scroll bar will fit into the area avaialble. - */ - var iOrigWidth = $(n).width(); - n.style.width = _fnStringToCss( $(n).outerWidth()-oSettings.oScroll.iBarWidth ); - } - else if ( oSettings.oScroll.sX !== "" ) - { - /* When x-scrolling both ways, fix the table at it's current size, without adjusting */ - n.style.width = _fnStringToCss( $(n).outerWidth() ); - } - } - - - /** - * Get the widest node - * @param {object} oSettings dataTables settings object - * @param {int} iCol column of interest - * @returns {node} widest table node - * @memberof DataTable#oApi - */ - function _fnGetWidestNode( oSettings, iCol ) - { - var iMaxIndex = _fnGetMaxLenString( oSettings, iCol ); - if ( iMaxIndex < 0 ) - { - return null; - } - - if ( oSettings.aoData[iMaxIndex].nTr === null ) - { - var n = document.createElement('td'); - n.innerHTML = _fnGetCellData( oSettings, iMaxIndex, iCol, '' ); - return n; - } - return _fnGetTdNodes(oSettings, iMaxIndex)[iCol]; - } - - - /** - * Get the maximum strlen for each data column - * @param {object} oSettings dataTables settings object - * @param {int} iCol column of interest - * @returns {string} max string length for each column - * @memberof DataTable#oApi - */ - function _fnGetMaxLenString( oSettings, iCol ) - { - var iMax = -1; - var iMaxIndex = -1; - - for ( var i=0 ; i/g, "" ); - if ( s.length > iMax ) - { - iMax = s.length; - iMaxIndex = i; - } - } - - return iMaxIndex; - } - - - /** - * Append a CSS unit (only if required) to a string - * @param {array} aArray1 first array - * @param {array} aArray2 second array - * @returns {int} 0 if match, 1 if length is different, 2 if no match - * @memberof DataTable#oApi - */ - function _fnStringToCss( s ) - { - if ( s === null ) - { - return "0px"; - } - - if ( typeof s == 'number' ) - { - if ( s < 0 ) - { - return "0px"; - } - return s+"px"; - } - - /* Check if the last character is not 0-9 */ - var c = s.charCodeAt( s.length-1 ); - if (c < 0x30 || c > 0x39) - { - return s; - } - return s+"px"; - } - - - /** - * Get the width of a scroll bar in this browser being used - * @returns {int} width in pixels - * @memberof DataTable#oApi - */ - function _fnScrollBarWidth () - { - var inner = document.createElement('p'); - var style = inner.style; - style.width = "100%"; - style.height = "200px"; - style.padding = "0px"; - - var outer = document.createElement('div'); - style = outer.style; - style.position = "absolute"; - style.top = "0px"; - style.left = "0px"; - style.visibility = "hidden"; - style.width = "200px"; - style.height = "150px"; - style.padding = "0px"; - style.overflow = "hidden"; - outer.appendChild(inner); - - document.body.appendChild(outer); - var w1 = inner.offsetWidth; - outer.style.overflow = 'scroll'; - var w2 = inner.offsetWidth; - if ( w1 == w2 ) - { - w2 = outer.clientWidth; - } - - document.body.removeChild(outer); - return (w1 - w2); - } - - /** - * Change the order of the table - * @param {object} oSettings dataTables settings object - * @param {bool} bApplyClasses optional - should we apply classes or not - * @memberof DataTable#oApi - */ - function _fnSort ( oSettings, bApplyClasses ) - { - var - i, iLen, j, jLen, k, kLen, - sDataType, nTh, - aaSort = [], - aiOrig = [], - oSort = DataTable.ext.oSort, - aoData = oSettings.aoData, - aoColumns = oSettings.aoColumns, - oAria = oSettings.oLanguage.oAria; - - /* No sorting required if server-side or no sorting array */ - if ( !oSettings.oFeatures.bServerSide && - (oSettings.aaSorting.length !== 0 || oSettings.aaSortingFixed !== null) ) - { - aaSort = ( oSettings.aaSortingFixed !== null ) ? - oSettings.aaSortingFixed.concat( oSettings.aaSorting ) : - oSettings.aaSorting.slice(); - - /* If there is a sorting data type, and a function belonging to it, then we need to - * get the data from the developer's function and apply it for this column - */ - for ( i=0 ; i/g, "" ); - nTh = aoColumns[i].nTh; - nTh.removeAttribute('aria-sort'); - nTh.removeAttribute('aria-label'); - - /* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */ - if ( aoColumns[i].bSortable ) - { - if ( aaSort.length > 0 && aaSort[0][0] == i ) - { - nTh.setAttribute('aria-sort', aaSort[0][1]=="asc" ? "ascending" : "descending" ); - - var nextSort = (aoColumns[i].asSorting[ aaSort[0][2]+1 ]) ? - aoColumns[i].asSorting[ aaSort[0][2]+1 ] : aoColumns[i].asSorting[0]; - nTh.setAttribute('aria-label', sTitle+ - (nextSort=="asc" ? oAria.sSortAscending : oAria.sSortDescending) ); - } - else - { - nTh.setAttribute('aria-label', sTitle+ - (aoColumns[i].asSorting[0]=="asc" ? oAria.sSortAscending : oAria.sSortDescending) ); - } - } - else - { - nTh.setAttribute('aria-label', sTitle); - } - } - - /* Tell the draw function that we have sorted the data */ - oSettings.bSorted = true; - $(oSettings.oInstance).trigger('sort', oSettings); - - /* Copy the master data into the draw array and re-draw */ - if ( oSettings.oFeatures.bFilter ) - { - /* _fnFilter() will redraw the table for us */ - _fnFilterComplete( oSettings, oSettings.oPreviousSearch, 1 ); - } - else - { - oSettings.aiDisplay = oSettings.aiDisplayMaster.slice(); - oSettings._iDisplayStart = 0; /* reset display back to page 0 */ - _fnCalculateEnd( oSettings ); - _fnDraw( oSettings ); - } - } - - - /** - * Attach a sort handler (click) to a node - * @param {object} oSettings dataTables settings object - * @param {node} nNode node to attach the handler to - * @param {int} iDataIndex column sorting index - * @param {function} [fnCallback] callback function - * @memberof DataTable#oApi - */ - function _fnSortAttachListener ( oSettings, nNode, iDataIndex, fnCallback ) - { - _fnBindAction( nNode, {}, function (e) { - /* If the column is not sortable - don't to anything */ - if ( oSettings.aoColumns[iDataIndex].bSortable === false ) - { - return; - } - - /* - * This is a little bit odd I admit... I declare a temporary function inside the scope of - * _fnBuildHead and the click handler in order that the code presented here can be used - * twice - once for when bProcessing is enabled, and another time for when it is - * disabled, as we need to perform slightly different actions. - * Basically the issue here is that the Javascript engine in modern browsers don't - * appear to allow the rendering engine to update the display while it is still executing - * it's thread (well - it does but only after long intervals). This means that the - * 'processing' display doesn't appear for a table sort. To break the js thread up a bit - * I force an execution break by using setTimeout - but this breaks the expected - * thread continuation for the end-developer's point of view (their code would execute - * too early), so we only do it when we absolutely have to. - */ - var fnInnerSorting = function () { - var iColumn, iNextSort; - - /* If the shift key is pressed then we are multiple column sorting */ - if ( e.shiftKey ) - { - /* Are we already doing some kind of sort on this column? */ - var bFound = false; - for ( var i=0 ; i 0 && sCurrentClass.indexOf(sNewClass) == -1 ) - { - /* We need to add a class */ - nTds[i].className = sCurrentClass + " " + sNewClass; - } - } - } - } - - - - /** - * Save the state of a table in a cookie such that the page can be reloaded - * @param {object} oSettings dataTables settings object - * @memberof DataTable#oApi - */ - function _fnSaveState ( oSettings ) - { - if ( !oSettings.oFeatures.bStateSave || oSettings.bDestroying ) - { - return; - } - - /* Store the interesting variables */ - var i, iLen, bInfinite=oSettings.oScroll.bInfinite; - var oState = { - "iCreate": new Date().getTime(), - "iStart": (bInfinite ? 0 : oSettings._iDisplayStart), - "iEnd": (bInfinite ? oSettings._iDisplayLength : oSettings._iDisplayEnd), - "iLength": oSettings._iDisplayLength, - "aaSorting": $.extend( true, [], oSettings.aaSorting ), - "oSearch": $.extend( true, {}, oSettings.oPreviousSearch ), - "aoSearchCols": $.extend( true, [], oSettings.aoPreSearchCols ), - "abVisCols": [] - }; - - for ( i=0, iLen=oSettings.aoColumns.length ; i 4096 ) /* Magic 10 for padding */ - { - for ( var i=0, iLen=aCookies.length ; i 4096 ) { - if ( aOldCookies.length === 0 ) { - // Deleted all DT cookies and still not enough space. Can't state save - return; - } - - var old = aOldCookies.pop(); - document.cookie = old.name+"=; expires=Thu, 01-Jan-1970 00:00:01 GMT; path="+ - aParts.join('/') + "/"; - } - } - - document.cookie = sFullCookie; - } - - - /** - * Read an old cookie to get a cookie with an old table state - * @param {string} sName name of the cookie to read - * @returns {string} contents of the cookie - or null if no cookie with that name found - * @memberof DataTable#oApi - */ - function _fnReadCookie ( sName ) - { - var - aParts = window.location.pathname.split('/'), - sNameEQ = sName + '_' + aParts[aParts.length-1].replace(/[\/:]/g,"").toLowerCase() + '=', - sCookieContents = document.cookie.split(';'); - - for( var i=0 ; i=0 ; i-- ) - { - aRet.push( aoStore[i].fn.apply( oSettings.oInstance, aArgs ) ); - } - - if ( sTrigger !== null ) - { - $(oSettings.oInstance).trigger(sTrigger, aArgs); - } - - return aRet; - } - - - /** - * JSON stringify. If JSON.stringify it provided by the browser, json2.js or any other - * library, then we use that as it is fast, safe and accurate. If the function isn't - * available then we need to built it ourselves - the inspiration for this function comes - * from Craig Buckler ( http://www.sitepoint.com/javascript-json-serialization/ ). It is - * not perfect and absolutely should not be used as a replacement to json2.js - but it does - * do what we need, without requiring a dependency for DataTables. - * @param {object} o JSON object to be converted - * @returns {string} JSON string - * @memberof DataTable#oApi - */ - var _fnJsonString = (window.JSON) ? JSON.stringify : function( o ) - { - /* Not an object or array */ - var sType = typeof o; - if (sType !== "object" || o === null) - { - // simple data type - if (sType === "string") - { - o = '"'+o+'"'; - } - return o+""; - } - - /* If object or array, need to recurse over it */ - var - sProp, mValue, - json = [], - bArr = $.isArray(o); - - for (sProp in o) - { - mValue = o[sProp]; - sType = typeof mValue; - - if (sType === "string") - { - mValue = '"'+mValue+'"'; - } - else if (sType === "object" && mValue !== null) - { - mValue = _fnJsonString(mValue); - } - - json.push((bArr ? "" : '"'+sProp+'":') + mValue); - } - - return (bArr ? "[" : "{") + json + (bArr ? "]" : "}"); - }; - - - /** - * From some browsers (specifically IE6/7) we need special handling to work around browser - * bugs - this function is used to detect when these workarounds are needed. - * @param {object} oSettings dataTables settings object - * @memberof DataTable#oApi - */ - function _fnBrowserDetect( oSettings ) - { - /* IE6/7 will oversize a width 100% element inside a scrolling element, to include the - * width of the scrollbar, while other browsers ensure the inner element is contained - * without forcing scrolling - */ - var n = $( - '
    '+ - '
    '+ - '
    '+ - '
    '+ - '
    ')[0]; - - document.body.appendChild( n ); - oSettings.oBrowser.bScrollOversize = $('#DT_BrowserTest', n)[0].offsetWidth === 100 ? true : false; - document.body.removeChild( n ); - } - - - /** - * Perform a jQuery selector action on the table's TR elements (from the tbody) and - * return the resulting jQuery object. - * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on - * @param {object} [oOpts] Optional parameters for modifying the rows to be included - * @param {string} [oOpts.filter=none] Select TR elements that meet the current filter - * criterion ("applied") or all TR elements (i.e. no filter). - * @param {string} [oOpts.order=current] Order of the TR elements in the processed array. - * Can be either 'current', whereby the current sorting of the table is used, or - * 'original' whereby the original order the data was read into the table is used. - * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page - * ("current") or not ("all"). If 'current' is given, then order is assumed to be - * 'current' and filter is 'applied', regardless of what they might be given as. - * @returns {object} jQuery object, filtered by the given selector. - * @dtopt API - * - * @example - * $(document).ready(function() { - * var oTable = $('#example').dataTable(); - * - * // Highlight every second row - * oTable.$('tr:odd').css('backgroundColor', 'blue'); - * } ); - * - * @example - * $(document).ready(function() { - * var oTable = $('#example').dataTable(); - * - * // Filter to rows with 'Webkit' in them, add a background colour and then - * // remove the filter, thus highlighting the 'Webkit' rows only. - * oTable.fnFilter('Webkit'); - * oTable.$('tr', {"filter": "applied"}).css('backgroundColor', 'blue'); - * oTable.fnFilter(''); - * } ); - */ - this.$ = function ( sSelector, oOpts ) - { - var i, iLen, a = [], tr; - var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] ); - var aoData = oSettings.aoData; - var aiDisplay = oSettings.aiDisplay; - var aiDisplayMaster = oSettings.aiDisplayMaster; - - if ( !oOpts ) - { - oOpts = {}; - } - - oOpts = $.extend( {}, { - "filter": "none", // applied - "order": "current", // "original" - "page": "all" // current - }, oOpts ); - - // Current page implies that order=current and fitler=applied, since it is fairly - // senseless otherwise - if ( oOpts.page == 'current' ) - { - for ( i=oSettings._iDisplayStart, iLen=oSettings.fnDisplayEnd() ; i - *
  • 1D array of data - add a single row with the data provided
  • - *
  • 2D array of arrays - add multiple rows in a single call
  • - *
  • object - data object when using mData
  • - *
  • array of objects - multiple data objects when using mData
  • - * - * @param {bool} [bRedraw=true] redraw the table or not - * @returns {array} An array of integers, representing the list of indexes in - * aoData ({@link DataTable.models.oSettings}) that have been added to - * the table. - * @dtopt API - * - * @example - * // Global var for counter - * var giCount = 2; - * - * $(document).ready(function() { - * $('#example').dataTable(); - * } ); - * - * function fnClickAddRow() { - * $('#example').dataTable().fnAddData( [ - * giCount+".1", - * giCount+".2", - * giCount+".3", - * giCount+".4" ] - * ); - * - * giCount++; - * } - */ - this.fnAddData = function( mData, bRedraw ) - { - if ( mData.length === 0 ) - { - return []; - } - - var aiReturn = []; - var iTest; - - /* Find settings from table node */ - var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] ); - - /* Check if we want to add multiple rows or not */ - if ( typeof mData[0] === "object" && mData[0] !== null ) - { - for ( var i=0 ; i= oSettings.fnRecordsDisplay() ) - { - oSettings._iDisplayStart -= oSettings._iDisplayLength; - if ( oSettings._iDisplayStart < 0 ) - { - oSettings._iDisplayStart = 0; - } - } - - if ( bRedraw === undefined || bRedraw ) - { - _fnCalculateEnd( oSettings ); - _fnDraw( oSettings ); - } - - return oData; - }; - - - /** - * Restore the table to it's original state in the DOM by removing all of DataTables - * enhancements, alterations to the DOM structure of the table and event listeners. - * @param {boolean} [bRemove=false] Completely remove the table from the DOM - * @dtopt API - * - * @example - * $(document).ready(function() { - * // This example is fairly pointless in reality, but shows how fnDestroy can be used - * var oTable = $('#example').dataTable(); - * oTable.fnDestroy(); - * } ); - */ - this.fnDestroy = function ( bRemove ) - { - var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] ); - var nOrig = oSettings.nTableWrapper.parentNode; - var nBody = oSettings.nTBody; - var i, iLen; - - bRemove = (bRemove===undefined) ? false : bRemove; - - /* Flag to note that the table is currently being destroyed - no action should be taken */ - oSettings.bDestroying = true; - - /* Fire off the destroy callbacks for plug-ins etc */ - _fnCallbackFire( oSettings, "aoDestroyCallback", "destroy", [oSettings] ); - - /* If the table is not being removed, restore the hidden columns */ - if ( !bRemove ) - { - for ( i=0, iLen=oSettings.aoColumns.length ; itr>td.'+oSettings.oClasses.sRowEmpty, oSettings.nTable).parent().remove(); - - /* When scrolling we had to break the table up - restore it */ - if ( oSettings.nTable != oSettings.nTHead.parentNode ) - { - $(oSettings.nTable).children('thead').remove(); - oSettings.nTable.appendChild( oSettings.nTHead ); - } - - if ( oSettings.nTFoot && oSettings.nTable != oSettings.nTFoot.parentNode ) - { - $(oSettings.nTable).children('tfoot').remove(); - oSettings.nTable.appendChild( oSettings.nTFoot ); - } - - /* Remove the DataTables generated nodes, events and classes */ - oSettings.nTable.parentNode.removeChild( oSettings.nTable ); - $(oSettings.nTableWrapper).remove(); - - oSettings.aaSorting = []; - oSettings.aaSortingFixed = []; - _fnSortingClasses( oSettings ); - - $(_fnGetTrNodes( oSettings )).removeClass( oSettings.asStripeClasses.join(' ') ); - - $('th, td', oSettings.nTHead).removeClass( [ - oSettings.oClasses.sSortable, - oSettings.oClasses.sSortableAsc, - oSettings.oClasses.sSortableDesc, - oSettings.oClasses.sSortableNone ].join(' ') - ); - if ( oSettings.bJUI ) - { - $('th span.'+oSettings.oClasses.sSortIcon - + ', td span.'+oSettings.oClasses.sSortIcon, oSettings.nTHead).remove(); - - $('th, td', oSettings.nTHead).each( function () { - var jqWrapper = $('div.'+oSettings.oClasses.sSortJUIWrapper, this); - var kids = jqWrapper.contents(); - $(this).append( kids ); - jqWrapper.remove(); - } ); - } - - /* Add the TR elements back into the table in their original order */ - if ( !bRemove && oSettings.nTableReinsertBefore ) - { - nOrig.insertBefore( oSettings.nTable, oSettings.nTableReinsertBefore ); - } - else if ( !bRemove ) - { - nOrig.appendChild( oSettings.nTable ); - } - - for ( i=0, iLen=oSettings.aoData.length ; i
    ' + - '
    ' + - '
    ' + - '
    ' + - '
    ' + - '' + - '' + - '
    ' + - '
    ' + - '' + - '' + - '
    ' + - ' ' + - '' + - '
    ' + - '
    ' + - '
    '; - - this.parentEl = (hasOptions && options.parentEl && $(options.parentEl)) || $(this.parentEl); - //the date range picker - this.container = $(DRPTemplate).appendTo(this.parentEl); - - if (hasOptions) { - - if (typeof options.format == 'string') - this.format = options.format; - - if (typeof options.separator == 'string') - this.separator = options.separator; - - if (typeof options.startDate == 'string') - this.startDate = moment(options.startDate, this.format); - - if (typeof options.endDate == 'string') - this.endDate = moment(options.endDate, this.format); - - if (typeof options.minDate == 'string') - this.minDate = moment(options.minDate, this.format); - - if (typeof options.maxDate == 'string') - this.maxDate = moment(options.maxDate, this.format); - - if (typeof options.startDate == 'object') - this.startDate = moment(options.startDate); - - if (typeof options.endDate == 'object') - this.endDate = moment(options.endDate); - - if (typeof options.minDate == 'object') - this.minDate = moment(options.minDate); - - if (typeof options.maxDate == 'object') - this.maxDate = moment(options.maxDate); - - if (typeof options.ranges == 'object') { - for (var range in options.ranges) { - - var start = moment(options.ranges[range][0]); - var end = moment(options.ranges[range][1]); - - // If we have a min/max date set, bound this range - // to it, but only if it would otherwise fall - // outside of the min/max. - if (this.minDate && start.isBefore(this.minDate)) - start = moment(this.minDate); - - if (this.maxDate && end.isAfter(this.maxDate)) - end = moment(this.maxDate); - - // If the end of the range is before the minimum (if min is set) OR - // the start of the range is after the max (also if set) don't display this - // range option. - if ((this.minDate && end.isBefore(this.minDate)) || (this.maxDate && start.isAfter(this.maxDate))) { - continue; - } - - this.ranges[range] = [start, end]; - } - - var list = '
      '; - for (var range in this.ranges) { - list += '
    • ' + range + '
    • '; - } - list += '
    • ' + this.locale.customRangeLabel + '
    • '; - list += '
    '; - this.container.find('.ranges').prepend(list); - } - - if (typeof options.dateLimit == 'object') - this.dateLimit = options.dateLimit; - - // update day names order to firstDay - if (typeof options.locale == 'object') { - - if (typeof options.locale.daysOfWeek == 'object') { - - // Create a copy of daysOfWeek to avoid modification of original - // options object for reusability in multiple daterangepicker instances - this.locale.daysOfWeek = options.locale.daysOfWeek.slice(); - } - - if (typeof options.locale.firstDay == 'number') { - this.locale.firstDay = options.locale.firstDay; - var iterator = options.locale.firstDay; - while (iterator > 0) { - this.locale.daysOfWeek.push(this.locale.daysOfWeek.shift()); - iterator--; - } - } - } - - if (typeof options.opens == 'string') - this.opens = options.opens; - - if (typeof options.showWeekNumbers == 'boolean') { - this.showWeekNumbers = options.showWeekNumbers; - } - - if (typeof options.buttonClasses == 'string') { - this.buttonClasses = [options.buttonClasses]; - } - - if (typeof options.buttonClasses == 'object') { - this.buttonClasses = options.buttonClasses; - } - - if (typeof options.showDropdowns == 'boolean') { - this.showDropdowns = options.showDropdowns; - } - - if (typeof options.timePicker == 'boolean') { - this.timePicker = options.timePicker; - } - - if (typeof options.timePickerIncrement == 'number') { - this.timePickerIncrement = options.timePickerIncrement; - } - - if (typeof options.timePicker12Hour == 'boolean') { - this.timePicker12Hour = options.timePicker12Hour; - } - - } - - if (!this.timePicker) { - this.startDate = this.startDate.startOf('day'); - this.endDate = this.endDate.startOf('day'); - } - - //apply CSS classes to buttons - var c = this.container; - $.each(this.buttonClasses, function (idx, val) { - c.find('button').addClass(val); - }); - - if (this.opens == 'right') { - //swap calendar positions - var left = this.container.find('.calendar.left'); - var right = this.container.find('.calendar.right'); - left.removeClass('left').addClass('right'); - right.removeClass('right').addClass('left'); - } - - if (typeof options == 'undefined' || typeof options.ranges == 'undefined') { - this.container.find('.calendar').show(); - this.move(); - } - - if (typeof cb == 'function') - this.cb = cb; - - this.container.addClass('opens' + this.opens); - - //try parse date if in text input - if (!hasOptions || (typeof options.startDate == 'undefined' && typeof options.endDate == 'undefined')) { - if ($(this.element).is('input[type=text]')) { - var val = $(this.element).val(); - var split = val.split(this.separator); - var start, end; - if (split.length == 2) { - start = moment(split[0], this.format); - end = moment(split[1], this.format); - } - if (start != null && end != null) { - this.startDate = start; - this.endDate = end; - } - } - } - - //state - this.oldStartDate = this.startDate.clone(); - this.oldEndDate = this.endDate.clone(); - - this.leftCalendar = { - month: moment([this.startDate.year(), this.startDate.month(), 1, this.startDate.hour(), this.startDate.minute()]), - calendar: [] - }; - - this.rightCalendar = { - month: moment([this.endDate.year(), this.endDate.month(), 1, this.endDate.hour(), this.endDate.minute()]), - calendar: [] - }; - - //event listeners - this.container.on('mousedown', $.proxy(this.mousedown, this)); - - this.container.find('.calendar') - .on('click', '.prev', $.proxy(this.clickPrev, this)) - .on('click', '.next', $.proxy(this.clickNext, this)) - .on('click', 'td.available', $.proxy(this.clickDate, this)) - .on('mouseenter', 'td.available', $.proxy(this.enterDate, this)) - .on('mouseleave', 'td.available', $.proxy(this.updateFormInputs, this)) - .on('change', 'select.yearselect', $.proxy(this.updateMonthYear, this)) - .on('change', 'select.monthselect', $.proxy(this.updateMonthYear, this)) - .on('change', 'select.hourselect,select.minuteselect,select.ampmselect', $.proxy(this.updateTime, this)); - - this.container.find('.ranges') - .on('click', 'button.applyBtn', $.proxy(this.clickApply, this)) - .on('click', 'button.cancelBtn', $.proxy(this.clickCancel, this)) - .on('click', '.daterangepicker_start_input,.daterangepicker_end_input', $.proxy(this.showCalendars, this)) - .on('click', 'li', $.proxy(this.clickRange, this)) - .on('mouseenter', 'li', $.proxy(this.enterRange, this)) - .on('mouseleave', 'li', $.proxy(this.updateFormInputs, this)); - - this.element.on('keyup', $.proxy(this.updateFromControl, this)); - - this.updateView(); - this.updateCalendars(); - - }; - - DateRangePicker.prototype = { - - constructor: DateRangePicker, - - mousedown: function (e) { - e.stopPropagation(); - }, - - updateView: function () { - this.leftCalendar.month.month(this.startDate.month()).year(this.startDate.year()); - this.rightCalendar.month.month(this.endDate.month()).year(this.endDate.year()); - this.updateFormInputs(); - }, - - updateFormInputs: function () { - this.container.find('input[name=daterangepicker_start]').val(this.startDate.format(this.format)); - this.container.find('input[name=daterangepicker_end]').val(this.endDate.format(this.format)); - - if (this.startDate.isSame(this.endDate) || this.startDate.isBefore(this.endDate)) { - this.container.find('button.applyBtn').removeAttr('disabled'); - } else { - this.container.find('button.applyBtn').attr('disabled', 'disabled'); - } - }, - - updateFromControl: function () { - if (!this.element.is('input')) return; - if (!this.element.val().length) return; - - var dateString = this.element.val().split(this.separator); - var start = moment(dateString[0], this.format); - var end = moment(dateString[1], this.format); - - if (start == null || end == null) return; - if (end.isBefore(start)) return; - - this.oldStartDate = this.startDate.clone(); - this.oldEndDate = this.endDate.clone(); - - this.startDate = start; - this.endDate = end; - - if (!this.startDate.isSame(this.oldStartDate) || !this.endDate.isSame(this.oldEndDate)) - this.notify(); - - this.updateCalendars(); - }, - - notify: function () { - this.updateView(); - this.cb(this.startDate, this.endDate); - }, - - move: function () { - var parentOffset = { - top: this.parentEl.offset().top - (this.parentEl.is('body') ? 0 : this.parentEl.scrollTop()), - left: this.parentEl.offset().left - (this.parentEl.is('body') ? 0 : this.parentEl.scrollLeft()) - }; - if (this.opens == 'left') { - this.container.css({ - top: this.element.offset().top + this.element.outerHeight() - parentOffset.top, - right: $(window).width() - this.element.offset().left - this.element.outerWidth() - parentOffset.left, - left: 'auto' - }); - if (this.container.offset().left < 0) { - this.container.css({ - right: 'auto', - left: 9 - }); - } - } else { - this.container.css({ - top: this.element.offset().top + this.element.outerHeight() - parentOffset.top, - left: this.element.offset().left - parentOffset.left, - right: 'auto' - }); - if (this.container.offset().left + this.container.outerWidth() > $(window).width()) { - this.container.css({ - left: 'auto', - right: 0 - }); - } - } - }, - - show: function (e) { - this.container.show(); - this.move(); - - if (e) { - e.stopPropagation(); - e.preventDefault(); - } - - $(document).on('mousedown', $.proxy(this.hide, this)); - this.element.trigger('shown', {target: e.target, picker: this}); - }, - - hide: function (e) { - this.container.hide(); - - if (!this.startDate.isSame(this.oldStartDate) || !this.endDate.isSame(this.oldEndDate)) - this.notify(); - - this.oldStartDate = this.startDate.clone(); - this.oldEndDate = this.endDate.clone(); - - $(document).off('mousedown', this.hide); - this.element.trigger('hidden', { picker: this }); - }, - - enterRange: function (e) { - var label = e.target.innerHTML; - if (label == this.locale.customRangeLabel) { - this.updateView(); - } else { - var dates = this.ranges[label]; - this.container.find('input[name=daterangepicker_start]').val(dates[0].format(this.format)); - this.container.find('input[name=daterangepicker_end]').val(dates[1].format(this.format)); - } - }, - - showCalendars: function() { - this.container.find('.calendar').show(); - this.move(); - }, - - updateInputText: function() { - if (this.element.is('input')) - this.element.val(this.startDate.format(this.format) + this.separator + this.endDate.format(this.format)); - }, - - clickRange: function (e) { - var label = e.target.innerHTML; - if (label == this.locale.customRangeLabel) { - this.showCalendars(); - } else { - var dates = this.ranges[label]; - - this.startDate = dates[0]; - this.endDate = dates[1]; - - if (!this.timePicker) { - this.startDate.startOf('day'); - this.endDate.startOf('day'); - } - - this.leftCalendar.month.month(this.startDate.month()).year(this.startDate.year()).hour(this.startDate.hour()).minute(this.startDate.minute()); - this.rightCalendar.month.month(this.endDate.month()).year(this.endDate.year()).hour(this.endDate.hour()).minute(this.endDate.minute()); - this.updateCalendars(); - - this.updateInputText(); - - this.container.find('.calendar').hide(); - this.hide(); - } - }, - - clickPrev: function (e) { - var cal = $(e.target).parents('.calendar'); - if (cal.hasClass('left')) { - this.leftCalendar.month.subtract('month', 1); - } else { - this.rightCalendar.month.subtract('month', 1); - } - this.updateCalendars(); - }, - - clickNext: function (e) { - var cal = $(e.target).parents('.calendar'); - if (cal.hasClass('left')) { - this.leftCalendar.month.add('month', 1); - } else { - this.rightCalendar.month.add('month', 1); - } - this.updateCalendars(); - }, - - enterDate: function (e) { - - var title = $(e.target).attr('data-title'); - var row = title.substr(1, 1); - var col = title.substr(3, 1); - var cal = $(e.target).parents('.calendar'); - - if (cal.hasClass('left')) { - this.container.find('input[name=daterangepicker_start]').val(this.leftCalendar.calendar[row][col].format(this.format)); - } else { - this.container.find('input[name=daterangepicker_end]').val(this.rightCalendar.calendar[row][col].format(this.format)); - } - - }, - - clickDate: function (e) { - var title = $(e.target).attr('data-title'); - var row = title.substr(1, 1); - var col = title.substr(3, 1); - var cal = $(e.target).parents('.calendar'); - - if (cal.hasClass('left')) { - var startDate = this.leftCalendar.calendar[row][col]; - var endDate = this.endDate; - if (typeof this.dateLimit == 'object') { - var maxDate = moment(startDate).add(this.dateLimit).startOf('day'); - if (endDate.isAfter(maxDate)) { - endDate = maxDate; - } - } - } else { - var startDate = this.startDate; - var endDate = this.rightCalendar.calendar[row][col]; - if (typeof this.dateLimit == 'object') { - var minDate = moment(endDate).subtract(this.dateLimit).startOf('day'); - if (startDate.isBefore(minDate)) { - startDate = minDate; - } - } - } - - cal.find('td').removeClass('active'); - - if (startDate.isSame(endDate) || startDate.isBefore(endDate)) { - $(e.target).addClass('active'); - this.startDate = startDate; - this.endDate = endDate; - } else if (startDate.isAfter(endDate)) { - $(e.target).addClass('active'); - this.startDate = startDate; - this.endDate = moment(startDate).add('day', 1).startOf('day'); - } - - this.leftCalendar.month.month(this.startDate.month()).year(this.startDate.year()); - this.rightCalendar.month.month(this.endDate.month()).year(this.endDate.year()); - this.updateCalendars(); - }, - - clickApply: function (e) { - this.updateInputText(); - this.hide(); - }, - - clickCancel: function (e) { - this.startDate = this.oldStartDate; - this.endDate = this.oldEndDate; - this.updateView(); - this.updateCalendars(); - this.hide(); - }, - - updateMonthYear: function (e) { - - var isLeft = $(e.target).closest('.calendar').hasClass('left'); - var cal = this.container.find('.calendar.left'); - if (!isLeft) - cal = this.container.find('.calendar.right'); - - // Month must be Number for new moment versions - var month = parseInt(cal.find('.monthselect').val(), 10); - var year = cal.find('.yearselect').val(); - - if (isLeft) { - this.leftCalendar.month.month(month).year(year); - } else { - this.rightCalendar.month.month(month).year(year); - } - - this.updateCalendars(); - - }, - - updateTime: function(e) { - - var isLeft = $(e.target).closest('.calendar').hasClass('left'); - var cal = this.container.find('.calendar.left'); - if (!isLeft) - cal = this.container.find('.calendar.right'); - - var hour = parseInt(cal.find('.hourselect').val()); - var minute = parseInt(cal.find('.minuteselect').val()); - - if (this.timePicker12Hour) { - var ampm = cal.find('.ampmselect').val(); - if (ampm == 'PM' && hour < 12) - hour += 12; - if (ampm == 'AM' && hour == 12) - hour = 0; - } - - if (isLeft) { - var start = this.startDate.clone(); - start.hour(hour); - start.minute(minute); - this.startDate = start; - this.leftCalendar.month.hour(hour).minute(minute); - } else { - var end = this.endDate.clone(); - end.hour(hour); - end.minute(minute); - this.endDate = end; - this.rightCalendar.month.hour(hour).minute(minute); - } - - this.updateCalendars(); - - }, - - updateCalendars: function () { - this.leftCalendar.calendar = this.buildCalendar(this.leftCalendar.month.month(), this.leftCalendar.month.year(), this.leftCalendar.month.hour(), this.leftCalendar.month.minute(), 'left'); - this.rightCalendar.calendar = this.buildCalendar(this.rightCalendar.month.month(), this.rightCalendar.month.year(), this.rightCalendar.month.hour(), this.rightCalendar.month.minute(), 'right'); - this.container.find('.calendar.left').html(this.renderCalendar(this.leftCalendar.calendar, this.startDate, this.minDate, this.maxDate)); - this.container.find('.calendar.right').html(this.renderCalendar(this.rightCalendar.calendar, this.endDate, this.startDate, this.maxDate)); - - this.container.find('.ranges li').removeClass('active'); - var customRange = true; - var i = 0; - for (var range in this.ranges) { - if (this.timePicker) { - if (this.startDate.isSame(this.ranges[range][0]) && this.endDate.isSame(this.ranges[range][1])) { - customRange = false; - this.container.find('.ranges li:eq(' + i + ')').addClass('active'); - } - } else { - //ignore times when comparing dates if time picker is not enabled - if (this.startDate.format('YYYY-MM-DD') == this.ranges[range][0].format('YYYY-MM-DD') && this.endDate.format('YYYY-MM-DD') == this.ranges[range][1].format('YYYY-MM-DD')) { - customRange = false; - this.container.find('.ranges li:eq(' + i + ')').addClass('active'); - } - } - i++; - } - if (customRange) - this.container.find('.ranges li:last').addClass('active'); - }, - - buildCalendar: function (month, year, hour, minute, side) { - - var firstDay = moment([year, month, 1]); - var lastMonth = moment(firstDay).subtract('month', 1).month(); - var lastYear = moment(firstDay).subtract('month', 1).year(); - - var daysInLastMonth = moment([lastYear, lastMonth]).daysInMonth(); - - var dayOfWeek = firstDay.day(); - - //initialize a 6 rows x 7 columns array for the calendar - var calendar = []; - for (var i = 0; i < 6; i++) { - calendar[i] = []; - } - - //populate the calendar with date objects - var startDay = daysInLastMonth - dayOfWeek + this.locale.firstDay + 1; - if (startDay > daysInLastMonth) - startDay -= 7; - - if (dayOfWeek == this.locale.firstDay) - startDay = daysInLastMonth - 6; - - var curDate = moment([lastYear, lastMonth, startDay, 12, minute]); - for (var i = 0, col = 0, row = 0; i < 42; i++, col++, curDate = moment(curDate).add('hour', 24)) { - if (i > 0 && col % 7 == 0) { - col = 0; - row++; - } - calendar[row][col] = curDate.clone().hour(hour); - curDate.hour(12); - } - - return calendar; - - }, - - renderDropdowns: function (selected, minDate, maxDate) { - var currentMonth = selected.month(); - var monthHtml = '"; - - var currentYear = selected.year(); - var maxYear = (maxDate && maxDate.year()) || (currentYear + 5); - var minYear = (minDate && minDate.year()) || (currentYear - 50); - var yearHtml = ''; - - return monthHtml + yearHtml; - }, - - renderCalendar: function (calendar, selected, minDate, maxDate) { - - var html = '
    '; - html += ''; - html += ''; - html += ''; - - // add empty cell for week number - if (this.showWeekNumbers) - html += ''; - - if (!minDate || minDate.isBefore(calendar[1][1])) { - html += ''; - } else { - html += ''; - } - - var dateHtml = this.locale.monthNames[calendar[1][1].month()] + calendar[1][1].format(" YYYY"); - - if (this.showDropdowns) { - dateHtml = this.renderDropdowns(calendar[1][1], minDate, maxDate); - } - - html += ''; - if (!maxDate || maxDate.isAfter(calendar[1][1])) { - html += ''; - } else { - html += ''; - } - - html += ''; - html += ''; - - // add week number label - if (this.showWeekNumbers) - html += ''; - - $.each(this.locale.daysOfWeek, function (index, dayOfWeek) { - html += ''; - }); - - html += ''; - html += ''; - html += ''; - - for (var row = 0; row < 6; row++) { - html += ''; - - // add week number - if (this.showWeekNumbers) - html += ''; - - for (var col = 0; col < 7; col++) { - var cname = 'available '; - cname += (calendar[row][col].month() == calendar[1][1].month()) ? '' : 'off'; - - if ((minDate && calendar[row][col].isBefore(minDate)) || (maxDate && calendar[row][col].isAfter(maxDate))) { - cname = ' off disabled '; - } else if (calendar[row][col].format('YYYY-MM-DD') == selected.format('YYYY-MM-DD')) { - cname += ' active '; - if (calendar[row][col].format('YYYY-MM-DD') == this.startDate.format('YYYY-MM-DD')) { - cname += ' start-date '; - } - if (calendar[row][col].format('YYYY-MM-DD') == this.endDate.format('YYYY-MM-DD')) { - cname += ' end-date '; - } - } else if (calendar[row][col] >= this.startDate && calendar[row][col] <= this.endDate) { - cname += ' in-range '; - if (calendar[row][col].isSame(this.startDate)) { cname += ' start-date '; } - if (calendar[row][col].isSame(this.endDate)) { cname += ' end-date '; } - } - - var title = 'r' + row + 'c' + col; - html += ''; - } - html += ''; - } - - html += ''; - html += '
    ' + dateHtml + '
    ' + this.locale.weekLabel + '' + dayOfWeek + '
    ' + calendar[row][0].week() + '' + calendar[row][col].date() + '
    '; - html += '
    '; - - if (this.timePicker) { - - html += '
    '; - html += ' : '; - - html += ' '; - - if (this.timePicker12Hour) { - html += ''; - } - - html += '
    '; - - } - - return html; - - } - - }; - - $.fn.daterangepicker = function (options, cb) { - this.each(function () { - var el = $(this); - if (!el.data('daterangepicker')) - el.data('daterangepicker', new DateRangePicker(el, options, cb)); - }); - return this; - }; - -}(window.jQuery); diff --git a/public/assets/js/plugins/misc/html5shiv.js b/public/assets/js/plugins/misc/html5shiv.js deleted file mode 100755 index 448cebd7..00000000 --- a/public/assets/js/plugins/misc/html5shiv.js +++ /dev/null @@ -1,8 +0,0 @@ -/* - HTML5 Shiv v3.7.0 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed -*/ -(function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag(); -a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/[\w\-]+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x"; -c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode|| -"undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:"3.7.0",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f); -if(g)return a.createDocumentFragment();for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;d').attr($.extend(args(this), { 'type': 'text' })); - } - $replacement - .removeAttr('name') - .data({ - 'placeholder-password': $input, - 'placeholder-id': id - }) - .bind('focus.placeholder', clearPlaceholder); - $input - .data({ - 'placeholder-textinput': $replacement, - 'placeholder-id': id - }) - .before($replacement); - } - $input = $input.removeAttr('id').hide().prev().attr('id', id).show(); - // Note: `$input[0] != input` now! - } - $input.addClass('placeholder'); - $input[0].value = $input.attr('placeholder'); - } else { - $input.removeClass('placeholder'); - } - } - - function safeActiveElement() { - // Avoid IE9 `document.activeElement` of death - // https://github.com/mathiasbynens/jquery-placeholder/pull/99 - try { - return document.activeElement; - } catch (err) {} - } - -}(this, document, jQuery)); - -$(function(){ - $("[placeholder]").placeholder(); -}); diff --git a/public/assets/js/plugins/misc/modernizr.min.js b/public/assets/js/plugins/misc/modernizr.min.js deleted file mode 100755 index 4a76012e..00000000 --- a/public/assets/js/plugins/misc/modernizr.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/* Modernizr 2.7.1 (Custom Build) | MIT & BSD - * Build: http://modernizr.com/download/#-fontface-backgroundsize-borderimage-borderradius-boxshadow-flexbox-flexboxlegacy-hsla-multiplebgs-opacity-rgba-textshadow-cssanimations-csscolumns-generatedcontent-cssgradients-cssreflections-csstransforms-csstransforms3d-csstransitions-applicationcache-canvas-canvastext-draganddrop-hashchange-history-audio-video-indexeddb-input-inputtypes-localstorage-postmessage-sessionstorage-websockets-websqldatabase-webworkers-geolocation-inlinesvg-smil-svg-svgclippaths-touch-webgl-printshiv-mq-cssclasses-teststyles-testprop-testallprops-hasevent-prefixes-domprefixes-load-cssclassprefix:modernizr - */ -;window.Modernizr=function(a,b,c){function D(a){j.cssText=a}function E(a,b){return D(n.join(a+";")+(b||""))}function F(a,b){return typeof a===b}function G(a,b){return!!~(""+a).indexOf(b)}function H(a,b){for(var d in a){var e=a[d];if(!G(e,"-")&&j[e]!==c)return b=="pfx"?e:!0}return!1}function I(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:F(f,"function")?f.bind(d||b):f}return!1}function J(a,b,c){var d=a.charAt(0).toUpperCase()+a.slice(1),e=(a+" "+p.join(d+" ")+d).split(" ");return F(b,"string")||F(b,"undefined")?H(e,b):(e=(a+" "+q.join(d+" ")+d).split(" "),I(e,b,c))}function K(){e.input=function(c){for(var d=0,e=c.length;d',a,""].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},z=function(b){var c=a.matchMedia||a.msMatchMedia;if(c)return c(b).matches;var d;return y("@media "+b+" { #"+h+" { position: absolute; } }",function(b){d=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle)["position"]=="absolute"}),d},A=function(){function d(d,e){e=e||b.createElement(a[d]||"div"),d="on"+d;var f=d in e;return f||(e.setAttribute||(e=b.createElement("div")),e.setAttribute&&e.removeAttribute&&(e.setAttribute(d,""),f=F(e[d],"function"),F(e[d],"undefined")||(e[d]=c),e.removeAttribute(d))),e=null,f}var a={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return d}(),B={}.hasOwnProperty,C;!F(B,"undefined")&&!F(B.call,"undefined")?C=function(a,b){return B.call(a,b)}:C=function(a,b){return b in a&&F(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=w.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(w.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(w.call(arguments)))};return e}),s.flexbox=function(){return J("flexWrap")},s.flexboxlegacy=function(){return J("boxDirection")},s.canvas=function(){var a=b.createElement("canvas");return!!a.getContext&&!!a.getContext("2d")},s.canvastext=function(){return!!e.canvas&&!!F(b.createElement("canvas").getContext("2d").fillText,"function")},s.webgl=function(){return!!a.WebGLRenderingContext},s.touch=function(){var c;return"ontouchstart"in a||a.DocumentTouch&&b instanceof DocumentTouch?c=!0:y(["@media (",n.join("touch-enabled),("),h,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(a){c=a.offsetTop===9}),c},s.geolocation=function(){return"geolocation"in navigator},s.postmessage=function(){return!!a.postMessage},s.websqldatabase=function(){return!!a.openDatabase},s.indexedDB=function(){return!!J("indexedDB",a)},s.hashchange=function(){return A("hashchange",a)&&(b.documentMode===c||b.documentMode>7)},s.history=function(){return!!a.history&&!!history.pushState},s.draganddrop=function(){var a=b.createElement("div");return"draggable"in a||"ondragstart"in a&&"ondrop"in a},s.websockets=function(){return"WebSocket"in a||"MozWebSocket"in a},s.rgba=function(){return D("background-color:rgba(150,255,150,.5)"),G(j.backgroundColor,"rgba")},s.hsla=function(){return D("background-color:hsla(120,40%,100%,.5)"),G(j.backgroundColor,"rgba")||G(j.backgroundColor,"hsla")},s.multiplebgs=function(){return D("background:url(https://),url(https://),red url(https://)"),/(url\s*\(.*?){3}/.test(j.background)},s.backgroundsize=function(){return J("backgroundSize")},s.borderimage=function(){return J("borderImage")},s.borderradius=function(){return J("borderRadius")},s.boxshadow=function(){return J("boxShadow")},s.textshadow=function(){return b.createElement("div").style.textShadow===""},s.opacity=function(){return E("opacity:.55"),/^0.55$/.test(j.opacity)},s.cssanimations=function(){return J("animationName")},s.csscolumns=function(){return J("columnCount")},s.cssgradients=function(){var a="background-image:",b="gradient(linear,left top,right bottom,from(#9f9),to(white));",c="linear-gradient(left top,#9f9, white);";return D((a+"-webkit- ".split(" ").join(b+a)+n.join(c+a)).slice(0,-a.length)),G(j.backgroundImage,"gradient")},s.cssreflections=function(){return J("boxReflect")},s.csstransforms=function(){return!!J("transform")},s.csstransforms3d=function(){var a=!!J("perspective");return a&&"webkitPerspective"in g.style&&y("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(b,c){a=b.offsetLeft===9&&b.offsetHeight===3}),a},s.csstransitions=function(){return J("transition")},s.fontface=function(){var a;return y('@font-face {font-family:"font";src:url("https://")}',function(c,d){var e=b.getElementById("smodernizr"),f=e.sheet||e.styleSheet,g=f?f.cssRules&&f.cssRules[0]?f.cssRules[0].cssText:f.cssText||"":"";a=/src/i.test(g)&&g.indexOf(d.split(" ")[0])===0}),a},s.generatedcontent=function(){var a;return y(["#",h,"{font:0/0 a}#",h,':after{content:"',l,'";visibility:hidden;font:3px/1 a}'].join(""),function(b){a=b.offsetHeight>=3}),a},s.video=function(){var a=b.createElement("video"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),c.h264=a.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),c.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,"")}catch(d){}return c},s.audio=function(){var a=b.createElement("audio"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),c.mp3=a.canPlayType("audio/mpeg;").replace(/^no$/,""),c.wav=a.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),c.m4a=(a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;")).replace(/^no$/,"")}catch(d){}return c},s.localstorage=function(){try{return localStorage.setItem(h,h),localStorage.removeItem(h),!0}catch(a){return!1}},s.sessionstorage=function(){try{return sessionStorage.setItem(h,h),sessionStorage.removeItem(h),!0}catch(a){return!1}},s.webworkers=function(){return!!a.Worker},s.applicationcache=function(){return!!a.applicationCache},s.svg=function(){return!!b.createElementNS&&!!b.createElementNS(r.svg,"svg").createSVGRect},s.inlinesvg=function(){var a=b.createElement("div");return a.innerHTML="",(a.firstChild&&a.firstChild.namespaceURI)==r.svg},s.smil=function(){return!!b.createElementNS&&/SVGAnimate/.test(m.call(b.createElementNS(r.svg,"animate")))},s.svgclippaths=function(){return!!b.createElementNS&&/SVGClipPath/.test(m.call(b.createElementNS(r.svg,"clipPath")))};for(var L in s)C(s,L)&&(x=L.toLowerCase(),e[x]=s[L](),v.push((e[x]?"":"no-")+x));return e.input||K(),e.addTest=function(a,b){if(typeof a=="object")for(var d in a)C(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" modernizr"+(b?"":"no-")+a),e[a]=b}return e},D(""),i=k=null,e._version=d,e._prefixes=n,e._domPrefixes=q,e._cssomPrefixes=p,e.mq=z,e.hasEvent=A,e.testProp=function(a){return H([a])},e.testAllProps=J,e.testStyles=y,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" modernizrjs modernizr"+v.join(" modernizr"):""),e}(this,this.document),function(a,b){function l(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function m(){var a=s.elements;return typeof a=="string"?a.split(" "):a}function n(a){var b=j[a[h]];return b||(b={},i++,a[h]=i,j[i]=b),b}function o(a,c,d){c||(c=b);if(k)return c.createElement(a);d||(d=n(c));var g;return d.cache[a]?g=d.cache[a].cloneNode():f.test(a)?g=(d.cache[a]=d.createElem(a)).cloneNode():g=d.createElem(a),g.canHaveChildren&&!e.test(a)&&!g.tagUrn?d.frag.appendChild(g):g}function p(a,c){a||(a=b);if(k)return a.createDocumentFragment();c=c||n(a);var d=c.frag.cloneNode(),e=0,f=m(),g=f.length;for(;e+~])("+m().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),f="$1"+u+"\\:$2";while(d--)b=c[d]=c[d].split("}"),b[b.length-1]=b[b.length-1].replace(e,f),c[d]=b.join("}");return c.join("{")}function z(a){var b=a.length;while(b--)a[b].removeNode()}function A(a){function g(){clearTimeout(d._removeSheetTimer),b&&b.removeNode(!0),b=null}var b,c,d=n(a),e=a.namespaces,f=a.parentWindow;return!v||a.printShived?a:(typeof e[u]=="undefined"&&e.add(u),f.attachEvent("onbeforeprint",function(){g();var d,e,f,h=a.styleSheets,i=[],j=h.length,k=Array(j);while(j--)k[j]=h[j];while(f=k.pop())if(!f.disabled&&t.test(f.media)){try{d=f.imports,e=d.length}catch(m){e=0}for(j=0;j",g="hidden"in a,k=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){g=!0,k=!0}})();var s={elements:d.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:c,shivCSS:d.shivCSS!==!1,supportsUnknownElements:k,shivMethods:d.shivMethods!==!1,type:"default",shivDocument:r,createElement:o,createDocumentFragment:p};a.html5=s,r(b);var t=/^$|\b(?:all|print)\b/,u="html5shiv",v=!k&&function(){var c=b.documentElement;return typeof b.namespaces!="undefined"&&typeof b.parentWindow!="undefined"&&typeof c.applyElement!="undefined"&&typeof c.removeNode!="undefined"&&typeof a.attachEvent!="undefined"}();s.type+=" print",s.shivPrint=A,A(b)}(this,document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f #mq-test-1 { width: 42px; }',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){u(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))};if(c.ajax=f,c.queue=d,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/,maxw:/\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var g,h,i,j=a.document,k=j.documentElement,l=[],m=[],n=[],o={},p=30,q=j.getElementsByTagName("head")[0]||k,r=j.getElementsByTagName("base")[0],s=q.getElementsByTagName("link"),t=function(){var a,b=j.createElement("div"),c=j.body,d=k.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=j.createElement("body"),c.style.background="none"),k.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&k.insertBefore(c,k.firstChild),a=b.offsetWidth,f?k.removeChild(c):c.removeChild(b),k.style.fontSize=d,e&&(c.style.fontSize=e),a=i=parseFloat(a)},u=function(b){var c="clientWidth",d=k[c],e="CSS1Compat"===j.compatMode&&d||j.body[c]||d,f={},o=s[s.length-1],r=(new Date).getTime();if(b&&g&&p>r-g)return a.clearTimeout(h),h=a.setTimeout(u,p),void 0;g=r;for(var v in l)if(l.hasOwnProperty(v)){var w=l[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?i||t():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?i||t():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(m[w.rules]))}for(var C in n)n.hasOwnProperty(C)&&n[C]&&n[C].parentNode===q&&q.removeChild(n[C]);n.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=j.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,q.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(j.createTextNode(F)),n.push(E)}},v=function(a,b,d){var e=a.replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var g=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},h=!f&&d;b.length&&(b+="/"),h&&(f=1);for(var i=0;f>i;i++){var j,k,n,o;h?(j=d,m.push(g(a))):(j=e[i].match(c.regex.findStyles)&&RegExp.$1,m.push(RegExp.$2&&g(RegExp.$2))),n=j.split(","),o=n.length;for(var p=0;o>p;p++)k=n[p],l.push({media:k.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:m.length-1,hasquery:k.indexOf("(")>-1,minw:k.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:k.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},w=function(){if(d.length){var b=d.shift();f(b.href,function(c){v(c,b.href,b.media),o[b.href]=!0,a.setTimeout(function(){w()},0)})}},x=function(){for(var b=0;bb;b++)if(b in this&&this[b]===a)return b;return-1};b=window.Morris={},a=jQuery,b.EventEmitter=function(){function a(){}return a.prototype.on=function(a,b){return null==this.handlers&&(this.handlers={}),null==this.handlers[a]&&(this.handlers[a]=[]),this.handlers[a].push(b),this},a.prototype.fire=function(){var a,b,c,d,f,g,h;if(c=arguments[0],a=2<=arguments.length?e.call(arguments,1):[],null!=this.handlers&&null!=this.handlers[c]){for(g=this.handlers[c],h=[],d=0,f=g.length;f>d;d++)b=g[d],h.push(b.apply(null,a));return h}},a}(),b.commas=function(a){var b,c,d,e;return null!=a?(d=0>a?"-":"",b=Math.abs(a),c=Math.floor(b).toFixed(0),d+=c.replace(/(?=(?:\d{3})+$)(?!^)/g,","),e=b.toString(),e.length>c.length&&(d+=e.slice(c.length)),d):"-"},b.pad2=function(a){return(10>a?"0":"")+a},b.Grid=function(c){function d(b){this.resizeHandler=f(this.resizeHandler,this);var c=this;if(this.el="string"==typeof b.element?a(document.getElementById(b.element)):a(b.element),null==this.el||0===this.el.length)throw new Error("Graph container element not found");"static"===this.el.css("position")&&this.el.css("position","relative"),this.options=a.extend({},this.gridDefaults,this.defaults||{},b),"string"==typeof this.options.units&&(this.options.postUnits=b.units),this.raphael=new Raphael(this.el[0]),this.elementWidth=null,this.elementHeight=null,this.dirty=!1,this.selectFrom=null,this.init&&this.init(),this.setData(this.options.data),this.el.bind("mousemove",function(a){var b,d,e,f,g;return d=c.el.offset(),g=a.pageX-d.left,c.selectFrom?(b=c.data[c.hitTest(Math.min(g,c.selectFrom))]._x,e=c.data[c.hitTest(Math.max(g,c.selectFrom))]._x,f=e-b,c.selectionRect.attr({x:b,width:f})):c.fire("hovermove",g,a.pageY-d.top)}),this.el.bind("mouseleave",function(){return c.selectFrom&&(c.selectionRect.hide(),c.selectFrom=null),c.fire("hoverout")}),this.el.bind("touchstart touchmove touchend",function(a){var b,d;return d=a.originalEvent.touches[0]||a.originalEvent.changedTouches[0],b=c.el.offset(),c.fire("hover",d.pageX-b.left,d.pageY-b.top),d}),this.el.bind("click",function(a){var b;return b=c.el.offset(),c.fire("gridclick",a.pageX-b.left,a.pageY-b.top)}),this.options.rangeSelect&&(this.selectionRect=this.raphael.rect(0,0,0,this.el.innerHeight()).attr({fill:this.options.rangeSelectColor,stroke:!1}).toBack().hide(),this.el.bind("mousedown",function(a){var b;return b=c.el.offset(),c.startRange(a.pageX-b.left)}),this.el.bind("mouseup",function(a){var b;return b=c.el.offset(),c.endRange(a.pageX-b.left),c.fire("hovermove",a.pageX-b.left,a.pageY-b.top)})),this.options.resize&&a(window).bind("resize",function(){return null!=c.timeoutId&&window.clearTimeout(c.timeoutId),c.timeoutId=window.setTimeout(c.resizeHandler,100)}),this.postInit&&this.postInit()}return h(d,c),d.prototype.gridDefaults={dateFormat:null,axes:!0,grid:!0,gridLineColor:"#aaa",gridStrokeWidth:.5,gridTextColor:"#888",gridTextSize:12,gridTextFamily:"sans-serif",gridTextWeight:"normal",hideHover:!1,yLabelFormat:null,xLabelAngle:0,numLines:5,padding:25,parseTime:!0,postUnits:"",preUnits:"",ymax:"auto",ymin:"auto 0",goals:[],goalStrokeWidth:1,goalLineColors:["#666633","#999966","#cc6666","#663333"],events:[],eventStrokeWidth:1,eventLineColors:["#005a04","#ccffbb","#3a5f0b","#005502"],rangeSelect:null,rangeSelectColor:"#eef",resize:!1},d.prototype.setData=function(a,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;return null==c&&(c=!0),this.options.data=a,null==a||0===a.length?(this.data=[],this.raphael.clear(),null!=this.hover&&this.hover.hide(),void 0):(o=this.cumulative?0:null,p=this.cumulative?0:null,this.options.goals.length>0&&(h=Math.min.apply(Math,this.options.goals),g=Math.max.apply(Math,this.options.goals),p=null!=p?Math.min(p,h):h,o=null!=o?Math.max(o,g):g),this.data=function(){var c,d,g;for(g=[],f=c=0,d=a.length;d>c;f=++c)j=a[f],i={src:j},i.label=j[this.options.xkey],this.options.parseTime?(i.x=b.parseDate(i.label),this.options.dateFormat?i.label=this.options.dateFormat(i.x):"number"==typeof i.label&&(i.label=new Date(i.label).toString())):(i.x=f,this.options.xLabelFormat&&(i.label=this.options.xLabelFormat(i))),l=0,i.y=function(){var a,b,c,d;for(c=this.options.ykeys,d=[],e=a=0,b=c.length;b>a;e=++a)n=c[e],q=j[n],"string"==typeof q&&(q=parseFloat(q)),null!=q&&"number"!=typeof q&&(q=null),null!=q&&(this.cumulative?l+=q:null!=o?(o=Math.max(q,o),p=Math.min(q,p)):o=p=q),this.cumulative&&null!=l&&(o=Math.max(l,o),p=Math.min(l,p)),d.push(q);return d}.call(this),g.push(i);return g}.call(this),this.options.parseTime&&(this.data=this.data.sort(function(a,b){return(a.x>b.x)-(b.x>a.x)})),this.xmin=this.data[0].x,this.xmax=this.data[this.data.length-1].x,this.events=[],this.options.events.length>0&&(this.events=this.options.parseTime?function(){var a,c,e,f;for(e=this.options.events,f=[],a=0,c=e.length;c>a;a++)d=e[a],f.push(b.parseDate(d));return f}.call(this):this.options.events,this.xmax=Math.max(this.xmax,Math.max.apply(Math,this.events)),this.xmin=Math.min(this.xmin,Math.min.apply(Math,this.events))),this.xmin===this.xmax&&(this.xmin-=1,this.xmax+=1),this.ymin=this.yboundary("min",p),this.ymax=this.yboundary("max",o),this.ymin===this.ymax&&(p&&(this.ymin-=1),this.ymax+=1),((r=this.options.axes)===!0||"both"===r||"y"===r||this.options.grid===!0)&&(this.options.ymax===this.gridDefaults.ymax&&this.options.ymin===this.gridDefaults.ymin?(this.grid=this.autoGridLines(this.ymin,this.ymax,this.options.numLines),this.ymin=Math.min(this.ymin,this.grid[0]),this.ymax=Math.max(this.ymax,this.grid[this.grid.length-1])):(k=(this.ymax-this.ymin)/(this.options.numLines-1),this.grid=function(){var a,b,c,d;for(d=[],m=a=b=this.ymin,c=this.ymax;k>0?c>=a:a>=c;m=a+=k)d.push(m);return d}.call(this))),this.dirty=!0,c?this.redraw():void 0)},d.prototype.yboundary=function(a,b){var c,d;return c=this.options["y"+a],"string"==typeof c?"auto"===c.slice(0,4)?c.length>5?(d=parseInt(c.slice(5),10),null==b?d:Math[a](b,d)):null!=b?b:0:parseInt(c,10):c},d.prototype.autoGridLines=function(a,b,c){var d,e,f,g,h,i,j,k,l;return h=b-a,l=Math.floor(Math.log(h)/Math.log(10)),j=Math.pow(10,l),e=Math.floor(a/j)*j,d=Math.ceil(b/j)*j,i=(d-e)/(c-1),1===j&&i>1&&Math.ceil(i)!==i&&(i=Math.ceil(i),d=e+i*(c-1)),0>e&&d>0&&(e=Math.floor(a/i)*i,d=Math.ceil(b/i)*i),1>i?(g=Math.floor(Math.log(i)/Math.log(10)),f=function(){var a,b;for(b=[],k=a=e;i>0?d>=a:a>=d;k=a+=i)b.push(parseFloat(k.toFixed(1-g)));return b}()):f=function(){var a,b;for(b=[],k=a=e;i>0?d>=a:a>=d;k=a+=i)b.push(k);return b}(),f},d.prototype._calc=function(){var a,b,c,d,e,f,g,h;return e=this.el.width(),c=this.el.height(),(this.elementWidth!==e||this.elementHeight!==c||this.dirty)&&(this.elementWidth=e,this.elementHeight=c,this.dirty=!1,this.left=this.options.padding,this.right=this.elementWidth-this.options.padding,this.top=this.options.padding,this.bottom=this.elementHeight-this.options.padding,((g=this.options.axes)===!0||"both"===g||"y"===g)&&(f=function(){var a,c,d,e;for(d=this.grid,e=[],a=0,c=d.length;c>a;a++)b=d[a],e.push(this.measureText(this.yAxisFormat(b)).width);return e}.call(this),this.left+=Math.max.apply(Math,f)),((h=this.options.axes)===!0||"both"===h||"x"===h)&&(a=function(){var a,b,c;for(c=[],d=a=0,b=this.data.length;b>=0?b>a:a>b;d=b>=0?++a:--a)c.push(this.measureText(this.data[d].text,-this.options.xLabelAngle).height);return c}.call(this),this.bottom-=Math.max.apply(Math,a)),this.width=Math.max(1,this.right-this.left),this.height=Math.max(1,this.bottom-this.top),this.dx=this.width/(this.xmax-this.xmin),this.dy=this.height/(this.ymax-this.ymin),this.calc)?this.calc():void 0},d.prototype.transY=function(a){return this.bottom-(a-this.ymin)*this.dy},d.prototype.transX=function(a){return 1===this.data.length?(this.left+this.right)/2:this.left+(a-this.xmin)*this.dx},d.prototype.redraw=function(){return this.raphael.clear(),this._calc(),this.drawGrid(),this.drawGoals(),this.drawEvents(),this.draw?this.draw():void 0},d.prototype.measureText=function(a,b){var c,d;return null==b&&(b=0),d=this.raphael.text(100,100,a).attr("font-size",this.options.gridTextSize).attr("font-family",this.options.gridTextFamily).attr("font-weight",this.options.gridTextWeight).rotate(b),c=d.getBBox(),d.remove(),c},d.prototype.yAxisFormat=function(a){return this.yLabelFormat(a)},d.prototype.yLabelFormat=function(a){return"function"==typeof this.options.yLabelFormat?this.options.yLabelFormat(a):""+this.options.preUnits+b.commas(a)+this.options.postUnits},d.prototype.drawGrid=function(){var a,b,c,d,e,f,g,h;if(this.options.grid!==!1||(e=this.options.axes)===!0||"both"===e||"y"===e){for(f=this.grid,h=[],c=0,d=f.length;d>c;c++)a=f[c],b=this.transY(a),((g=this.options.axes)===!0||"both"===g||"y"===g)&&this.drawYAxisLabel(this.left-this.options.padding/2,b,this.yAxisFormat(a)),this.options.grid?h.push(this.drawGridLine("M"+this.left+","+b+"H"+(this.left+this.width))):h.push(void 0);return h}},d.prototype.drawGoals=function(){var a,b,c,d,e,f,g;for(f=this.options.goals,g=[],c=d=0,e=f.length;e>d;c=++d)b=f[c],a=this.options.goalLineColors[c%this.options.goalLineColors.length],g.push(this.drawGoal(b,a));return g},d.prototype.drawEvents=function(){var a,b,c,d,e,f,g;for(f=this.events,g=[],c=d=0,e=f.length;e>d;c=++d)b=f[c],a=this.options.eventLineColors[c%this.options.eventLineColors.length],g.push(this.drawEvent(b,a));return g},d.prototype.drawGoal=function(a,b){return this.raphael.path("M"+this.left+","+this.transY(a)+"H"+this.right).attr("stroke",b).attr("stroke-width",this.options.goalStrokeWidth)},d.prototype.drawEvent=function(a,b){return this.raphael.path("M"+this.transX(a)+","+this.bottom+"V"+this.top).attr("stroke",b).attr("stroke-width",this.options.eventStrokeWidth)},d.prototype.drawYAxisLabel=function(a,b,c){return this.raphael.text(a,b,c).attr("font-size",this.options.gridTextSize).attr("font-family",this.options.gridTextFamily).attr("font-weight",this.options.gridTextWeight).attr("fill",this.options.gridTextColor).attr("text-anchor","end")},d.prototype.drawGridLine=function(a){return this.raphael.path(a).attr("stroke",this.options.gridLineColor).attr("stroke-width",this.options.gridStrokeWidth)},d.prototype.startRange=function(a){return this.hover.hide(),this.selectFrom=a,this.selectionRect.attr({x:a,width:0}).show()},d.prototype.endRange=function(a){var b,c;return this.selectFrom?(c=Math.min(this.selectFrom,a),b=Math.max(this.selectFrom,a),this.options.rangeSelect.call(this.el,{start:this.data[this.hitTest(c)].x,end:this.data[this.hitTest(b)].x}),this.selectFrom=null):void 0},d.prototype.resizeHandler=function(){return this.timeoutId=null,this.raphael.setSize(this.el.width(),this.el.height()),this.redraw()},d}(b.EventEmitter),b.parseDate=function(a){var b,c,d,e,f,g,h,i,j,k,l;return"number"==typeof a?a:(c=a.match(/^(\d+) Q(\d)$/),e=a.match(/^(\d+)-(\d+)$/),f=a.match(/^(\d+)-(\d+)-(\d+)$/),h=a.match(/^(\d+) W(\d+)$/),i=a.match(/^(\d+)-(\d+)-(\d+)[ T](\d+):(\d+)(Z|([+-])(\d\d):?(\d\d))?$/),j=a.match(/^(\d+)-(\d+)-(\d+)[ T](\d+):(\d+):(\d+(\.\d+)?)(Z|([+-])(\d\d):?(\d\d))?$/),c?new Date(parseInt(c[1],10),3*parseInt(c[2],10)-1,1).getTime():e?new Date(parseInt(e[1],10),parseInt(e[2],10)-1,1).getTime():f?new Date(parseInt(f[1],10),parseInt(f[2],10)-1,parseInt(f[3],10)).getTime():h?(k=new Date(parseInt(h[1],10),0,1),4!==k.getDay()&&k.setMonth(0,1+(4-k.getDay()+7)%7),k.getTime()+6048e5*parseInt(h[2],10)):i?i[6]?(g=0,"Z"!==i[6]&&(g=60*parseInt(i[8],10)+parseInt(i[9],10),"+"===i[7]&&(g=0-g)),Date.UTC(parseInt(i[1],10),parseInt(i[2],10)-1,parseInt(i[3],10),parseInt(i[4],10),parseInt(i[5],10)+g)):new Date(parseInt(i[1],10),parseInt(i[2],10)-1,parseInt(i[3],10),parseInt(i[4],10),parseInt(i[5],10)).getTime():j?(l=parseFloat(j[6]),b=Math.floor(l),d=Math.round(1e3*(l-b)),j[8]?(g=0,"Z"!==j[8]&&(g=60*parseInt(j[10],10)+parseInt(j[11],10),"+"===j[9]&&(g=0-g)),Date.UTC(parseInt(j[1],10),parseInt(j[2],10)-1,parseInt(j[3],10),parseInt(j[4],10),parseInt(j[5],10)+g,b,d)):new Date(parseInt(j[1],10),parseInt(j[2],10)-1,parseInt(j[3],10),parseInt(j[4],10),parseInt(j[5],10),b,d).getTime()):new Date(parseInt(a,10),0,1).getTime())},b.Hover=function(){function c(c){null==c&&(c={}),this.options=a.extend({},b.Hover.defaults,c),this.el=a("
    "),this.el.hide(),this.options.parent.append(this.el)}return c.defaults={"class":"morris-hover morris-default-style"},c.prototype.update=function(a,b,c){return this.html(a),this.show(),this.moveTo(b,c)},c.prototype.html=function(a){return this.el.html(a)},c.prototype.moveTo=function(a,b){var c,d,e,f,g,h;return g=this.options.parent.innerWidth(),f=this.options.parent.innerHeight(),d=this.el.outerWidth(),c=this.el.outerHeight(),e=Math.min(Math.max(0,a-d/2),g-d),null!=b?(h=b-c-10,0>h&&(h=b+10,h+c>f&&(h=f/2-c/2))):h=f/2-c/2,this.el.css({left:e+"px",top:parseInt(h)+"px"})},c.prototype.show=function(){return this.el.show()},c.prototype.hide=function(){return this.el.hide()},c}(),b.Line=function(a){function c(a){return this.hilight=f(this.hilight,this),this.onHoverOut=f(this.onHoverOut,this),this.onHoverMove=f(this.onHoverMove,this),this.onGridClick=f(this.onGridClick,this),this instanceof b.Line?(c.__super__.constructor.call(this,a),void 0):new b.Line(a)}return h(c,a),c.prototype.init=function(){return"always"!==this.options.hideHover?(this.hover=new b.Hover({parent:this.el}),this.on("hovermove",this.onHoverMove),this.on("hoverout",this.onHoverOut),this.on("gridclick",this.onGridClick)):void 0},c.prototype.defaults={lineWidth:3,pointSize:4,lineColors:["#0b62a4","#7A92A3","#4da74d","#afd8f8","#edc240","#cb4b4b","#9440ed"],pointStrokeWidths:[1],pointStrokeColors:["#ffffff"],pointFillColors:[],smooth:!0,xLabels:"auto",xLabelFormat:null,xLabelMargin:24,continuousLine:!0,hideHover:!1},c.prototype.calc=function(){return this.calcPoints(),this.generatePaths()},c.prototype.calcPoints=function(){var a,b,c,d,e,f;for(e=this.data,f=[],c=0,d=e.length;d>c;c++)a=e[c],a._x=this.transX(a.x),a._y=function(){var c,d,e,f;for(e=a.y,f=[],c=0,d=e.length;d>c;c++)b=e[c],null!=b?f.push(this.transY(b)):f.push(b);return f}.call(this),f.push(a._ymax=Math.min.apply(Math,[this.bottom].concat(function(){var c,d,e,f;for(e=a._y,f=[],c=0,d=e.length;d>c;c++)b=e[c],null!=b&&f.push(b);return f}())));return f},c.prototype.hitTest=function(a){var b,c,d,e,f;if(0===this.data.length)return null;for(f=this.data.slice(1),b=d=0,e=f.length;e>d&&(c=f[b],!(a<(c._x+this.data[b]._x)/2));b=++d);return b},c.prototype.onGridClick=function(a,b){var c;return c=this.hitTest(a),this.fire("click",c,this.data[c].src,a,b)},c.prototype.onHoverMove=function(a){var b;return b=this.hitTest(a),this.displayHoverForRow(b)},c.prototype.onHoverOut=function(){return this.options.hideHover!==!1?this.displayHoverForRow(null):void 0},c.prototype.displayHoverForRow=function(a){var b;return null!=a?((b=this.hover).update.apply(b,this.hoverContentForRow(a)),this.hilight(a)):(this.hover.hide(),this.hilight())},c.prototype.hoverContentForRow=function(a){var b,c,d,e,f,g,h;for(d=this.data[a],b="
    "+d.label+"
    ",h=d.y,c=f=0,g=h.length;g>f;c=++f)e=h[c],b+="
    \n "+this.options.labels[c]+":\n "+this.yLabelFormat(e)+"\n
    ";return"function"==typeof this.options.hoverCallback&&(b=this.options.hoverCallback(a,this.options,b,d.src)),[b,d._x,d._ymax]},c.prototype.generatePaths=function(){var a,c,d,e,f;return this.paths=function(){var g,h,j,k;for(k=[],d=g=0,h=this.options.ykeys.length;h>=0?h>g:g>h;d=h>=0?++g:--g)f="boolean"==typeof this.options.smooth?this.options.smooth:(j=this.options.ykeys[d],i.call(this.options.smooth,j)>=0),c=function(){var a,b,c,f;for(c=this.data,f=[],a=0,b=c.length;b>a;a++)e=c[a],void 0!==e._y[d]&&f.push({x:e._x,y:e._y[d]});return f}.call(this),this.options.continuousLine&&(c=function(){var b,d,e;for(e=[],b=0,d=c.length;d>b;b++)a=c[b],null!==a.y&&e.push(a);return e}()),c.length>1?k.push(b.Line.createPath(c,f,this.bottom)):k.push(null);return k}.call(this)},c.prototype.draw=function(){var a;return((a=this.options.axes)===!0||"both"===a||"x"===a)&&this.drawXAxis(),this.drawSeries(),this.options.hideHover===!1?this.displayHoverForRow(this.data.length-1):void 0},c.prototype.drawXAxis=function(){var a,c,d,e,f,g,h,i,j,k,l=this;for(h=this.bottom+this.options.padding/2,f=null,e=null,a=function(a,b){var c,d,g,i,j;return c=l.drawXAxisLabel(l.transX(b),h,a),j=c.getBBox(),c.transform("r"+-l.options.xLabelAngle),d=c.getBBox(),c.transform("t0,"+d.height/2+"..."),0!==l.options.xLabelAngle&&(i=-.5*j.width*Math.cos(l.options.xLabelAngle*Math.PI/180),c.transform("t"+i+",0...")),d=c.getBBox(),(null==f||f>=d.x+d.width||null!=e&&e>=d.x)&&d.x>=0&&d.x+d.widtha;a++)g=c[a],d.push([g.label,g.x]);return d}.call(this),d.reverse(),k=[],i=0,j=d.length;j>i;i++)c=d[i],k.push(a(c[0],c[1]));return k},c.prototype.drawSeries=function(){var a,b,c,d,e,f;for(this.seriesPoints=[],a=b=d=this.options.ykeys.length-1;0>=d?0>=b:b>=0;a=0>=d?++b:--b)this._drawLineFor(a);for(f=[],a=c=e=this.options.ykeys.length-1;0>=e?0>=c:c>=0;a=0>=e?++c:--c)f.push(this._drawPointFor(a));return f},c.prototype._drawPointFor=function(a){var b,c,d,e,f,g;for(this.seriesPoints[a]=[],f=this.data,g=[],d=0,e=f.length;e>d;d++)c=f[d],b=null,null!=c._y[a]&&(b=this.drawLinePoint(c._x,c._y[a],this.colorFor(c,a,"point"),a)),g.push(this.seriesPoints[a].push(b));return g},c.prototype._drawLineFor=function(a){var b;return b=this.paths[a],null!==b?this.drawLinePath(b,this.colorFor(null,a,"line"),a):void 0},c.createPath=function(a,c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q,r;for(k="",c&&(g=b.Line.gradients(a)),l={y:null},h=q=0,r=a.length;r>q;h=++q)e=a[h],null!=e.y&&(null!=l.y?c?(f=g[h],j=g[h-1],i=(e.x-l.x)/4,m=l.x+i,o=Math.min(d,l.y+i*j),n=e.x-i,p=Math.min(d,e.y-i*f),k+="C"+m+","+o+","+n+","+p+","+e.x+","+e.y):k+="L"+e.x+","+e.y:c&&null==g[h]||(k+="M"+e.x+","+e.y)),l=e;return k},c.gradients=function(a){var b,c,d,e,f,g,h,i;for(c=function(a,b){return(a.y-b.y)/(a.x-b.x)},i=[],d=g=0,h=a.length;h>g;d=++g)b=a[d],null!=b.y?(e=a[d+1]||{y:null},f=a[d-1]||{y:null},null!=f.y&&null!=e.y?i.push(c(f,e)):null!=f.y?i.push(c(f,b)):null!=e.y?i.push(c(b,e)):i.push(null)):i.push(null);return i},c.prototype.hilight=function(a){var b,c,d,e,f;if(null!==this.prevHilight&&this.prevHilight!==a)for(b=c=0,e=this.seriesPoints.length-1;e>=0?e>=c:c>=e;b=e>=0?++c:--c)this.seriesPoints[b][this.prevHilight]&&this.seriesPoints[b][this.prevHilight].animate(this.pointShrinkSeries(b));if(null!==a&&this.prevHilight!==a)for(b=d=0,f=this.seriesPoints.length-1;f>=0?f>=d:d>=f;b=f>=0?++d:--d)this.seriesPoints[b][a]&&this.seriesPoints[b][a].animate(this.pointGrowSeries(b));return this.prevHilight=a},c.prototype.colorFor=function(a,b,c){return"function"==typeof this.options.lineColors?this.options.lineColors.call(this,a,b,c):"point"===c?this.options.pointFillColors[b%this.options.pointFillColors.length]||this.options.lineColors[b%this.options.lineColors.length]:this.options.lineColors[b%this.options.lineColors.length]},c.prototype.drawXAxisLabel=function(a,b,c){return this.raphael.text(a,b,c).attr("font-size",this.options.gridTextSize).attr("font-family",this.options.gridTextFamily).attr("font-weight",this.options.gridTextWeight).attr("fill",this.options.gridTextColor)},c.prototype.drawLinePath=function(a,b,c){return this.raphael.path(a).attr("stroke",b).attr("stroke-width",this.lineWidthForSeries(c))},c.prototype.drawLinePoint=function(a,b,c,d){return this.raphael.circle(a,b,this.pointSizeForSeries(d)).attr("fill",c).attr("stroke-width",this.pointStrokeWidthForSeries(d)).attr("stroke",this.pointStrokeColorForSeries(d))},c.prototype.pointStrokeWidthForSeries=function(a){return this.options.pointStrokeWidths[a%this.options.pointStrokeWidths.length]},c.prototype.pointStrokeColorForSeries=function(a){return this.options.pointStrokeColors[a%this.options.pointStrokeColors.length]},c.prototype.lineWidthForSeries=function(a){return this.options.lineWidth instanceof Array?this.options.lineWidth[a%this.options.lineWidth.length]:this.options.lineWidth},c.prototype.pointSizeForSeries=function(a){return this.options.pointSize instanceof Array?this.options.pointSize[a%this.options.pointSize.length]:this.options.pointSize},c.prototype.pointGrowSeries=function(a){return Raphael.animation({r:this.pointSizeForSeries(a)+3},25,"linear")},c.prototype.pointShrinkSeries=function(a){return Raphael.animation({r:this.pointSizeForSeries(a)},25,"linear")},c}(b.Grid),b.labelSeries=function(c,d,e,f,g){var h,i,j,k,l,m,n,o,p,q,r;if(j=200*(d-c)/e,i=new Date(c),n=b.LABEL_SPECS[f],void 0===n)for(r=b.AUTO_LABEL_ORDER,p=0,q=r.length;q>p;p++)if(k=r[p],m=b.LABEL_SPECS[k],j>=m.span){n=m;break}for(void 0===n&&(n=b.LABEL_SPECS.second),g&&(n=a.extend({},n,{fmt:g})),h=n.start(i),l=[];(o=h.getTime())<=d;)o>=c&&l.push([n.fmt(h),o]),n.incr(h);return l},c=function(a){return{span:60*a*1e3,start:function(a){return new Date(a.getFullYear(),a.getMonth(),a.getDate(),a.getHours())},fmt:function(a){return""+b.pad2(a.getHours())+":"+b.pad2(a.getMinutes())},incr:function(b){return b.setUTCMinutes(b.getUTCMinutes()+a)}}},d=function(a){return{span:1e3*a,start:function(a){return new Date(a.getFullYear(),a.getMonth(),a.getDate(),a.getHours(),a.getMinutes())},fmt:function(a){return""+b.pad2(a.getHours())+":"+b.pad2(a.getMinutes())+":"+b.pad2(a.getSeconds())},incr:function(b){return b.setUTCSeconds(b.getUTCSeconds()+a)}}},b.LABEL_SPECS={decade:{span:1728e8,start:function(a){return new Date(a.getFullYear()-a.getFullYear()%10,0,1)},fmt:function(a){return""+a.getFullYear()},incr:function(a){return a.setFullYear(a.getFullYear()+10)}},year:{span:1728e7,start:function(a){return new Date(a.getFullYear(),0,1)},fmt:function(a){return""+a.getFullYear()},incr:function(a){return a.setFullYear(a.getFullYear()+1)}},month:{span:24192e5,start:function(a){return new Date(a.getFullYear(),a.getMonth(),1)},fmt:function(a){return""+a.getFullYear()+"-"+b.pad2(a.getMonth()+1)},incr:function(a){return a.setMonth(a.getMonth()+1)}},week:{span:6048e5,start:function(a){return new Date(a.getFullYear(),a.getMonth(),a.getDate())},fmt:function(a){return""+a.getFullYear()+"-"+b.pad2(a.getMonth()+1)+"-"+b.pad2(a.getDate())},incr:function(a){return a.setDate(a.getDate()+7)}},day:{span:864e5,start:function(a){return new Date(a.getFullYear(),a.getMonth(),a.getDate())},fmt:function(a){return""+a.getFullYear()+"-"+b.pad2(a.getMonth()+1)+"-"+b.pad2(a.getDate())},incr:function(a){return a.setDate(a.getDate()+1)}},hour:c(60),"30min":c(30),"15min":c(15),"10min":c(10),"5min":c(5),minute:c(1),"30sec":d(30),"15sec":d(15),"10sec":d(10),"5sec":d(5),second:d(1)},b.AUTO_LABEL_ORDER=["decade","year","month","week","day","hour","30min","15min","10min","5min","minute","30sec","15sec","10sec","5sec","second"],b.Area=function(c){function d(c){var f;return this instanceof b.Area?(f=a.extend({},e,c),this.cumulative=!f.behaveLikeLine,"auto"===f.fillOpacity&&(f.fillOpacity=f.behaveLikeLine?.8:1),d.__super__.constructor.call(this,f),void 0):new b.Area(c)}var e;return h(d,c),e={fillOpacity:"auto",behaveLikeLine:!1},d.prototype.calcPoints=function(){var a,b,c,d,e,f,g;for(f=this.data,g=[],d=0,e=f.length;e>d;d++)a=f[d],a._x=this.transX(a.x),b=0,a._y=function(){var d,e,f,g;for(f=a.y,g=[],d=0,e=f.length;e>d;d++)c=f[d],this.options.behaveLikeLine?g.push(this.transY(c)):(b+=c||0,g.push(this.transY(b)));return g}.call(this),g.push(a._ymax=Math.max.apply(Math,a._y));return g},d.prototype.drawSeries=function(){var a,b,c,d,e,f,g,h;for(this.seriesPoints=[],b=this.options.behaveLikeLine?function(){f=[];for(var a=0,b=this.options.ykeys.length-1;b>=0?b>=a:a>=b;b>=0?a++:a--)f.push(a);return f}.apply(this):function(){g=[];for(var a=e=this.options.ykeys.length-1;0>=e?0>=a:a>=0;0>=e?a++:a--)g.push(a);return g}.apply(this),h=[],c=0,d=b.length;d>c;c++)a=b[c],this._drawFillFor(a),this._drawLineFor(a),h.push(this._drawPointFor(a));return h},d.prototype._drawFillFor=function(a){var b;return b=this.paths[a],null!==b?(b+="L"+this.transX(this.xmax)+","+this.bottom+"L"+this.transX(this.xmin)+","+this.bottom+"Z",this.drawFilledPath(b,this.fillForSeries(a))):void 0},d.prototype.fillForSeries=function(a){var b;return b=Raphael.rgb2hsl(this.colorFor(this.data[a],a,"line")),Raphael.hsl(b.h,this.options.behaveLikeLine?.9*b.s:.75*b.s,Math.min(.98,this.options.behaveLikeLine?1.2*b.l:1.25*b.l))},d.prototype.drawFilledPath=function(a,b){return this.raphael.path(a).attr("fill",b).attr("fill-opacity",this.options.fillOpacity).attr("stroke","none")},d}(b.Line),b.Bar=function(c){function d(c){return this.onHoverOut=f(this.onHoverOut,this),this.onHoverMove=f(this.onHoverMove,this),this.onGridClick=f(this.onGridClick,this),this instanceof b.Bar?(d.__super__.constructor.call(this,a.extend({},c,{parseTime:!1})),void 0):new b.Bar(c)}return h(d,c),d.prototype.init=function(){return this.cumulative=this.options.stacked,"always"!==this.options.hideHover?(this.hover=new b.Hover({parent:this.el}),this.on("hovermove",this.onHoverMove),this.on("hoverout",this.onHoverOut),this.on("gridclick",this.onGridClick)):void 0},d.prototype.defaults={barSizeRatio:.75,barGap:3,barColors:["#0b62a4","#7a92a3","#4da74d","#afd8f8","#edc240","#cb4b4b","#9440ed"],barOpacity:1,barRadius:[0,0,0,0],xLabelMargin:50},d.prototype.calc=function(){var a;return this.calcBars(),this.options.hideHover===!1?(a=this.hover).update.apply(a,this.hoverContentForRow(this.data.length-1)):void 0},d.prototype.calcBars=function(){var a,b,c,d,e,f,g;for(f=this.data,g=[],a=d=0,e=f.length;e>d;a=++d)b=f[a],b._x=this.left+this.width*(a+.5)/this.data.length,g.push(b._y=function(){var a,d,e,f;for(e=b.y,f=[],a=0,d=e.length;d>a;a++)c=e[a],null!=c?f.push(this.transY(c)):f.push(null);return f}.call(this));return g},d.prototype.draw=function(){var a;return((a=this.options.axes)===!0||"both"===a||"x"===a)&&this.drawXAxis(),this.drawSeries()},d.prototype.drawXAxis=function(){var a,b,c,d,e,f,g,h,i,j,k,l,m;for(j=this.bottom+(this.options.xAxisLabelTopPadding||this.options.padding/2),g=null,f=null,m=[],a=k=0,l=this.data.length;l>=0?l>k:k>l;a=l>=0?++k:--k)h=this.data[this.data.length-1-a],b=this.drawXAxisLabel(h._x,j,h.label),i=b.getBBox(),b.transform("r"+-this.options.xLabelAngle),c=b.getBBox(),b.transform("t0,"+c.height/2+"..."),0!==this.options.xLabelAngle&&(e=-.5*i.width*Math.cos(this.options.xLabelAngle*Math.PI/180),b.transform("t"+e+",0...")),(null==g||g>=c.x+c.width||null!=f&&f>=c.x)&&c.x>=0&&c.x+c.width=0?this.transY(0):null,this.bars=function(){var h,o,p,q;for(p=this.data,q=[],d=h=0,o=p.length;o>h;d=++h)i=p[d],e=0,q.push(function(){var h,o,p,q;for(p=i._y,q=[],j=h=0,o=p.length;o>h;j=++h)m=p[j],null!==m?(n?(l=Math.min(m,n),b=Math.max(m,n)):(l=m,b=this.bottom),f=this.left+d*c+g,this.options.stacked||(f+=j*(a+this.options.barGap)),k=b-l,this.options.stacked&&(l-=e),this.drawBar(f,l,a,k,this.colorFor(i,j,"bar"),this.options.barOpacity,this.options.barRadius),q.push(e+=k)):q.push(null);return q}.call(this));return q}.call(this)},d.prototype.colorFor=function(a,b,c){var d,e;return"function"==typeof this.options.barColors?(d={x:a.x,y:a.y[b],label:a.label},e={index:b,key:this.options.ykeys[b],label:this.options.labels[b]},this.options.barColors.call(this,d,e,c)):this.options.barColors[b%this.options.barColors.length]},d.prototype.hitTest=function(a){return 0===this.data.length?null:(a=Math.max(Math.min(a,this.right),this.left),Math.min(this.data.length-1,Math.floor((a-this.left)/(this.width/this.data.length))))},d.prototype.onGridClick=function(a,b){var c;return c=this.hitTest(a),this.fire("click",c,this.data[c].src,a,b)},d.prototype.onHoverMove=function(a){var b,c;return b=this.hitTest(a),(c=this.hover).update.apply(c,this.hoverContentForRow(b))},d.prototype.onHoverOut=function(){return this.options.hideHover!==!1?this.hover.hide():void 0},d.prototype.hoverContentForRow=function(a){var b,c,d,e,f,g,h,i;for(d=this.data[a],b="
    "+d.label+"
    ",i=d.y,c=g=0,h=i.length;h>g;c=++g)f=i[c],b+="
    \n "+this.options.labels[c]+":\n "+this.yLabelFormat(f)+"\n
    ";return"function"==typeof this.options.hoverCallback&&(b=this.options.hoverCallback(a,this.options,b,d.src)),e=this.left+(a+.5)*this.width/this.data.length,[b,e]},d.prototype.drawXAxisLabel=function(a,b,c){var d;return d=this.raphael.text(a,b,c).attr("font-size",this.options.gridTextSize).attr("font-family",this.options.gridTextFamily).attr("font-weight",this.options.gridTextWeight).attr("fill",this.options.gridTextColor)},d.prototype.drawBar=function(a,b,c,d,e,f,g){var h,i;return h=Math.max.apply(Math,g),i=0===h||h>d?this.raphael.rect(a,b,c,d):this.raphael.path(this.roundedRect(a,b,c,d,g)),i.attr("fill",e).attr("fill-opacity",f).attr("stroke","none")},d.prototype.roundedRect=function(a,b,c,d,e){return null==e&&(e=[0,0,0,0]),["M",a,e[0]+b,"Q",a,b,a+e[0],b,"L",a+c-e[1],b,"Q",a+c,b,a+c,b+e[1],"L",a+c,b+d-e[2],"Q",a+c,b+d,a+c-e[2],b+d,"L",a+e[3],b+d,"Q",a,b+d,a,b+d-e[3],"Z"]},d}(b.Grid),b.Donut=function(c){function d(c){this.resizeHandler=f(this.resizeHandler,this),this.select=f(this.select,this),this.click=f(this.click,this);var d=this;if(!(this instanceof b.Donut))return new b.Donut(c);if(this.options=a.extend({},this.defaults,c),this.el="string"==typeof c.element?a(document.getElementById(c.element)):a(c.element),null===this.el||0===this.el.length)throw new Error("Graph placeholder not found.");void 0!==c.data&&0!==c.data.length&&(this.raphael=new Raphael(this.el[0]),this.options.resize&&a(window).bind("resize",function(){return null!=d.timeoutId&&window.clearTimeout(d.timeoutId),d.timeoutId=window.setTimeout(d.resizeHandler,100)}),this.setData(c.data))}return h(d,c),d.prototype.defaults={colors:["#0B62A4","#3980B5","#679DC6","#95BBD7","#B0CCE1","#095791","#095085","#083E67","#052C48","#042135"],backgroundColor:"#FFFFFF",labelColor:"#000000",formatter:b.commas,resize:!1},d.prototype.redraw=function(){var a,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x;for(this.raphael.clear(),c=this.el.width()/2,d=this.el.height()/2,n=(Math.min(c,d)-10)/3,l=0,u=this.values,o=0,r=u.length;r>o;o++)m=u[o],l+=m;for(i=5/(2*n),a=1.9999*Math.PI-i*this.data.length,g=0,f=0,this.segments=[],v=this.values,e=p=0,s=v.length;s>p;e=++p)m=v[e],j=g+i+a*(m/l),k=new b.DonutSegment(c,d,2*n,n,g,j,this.data[e].color||this.options.colors[f%this.options.colors.length],this.options.backgroundColor,f,this.raphael),k.render(),this.segments.push(k),k.on("hover",this.select),k.on("click",this.click),g=j,f+=1;for(this.text1=this.drawEmptyDonutLabel(c,d-10,this.options.labelColor,15,800),this.text2=this.drawEmptyDonutLabel(c,d+10,this.options.labelColor,14),h=Math.max.apply(Math,this.values),f=0,w=this.values,x=[],q=0,t=w.length;t>q;q++){if(m=w[q],m===h){this.select(f);break}x.push(f+=1)}return x},d.prototype.setData=function(a){var b; -return this.data=a,this.values=function(){var a,c,d,e;for(d=this.data,e=[],a=0,c=d.length;c>a;a++)b=d[a],e.push(parseFloat(b.value));return e}.call(this),this.redraw()},d.prototype.click=function(a){return this.fire("click",a,this.data[a])},d.prototype.select=function(a){var b,c,d,e,f,g;for(g=this.segments,e=0,f=g.length;f>e;e++)c=g[e],c.deselect();return d=this.segments[a],d.select(),b=this.data[a],this.setLabels(b.label,this.options.formatter(b.value,b))},d.prototype.setLabels=function(a,b){var c,d,e,f,g,h,i,j;return c=2*(Math.min(this.el.width()/2,this.el.height()/2)-10)/3,f=1.8*c,e=c/2,d=c/3,this.text1.attr({text:a,transform:""}),g=this.text1.getBBox(),h=Math.min(f/g.width,e/g.height),this.text1.attr({transform:"S"+h+","+h+","+(g.x+g.width/2)+","+(g.y+g.height)}),this.text2.attr({text:b,transform:""}),i=this.text2.getBBox(),j=Math.min(f/i.width,d/i.height),this.text2.attr({transform:"S"+j+","+j+","+(i.x+i.width/2)+","+i.y})},d.prototype.drawEmptyDonutLabel=function(a,b,c,d,e){var f;return f=this.raphael.text(a,b,"").attr("font-size",d).attr("fill",c),null!=e&&f.attr("font-weight",e),f},d.prototype.resizeHandler=function(){return this.timeoutId=null,this.raphael.setSize(this.el.width(),this.el.height()),this.redraw()},d}(b.EventEmitter),b.DonutSegment=function(a){function b(a,b,c,d,e,g,h,i,j,k){this.cx=a,this.cy=b,this.inner=c,this.outer=d,this.color=h,this.backgroundColor=i,this.index=j,this.raphael=k,this.deselect=f(this.deselect,this),this.select=f(this.select,this),this.sin_p0=Math.sin(e),this.cos_p0=Math.cos(e),this.sin_p1=Math.sin(g),this.cos_p1=Math.cos(g),this.is_long=g-e>Math.PI?1:0,this.path=this.calcSegment(this.inner+3,this.inner+this.outer-5),this.selectedPath=this.calcSegment(this.inner+3,this.inner+this.outer),this.hilight=this.calcArc(this.inner)}return h(b,a),b.prototype.calcArcPoints=function(a){return[this.cx+a*this.sin_p0,this.cy+a*this.cos_p0,this.cx+a*this.sin_p1,this.cy+a*this.cos_p1]},b.prototype.calcSegment=function(a,b){var c,d,e,f,g,h,i,j,k,l;return k=this.calcArcPoints(a),c=k[0],e=k[1],d=k[2],f=k[3],l=this.calcArcPoints(b),g=l[0],i=l[1],h=l[2],j=l[3],"M"+c+","+e+("A"+a+","+a+",0,"+this.is_long+",0,"+d+","+f)+("L"+h+","+j)+("A"+b+","+b+",0,"+this.is_long+",1,"+g+","+i)+"Z"},b.prototype.calcArc=function(a){var b,c,d,e,f;return f=this.calcArcPoints(a),b=f[0],d=f[1],c=f[2],e=f[3],"M"+b+","+d+("A"+a+","+a+",0,"+this.is_long+",0,"+c+","+e)},b.prototype.render=function(){var a=this;return this.arc=this.drawDonutArc(this.hilight,this.color),this.seg=this.drawDonutSegment(this.path,this.color,this.backgroundColor,function(){return a.fire("hover",a.index)},function(){return a.fire("click",a.index)})},b.prototype.drawDonutArc=function(a,b){return this.raphael.path(a).attr({stroke:b,"stroke-width":2,opacity:0})},b.prototype.drawDonutSegment=function(a,b,c,d,e){return this.raphael.path(a).attr({fill:b,stroke:c,"stroke-width":3}).hover(d).click(e)},b.prototype.select=function(){return this.selected?void 0:(this.seg.animate({path:this.selectedPath},150,"<>"),this.arc.animate({opacity:1},150,"<>"),this.selected=!0)},b.prototype.deselect=function(){return this.selected?(this.seg.animate({path:this.path},150,"<>"),this.arc.animate({opacity:0},150,"<>"),this.selected=!1):void 0},b}(b.EventEmitter)}).call(this); \ No newline at end of file diff --git a/public/assets/js/plugins/slimScroll/jquery.slimscroll.min.js b/public/assets/js/plugins/slimScroll/jquery.slimscroll.min.js deleted file mode 100755 index 26220d6b..00000000 --- a/public/assets/js/plugins/slimScroll/jquery.slimscroll.min.js +++ /dev/null @@ -1,16 +0,0 @@ -/*! Copyright (c) 2011 Piotr Rochala (http://rocha.la) - * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) - * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. - * - * Version: 1.3.0 - * - */ -(function(f){jQuery.fn.extend({slimScroll:function(h){var a=f.extend({width:"auto",height:"250px",size:"7px",color:"#000",position:"right",distance:"1px",start:"top",opacity:0.4,alwaysVisible:!1,disableFadeOut:!1,railVisible:!1,railColor:"#333",railOpacity:0.2,railDraggable:!0,railClass:"slimScrollRail",barClass:"slimScrollBar",wrapperClass:"slimScrollDiv",allowPageScroll:!1,wheelStep:20,touchScrollStep:200,borderRadius:"7px",railBorderRadius:"7px"},h);this.each(function(){function r(d){if(s){d=d|| -window.event;var c=0;d.wheelDelta&&(c=-d.wheelDelta/120);d.detail&&(c=d.detail/3);f(d.target||d.srcTarget||d.srcElement).closest("."+a.wrapperClass).is(b.parent())&&m(c,!0);d.preventDefault&&!k&&d.preventDefault();k||(d.returnValue=!1)}}function m(d,f,h){k=!1;var e=d,g=b.outerHeight()-c.outerHeight();f&&(e=parseInt(c.css("top"))+d*parseInt(a.wheelStep)/100*c.outerHeight(),e=Math.min(Math.max(e,0),g),e=0=b.outerHeight()?k=!0:(c.stop(!0,!0).fadeIn("fast"),a.railVisible&&g.stop(!0,!0).fadeIn("fast"))}function p(){a.alwaysVisible||(A=setTimeout(function(){a.disableFadeOut&&s||(x||y)||(c.fadeOut("slow"),g.fadeOut("slow"))},1E3))}var s,x,y,A,z,u,l,B,D=30,k=!1,b=f(this);if(b.parent().hasClass(a.wrapperClass)){var n=b.scrollTop(), -c=b.parent().find("."+a.barClass),g=b.parent().find("."+a.railClass);w();if(f.isPlainObject(h)){if("height"in h&&"auto"==h.height){b.parent().css("height","auto");b.css("height","auto");var q=b.parent().parent().height();b.parent().css("height",q);b.css("height",q)}if("scrollTo"in h)n=parseInt(a.scrollTo);else if("scrollBy"in h)n+=parseInt(a.scrollBy);else if("destroy"in h){c.remove();g.remove();b.unwrap();return}m(n,!1,!0)}}else{a.height="auto"==a.height?b.parent().height():a.height;n=f("
    ").addClass(a.wrapperClass).css({position:"relative", -overflow:"hidden",width:a.width,height:a.height});b.css({overflow:"hidden",width:a.width,height:a.height});var g=f("
    ").addClass(a.railClass).css({width:a.size,height:"100%",position:"absolute",top:0,display:a.alwaysVisible&&a.railVisible?"block":"none","border-radius":a.railBorderRadius,background:a.railColor,opacity:a.railOpacity,zIndex:90}),c=f("
    ").addClass(a.barClass).css({background:a.color,width:a.size,position:"absolute",top:0,opacity:a.opacity,display:a.alwaysVisible? -"block":"none","border-radius":a.borderRadius,BorderRadius:a.borderRadius,MozBorderRadius:a.borderRadius,WebkitBorderRadius:a.borderRadius,zIndex:99}),q="right"==a.position?{right:a.distance}:{left:a.distance};g.css(q);c.css(q);b.wrap(n);b.parent().append(c);b.parent().append(g);a.railDraggable&&c.bind("mousedown",function(a){var b=f(document);y=!0;t=parseFloat(c.css("top"));pageY=a.pageY;b.bind("mousemove.slimscroll",function(a){currTop=t+a.pageY-pageY;c.css("top",currTop);m(0,c.position().top,!1)}); -b.bind("mouseup.slimscroll",function(a){y=!1;p();b.unbind(".slimscroll")});return!1}).bind("selectstart.slimscroll",function(a){a.stopPropagation();a.preventDefault();return!1});g.hover(function(){v()},function(){p()});c.hover(function(){x=!0},function(){x=!1});b.hover(function(){s=!0;v();p()},function(){s=!1;p()});b.bind("touchstart",function(a,b){a.originalEvent.touches.length&&(z=a.originalEvent.touches[0].pageY)});b.bind("touchmove",function(b){k||b.originalEvent.preventDefault();b.originalEvent.touches.length&& -(m((z-b.originalEvent.touches[0].pageY)/a.touchScrollStep,!0),z=b.originalEvent.touches[0].pageY)});w();"bottom"===a.start?(c.css({top:b.outerHeight()-c.outerHeight()}),m(0,!0)):"top"!==a.start&&(m(f(a.start).position().top,null,!0),a.alwaysVisible||c.hide());C()}});return this}});jQuery.fn.extend({slimscroll:jQuery.fn.slimScroll})})(jQuery); \ No newline at end of file diff --git a/public/assets/js/plugins/slimScroll/slimScroll.jquery.json b/public/assets/js/plugins/slimScroll/slimScroll.jquery.json deleted file mode 100755 index 41174e64..00000000 --- a/public/assets/js/plugins/slimScroll/slimScroll.jquery.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name" : "slimScroll", - "version" : "1.2.0", - "title" : "jQuery slimScroll scrollbar", - "description" : "slimScroll is a small jQuery plugin that transforms any div into a scrollable area. slimScroll doesn't occupy any visual space as it only appears on a user initiated mouse-over.", - "keywords" : ["scrollbar", "scroll", "slimscroll", "scrollable", "scrolling", "scroller", "ui"], - "demo" : "http://rocha.la/jQuery-slimScroll/", - "homepage" : "http://rocha.la/jQuery-slimScroll/", - "download" : "http://rocha.la/jQuery-slimScroll/", - - "author" : { - "name" : "Piotr Rochala", - "url" : "http://rocha.la/" - }, - - "dependencies" : { - "jquery" : ">= 1.7" - }, - - "licenses" : [ - { - "type": "MIT", - "url": "http://www.opensource.org/licenses/mit-license.php" - }, - { - "type": "GPL", - "url": "http://www.opensource.org/licenses/gpl-license.php" - } - ] -} \ No newline at end of file diff --git a/public/assets/js/sprintf.min.map b/public/assets/js/sprintf.min.map new file mode 100644 index 00000000..bced4235 --- /dev/null +++ b/public/assets/js/sprintf.min.map @@ -0,0 +1 @@ +{"version":3,"file":"sprintf.min.js","sources":["../src/sprintf.js"],"names":["window","sprintf","key","arguments","cache","hasOwnProperty","parse","format","call","get_type","variable","Object","prototype","toString","slice","toLowerCase","str_repeat","input","multiplier","Array","join","re","not_string","number","json","not_json","text","modulo","placeholder","key_access","index_access","sign","parse_tree","argv","arg","i","k","match","pad","pad_character","pad_length","cursor","tree_length","length","node_type","output","is_positive","Error","test","isNaN","TypeError","String","fromCharCode","parseInt","JSON","stringify","toExponential","parseFloat","toFixed","toPrecision","substring","toUpperCase","replace","charAt","fmt","_fmt","arg_names","exec","SyntaxError","field_list","replacement_field","field_match","vsprintf","_argv","splice","apply","exports","define","amd","this"],"mappings":";;CAAA,SAAUA,GAeN,QAASC,KACL,GAAIC,GAAMC,UAAU,GAAIC,EAAQH,EAAQG,KAIxC,OAHMA,GAAMF,IAAQE,EAAMC,eAAeH,KACrCE,EAAMF,GAAOD,EAAQK,MAAMJ,IAExBD,EAAQM,OAAOC,KAAK,KAAMJ,EAAMF,GAAMC,WA+JjD,QAASM,GAASC,GACd,MAAOC,QAAOC,UAAUC,SAASL,KAAKE,GAAUI,MAAM,EAAG,IAAIC,cAGjE,QAASC,GAAWC,EAAOC,GACvB,MAAOC,OAAMD,EAAa,GAAGE,KAAKH,GAvLtC,GAAII,IACAC,WAAY,OACZC,OAAQ,UACRC,KAAM,MACNC,SAAU,OACVC,KAAM,YACNC,OAAQ,WACRC,YAAa,yFACb1B,IAAK,sBACL2B,WAAY,wBACZC,aAAc,aACdC,KAAM,UAWV9B,GAAQM,OAAS,SAASyB,EAAYC,GAClC,GAAiEC,GAAkBC,EAAGC,EAAGC,EAAOC,EAAKC,EAAeC,EAAhHC,EAAS,EAAGC,EAAcV,EAAWW,OAAQC,EAAY,GAASC,KAA0DC,GAAc,EAAMf,EAAO,EAC3J,KAAKI,EAAI,EAAOO,EAAJP,EAAiBA,IAEzB,GADAS,EAAYnC,EAASuB,EAAWG,IACd,WAAdS,EACAC,EAAOA,EAAOF,QAAUX,EAAWG,OAElC,IAAkB,UAAdS,EAAuB,CAE5B,GADAP,EAAQL,EAAWG,GACfE,EAAM,GAEN,IADAH,EAAMD,EAAKQ,GACNL,EAAI,EAAGA,EAAIC,EAAM,GAAGM,OAAQP,IAAK,CAClC,IAAKF,EAAI7B,eAAegC,EAAM,GAAGD,IAC7B,KAAM,IAAIW,OAAM9C,EAAQ,yCAA0CoC,EAAM,GAAGD,IAE/EF,GAAMA,EAAIG,EAAM,GAAGD,QAIvBF,GADKG,EAAM,GACLJ,EAAKI,EAAM,IAGXJ,EAAKQ,IAOf,IAJqB,YAAjBhC,EAASyB,KACTA,EAAMA,KAGNb,EAAGC,WAAW0B,KAAKX,EAAM,KAAOhB,EAAGI,SAASuB,KAAKX,EAAM,KAAyB,UAAjB5B,EAASyB,IAAoBe,MAAMf,GAClG,KAAM,IAAIgB,WAAUjD,EAAQ,0CAA2CQ,EAASyB,IAOpF,QAJIb,EAAGE,OAAOyB,KAAKX,EAAM,MACrBS,EAAcZ,GAAO,GAGjBG,EAAM,IACV,IAAK,IACDH,EAAMA,EAAIrB,SAAS,EACvB,MACA,KAAK,IACDqB,EAAMiB,OAAOC,aAAalB,EAC9B,MACA,KAAK,IACL,IAAK,IACDA,EAAMmB,SAASnB,EAAK,GACxB,MACA,KAAK,IACDA,EAAMoB,KAAKC,UAAUrB,EAAK,KAAMG,EAAM,GAAKgB,SAAShB,EAAM,IAAM,EACpE,MACA,KAAK,IACDH,EAAMG,EAAM,GAAKH,EAAIsB,cAAcnB,EAAM,IAAMH,EAAIsB,eACvD,MACA,KAAK,IACDtB,EAAMG,EAAM,GAAKoB,WAAWvB,GAAKwB,QAAQrB,EAAM,IAAMoB,WAAWvB,EACpE,MACA,KAAK,IACDA,EAAMG,EAAM,GAAKoB,WAAWvB,GAAKyB,YAAYtB,EAAM,IAAMoB,WAAWvB,EACxE,MACA,KAAK,IACDA,EAAMA,EAAIrB,SAAS,EACvB,MACA,KAAK,IACDqB,GAAQA,EAAMiB,OAAOjB,KAASG,EAAM,GAAKH,EAAI0B,UAAU,EAAGvB,EAAM,IAAMH,CAC1E,MACA,KAAK,IACDA,KAAc,CAClB,MACA,KAAK,IACDA,EAAMA,EAAIrB,SAAS,GACvB,MACA,KAAK,IACDqB,EAAMA,EAAIrB,SAAS,IAAIgD,cAG3BxC,EAAGG,KAAKwB,KAAKX,EAAM,IACnBQ,EAAOA,EAAOF,QAAUT,IAGpBb,EAAGE,OAAOyB,KAAKX,EAAM,KAASS,IAAeT,EAAM,GAKnDN,EAAO,IAJPA,EAAOe,EAAc,IAAM,IAC3BZ,EAAMA,EAAIrB,WAAWiD,QAAQzC,EAAGU,KAAM,KAK1CQ,EAAgBF,EAAM,GAAkB,MAAbA,EAAM,GAAa,IAAMA,EAAM,GAAG0B,OAAO,GAAK,IACzEvB,EAAaH,EAAM,IAAMN,EAAOG,GAAKS,OACrCL,EAAMD,EAAM,IAAMG,EAAa,EAAIxB,EAAWuB,EAAeC,GAAoB,GACjFK,EAAOA,EAAOF,QAAUN,EAAM,GAAKN,EAAOG,EAAMI,EAAyB,MAAlBC,EAAwBR,EAAOO,EAAMJ,EAAMI,EAAMP,EAAOG,GAI3H,MAAOW,GAAOzB,KAAK,KAGvBnB,EAAQG,SAERH,EAAQK,MAAQ,SAAS0D,GAErB,IADA,GAAIC,GAAOD,EAAK3B,KAAYL,KAAiBkC,EAAY,EAClDD,GAAM,CACT,GAAqC,QAAhC5B,EAAQhB,EAAGK,KAAKyC,KAAKF,IACtBjC,EAAWA,EAAWW,QAAUN,EAAM,OAErC,IAAuC,QAAlCA,EAAQhB,EAAGM,OAAOwC,KAAKF,IAC7BjC,EAAWA,EAAWW,QAAU,QAE/B,CAAA,GAA4C,QAAvCN,EAAQhB,EAAGO,YAAYuC,KAAKF,IAgClC,KAAM,IAAIG,aAAY,mCA/BtB,IAAI/B,EAAM,GAAI,CACV6B,GAAa,CACb,IAAIG,MAAiBC,EAAoBjC,EAAM,GAAIkC,IACnD,IAAuD,QAAlDA,EAAclD,EAAGnB,IAAIiE,KAAKG,IAe3B,KAAM,IAAIF,aAAY,+CAbtB,KADAC,EAAWA,EAAW1B,QAAU4B,EAAY,GACwC,MAA5ED,EAAoBA,EAAkBV,UAAUW,EAAY,GAAG5B,UACnE,GAA8D,QAAzD4B,EAAclD,EAAGQ,WAAWsC,KAAKG,IAClCD,EAAWA,EAAW1B,QAAU4B,EAAY,OAE3C,CAAA,GAAgE,QAA3DA,EAAclD,EAAGS,aAAaqC,KAAKG,IAIzC,KAAM,IAAIF,aAAY,+CAHtBC,GAAWA,EAAW1B,QAAU4B,EAAY,GAUxDlC,EAAM,GAAKgC,MAGXH,IAAa,CAEjB,IAAkB,IAAdA,EACA,KAAM,IAAInB,OAAM,4EAEpBf,GAAWA,EAAWW,QAAUN,EAKpC4B,EAAOA,EAAKL,UAAUvB,EAAM,GAAGM,QAEnC,MAAOX,GAGX,IAAIwC,GAAW,SAASR,EAAK/B,EAAMwC,GAG/B,MAFAA,IAASxC,OAAYnB,MAAM,GAC3B2D,EAAMC,OAAO,EAAG,EAAGV,GACZ/D,EAAQ0E,MAAM,KAAMF,GAiBR,oBAAZG,UACPA,QAAQ3E,QAAUA,EAClB2E,QAAQJ,SAAWA,IAGnBxE,EAAOC,QAAUA,EACjBD,EAAOwE,SAAWA,EAEI,kBAAXK,SAAyBA,OAAOC,KACvCD,OAAO,WACH,OACI5E,QAASA,EACTuE,SAAUA,OAKT,mBAAXxE,QAAyB+E,KAAO/E"} diff --git a/public/assets/js/plugins/bootstrap-slider/bootstrap-slider.js b/public/assets/plugins/bootstrap-slider/bootstrap-slider.js old mode 100755 new mode 100644 similarity index 100% rename from public/assets/js/plugins/bootstrap-slider/bootstrap-slider.js rename to public/assets/plugins/bootstrap-slider/bootstrap-slider.js diff --git a/public/assets/css/bootstrap-slider/slider.css b/public/assets/plugins/bootstrap-slider/slider.css old mode 100755 new mode 100644 similarity index 100% rename from public/assets/css/bootstrap-slider/slider.css rename to public/assets/plugins/bootstrap-slider/slider.css diff --git a/public/assets/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.js b/public/assets/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.js new file mode 100644 index 00000000..acccf91e --- /dev/null +++ b/public/assets/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.js @@ -0,0 +1,14975 @@ +// TODO: in future try to replace most inline compability checks with polyfills for code readability + +// element.textContent polyfill. +// Unsupporting browsers: IE8 + +if (Object.defineProperty && Object.getOwnPropertyDescriptor && Object.getOwnPropertyDescriptor(Element.prototype, "textContent") && !Object.getOwnPropertyDescriptor(Element.prototype, "textContent").get) { + (function() { + var innerText = Object.getOwnPropertyDescriptor(Element.prototype, "innerText"); + Object.defineProperty(Element.prototype, "textContent", + { + get: function() { + return innerText.get.call(this); + }, + set: function(s) { + return innerText.set.call(this, s); + } + } + ); + })(); +} + +// isArray polyfill for ie8 +if(!Array.isArray) { + Array.isArray = function(arg) { + return Object.prototype.toString.call(arg) === '[object Array]'; + }; +};/** + * @license wysihtml5x v0.4.15 + * https://github.com/Edicy/wysihtml5 + * + * Author: Christopher Blum (https://github.com/tiff) + * Secondary author of extended features: Oliver Pulges (https://github.com/pulges) + * + * Copyright (C) 2012 XING AG + * Licensed under the MIT license (MIT) + * + */ +var wysihtml5 = { + version: "0.4.15", + + // namespaces + commands: {}, + dom: {}, + quirks: {}, + toolbar: {}, + lang: {}, + selection: {}, + views: {}, + + INVISIBLE_SPACE: "\uFEFF", + + EMPTY_FUNCTION: function() {}, + + ELEMENT_NODE: 1, + TEXT_NODE: 3, + + BACKSPACE_KEY: 8, + ENTER_KEY: 13, + ESCAPE_KEY: 27, + SPACE_KEY: 32, + DELETE_KEY: 46 +}; +;/** + * Rangy, a cross-browser JavaScript range and selection library + * http://code.google.com/p/rangy/ + * + * Copyright 2014, Tim Down + * Licensed under the MIT license. + * Version: 1.3alpha.20140804 + * Build date: 4 August 2014 + */ + +(function(factory, global) { + if (typeof define == "function" && define.amd) { + // AMD. Register as an anonymous module. + define(factory); +/* + TODO: look into this properly. + + } else if (typeof exports == "object") { + // Node/CommonJS style for Browserify + module.exports = factory; +*/ + } else { + // No AMD or CommonJS support so we place Rangy in a global variable + global.rangy = factory(); + } +})(function() { + + var OBJECT = "object", FUNCTION = "function", UNDEFINED = "undefined"; + + // Minimal set of properties required for DOM Level 2 Range compliance. Comparison constants such as START_TO_START + // are omitted because ranges in KHTML do not have them but otherwise work perfectly well. See issue 113. + var domRangeProperties = ["startContainer", "startOffset", "endContainer", "endOffset", "collapsed", + "commonAncestorContainer"]; + + // Minimal set of methods required for DOM Level 2 Range compliance + var domRangeMethods = ["setStart", "setStartBefore", "setStartAfter", "setEnd", "setEndBefore", + "setEndAfter", "collapse", "selectNode", "selectNodeContents", "compareBoundaryPoints", "deleteContents", + "extractContents", "cloneContents", "insertNode", "surroundContents", "cloneRange", "toString", "detach"]; + + var textRangeProperties = ["boundingHeight", "boundingLeft", "boundingTop", "boundingWidth", "htmlText", "text"]; + + // Subset of TextRange's full set of methods that we're interested in + var textRangeMethods = ["collapse", "compareEndPoints", "duplicate", "moveToElementText", "parentElement", "select", + "setEndPoint", "getBoundingClientRect"]; + + /*----------------------------------------------------------------------------------------------------------------*/ + + // Trio of functions taken from Peter Michaux's article: + // http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting + function isHostMethod(o, p) { + var t = typeof o[p]; + return t == FUNCTION || (!!(t == OBJECT && o[p])) || t == "unknown"; + } + + function isHostObject(o, p) { + return !!(typeof o[p] == OBJECT && o[p]); + } + + function isHostProperty(o, p) { + return typeof o[p] != UNDEFINED; + } + + // Creates a convenience function to save verbose repeated calls to tests functions + function createMultiplePropertyTest(testFunc) { + return function(o, props) { + var i = props.length; + while (i--) { + if (!testFunc(o, props[i])) { + return false; + } + } + return true; + }; + } + + // Next trio of functions are a convenience to save verbose repeated calls to previous two functions + var areHostMethods = createMultiplePropertyTest(isHostMethod); + var areHostObjects = createMultiplePropertyTest(isHostObject); + var areHostProperties = createMultiplePropertyTest(isHostProperty); + + function isTextRange(range) { + return range && areHostMethods(range, textRangeMethods) && areHostProperties(range, textRangeProperties); + } + + function getBody(doc) { + return isHostObject(doc, "body") ? doc.body : doc.getElementsByTagName("body")[0]; + } + + var modules = {}; + + var api = { + version: "1.3alpha.20140804", + initialized: false, + supported: true, + + util: { + isHostMethod: isHostMethod, + isHostObject: isHostObject, + isHostProperty: isHostProperty, + areHostMethods: areHostMethods, + areHostObjects: areHostObjects, + areHostProperties: areHostProperties, + isTextRange: isTextRange, + getBody: getBody + }, + + features: {}, + + modules: modules, + config: { + alertOnFail: true, + alertOnWarn: false, + preferTextRange: false, + autoInitialize: (typeof rangyAutoInitialize == UNDEFINED) ? true : rangyAutoInitialize + } + }; + + function consoleLog(msg) { + if (isHostObject(window, "console") && isHostMethod(window.console, "log")) { + window.console.log(msg); + } + } + + function alertOrLog(msg, shouldAlert) { + if (shouldAlert) { + window.alert(msg); + } else { + consoleLog(msg); + } + } + + function fail(reason) { + api.initialized = true; + api.supported = false; + alertOrLog("Rangy is not supported on this page in your browser. Reason: " + reason, api.config.alertOnFail); + } + + api.fail = fail; + + function warn(msg) { + alertOrLog("Rangy warning: " + msg, api.config.alertOnWarn); + } + + api.warn = warn; + + // Add utility extend() method + if ({}.hasOwnProperty) { + api.util.extend = function(obj, props, deep) { + var o, p; + for (var i in props) { + if (props.hasOwnProperty(i)) { + o = obj[i]; + p = props[i]; + if (deep && o !== null && typeof o == "object" && p !== null && typeof p == "object") { + api.util.extend(o, p, true); + } + obj[i] = p; + } + } + // Special case for toString, which does not show up in for...in loops in IE <= 8 + if (props.hasOwnProperty("toString")) { + obj.toString = props.toString; + } + return obj; + }; + } else { + fail("hasOwnProperty not supported"); + } + + // Test whether Array.prototype.slice can be relied on for NodeLists and use an alternative toArray() if not + (function() { + var el = document.createElement("div"); + el.appendChild(document.createElement("span")); + var slice = [].slice; + var toArray; + try { + if (slice.call(el.childNodes, 0)[0].nodeType == 1) { + toArray = function(arrayLike) { + return slice.call(arrayLike, 0); + }; + } + } catch (e) {} + + if (!toArray) { + toArray = function(arrayLike) { + var arr = []; + for (var i = 0, len = arrayLike.length; i < len; ++i) { + arr[i] = arrayLike[i]; + } + return arr; + }; + } + + api.util.toArray = toArray; + })(); + + + // Very simple event handler wrapper function that doesn't attempt to solve issues such as "this" handling or + // normalization of event properties + var addListener; + if (isHostMethod(document, "addEventListener")) { + addListener = function(obj, eventType, listener) { + obj.addEventListener(eventType, listener, false); + }; + } else if (isHostMethod(document, "attachEvent")) { + addListener = function(obj, eventType, listener) { + obj.attachEvent("on" + eventType, listener); + }; + } else { + fail("Document does not have required addEventListener or attachEvent method"); + } + + api.util.addListener = addListener; + + var initListeners = []; + + function getErrorDesc(ex) { + return ex.message || ex.description || String(ex); + } + + // Initialization + function init() { + if (api.initialized) { + return; + } + var testRange; + var implementsDomRange = false, implementsTextRange = false; + + // First, perform basic feature tests + + if (isHostMethod(document, "createRange")) { + testRange = document.createRange(); + if (areHostMethods(testRange, domRangeMethods) && areHostProperties(testRange, domRangeProperties)) { + implementsDomRange = true; + } + } + + var body = getBody(document); + if (!body || body.nodeName.toLowerCase() != "body") { + fail("No body element found"); + return; + } + + if (body && isHostMethod(body, "createTextRange")) { + testRange = body.createTextRange(); + if (isTextRange(testRange)) { + implementsTextRange = true; + } + } + + if (!implementsDomRange && !implementsTextRange) { + fail("Neither Range nor TextRange are available"); + return; + } + + api.initialized = true; + api.features = { + implementsDomRange: implementsDomRange, + implementsTextRange: implementsTextRange + }; + + // Initialize modules + var module, errorMessage; + for (var moduleName in modules) { + if ( (module = modules[moduleName]) instanceof Module ) { + module.init(module, api); + } + } + + // Call init listeners + for (var i = 0, len = initListeners.length; i < len; ++i) { + try { + initListeners[i](api); + } catch (ex) { + errorMessage = "Rangy init listener threw an exception. Continuing. Detail: " + getErrorDesc(ex); + consoleLog(errorMessage); + } + } + } + + // Allow external scripts to initialize this library in case it's loaded after the document has loaded + api.init = init; + + // Execute listener immediately if already initialized + api.addInitListener = function(listener) { + if (api.initialized) { + listener(api); + } else { + initListeners.push(listener); + } + }; + + var shimListeners = []; + + api.addShimListener = function(listener) { + shimListeners.push(listener); + }; + + function shim(win) { + win = win || window; + init(); + + // Notify listeners + for (var i = 0, len = shimListeners.length; i < len; ++i) { + shimListeners[i](win); + } + } + + api.shim = api.createMissingNativeApi = shim; + + function Module(name, dependencies, initializer) { + this.name = name; + this.dependencies = dependencies; + this.initialized = false; + this.supported = false; + this.initializer = initializer; + } + + Module.prototype = { + init: function() { + var requiredModuleNames = this.dependencies || []; + for (var i = 0, len = requiredModuleNames.length, requiredModule, moduleName; i < len; ++i) { + moduleName = requiredModuleNames[i]; + + requiredModule = modules[moduleName]; + if (!requiredModule || !(requiredModule instanceof Module)) { + throw new Error("required module '" + moduleName + "' not found"); + } + + requiredModule.init(); + + if (!requiredModule.supported) { + throw new Error("required module '" + moduleName + "' not supported"); + } + } + + // Now run initializer + this.initializer(this); + }, + + fail: function(reason) { + this.initialized = true; + this.supported = false; + throw new Error("Module '" + this.name + "' failed to load: " + reason); + }, + + warn: function(msg) { + api.warn("Module " + this.name + ": " + msg); + }, + + deprecationNotice: function(deprecated, replacement) { + api.warn("DEPRECATED: " + deprecated + " in module " + this.name + "is deprecated. Please use " + + replacement + " instead"); + }, + + createError: function(msg) { + return new Error("Error in Rangy " + this.name + " module: " + msg); + } + }; + + function createModule(isCore, name, dependencies, initFunc) { + var newModule = new Module(name, dependencies, function(module) { + if (!module.initialized) { + module.initialized = true; + try { + initFunc(api, module); + module.supported = true; + } catch (ex) { + var errorMessage = "Module '" + name + "' failed to load: " + getErrorDesc(ex); + consoleLog(errorMessage); + } + } + }); + modules[name] = newModule; + } + + api.createModule = function(name) { + // Allow 2 or 3 arguments (second argument is an optional array of dependencies) + var initFunc, dependencies; + if (arguments.length == 2) { + initFunc = arguments[1]; + dependencies = []; + } else { + initFunc = arguments[2]; + dependencies = arguments[1]; + } + + var module = createModule(false, name, dependencies, initFunc); + + // Initialize the module immediately if the core is already initialized + if (api.initialized) { + module.init(); + } + }; + + api.createCoreModule = function(name, dependencies, initFunc) { + createModule(true, name, dependencies, initFunc); + }; + + /*----------------------------------------------------------------------------------------------------------------*/ + + // Ensure rangy.rangePrototype and rangy.selectionPrototype are available immediately + + function RangePrototype() {} + api.RangePrototype = RangePrototype; + api.rangePrototype = new RangePrototype(); + + function SelectionPrototype() {} + api.selectionPrototype = new SelectionPrototype(); + + /*----------------------------------------------------------------------------------------------------------------*/ + + // Wait for document to load before running tests + + var docReady = false; + + var loadHandler = function(e) { + if (!docReady) { + docReady = true; + if (!api.initialized && api.config.autoInitialize) { + init(); + } + } + }; + + // Test whether we have window and document objects that we will need + if (typeof window == UNDEFINED) { + fail("No window found"); + return; + } + if (typeof document == UNDEFINED) { + fail("No document found"); + return; + } + + if (isHostMethod(document, "addEventListener")) { + document.addEventListener("DOMContentLoaded", loadHandler, false); + } + + // Add a fallback in case the DOMContentLoaded event isn't supported + addListener(window, "load", loadHandler); + + /*----------------------------------------------------------------------------------------------------------------*/ + + // DOM utility methods used by Rangy + api.createCoreModule("DomUtil", [], function(api, module) { + var UNDEF = "undefined"; + var util = api.util; + + // Perform feature tests + if (!util.areHostMethods(document, ["createDocumentFragment", "createElement", "createTextNode"])) { + module.fail("document missing a Node creation method"); + } + + if (!util.isHostMethod(document, "getElementsByTagName")) { + module.fail("document missing getElementsByTagName method"); + } + + var el = document.createElement("div"); + if (!util.areHostMethods(el, ["insertBefore", "appendChild", "cloneNode"] || + !util.areHostObjects(el, ["previousSibling", "nextSibling", "childNodes", "parentNode"]))) { + module.fail("Incomplete Element implementation"); + } + + // innerHTML is required for Range's createContextualFragment method + if (!util.isHostProperty(el, "innerHTML")) { + module.fail("Element is missing innerHTML property"); + } + + var textNode = document.createTextNode("test"); + if (!util.areHostMethods(textNode, ["splitText", "deleteData", "insertData", "appendData", "cloneNode"] || + !util.areHostObjects(el, ["previousSibling", "nextSibling", "childNodes", "parentNode"]) || + !util.areHostProperties(textNode, ["data"]))) { + module.fail("Incomplete Text Node implementation"); + } + + /*----------------------------------------------------------------------------------------------------------------*/ + + // Removed use of indexOf because of a bizarre bug in Opera that is thrown in one of the Acid3 tests. I haven't been + // able to replicate it outside of the test. The bug is that indexOf returns -1 when called on an Array that + // contains just the document as a single element and the value searched for is the document. + var arrayContains = /*Array.prototype.indexOf ? + function(arr, val) { + return arr.indexOf(val) > -1; + }:*/ + + function(arr, val) { + var i = arr.length; + while (i--) { + if (arr[i] === val) { + return true; + } + } + return false; + }; + + // Opera 11 puts HTML elements in the null namespace, it seems, and IE 7 has undefined namespaceURI + function isHtmlNamespace(node) { + var ns; + return typeof node.namespaceURI == UNDEF || ((ns = node.namespaceURI) === null || ns == "http://www.w3.org/1999/xhtml"); + } + + function parentElement(node) { + var parent = node.parentNode; + return (parent.nodeType == 1) ? parent : null; + } + + function getNodeIndex(node) { + var i = 0; + while( (node = node.previousSibling) ) { + ++i; + } + return i; + } + + function getNodeLength(node) { + switch (node.nodeType) { + case 7: + case 10: + return 0; + case 3: + case 8: + return node.length; + default: + return node.childNodes.length; + } + } + + function getCommonAncestor(node1, node2) { + var ancestors = [], n; + for (n = node1; n; n = n.parentNode) { + ancestors.push(n); + } + + for (n = node2; n; n = n.parentNode) { + if (arrayContains(ancestors, n)) { + return n; + } + } + + return null; + } + + function isAncestorOf(ancestor, descendant, selfIsAncestor) { + var n = selfIsAncestor ? descendant : descendant.parentNode; + while (n) { + if (n === ancestor) { + return true; + } else { + n = n.parentNode; + } + } + return false; + } + + function isOrIsAncestorOf(ancestor, descendant) { + return isAncestorOf(ancestor, descendant, true); + } + + function getClosestAncestorIn(node, ancestor, selfIsAncestor) { + var p, n = selfIsAncestor ? node : node.parentNode; + while (n) { + p = n.parentNode; + if (p === ancestor) { + return n; + } + n = p; + } + return null; + } + + function isCharacterDataNode(node) { + var t = node.nodeType; + return t == 3 || t == 4 || t == 8 ; // Text, CDataSection or Comment + } + + function isTextOrCommentNode(node) { + if (!node) { + return false; + } + var t = node.nodeType; + return t == 3 || t == 8 ; // Text or Comment + } + + function insertAfter(node, precedingNode) { + var nextNode = precedingNode.nextSibling, parent = precedingNode.parentNode; + if (nextNode) { + parent.insertBefore(node, nextNode); + } else { + parent.appendChild(node); + } + return node; + } + + // Note that we cannot use splitText() because it is bugridden in IE 9. + function splitDataNode(node, index, positionsToPreserve) { + var newNode = node.cloneNode(false); + newNode.deleteData(0, index); + node.deleteData(index, node.length - index); + insertAfter(newNode, node); + + // Preserve positions + if (positionsToPreserve) { + for (var i = 0, position; position = positionsToPreserve[i++]; ) { + // Handle case where position was inside the portion of node after the split point + if (position.node == node && position.offset > index) { + position.node = newNode; + position.offset -= index; + } + // Handle the case where the position is a node offset within node's parent + else if (position.node == node.parentNode && position.offset > getNodeIndex(node)) { + ++position.offset; + } + } + } + return newNode; + } + + function getDocument(node) { + if (node.nodeType == 9) { + return node; + } else if (typeof node.ownerDocument != UNDEF) { + return node.ownerDocument; + } else if (typeof node.document != UNDEF) { + return node.document; + } else if (node.parentNode) { + return getDocument(node.parentNode); + } else { + throw module.createError("getDocument: no document found for node"); + } + } + + function getWindow(node) { + var doc = getDocument(node); + if (typeof doc.defaultView != UNDEF) { + return doc.defaultView; + } else if (typeof doc.parentWindow != UNDEF) { + return doc.parentWindow; + } else { + throw module.createError("Cannot get a window object for node"); + } + } + + function getIframeDocument(iframeEl) { + if (typeof iframeEl.contentDocument != UNDEF) { + return iframeEl.contentDocument; + } else if (typeof iframeEl.contentWindow != UNDEF) { + return iframeEl.contentWindow.document; + } else { + throw module.createError("getIframeDocument: No Document object found for iframe element"); + } + } + + function getIframeWindow(iframeEl) { + if (typeof iframeEl.contentWindow != UNDEF) { + return iframeEl.contentWindow; + } else if (typeof iframeEl.contentDocument != UNDEF) { + return iframeEl.contentDocument.defaultView; + } else { + throw module.createError("getIframeWindow: No Window object found for iframe element"); + } + } + + // This looks bad. Is it worth it? + function isWindow(obj) { + return obj && util.isHostMethod(obj, "setTimeout") && util.isHostObject(obj, "document"); + } + + function getContentDocument(obj, module, methodName) { + var doc; + + if (!obj) { + doc = document; + } + + // Test if a DOM node has been passed and obtain a document object for it if so + else if (util.isHostProperty(obj, "nodeType")) { + doc = (obj.nodeType == 1 && obj.tagName.toLowerCase() == "iframe") ? + getIframeDocument(obj) : getDocument(obj); + } + + // Test if the doc parameter appears to be a Window object + else if (isWindow(obj)) { + doc = obj.document; + } + + if (!doc) { + throw module.createError(methodName + "(): Parameter must be a Window object or DOM node"); + } + + return doc; + } + + function getRootContainer(node) { + var parent; + while ( (parent = node.parentNode) ) { + node = parent; + } + return node; + } + + function comparePoints(nodeA, offsetA, nodeB, offsetB) { + // See http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Comparing + var nodeC, root, childA, childB, n; + if (nodeA == nodeB) { + // Case 1: nodes are the same + return offsetA === offsetB ? 0 : (offsetA < offsetB) ? -1 : 1; + } else if ( (nodeC = getClosestAncestorIn(nodeB, nodeA, true)) ) { + // Case 2: node C (container B or an ancestor) is a child node of A + return offsetA <= getNodeIndex(nodeC) ? -1 : 1; + } else if ( (nodeC = getClosestAncestorIn(nodeA, nodeB, true)) ) { + // Case 3: node C (container A or an ancestor) is a child node of B + return getNodeIndex(nodeC) < offsetB ? -1 : 1; + } else { + root = getCommonAncestor(nodeA, nodeB); + if (!root) { + throw new Error("comparePoints error: nodes have no common ancestor"); + } + + // Case 4: containers are siblings or descendants of siblings + childA = (nodeA === root) ? root : getClosestAncestorIn(nodeA, root, true); + childB = (nodeB === root) ? root : getClosestAncestorIn(nodeB, root, true); + + if (childA === childB) { + // This shouldn't be possible + throw module.createError("comparePoints got to case 4 and childA and childB are the same!"); + } else { + n = root.firstChild; + while (n) { + if (n === childA) { + return -1; + } else if (n === childB) { + return 1; + } + n = n.nextSibling; + } + } + } + } + + /*----------------------------------------------------------------------------------------------------------------*/ + + // Test for IE's crash (IE 6/7) or exception (IE >= 8) when a reference to garbage-collected text node is queried + var crashyTextNodes = false; + + function isBrokenNode(node) { + var n; + try { + n = node.parentNode; + return false; + } catch (e) { + return true; + } + } + + (function() { + var el = document.createElement("b"); + el.innerHTML = "1"; + var textNode = el.firstChild; + el.innerHTML = "
    "; + crashyTextNodes = isBrokenNode(textNode); + + api.features.crashyTextNodes = crashyTextNodes; + })(); + + /*----------------------------------------------------------------------------------------------------------------*/ + + function inspectNode(node) { + if (!node) { + return "[No node]"; + } + if (crashyTextNodes && isBrokenNode(node)) { + return "[Broken node]"; + } + if (isCharacterDataNode(node)) { + return '"' + node.data + '"'; + } + if (node.nodeType == 1) { + var idAttr = node.id ? ' id="' + node.id + '"' : ""; + return "<" + node.nodeName + idAttr + ">[index:" + getNodeIndex(node) + ",length:" + node.childNodes.length + "][" + (node.innerHTML || "[innerHTML not supported]").slice(0, 25) + "]"; + } + return node.nodeName; + } + + function fragmentFromNodeChildren(node) { + var fragment = getDocument(node).createDocumentFragment(), child; + while ( (child = node.firstChild) ) { + fragment.appendChild(child); + } + return fragment; + } + + var getComputedStyleProperty; + if (typeof window.getComputedStyle != UNDEF) { + getComputedStyleProperty = function(el, propName) { + return getWindow(el).getComputedStyle(el, null)[propName]; + }; + } else if (typeof document.documentElement.currentStyle != UNDEF) { + getComputedStyleProperty = function(el, propName) { + return el.currentStyle[propName]; + }; + } else { + module.fail("No means of obtaining computed style properties found"); + } + + function NodeIterator(root) { + this.root = root; + this._next = root; + } + + NodeIterator.prototype = { + _current: null, + + hasNext: function() { + return !!this._next; + }, + + next: function() { + var n = this._current = this._next; + var child, next; + if (this._current) { + child = n.firstChild; + if (child) { + this._next = child; + } else { + next = null; + while ((n !== this.root) && !(next = n.nextSibling)) { + n = n.parentNode; + } + this._next = next; + } + } + return this._current; + }, + + detach: function() { + this._current = this._next = this.root = null; + } + }; + + function createIterator(root) { + return new NodeIterator(root); + } + + function DomPosition(node, offset) { + this.node = node; + this.offset = offset; + } + + DomPosition.prototype = { + equals: function(pos) { + return !!pos && this.node === pos.node && this.offset == pos.offset; + }, + + inspect: function() { + return "[DomPosition(" + inspectNode(this.node) + ":" + this.offset + ")]"; + }, + + toString: function() { + return this.inspect(); + } + }; + + function DOMException(codeName) { + this.code = this[codeName]; + this.codeName = codeName; + this.message = "DOMException: " + this.codeName; + } + + DOMException.prototype = { + INDEX_SIZE_ERR: 1, + HIERARCHY_REQUEST_ERR: 3, + WRONG_DOCUMENT_ERR: 4, + NO_MODIFICATION_ALLOWED_ERR: 7, + NOT_FOUND_ERR: 8, + NOT_SUPPORTED_ERR: 9, + INVALID_STATE_ERR: 11, + INVALID_NODE_TYPE_ERR: 24 + }; + + DOMException.prototype.toString = function() { + return this.message; + }; + + api.dom = { + arrayContains: arrayContains, + isHtmlNamespace: isHtmlNamespace, + parentElement: parentElement, + getNodeIndex: getNodeIndex, + getNodeLength: getNodeLength, + getCommonAncestor: getCommonAncestor, + isAncestorOf: isAncestorOf, + isOrIsAncestorOf: isOrIsAncestorOf, + getClosestAncestorIn: getClosestAncestorIn, + isCharacterDataNode: isCharacterDataNode, + isTextOrCommentNode: isTextOrCommentNode, + insertAfter: insertAfter, + splitDataNode: splitDataNode, + getDocument: getDocument, + getWindow: getWindow, + getIframeWindow: getIframeWindow, + getIframeDocument: getIframeDocument, + getBody: util.getBody, + isWindow: isWindow, + getContentDocument: getContentDocument, + getRootContainer: getRootContainer, + comparePoints: comparePoints, + isBrokenNode: isBrokenNode, + inspectNode: inspectNode, + getComputedStyleProperty: getComputedStyleProperty, + fragmentFromNodeChildren: fragmentFromNodeChildren, + createIterator: createIterator, + DomPosition: DomPosition + }; + + api.DOMException = DOMException; + }); + + /*----------------------------------------------------------------------------------------------------------------*/ + + // Pure JavaScript implementation of DOM Range + api.createCoreModule("DomRange", ["DomUtil"], function(api, module) { + var dom = api.dom; + var util = api.util; + var DomPosition = dom.DomPosition; + var DOMException = api.DOMException; + + var isCharacterDataNode = dom.isCharacterDataNode; + var getNodeIndex = dom.getNodeIndex; + var isOrIsAncestorOf = dom.isOrIsAncestorOf; + var getDocument = dom.getDocument; + var comparePoints = dom.comparePoints; + var splitDataNode = dom.splitDataNode; + var getClosestAncestorIn = dom.getClosestAncestorIn; + var getNodeLength = dom.getNodeLength; + var arrayContains = dom.arrayContains; + var getRootContainer = dom.getRootContainer; + var crashyTextNodes = api.features.crashyTextNodes; + + /*----------------------------------------------------------------------------------------------------------------*/ + + // Utility functions + + function isNonTextPartiallySelected(node, range) { + return (node.nodeType != 3) && + (isOrIsAncestorOf(node, range.startContainer) || isOrIsAncestorOf(node, range.endContainer)); + } + + function getRangeDocument(range) { + return range.document || getDocument(range.startContainer); + } + + function getBoundaryBeforeNode(node) { + return new DomPosition(node.parentNode, getNodeIndex(node)); + } + + function getBoundaryAfterNode(node) { + return new DomPosition(node.parentNode, getNodeIndex(node) + 1); + } + + function insertNodeAtPosition(node, n, o) { + var firstNodeInserted = node.nodeType == 11 ? node.firstChild : node; + if (isCharacterDataNode(n)) { + if (o == n.length) { + dom.insertAfter(node, n); + } else { + n.parentNode.insertBefore(node, o == 0 ? n : splitDataNode(n, o)); + } + } else if (o >= n.childNodes.length) { + n.appendChild(node); + } else { + n.insertBefore(node, n.childNodes[o]); + } + return firstNodeInserted; + } + + function rangesIntersect(rangeA, rangeB, touchingIsIntersecting) { + assertRangeValid(rangeA); + assertRangeValid(rangeB); + + if (getRangeDocument(rangeB) != getRangeDocument(rangeA)) { + throw new DOMException("WRONG_DOCUMENT_ERR"); + } + + var startComparison = comparePoints(rangeA.startContainer, rangeA.startOffset, rangeB.endContainer, rangeB.endOffset), + endComparison = comparePoints(rangeA.endContainer, rangeA.endOffset, rangeB.startContainer, rangeB.startOffset); + + return touchingIsIntersecting ? startComparison <= 0 && endComparison >= 0 : startComparison < 0 && endComparison > 0; + } + + function cloneSubtree(iterator) { + var partiallySelected; + for (var node, frag = getRangeDocument(iterator.range).createDocumentFragment(), subIterator; node = iterator.next(); ) { + partiallySelected = iterator.isPartiallySelectedSubtree(); + node = node.cloneNode(!partiallySelected); + if (partiallySelected) { + subIterator = iterator.getSubtreeIterator(); + node.appendChild(cloneSubtree(subIterator)); + subIterator.detach(); + } + + if (node.nodeType == 10) { // DocumentType + throw new DOMException("HIERARCHY_REQUEST_ERR"); + } + frag.appendChild(node); + } + return frag; + } + + function iterateSubtree(rangeIterator, func, iteratorState) { + var it, n; + iteratorState = iteratorState || { stop: false }; + for (var node, subRangeIterator; node = rangeIterator.next(); ) { + if (rangeIterator.isPartiallySelectedSubtree()) { + if (func(node) === false) { + iteratorState.stop = true; + return; + } else { + // The node is partially selected by the Range, so we can use a new RangeIterator on the portion of + // the node selected by the Range. + subRangeIterator = rangeIterator.getSubtreeIterator(); + iterateSubtree(subRangeIterator, func, iteratorState); + subRangeIterator.detach(); + if (iteratorState.stop) { + return; + } + } + } else { + // The whole node is selected, so we can use efficient DOM iteration to iterate over the node and its + // descendants + it = dom.createIterator(node); + while ( (n = it.next()) ) { + if (func(n) === false) { + iteratorState.stop = true; + return; + } + } + } + } + } + + function deleteSubtree(iterator) { + var subIterator; + while (iterator.next()) { + if (iterator.isPartiallySelectedSubtree()) { + subIterator = iterator.getSubtreeIterator(); + deleteSubtree(subIterator); + subIterator.detach(); + } else { + iterator.remove(); + } + } + } + + function extractSubtree(iterator) { + for (var node, frag = getRangeDocument(iterator.range).createDocumentFragment(), subIterator; node = iterator.next(); ) { + + if (iterator.isPartiallySelectedSubtree()) { + node = node.cloneNode(false); + subIterator = iterator.getSubtreeIterator(); + node.appendChild(extractSubtree(subIterator)); + subIterator.detach(); + } else { + iterator.remove(); + } + if (node.nodeType == 10) { // DocumentType + throw new DOMException("HIERARCHY_REQUEST_ERR"); + } + frag.appendChild(node); + } + return frag; + } + + function getNodesInRange(range, nodeTypes, filter) { + var filterNodeTypes = !!(nodeTypes && nodeTypes.length), regex; + var filterExists = !!filter; + if (filterNodeTypes) { + regex = new RegExp("^(" + nodeTypes.join("|") + ")$"); + } + + var nodes = []; + iterateSubtree(new RangeIterator(range, false), function(node) { + if (filterNodeTypes && !regex.test(node.nodeType)) { + return; + } + if (filterExists && !filter(node)) { + return; + } + // Don't include a boundary container if it is a character data node and the range does not contain any + // of its character data. See issue 190. + var sc = range.startContainer; + if (node == sc && isCharacterDataNode(sc) && range.startOffset == sc.length) { + return; + } + + var ec = range.endContainer; + if (node == ec && isCharacterDataNode(ec) && range.endOffset == 0) { + return; + } + + nodes.push(node); + }); + return nodes; + } + + function inspect(range) { + var name = (typeof range.getName == "undefined") ? "Range" : range.getName(); + return "[" + name + "(" + dom.inspectNode(range.startContainer) + ":" + range.startOffset + ", " + + dom.inspectNode(range.endContainer) + ":" + range.endOffset + ")]"; + } + + /*----------------------------------------------------------------------------------------------------------------*/ + + // RangeIterator code partially borrows from IERange by Tim Ryan (http://github.com/timcameronryan/IERange) + + function RangeIterator(range, clonePartiallySelectedTextNodes) { + this.range = range; + this.clonePartiallySelectedTextNodes = clonePartiallySelectedTextNodes; + + + if (!range.collapsed) { + this.sc = range.startContainer; + this.so = range.startOffset; + this.ec = range.endContainer; + this.eo = range.endOffset; + var root = range.commonAncestorContainer; + + if (this.sc === this.ec && isCharacterDataNode(this.sc)) { + this.isSingleCharacterDataNode = true; + this._first = this._last = this._next = this.sc; + } else { + this._first = this._next = (this.sc === root && !isCharacterDataNode(this.sc)) ? + this.sc.childNodes[this.so] : getClosestAncestorIn(this.sc, root, true); + this._last = (this.ec === root && !isCharacterDataNode(this.ec)) ? + this.ec.childNodes[this.eo - 1] : getClosestAncestorIn(this.ec, root, true); + } + } + } + + RangeIterator.prototype = { + _current: null, + _next: null, + _first: null, + _last: null, + isSingleCharacterDataNode: false, + + reset: function() { + this._current = null; + this._next = this._first; + }, + + hasNext: function() { + return !!this._next; + }, + + next: function() { + // Move to next node + var current = this._current = this._next; + if (current) { + this._next = (current !== this._last) ? current.nextSibling : null; + + // Check for partially selected text nodes + if (isCharacterDataNode(current) && this.clonePartiallySelectedTextNodes) { + if (current === this.ec) { + (current = current.cloneNode(true)).deleteData(this.eo, current.length - this.eo); + } + if (this._current === this.sc) { + (current = current.cloneNode(true)).deleteData(0, this.so); + } + } + } + + return current; + }, + + remove: function() { + var current = this._current, start, end; + + if (isCharacterDataNode(current) && (current === this.sc || current === this.ec)) { + start = (current === this.sc) ? this.so : 0; + end = (current === this.ec) ? this.eo : current.length; + if (start != end) { + current.deleteData(start, end - start); + } + } else { + if (current.parentNode) { + current.parentNode.removeChild(current); + } else { + } + } + }, + + // Checks if the current node is partially selected + isPartiallySelectedSubtree: function() { + var current = this._current; + return isNonTextPartiallySelected(current, this.range); + }, + + getSubtreeIterator: function() { + var subRange; + if (this.isSingleCharacterDataNode) { + subRange = this.range.cloneRange(); + subRange.collapse(false); + } else { + subRange = new Range(getRangeDocument(this.range)); + var current = this._current; + var startContainer = current, startOffset = 0, endContainer = current, endOffset = getNodeLength(current); + + if (isOrIsAncestorOf(current, this.sc)) { + startContainer = this.sc; + startOffset = this.so; + } + if (isOrIsAncestorOf(current, this.ec)) { + endContainer = this.ec; + endOffset = this.eo; + } + + updateBoundaries(subRange, startContainer, startOffset, endContainer, endOffset); + } + return new RangeIterator(subRange, this.clonePartiallySelectedTextNodes); + }, + + detach: function() { + this.range = this._current = this._next = this._first = this._last = this.sc = this.so = this.ec = this.eo = null; + } + }; + + /*----------------------------------------------------------------------------------------------------------------*/ + + var beforeAfterNodeTypes = [1, 3, 4, 5, 7, 8, 10]; + var rootContainerNodeTypes = [2, 9, 11]; + var readonlyNodeTypes = [5, 6, 10, 12]; + var insertableNodeTypes = [1, 3, 4, 5, 7, 8, 10, 11]; + var surroundNodeTypes = [1, 3, 4, 5, 7, 8]; + + function createAncestorFinder(nodeTypes) { + return function(node, selfIsAncestor) { + var t, n = selfIsAncestor ? node : node.parentNode; + while (n) { + t = n.nodeType; + if (arrayContains(nodeTypes, t)) { + return n; + } + n = n.parentNode; + } + return null; + }; + } + + var getDocumentOrFragmentContainer = createAncestorFinder( [9, 11] ); + var getReadonlyAncestor = createAncestorFinder(readonlyNodeTypes); + var getDocTypeNotationEntityAncestor = createAncestorFinder( [6, 10, 12] ); + + function assertNoDocTypeNotationEntityAncestor(node, allowSelf) { + if (getDocTypeNotationEntityAncestor(node, allowSelf)) { + throw new DOMException("INVALID_NODE_TYPE_ERR"); + } + } + + function assertValidNodeType(node, invalidTypes) { + if (!arrayContains(invalidTypes, node.nodeType)) { + throw new DOMException("INVALID_NODE_TYPE_ERR"); + } + } + + function assertValidOffset(node, offset) { + if (offset < 0 || offset > (isCharacterDataNode(node) ? node.length : node.childNodes.length)) { + throw new DOMException("INDEX_SIZE_ERR"); + } + } + + function assertSameDocumentOrFragment(node1, node2) { + if (getDocumentOrFragmentContainer(node1, true) !== getDocumentOrFragmentContainer(node2, true)) { + throw new DOMException("WRONG_DOCUMENT_ERR"); + } + } + + function assertNodeNotReadOnly(node) { + if (getReadonlyAncestor(node, true)) { + throw new DOMException("NO_MODIFICATION_ALLOWED_ERR"); + } + } + + function assertNode(node, codeName) { + if (!node) { + throw new DOMException(codeName); + } + } + + function isOrphan(node) { + return (crashyTextNodes && dom.isBrokenNode(node)) || + !arrayContains(rootContainerNodeTypes, node.nodeType) && !getDocumentOrFragmentContainer(node, true); + } + + function isValidOffset(node, offset) { + return offset <= (isCharacterDataNode(node) ? node.length : node.childNodes.length); + } + + function isRangeValid(range) { + return (!!range.startContainer && !!range.endContainer && + !isOrphan(range.startContainer) && + !isOrphan(range.endContainer) && + isValidOffset(range.startContainer, range.startOffset) && + isValidOffset(range.endContainer, range.endOffset)); + } + + function assertRangeValid(range) { + if (!isRangeValid(range)) { + throw new Error("Range error: Range is no longer valid after DOM mutation (" + range.inspect() + ")"); + } + } + + /*----------------------------------------------------------------------------------------------------------------*/ + + // Test the browser's innerHTML support to decide how to implement createContextualFragment + var styleEl = document.createElement("style"); + var htmlParsingConforms = false; + try { + styleEl.innerHTML = "x"; + htmlParsingConforms = (styleEl.firstChild.nodeType == 3); // Opera incorrectly creates an element node + } catch (e) { + // IE 6 and 7 throw + } + + api.features.htmlParsingConforms = htmlParsingConforms; + + var createContextualFragment = htmlParsingConforms ? + + // Implementation as per HTML parsing spec, trusting in the browser's implementation of innerHTML. See + // discussion and base code for this implementation at issue 67. + // Spec: http://html5.org/specs/dom-parsing.html#extensions-to-the-range-interface + // Thanks to Aleks Williams. + function(fragmentStr) { + // "Let node the context object's start's node." + var node = this.startContainer; + var doc = getDocument(node); + + // "If the context object's start's node is null, raise an INVALID_STATE_ERR + // exception and abort these steps." + if (!node) { + throw new DOMException("INVALID_STATE_ERR"); + } + + // "Let element be as follows, depending on node's interface:" + // Document, Document Fragment: null + var el = null; + + // "Element: node" + if (node.nodeType == 1) { + el = node; + + // "Text, Comment: node's parentElement" + } else if (isCharacterDataNode(node)) { + el = dom.parentElement(node); + } + + // "If either element is null or element's ownerDocument is an HTML document + // and element's local name is "html" and element's namespace is the HTML + // namespace" + if (el === null || ( + el.nodeName == "HTML" && + dom.isHtmlNamespace(getDocument(el).documentElement) && + dom.isHtmlNamespace(el) + )) { + + // "let element be a new Element with "body" as its local name and the HTML + // namespace as its namespace."" + el = doc.createElement("body"); + } else { + el = el.cloneNode(false); + } + + // "If the node's document is an HTML document: Invoke the HTML fragment parsing algorithm." + // "If the node's document is an XML document: Invoke the XML fragment parsing algorithm." + // "In either case, the algorithm must be invoked with fragment as the input + // and element as the context element." + el.innerHTML = fragmentStr; + + // "If this raises an exception, then abort these steps. Otherwise, let new + // children be the nodes returned." + + // "Let fragment be a new DocumentFragment." + // "Append all new children to fragment." + // "Return fragment." + return dom.fragmentFromNodeChildren(el); + } : + + // In this case, innerHTML cannot be trusted, so fall back to a simpler, non-conformant implementation that + // previous versions of Rangy used (with the exception of using a body element rather than a div) + function(fragmentStr) { + var doc = getRangeDocument(this); + var el = doc.createElement("body"); + el.innerHTML = fragmentStr; + + return dom.fragmentFromNodeChildren(el); + }; + + function splitRangeBoundaries(range, positionsToPreserve) { + assertRangeValid(range); + + var sc = range.startContainer, so = range.startOffset, ec = range.endContainer, eo = range.endOffset; + var startEndSame = (sc === ec); + + if (isCharacterDataNode(ec) && eo > 0 && eo < ec.length) { + splitDataNode(ec, eo, positionsToPreserve); + } + + if (isCharacterDataNode(sc) && so > 0 && so < sc.length) { + sc = splitDataNode(sc, so, positionsToPreserve); + if (startEndSame) { + eo -= so; + ec = sc; + } else if (ec == sc.parentNode && eo >= getNodeIndex(sc)) { + eo++; + } + so = 0; + } + range.setStartAndEnd(sc, so, ec, eo); + } + + function rangeToHtml(range) { + assertRangeValid(range); + var container = range.commonAncestorContainer.parentNode.cloneNode(false); + container.appendChild( range.cloneContents() ); + return container.innerHTML; + } + + /*----------------------------------------------------------------------------------------------------------------*/ + + var rangeProperties = ["startContainer", "startOffset", "endContainer", "endOffset", "collapsed", + "commonAncestorContainer"]; + + var s2s = 0, s2e = 1, e2e = 2, e2s = 3; + var n_b = 0, n_a = 1, n_b_a = 2, n_i = 3; + + util.extend(api.rangePrototype, { + compareBoundaryPoints: function(how, range) { + assertRangeValid(this); + assertSameDocumentOrFragment(this.startContainer, range.startContainer); + + var nodeA, offsetA, nodeB, offsetB; + var prefixA = (how == e2s || how == s2s) ? "start" : "end"; + var prefixB = (how == s2e || how == s2s) ? "start" : "end"; + nodeA = this[prefixA + "Container"]; + offsetA = this[prefixA + "Offset"]; + nodeB = range[prefixB + "Container"]; + offsetB = range[prefixB + "Offset"]; + return comparePoints(nodeA, offsetA, nodeB, offsetB); + }, + + insertNode: function(node) { + assertRangeValid(this); + assertValidNodeType(node, insertableNodeTypes); + assertNodeNotReadOnly(this.startContainer); + + if (isOrIsAncestorOf(node, this.startContainer)) { + throw new DOMException("HIERARCHY_REQUEST_ERR"); + } + + // No check for whether the container of the start of the Range is of a type that does not allow + // children of the type of node: the browser's DOM implementation should do this for us when we attempt + // to add the node + + var firstNodeInserted = insertNodeAtPosition(node, this.startContainer, this.startOffset); + this.setStartBefore(firstNodeInserted); + }, + + cloneContents: function() { + assertRangeValid(this); + + var clone, frag; + if (this.collapsed) { + return getRangeDocument(this).createDocumentFragment(); + } else { + if (this.startContainer === this.endContainer && isCharacterDataNode(this.startContainer)) { + clone = this.startContainer.cloneNode(true); + clone.data = clone.data.slice(this.startOffset, this.endOffset); + frag = getRangeDocument(this).createDocumentFragment(); + frag.appendChild(clone); + return frag; + } else { + var iterator = new RangeIterator(this, true); + clone = cloneSubtree(iterator); + iterator.detach(); + } + return clone; + } + }, + + canSurroundContents: function() { + assertRangeValid(this); + assertNodeNotReadOnly(this.startContainer); + assertNodeNotReadOnly(this.endContainer); + + // Check if the contents can be surrounded. Specifically, this means whether the range partially selects + // no non-text nodes. + var iterator = new RangeIterator(this, true); + var boundariesInvalid = (iterator._first && (isNonTextPartiallySelected(iterator._first, this)) || + (iterator._last && isNonTextPartiallySelected(iterator._last, this))); + iterator.detach(); + return !boundariesInvalid; + }, + + surroundContents: function(node) { + assertValidNodeType(node, surroundNodeTypes); + + if (!this.canSurroundContents()) { + throw new DOMException("INVALID_STATE_ERR"); + } + + // Extract the contents + var content = this.extractContents(); + + // Clear the children of the node + if (node.hasChildNodes()) { + while (node.lastChild) { + node.removeChild(node.lastChild); + } + } + + // Insert the new node and add the extracted contents + insertNodeAtPosition(node, this.startContainer, this.startOffset); + node.appendChild(content); + + this.selectNode(node); + }, + + cloneRange: function() { + assertRangeValid(this); + var range = new Range(getRangeDocument(this)); + var i = rangeProperties.length, prop; + while (i--) { + prop = rangeProperties[i]; + range[prop] = this[prop]; + } + return range; + }, + + toString: function() { + assertRangeValid(this); + var sc = this.startContainer; + if (sc === this.endContainer && isCharacterDataNode(sc)) { + return (sc.nodeType == 3 || sc.nodeType == 4) ? sc.data.slice(this.startOffset, this.endOffset) : ""; + } else { + var textParts = [], iterator = new RangeIterator(this, true); + iterateSubtree(iterator, function(node) { + // Accept only text or CDATA nodes, not comments + if (node.nodeType == 3 || node.nodeType == 4) { + textParts.push(node.data); + } + }); + iterator.detach(); + return textParts.join(""); + } + }, + + // The methods below are all non-standard. The following batch were introduced by Mozilla but have since + // been removed from Mozilla. + + compareNode: function(node) { + assertRangeValid(this); + + var parent = node.parentNode; + var nodeIndex = getNodeIndex(node); + + if (!parent) { + throw new DOMException("NOT_FOUND_ERR"); + } + + var startComparison = this.comparePoint(parent, nodeIndex), + endComparison = this.comparePoint(parent, nodeIndex + 1); + + if (startComparison < 0) { // Node starts before + return (endComparison > 0) ? n_b_a : n_b; + } else { + return (endComparison > 0) ? n_a : n_i; + } + }, + + comparePoint: function(node, offset) { + assertRangeValid(this); + assertNode(node, "HIERARCHY_REQUEST_ERR"); + assertSameDocumentOrFragment(node, this.startContainer); + + if (comparePoints(node, offset, this.startContainer, this.startOffset) < 0) { + return -1; + } else if (comparePoints(node, offset, this.endContainer, this.endOffset) > 0) { + return 1; + } + return 0; + }, + + createContextualFragment: createContextualFragment, + + toHtml: function() { + return rangeToHtml(this); + }, + + // touchingIsIntersecting determines whether this method considers a node that borders a range intersects + // with it (as in WebKit) or not (as in Gecko pre-1.9, and the default) + intersectsNode: function(node, touchingIsIntersecting) { + assertRangeValid(this); + assertNode(node, "NOT_FOUND_ERR"); + if (getDocument(node) !== getRangeDocument(this)) { + return false; + } + + var parent = node.parentNode, offset = getNodeIndex(node); + assertNode(parent, "NOT_FOUND_ERR"); + + var startComparison = comparePoints(parent, offset, this.endContainer, this.endOffset), + endComparison = comparePoints(parent, offset + 1, this.startContainer, this.startOffset); + + return touchingIsIntersecting ? startComparison <= 0 && endComparison >= 0 : startComparison < 0 && endComparison > 0; + }, + + isPointInRange: function(node, offset) { + assertRangeValid(this); + assertNode(node, "HIERARCHY_REQUEST_ERR"); + assertSameDocumentOrFragment(node, this.startContainer); + + return (comparePoints(node, offset, this.startContainer, this.startOffset) >= 0) && + (comparePoints(node, offset, this.endContainer, this.endOffset) <= 0); + }, + + // The methods below are non-standard and invented by me. + + // Sharing a boundary start-to-end or end-to-start does not count as intersection. + intersectsRange: function(range) { + return rangesIntersect(this, range, false); + }, + + // Sharing a boundary start-to-end or end-to-start does count as intersection. + intersectsOrTouchesRange: function(range) { + return rangesIntersect(this, range, true); + }, + + intersection: function(range) { + if (this.intersectsRange(range)) { + var startComparison = comparePoints(this.startContainer, this.startOffset, range.startContainer, range.startOffset), + endComparison = comparePoints(this.endContainer, this.endOffset, range.endContainer, range.endOffset); + + var intersectionRange = this.cloneRange(); + if (startComparison == -1) { + intersectionRange.setStart(range.startContainer, range.startOffset); + } + if (endComparison == 1) { + intersectionRange.setEnd(range.endContainer, range.endOffset); + } + return intersectionRange; + } + return null; + }, + + union: function(range) { + if (this.intersectsOrTouchesRange(range)) { + var unionRange = this.cloneRange(); + if (comparePoints(range.startContainer, range.startOffset, this.startContainer, this.startOffset) == -1) { + unionRange.setStart(range.startContainer, range.startOffset); + } + if (comparePoints(range.endContainer, range.endOffset, this.endContainer, this.endOffset) == 1) { + unionRange.setEnd(range.endContainer, range.endOffset); + } + return unionRange; + } else { + throw new DOMException("Ranges do not intersect"); + } + }, + + containsNode: function(node, allowPartial) { + if (allowPartial) { + return this.intersectsNode(node, false); + } else { + return this.compareNode(node) == n_i; + } + }, + + containsNodeContents: function(node) { + return this.comparePoint(node, 0) >= 0 && this.comparePoint(node, getNodeLength(node)) <= 0; + }, + + containsRange: function(range) { + var intersection = this.intersection(range); + return intersection !== null && range.equals(intersection); + }, + + containsNodeText: function(node) { + var nodeRange = this.cloneRange(); + nodeRange.selectNode(node); + var textNodes = nodeRange.getNodes([3]); + if (textNodes.length > 0) { + nodeRange.setStart(textNodes[0], 0); + var lastTextNode = textNodes.pop(); + nodeRange.setEnd(lastTextNode, lastTextNode.length); + return this.containsRange(nodeRange); + } else { + return this.containsNodeContents(node); + } + }, + + getNodes: function(nodeTypes, filter) { + assertRangeValid(this); + return getNodesInRange(this, nodeTypes, filter); + }, + + getDocument: function() { + return getRangeDocument(this); + }, + + collapseBefore: function(node) { + this.setEndBefore(node); + this.collapse(false); + }, + + collapseAfter: function(node) { + this.setStartAfter(node); + this.collapse(true); + }, + + getBookmark: function(containerNode) { + var doc = getRangeDocument(this); + var preSelectionRange = api.createRange(doc); + containerNode = containerNode || dom.getBody(doc); + preSelectionRange.selectNodeContents(containerNode); + var range = this.intersection(preSelectionRange); + var start = 0, end = 0; + if (range) { + preSelectionRange.setEnd(range.startContainer, range.startOffset); + start = preSelectionRange.toString().length; + end = start + range.toString().length; + } + + return { + start: start, + end: end, + containerNode: containerNode + }; + }, + + moveToBookmark: function(bookmark) { + var containerNode = bookmark.containerNode; + var charIndex = 0; + this.setStart(containerNode, 0); + this.collapse(true); + var nodeStack = [containerNode], node, foundStart = false, stop = false; + var nextCharIndex, i, childNodes; + + while (!stop && (node = nodeStack.pop())) { + if (node.nodeType == 3) { + nextCharIndex = charIndex + node.length; + if (!foundStart && bookmark.start >= charIndex && bookmark.start <= nextCharIndex) { + this.setStart(node, bookmark.start - charIndex); + foundStart = true; + } + if (foundStart && bookmark.end >= charIndex && bookmark.end <= nextCharIndex) { + this.setEnd(node, bookmark.end - charIndex); + stop = true; + } + charIndex = nextCharIndex; + } else { + childNodes = node.childNodes; + i = childNodes.length; + while (i--) { + nodeStack.push(childNodes[i]); + } + } + } + }, + + getName: function() { + return "DomRange"; + }, + + equals: function(range) { + return Range.rangesEqual(this, range); + }, + + isValid: function() { + return isRangeValid(this); + }, + + inspect: function() { + return inspect(this); + }, + + detach: function() { + // In DOM4, detach() is now a no-op. + } + }); + + function copyComparisonConstantsToObject(obj) { + obj.START_TO_START = s2s; + obj.START_TO_END = s2e; + obj.END_TO_END = e2e; + obj.END_TO_START = e2s; + + obj.NODE_BEFORE = n_b; + obj.NODE_AFTER = n_a; + obj.NODE_BEFORE_AND_AFTER = n_b_a; + obj.NODE_INSIDE = n_i; + } + + function copyComparisonConstants(constructor) { + copyComparisonConstantsToObject(constructor); + copyComparisonConstantsToObject(constructor.prototype); + } + + function createRangeContentRemover(remover, boundaryUpdater) { + return function() { + assertRangeValid(this); + + var sc = this.startContainer, so = this.startOffset, root = this.commonAncestorContainer; + + var iterator = new RangeIterator(this, true); + + // Work out where to position the range after content removal + var node, boundary; + if (sc !== root) { + node = getClosestAncestorIn(sc, root, true); + boundary = getBoundaryAfterNode(node); + sc = boundary.node; + so = boundary.offset; + } + + // Check none of the range is read-only + iterateSubtree(iterator, assertNodeNotReadOnly); + + iterator.reset(); + + // Remove the content + var returnValue = remover(iterator); + iterator.detach(); + + // Move to the new position + boundaryUpdater(this, sc, so, sc, so); + + return returnValue; + }; + } + + function createPrototypeRange(constructor, boundaryUpdater) { + function createBeforeAfterNodeSetter(isBefore, isStart) { + return function(node) { + assertValidNodeType(node, beforeAfterNodeTypes); + assertValidNodeType(getRootContainer(node), rootContainerNodeTypes); + + var boundary = (isBefore ? getBoundaryBeforeNode : getBoundaryAfterNode)(node); + (isStart ? setRangeStart : setRangeEnd)(this, boundary.node, boundary.offset); + }; + } + + function setRangeStart(range, node, offset) { + var ec = range.endContainer, eo = range.endOffset; + if (node !== range.startContainer || offset !== range.startOffset) { + // Check the root containers of the range and the new boundary, and also check whether the new boundary + // is after the current end. In either case, collapse the range to the new position + if (getRootContainer(node) != getRootContainer(ec) || comparePoints(node, offset, ec, eo) == 1) { + ec = node; + eo = offset; + } + boundaryUpdater(range, node, offset, ec, eo); + } + } + + function setRangeEnd(range, node, offset) { + var sc = range.startContainer, so = range.startOffset; + if (node !== range.endContainer || offset !== range.endOffset) { + // Check the root containers of the range and the new boundary, and also check whether the new boundary + // is after the current end. In either case, collapse the range to the new position + if (getRootContainer(node) != getRootContainer(sc) || comparePoints(node, offset, sc, so) == -1) { + sc = node; + so = offset; + } + boundaryUpdater(range, sc, so, node, offset); + } + } + + // Set up inheritance + var F = function() {}; + F.prototype = api.rangePrototype; + constructor.prototype = new F(); + + util.extend(constructor.prototype, { + setStart: function(node, offset) { + assertNoDocTypeNotationEntityAncestor(node, true); + assertValidOffset(node, offset); + + setRangeStart(this, node, offset); + }, + + setEnd: function(node, offset) { + assertNoDocTypeNotationEntityAncestor(node, true); + assertValidOffset(node, offset); + + setRangeEnd(this, node, offset); + }, + + /** + * Convenience method to set a range's start and end boundaries. Overloaded as follows: + * - Two parameters (node, offset) creates a collapsed range at that position + * - Three parameters (node, startOffset, endOffset) creates a range contained with node starting at + * startOffset and ending at endOffset + * - Four parameters (startNode, startOffset, endNode, endOffset) creates a range starting at startOffset in + * startNode and ending at endOffset in endNode + */ + setStartAndEnd: function() { + var args = arguments; + var sc = args[0], so = args[1], ec = sc, eo = so; + + switch (args.length) { + case 3: + eo = args[2]; + break; + case 4: + ec = args[2]; + eo = args[3]; + break; + } + + boundaryUpdater(this, sc, so, ec, eo); + }, + + setBoundary: function(node, offset, isStart) { + this["set" + (isStart ? "Start" : "End")](node, offset); + }, + + setStartBefore: createBeforeAfterNodeSetter(true, true), + setStartAfter: createBeforeAfterNodeSetter(false, true), + setEndBefore: createBeforeAfterNodeSetter(true, false), + setEndAfter: createBeforeAfterNodeSetter(false, false), + + collapse: function(isStart) { + assertRangeValid(this); + if (isStart) { + boundaryUpdater(this, this.startContainer, this.startOffset, this.startContainer, this.startOffset); + } else { + boundaryUpdater(this, this.endContainer, this.endOffset, this.endContainer, this.endOffset); + } + }, + + selectNodeContents: function(node) { + assertNoDocTypeNotationEntityAncestor(node, true); + + boundaryUpdater(this, node, 0, node, getNodeLength(node)); + }, + + selectNode: function(node) { + assertNoDocTypeNotationEntityAncestor(node, false); + assertValidNodeType(node, beforeAfterNodeTypes); + + var start = getBoundaryBeforeNode(node), end = getBoundaryAfterNode(node); + boundaryUpdater(this, start.node, start.offset, end.node, end.offset); + }, + + extractContents: createRangeContentRemover(extractSubtree, boundaryUpdater), + + deleteContents: createRangeContentRemover(deleteSubtree, boundaryUpdater), + + canSurroundContents: function() { + assertRangeValid(this); + assertNodeNotReadOnly(this.startContainer); + assertNodeNotReadOnly(this.endContainer); + + // Check if the contents can be surrounded. Specifically, this means whether the range partially selects + // no non-text nodes. + var iterator = new RangeIterator(this, true); + var boundariesInvalid = (iterator._first && isNonTextPartiallySelected(iterator._first, this) || + (iterator._last && isNonTextPartiallySelected(iterator._last, this))); + iterator.detach(); + return !boundariesInvalid; + }, + + splitBoundaries: function() { + splitRangeBoundaries(this); + }, + + splitBoundariesPreservingPositions: function(positionsToPreserve) { + splitRangeBoundaries(this, positionsToPreserve); + }, + + normalizeBoundaries: function() { + assertRangeValid(this); + + var sc = this.startContainer, so = this.startOffset, ec = this.endContainer, eo = this.endOffset; + + var mergeForward = function(node) { + var sibling = node.nextSibling; + if (sibling && sibling.nodeType == node.nodeType) { + ec = node; + eo = node.length; + node.appendData(sibling.data); + sibling.parentNode.removeChild(sibling); + } + }; + + var mergeBackward = function(node) { + var sibling = node.previousSibling; + if (sibling && sibling.nodeType == node.nodeType) { + sc = node; + var nodeLength = node.length; + so = sibling.length; + node.insertData(0, sibling.data); + sibling.parentNode.removeChild(sibling); + if (sc == ec) { + eo += so; + ec = sc; + } else if (ec == node.parentNode) { + var nodeIndex = getNodeIndex(node); + if (eo == nodeIndex) { + ec = node; + eo = nodeLength; + } else if (eo > nodeIndex) { + eo--; + } + } + } + }; + + var normalizeStart = true; + + if (isCharacterDataNode(ec)) { + if (ec.length == eo) { + mergeForward(ec); + } + } else { + if (eo > 0) { + var endNode = ec.childNodes[eo - 1]; + if (endNode && isCharacterDataNode(endNode)) { + mergeForward(endNode); + } + } + normalizeStart = !this.collapsed; + } + + if (normalizeStart) { + if (isCharacterDataNode(sc)) { + if (so == 0) { + mergeBackward(sc); + } + } else { + if (so < sc.childNodes.length) { + var startNode = sc.childNodes[so]; + if (startNode && isCharacterDataNode(startNode)) { + mergeBackward(startNode); + } + } + } + } else { + sc = ec; + so = eo; + } + + boundaryUpdater(this, sc, so, ec, eo); + }, + + collapseToPoint: function(node, offset) { + assertNoDocTypeNotationEntityAncestor(node, true); + assertValidOffset(node, offset); + this.setStartAndEnd(node, offset); + } + }); + + copyComparisonConstants(constructor); + } + + /*----------------------------------------------------------------------------------------------------------------*/ + + // Updates commonAncestorContainer and collapsed after boundary change + function updateCollapsedAndCommonAncestor(range) { + range.collapsed = (range.startContainer === range.endContainer && range.startOffset === range.endOffset); + range.commonAncestorContainer = range.collapsed ? + range.startContainer : dom.getCommonAncestor(range.startContainer, range.endContainer); + } + + function updateBoundaries(range, startContainer, startOffset, endContainer, endOffset) { + range.startContainer = startContainer; + range.startOffset = startOffset; + range.endContainer = endContainer; + range.endOffset = endOffset; + range.document = dom.getDocument(startContainer); + + updateCollapsedAndCommonAncestor(range); + } + + function Range(doc) { + this.startContainer = doc; + this.startOffset = 0; + this.endContainer = doc; + this.endOffset = 0; + this.document = doc; + updateCollapsedAndCommonAncestor(this); + } + + createPrototypeRange(Range, updateBoundaries); + + util.extend(Range, { + rangeProperties: rangeProperties, + RangeIterator: RangeIterator, + copyComparisonConstants: copyComparisonConstants, + createPrototypeRange: createPrototypeRange, + inspect: inspect, + toHtml: rangeToHtml, + getRangeDocument: getRangeDocument, + rangesEqual: function(r1, r2) { + return r1.startContainer === r2.startContainer && + r1.startOffset === r2.startOffset && + r1.endContainer === r2.endContainer && + r1.endOffset === r2.endOffset; + } + }); + + api.DomRange = Range; + }); + + /*----------------------------------------------------------------------------------------------------------------*/ + + // Wrappers for the browser's native DOM Range and/or TextRange implementation + api.createCoreModule("WrappedRange", ["DomRange"], function(api, module) { + var WrappedRange, WrappedTextRange; + var dom = api.dom; + var util = api.util; + var DomPosition = dom.DomPosition; + var DomRange = api.DomRange; + var getBody = dom.getBody; + var getContentDocument = dom.getContentDocument; + var isCharacterDataNode = dom.isCharacterDataNode; + + + /*----------------------------------------------------------------------------------------------------------------*/ + + if (api.features.implementsDomRange) { + // This is a wrapper around the browser's native DOM Range. It has two aims: + // - Provide workarounds for specific browser bugs + // - provide convenient extensions, which are inherited from Rangy's DomRange + + (function() { + var rangeProto; + var rangeProperties = DomRange.rangeProperties; + + function updateRangeProperties(range) { + var i = rangeProperties.length, prop; + while (i--) { + prop = rangeProperties[i]; + range[prop] = range.nativeRange[prop]; + } + // Fix for broken collapsed property in IE 9. + range.collapsed = (range.startContainer === range.endContainer && range.startOffset === range.endOffset); + } + + function updateNativeRange(range, startContainer, startOffset, endContainer, endOffset) { + var startMoved = (range.startContainer !== startContainer || range.startOffset != startOffset); + var endMoved = (range.endContainer !== endContainer || range.endOffset != endOffset); + var nativeRangeDifferent = !range.equals(range.nativeRange); + + // Always set both boundaries for the benefit of IE9 (see issue 35) + if (startMoved || endMoved || nativeRangeDifferent) { + range.setEnd(endContainer, endOffset); + range.setStart(startContainer, startOffset); + } + } + + var createBeforeAfterNodeSetter; + + WrappedRange = function(range) { + if (!range) { + throw module.createError("WrappedRange: Range must be specified"); + } + this.nativeRange = range; + updateRangeProperties(this); + }; + + DomRange.createPrototypeRange(WrappedRange, updateNativeRange); + + rangeProto = WrappedRange.prototype; + + rangeProto.selectNode = function(node) { + this.nativeRange.selectNode(node); + updateRangeProperties(this); + }; + + rangeProto.cloneContents = function() { + return this.nativeRange.cloneContents(); + }; + + // Due to a long-standing Firefox bug that I have not been able to find a reliable way to detect, + // insertNode() is never delegated to the native range. + + rangeProto.surroundContents = function(node) { + this.nativeRange.surroundContents(node); + updateRangeProperties(this); + }; + + rangeProto.collapse = function(isStart) { + this.nativeRange.collapse(isStart); + updateRangeProperties(this); + }; + + rangeProto.cloneRange = function() { + return new WrappedRange(this.nativeRange.cloneRange()); + }; + + rangeProto.refresh = function() { + updateRangeProperties(this); + }; + + rangeProto.toString = function() { + return this.nativeRange.toString(); + }; + + // Create test range and node for feature detection + + var testTextNode = document.createTextNode("test"); + getBody(document).appendChild(testTextNode); + var range = document.createRange(); + + /*--------------------------------------------------------------------------------------------------------*/ + + // Test for Firefox 2 bug that prevents moving the start of a Range to a point after its current end and + // correct for it + + range.setStart(testTextNode, 0); + range.setEnd(testTextNode, 0); + + try { + range.setStart(testTextNode, 1); + + rangeProto.setStart = function(node, offset) { + this.nativeRange.setStart(node, offset); + updateRangeProperties(this); + }; + + rangeProto.setEnd = function(node, offset) { + this.nativeRange.setEnd(node, offset); + updateRangeProperties(this); + }; + + createBeforeAfterNodeSetter = function(name) { + return function(node) { + this.nativeRange[name](node); + updateRangeProperties(this); + }; + }; + + } catch(ex) { + + rangeProto.setStart = function(node, offset) { + try { + this.nativeRange.setStart(node, offset); + } catch (ex) { + this.nativeRange.setEnd(node, offset); + this.nativeRange.setStart(node, offset); + } + updateRangeProperties(this); + }; + + rangeProto.setEnd = function(node, offset) { + try { + this.nativeRange.setEnd(node, offset); + } catch (ex) { + this.nativeRange.setStart(node, offset); + this.nativeRange.setEnd(node, offset); + } + updateRangeProperties(this); + }; + + createBeforeAfterNodeSetter = function(name, oppositeName) { + return function(node) { + try { + this.nativeRange[name](node); + } catch (ex) { + this.nativeRange[oppositeName](node); + this.nativeRange[name](node); + } + updateRangeProperties(this); + }; + }; + } + + rangeProto.setStartBefore = createBeforeAfterNodeSetter("setStartBefore", "setEndBefore"); + rangeProto.setStartAfter = createBeforeAfterNodeSetter("setStartAfter", "setEndAfter"); + rangeProto.setEndBefore = createBeforeAfterNodeSetter("setEndBefore", "setStartBefore"); + rangeProto.setEndAfter = createBeforeAfterNodeSetter("setEndAfter", "setStartAfter"); + + /*--------------------------------------------------------------------------------------------------------*/ + + // Always use DOM4-compliant selectNodeContents implementation: it's simpler and less code than testing + // whether the native implementation can be trusted + rangeProto.selectNodeContents = function(node) { + this.setStartAndEnd(node, 0, dom.getNodeLength(node)); + }; + + /*--------------------------------------------------------------------------------------------------------*/ + + // Test for and correct WebKit bug that has the behaviour of compareBoundaryPoints round the wrong way for + // constants START_TO_END and END_TO_START: https://bugs.webkit.org/show_bug.cgi?id=20738 + + range.selectNodeContents(testTextNode); + range.setEnd(testTextNode, 3); + + var range2 = document.createRange(); + range2.selectNodeContents(testTextNode); + range2.setEnd(testTextNode, 4); + range2.setStart(testTextNode, 2); + + if (range.compareBoundaryPoints(range.START_TO_END, range2) == -1 && + range.compareBoundaryPoints(range.END_TO_START, range2) == 1) { + // This is the wrong way round, so correct for it + + rangeProto.compareBoundaryPoints = function(type, range) { + range = range.nativeRange || range; + if (type == range.START_TO_END) { + type = range.END_TO_START; + } else if (type == range.END_TO_START) { + type = range.START_TO_END; + } + return this.nativeRange.compareBoundaryPoints(type, range); + }; + } else { + rangeProto.compareBoundaryPoints = function(type, range) { + return this.nativeRange.compareBoundaryPoints(type, range.nativeRange || range); + }; + } + + /*--------------------------------------------------------------------------------------------------------*/ + + // Test for IE 9 deleteContents() and extractContents() bug and correct it. See issue 107. + + var el = document.createElement("div"); + el.innerHTML = "123"; + var textNode = el.firstChild; + var body = getBody(document); + body.appendChild(el); + + range.setStart(textNode, 1); + range.setEnd(textNode, 2); + range.deleteContents(); + + if (textNode.data == "13") { + // Behaviour is correct per DOM4 Range so wrap the browser's implementation of deleteContents() and + // extractContents() + rangeProto.deleteContents = function() { + this.nativeRange.deleteContents(); + updateRangeProperties(this); + }; + + rangeProto.extractContents = function() { + var frag = this.nativeRange.extractContents(); + updateRangeProperties(this); + return frag; + }; + } else { + } + + body.removeChild(el); + body = null; + + /*--------------------------------------------------------------------------------------------------------*/ + + // Test for existence of createContextualFragment and delegate to it if it exists + if (util.isHostMethod(range, "createContextualFragment")) { + rangeProto.createContextualFragment = function(fragmentStr) { + return this.nativeRange.createContextualFragment(fragmentStr); + }; + } + + /*--------------------------------------------------------------------------------------------------------*/ + + // Clean up + getBody(document).removeChild(testTextNode); + + rangeProto.getName = function() { + return "WrappedRange"; + }; + + api.WrappedRange = WrappedRange; + + api.createNativeRange = function(doc) { + doc = getContentDocument(doc, module, "createNativeRange"); + return doc.createRange(); + }; + })(); + } + + if (api.features.implementsTextRange) { + /* + This is a workaround for a bug where IE returns the wrong container element from the TextRange's parentElement() + method. For example, in the following (where pipes denote the selection boundaries): + +
    • | a
    • b |
    + + var range = document.selection.createRange(); + alert(range.parentElement().id); // Should alert "ul" but alerts "b" + + This method returns the common ancestor node of the following: + - the parentElement() of the textRange + - the parentElement() of the textRange after calling collapse(true) + - the parentElement() of the textRange after calling collapse(false) + */ + var getTextRangeContainerElement = function(textRange) { + var parentEl = textRange.parentElement(); + var range = textRange.duplicate(); + range.collapse(true); + var startEl = range.parentElement(); + range = textRange.duplicate(); + range.collapse(false); + var endEl = range.parentElement(); + var startEndContainer = (startEl == endEl) ? startEl : dom.getCommonAncestor(startEl, endEl); + + return startEndContainer == parentEl ? startEndContainer : dom.getCommonAncestor(parentEl, startEndContainer); + }; + + var textRangeIsCollapsed = function(textRange) { + return textRange.compareEndPoints("StartToEnd", textRange) == 0; + }; + + // Gets the boundary of a TextRange expressed as a node and an offset within that node. This function started + // out as an improved version of code found in Tim Cameron Ryan's IERange (http://code.google.com/p/ierange/) + // but has grown, fixing problems with line breaks in preformatted text, adding workaround for IE TextRange + // bugs, handling for inputs and images, plus optimizations. + var getTextRangeBoundaryPosition = function(textRange, wholeRangeContainerElement, isStart, isCollapsed, startInfo) { + var workingRange = textRange.duplicate(); + workingRange.collapse(isStart); + var containerElement = workingRange.parentElement(); + + // Sometimes collapsing a TextRange that's at the start of a text node can move it into the previous node, so + // check for that + if (!dom.isOrIsAncestorOf(wholeRangeContainerElement, containerElement)) { + containerElement = wholeRangeContainerElement; + } + + + // Deal with nodes that cannot "contain rich HTML markup". In practice, this means form inputs, images and + // similar. See http://msdn.microsoft.com/en-us/library/aa703950%28VS.85%29.aspx + if (!containerElement.canHaveHTML) { + var pos = new DomPosition(containerElement.parentNode, dom.getNodeIndex(containerElement)); + return { + boundaryPosition: pos, + nodeInfo: { + nodeIndex: pos.offset, + containerElement: pos.node + } + }; + } + + var workingNode = dom.getDocument(containerElement).createElement("span"); + + // Workaround for HTML5 Shiv's insane violation of document.createElement(). See Rangy issue 104 and HTML5 + // Shiv issue 64: https://github.com/aFarkas/html5shiv/issues/64 + if (workingNode.parentNode) { + workingNode.parentNode.removeChild(workingNode); + } + + var comparison, workingComparisonType = isStart ? "StartToStart" : "StartToEnd"; + var previousNode, nextNode, boundaryPosition, boundaryNode; + var start = (startInfo && startInfo.containerElement == containerElement) ? startInfo.nodeIndex : 0; + var childNodeCount = containerElement.childNodes.length; + var end = childNodeCount; + + // Check end first. Code within the loop assumes that the endth child node of the container is definitely + // after the range boundary. + var nodeIndex = end; + + while (true) { + if (nodeIndex == childNodeCount) { + containerElement.appendChild(workingNode); + } else { + containerElement.insertBefore(workingNode, containerElement.childNodes[nodeIndex]); + } + workingRange.moveToElementText(workingNode); + comparison = workingRange.compareEndPoints(workingComparisonType, textRange); + if (comparison == 0 || start == end) { + break; + } else if (comparison == -1) { + if (end == start + 1) { + // We know the endth child node is after the range boundary, so we must be done. + break; + } else { + start = nodeIndex; + } + } else { + end = (end == start + 1) ? start : nodeIndex; + } + nodeIndex = Math.floor((start + end) / 2); + containerElement.removeChild(workingNode); + } + + + // We've now reached or gone past the boundary of the text range we're interested in + // so have identified the node we want + boundaryNode = workingNode.nextSibling; + + if (comparison == -1 && boundaryNode && isCharacterDataNode(boundaryNode)) { + // This is a character data node (text, comment, cdata). The working range is collapsed at the start of + // the node containing the text range's boundary, so we move the end of the working range to the + // boundary point and measure the length of its text to get the boundary's offset within the node. + workingRange.setEndPoint(isStart ? "EndToStart" : "EndToEnd", textRange); + + var offset; + + if (/[\r\n]/.test(boundaryNode.data)) { + /* + For the particular case of a boundary within a text node containing rendered line breaks (within a +
     element, for example), we need a slightly complicated approach to get the boundary's offset in
    +                        IE. The facts:
    +                        
    +                        - Each line break is represented as \r in the text node's data/nodeValue properties
    +                        - Each line break is represented as \r\n in the TextRange's 'text' property
    +                        - The 'text' property of the TextRange does not contain trailing line breaks
    +                        
    +                        To get round the problem presented by the final fact above, we can use the fact that TextRange's
    +                        moveStart() and moveEnd() methods return the actual number of characters moved, which is not
    +                        necessarily the same as the number of characters it was instructed to move. The simplest approach is
    +                        to use this to store the characters moved when moving both the start and end of the range to the
    +                        start of the document body and subtracting the start offset from the end offset (the
    +                        "move-negative-gazillion" method). However, this is extremely slow when the document is large and
    +                        the range is near the end of it. Clearly doing the mirror image (i.e. moving the range boundaries to
    +                        the end of the document) has the same problem.
    +                        
    +                        Another approach that works is to use moveStart() to move the start boundary of the range up to the
    +                        end boundary one character at a time and incrementing a counter with the value returned by the
    +                        moveStart() call. However, the check for whether the start boundary has reached the end boundary is
    +                        expensive, so this method is slow (although unlike "move-negative-gazillion" is largely unaffected
    +                        by the location of the range within the document).
    +                        
    +                        The approach used below is a hybrid of the two methods above. It uses the fact that a string
    +                        containing the TextRange's 'text' property with each \r\n converted to a single \r character cannot
    +                        be longer than the text of the TextRange, so the start of the range is moved that length initially
    +                        and then a character at a time to make up for any trailing line breaks not contained in the 'text'
    +                        property. This has good performance in most situations compared to the previous two methods.
    +                        */
    +                        var tempRange = workingRange.duplicate();
    +                        var rangeLength = tempRange.text.replace(/\r\n/g, "\r").length;
    +
    +                        offset = tempRange.moveStart("character", rangeLength);
    +                        while ( (comparison = tempRange.compareEndPoints("StartToEnd", tempRange)) == -1) {
    +                            offset++;
    +                            tempRange.moveStart("character", 1);
    +                        }
    +                    } else {
    +                        offset = workingRange.text.length;
    +                    }
    +                    boundaryPosition = new DomPosition(boundaryNode, offset);
    +                } else {
    +
    +                    // If the boundary immediately follows a character data node and this is the end boundary, we should favour
    +                    // a position within that, and likewise for a start boundary preceding a character data node
    +                    previousNode = (isCollapsed || !isStart) && workingNode.previousSibling;
    +                    nextNode = (isCollapsed || isStart) && workingNode.nextSibling;
    +                    if (nextNode && isCharacterDataNode(nextNode)) {
    +                        boundaryPosition = new DomPosition(nextNode, 0);
    +                    } else if (previousNode && isCharacterDataNode(previousNode)) {
    +                        boundaryPosition = new DomPosition(previousNode, previousNode.data.length);
    +                    } else {
    +                        boundaryPosition = new DomPosition(containerElement, dom.getNodeIndex(workingNode));
    +                    }
    +                }
    +
    +                // Clean up
    +                workingNode.parentNode.removeChild(workingNode);
    +
    +                return {
    +                    boundaryPosition: boundaryPosition,
    +                    nodeInfo: {
    +                        nodeIndex: nodeIndex,
    +                        containerElement: containerElement
    +                    }
    +                };
    +            };
    +
    +            // Returns a TextRange representing the boundary of a TextRange expressed as a node and an offset within that
    +            // node. This function started out as an optimized version of code found in Tim Cameron Ryan's IERange
    +            // (http://code.google.com/p/ierange/)
    +            var createBoundaryTextRange = function(boundaryPosition, isStart) {
    +                var boundaryNode, boundaryParent, boundaryOffset = boundaryPosition.offset;
    +                var doc = dom.getDocument(boundaryPosition.node);
    +                var workingNode, childNodes, workingRange = getBody(doc).createTextRange();
    +                var nodeIsDataNode = isCharacterDataNode(boundaryPosition.node);
    +
    +                if (nodeIsDataNode) {
    +                    boundaryNode = boundaryPosition.node;
    +                    boundaryParent = boundaryNode.parentNode;
    +                } else {
    +                    childNodes = boundaryPosition.node.childNodes;
    +                    boundaryNode = (boundaryOffset < childNodes.length) ? childNodes[boundaryOffset] : null;
    +                    boundaryParent = boundaryPosition.node;
    +                }
    +
    +                // Position the range immediately before the node containing the boundary
    +                workingNode = doc.createElement("span");
    +
    +                // Making the working element non-empty element persuades IE to consider the TextRange boundary to be within
    +                // the element rather than immediately before or after it
    +                workingNode.innerHTML = "&#feff;";
    +
    +                // insertBefore is supposed to work like appendChild if the second parameter is null. However, a bug report
    +                // for IERange suggests that it can crash the browser: http://code.google.com/p/ierange/issues/detail?id=12
    +                if (boundaryNode) {
    +                    boundaryParent.insertBefore(workingNode, boundaryNode);
    +                } else {
    +                    boundaryParent.appendChild(workingNode);
    +                }
    +
    +                workingRange.moveToElementText(workingNode);
    +                workingRange.collapse(!isStart);
    +
    +                // Clean up
    +                boundaryParent.removeChild(workingNode);
    +
    +                // Move the working range to the text offset, if required
    +                if (nodeIsDataNode) {
    +                    workingRange[isStart ? "moveStart" : "moveEnd"]("character", boundaryOffset);
    +                }
    +
    +                return workingRange;
    +            };
    +
    +            /*------------------------------------------------------------------------------------------------------------*/
    +
    +            // This is a wrapper around a TextRange, providing full DOM Range functionality using rangy's DomRange as a
    +            // prototype
    +
    +            WrappedTextRange = function(textRange) {
    +                this.textRange = textRange;
    +                this.refresh();
    +            };
    +
    +            WrappedTextRange.prototype = new DomRange(document);
    +
    +            WrappedTextRange.prototype.refresh = function() {
    +                var start, end, startBoundary;
    +
    +                // TextRange's parentElement() method cannot be trusted. getTextRangeContainerElement() works around that.
    +                var rangeContainerElement = getTextRangeContainerElement(this.textRange);
    +
    +                if (textRangeIsCollapsed(this.textRange)) {
    +                    end = start = getTextRangeBoundaryPosition(this.textRange, rangeContainerElement, true,
    +                        true).boundaryPosition;
    +                } else {
    +                    startBoundary = getTextRangeBoundaryPosition(this.textRange, rangeContainerElement, true, false);
    +                    start = startBoundary.boundaryPosition;
    +
    +                    // An optimization used here is that if the start and end boundaries have the same parent element, the
    +                    // search scope for the end boundary can be limited to exclude the portion of the element that precedes
    +                    // the start boundary
    +                    end = getTextRangeBoundaryPosition(this.textRange, rangeContainerElement, false, false,
    +                        startBoundary.nodeInfo).boundaryPosition;
    +                }
    +
    +                this.setStart(start.node, start.offset);
    +                this.setEnd(end.node, end.offset);
    +            };
    +
    +            WrappedTextRange.prototype.getName = function() {
    +                return "WrappedTextRange";
    +            };
    +
    +            DomRange.copyComparisonConstants(WrappedTextRange);
    +
    +            var rangeToTextRange = function(range) {
    +                if (range.collapsed) {
    +                    return createBoundaryTextRange(new DomPosition(range.startContainer, range.startOffset), true);
    +                } else {
    +                    var startRange = createBoundaryTextRange(new DomPosition(range.startContainer, range.startOffset), true);
    +                    var endRange = createBoundaryTextRange(new DomPosition(range.endContainer, range.endOffset), false);
    +                    var textRange = getBody( DomRange.getRangeDocument(range) ).createTextRange();
    +                    textRange.setEndPoint("StartToStart", startRange);
    +                    textRange.setEndPoint("EndToEnd", endRange);
    +                    return textRange;
    +                }
    +            };
    +
    +            WrappedTextRange.rangeToTextRange = rangeToTextRange;
    +
    +            WrappedTextRange.prototype.toTextRange = function() {
    +                return rangeToTextRange(this);
    +            };
    +
    +            api.WrappedTextRange = WrappedTextRange;
    +
    +            // IE 9 and above have both implementations and Rangy makes both available. The next few lines sets which
    +            // implementation to use by default.
    +            if (!api.features.implementsDomRange || api.config.preferTextRange) {
    +                // Add WrappedTextRange as the Range property of the global object to allow expression like Range.END_TO_END to work
    +                var globalObj = (function() { return this; })();
    +                if (typeof globalObj.Range == "undefined") {
    +                    globalObj.Range = WrappedTextRange;
    +                }
    +
    +                api.createNativeRange = function(doc) {
    +                    doc = getContentDocument(doc, module, "createNativeRange");
    +                    return getBody(doc).createTextRange();
    +                };
    +
    +                api.WrappedRange = WrappedTextRange;
    +            }
    +        }
    +
    +        api.createRange = function(doc) {
    +            doc = getContentDocument(doc, module, "createRange");
    +            return new api.WrappedRange(api.createNativeRange(doc));
    +        };
    +
    +        api.createRangyRange = function(doc) {
    +            doc = getContentDocument(doc, module, "createRangyRange");
    +            return new DomRange(doc);
    +        };
    +
    +        api.createIframeRange = function(iframeEl) {
    +            module.deprecationNotice("createIframeRange()", "createRange(iframeEl)");
    +            return api.createRange(iframeEl);
    +        };
    +
    +        api.createIframeRangyRange = function(iframeEl) {
    +            module.deprecationNotice("createIframeRangyRange()", "createRangyRange(iframeEl)");
    +            return api.createRangyRange(iframeEl);
    +        };
    +
    +        api.addShimListener(function(win) {
    +            var doc = win.document;
    +            if (typeof doc.createRange == "undefined") {
    +                doc.createRange = function() {
    +                    return api.createRange(doc);
    +                };
    +            }
    +            doc = win = null;
    +        });
    +    });
    +
    +    /*----------------------------------------------------------------------------------------------------------------*/
    +
    +    // This module creates a selection object wrapper that conforms as closely as possible to the Selection specification
    +    // in the HTML Editing spec (http://dvcs.w3.org/hg/editing/raw-file/tip/editing.html#selections)
    +    api.createCoreModule("WrappedSelection", ["DomRange", "WrappedRange"], function(api, module) {
    +        api.config.checkSelectionRanges = true;
    +
    +        var BOOLEAN = "boolean";
    +        var NUMBER = "number";
    +        var dom = api.dom;
    +        var util = api.util;
    +        var isHostMethod = util.isHostMethod;
    +        var DomRange = api.DomRange;
    +        var WrappedRange = api.WrappedRange;
    +        var DOMException = api.DOMException;
    +        var DomPosition = dom.DomPosition;
    +        var getNativeSelection;
    +        var selectionIsCollapsed;
    +        var features = api.features;
    +        var CONTROL = "Control";
    +        var getDocument = dom.getDocument;
    +        var getBody = dom.getBody;
    +        var rangesEqual = DomRange.rangesEqual;
    +
    +
    +        // Utility function to support direction parameters in the API that may be a string ("backward" or "forward") or a
    +        // Boolean (true for backwards).
    +        function isDirectionBackward(dir) {
    +            return (typeof dir == "string") ? /^backward(s)?$/i.test(dir) : !!dir;
    +        }
    +
    +        function getWindow(win, methodName) {
    +            if (!win) {
    +                return window;
    +            } else if (dom.isWindow(win)) {
    +                return win;
    +            } else if (win instanceof WrappedSelection) {
    +                return win.win;
    +            } else {
    +                var doc = dom.getContentDocument(win, module, methodName);
    +                return dom.getWindow(doc);
    +            }
    +        }
    +
    +        function getWinSelection(winParam) {
    +            return getWindow(winParam, "getWinSelection").getSelection();
    +        }
    +
    +        function getDocSelection(winParam) {
    +            return getWindow(winParam, "getDocSelection").document.selection;
    +        }
    +        
    +        function winSelectionIsBackward(sel) {
    +            var backward = false;
    +            if (sel.anchorNode) {
    +                backward = (dom.comparePoints(sel.anchorNode, sel.anchorOffset, sel.focusNode, sel.focusOffset) == 1);
    +            }
    +            return backward;
    +        }
    +
    +        // Test for the Range/TextRange and Selection features required
    +        // Test for ability to retrieve selection
    +        var implementsWinGetSelection = isHostMethod(window, "getSelection"),
    +            implementsDocSelection = util.isHostObject(document, "selection");
    +
    +        features.implementsWinGetSelection = implementsWinGetSelection;
    +        features.implementsDocSelection = implementsDocSelection;
    +
    +        var useDocumentSelection = implementsDocSelection && (!implementsWinGetSelection || api.config.preferTextRange);
    +
    +        if (useDocumentSelection) {
    +            getNativeSelection = getDocSelection;
    +            api.isSelectionValid = function(winParam) {
    +                var doc = getWindow(winParam, "isSelectionValid").document, nativeSel = doc.selection;
    +
    +                // Check whether the selection TextRange is actually contained within the correct document
    +                return (nativeSel.type != "None" || getDocument(nativeSel.createRange().parentElement()) == doc);
    +            };
    +        } else if (implementsWinGetSelection) {
    +            getNativeSelection = getWinSelection;
    +            api.isSelectionValid = function() {
    +                return true;
    +            };
    +        } else {
    +            module.fail("Neither document.selection or window.getSelection() detected.");
    +        }
    +
    +        api.getNativeSelection = getNativeSelection;
    +
    +        var testSelection = getNativeSelection();
    +        var testRange = api.createNativeRange(document);
    +        var body = getBody(document);
    +
    +        // Obtaining a range from a selection
    +        var selectionHasAnchorAndFocus = util.areHostProperties(testSelection,
    +            ["anchorNode", "focusNode", "anchorOffset", "focusOffset"]);
    +
    +        features.selectionHasAnchorAndFocus = selectionHasAnchorAndFocus;
    +
    +        // Test for existence of native selection extend() method
    +        var selectionHasExtend = isHostMethod(testSelection, "extend");
    +        features.selectionHasExtend = selectionHasExtend;
    +        
    +        // Test if rangeCount exists
    +        var selectionHasRangeCount = (typeof testSelection.rangeCount == NUMBER);
    +        features.selectionHasRangeCount = selectionHasRangeCount;
    +
    +        var selectionSupportsMultipleRanges = false;
    +        var collapsedNonEditableSelectionsSupported = true;
    +
    +        var addRangeBackwardToNative = selectionHasExtend ?
    +            function(nativeSelection, range) {
    +                var doc = DomRange.getRangeDocument(range);
    +                var endRange = api.createRange(doc);
    +                endRange.collapseToPoint(range.endContainer, range.endOffset);
    +                nativeSelection.addRange(getNativeRange(endRange));
    +                nativeSelection.extend(range.startContainer, range.startOffset);
    +            } : null;
    +
    +        if (util.areHostMethods(testSelection, ["addRange", "getRangeAt", "removeAllRanges"]) &&
    +                typeof testSelection.rangeCount == NUMBER && features.implementsDomRange) {
    +
    +            (function() {
    +                // Previously an iframe was used but this caused problems in some circumstances in IE, so tests are
    +                // performed on the current document's selection. See issue 109.
    +
    +                // Note also that if a selection previously existed, it is wiped by these tests. This should usually be fine
    +                // because initialization usually happens when the document loads, but could be a problem for a script that
    +                // loads and initializes Rangy later. If anyone complains, code could be added to save and restore the
    +                // selection.
    +                var sel = window.getSelection();
    +                if (sel) {
    +                    // Store the current selection
    +                    var originalSelectionRangeCount = sel.rangeCount;
    +                    var selectionHasMultipleRanges = (originalSelectionRangeCount > 1);
    +                    var originalSelectionRanges = [];
    +                    var originalSelectionBackward = winSelectionIsBackward(sel); 
    +                    for (var i = 0; i < originalSelectionRangeCount; ++i) {
    +                        originalSelectionRanges[i] = sel.getRangeAt(i);
    +                    }
    +                    
    +                    // Create some test elements
    +                    var body = getBody(document);
    +                    var testEl = body.appendChild( document.createElement("div") );
    +                    testEl.contentEditable = "false";
    +                    var textNode = testEl.appendChild( document.createTextNode("\u00a0\u00a0\u00a0") );
    +
    +                    // Test whether the native selection will allow a collapsed selection within a non-editable element
    +                    var r1 = document.createRange();
    +
    +                    r1.setStart(textNode, 1);
    +                    r1.collapse(true);
    +                    sel.addRange(r1);
    +                    collapsedNonEditableSelectionsSupported = (sel.rangeCount == 1);
    +                    sel.removeAllRanges();
    +
    +                    // Test whether the native selection is capable of supporting multiple ranges.
    +                    if (!selectionHasMultipleRanges) {
    +                        // Doing the original feature test here in Chrome 36 (and presumably later versions) prints a
    +                        // console error of "Discontiguous selection is not supported." that cannot be suppressed. There's
    +                        // nothing we can do about this while retaining the feature test so we have to resort to a browser
    +                        // sniff. I'm not happy about it. See
    +                        // https://code.google.com/p/chromium/issues/detail?id=399791
    +                        var chromeMatch = window.navigator.appVersion.match(/Chrome\/(.*?) /);
    +                        if (chromeMatch && parseInt(chromeMatch[1]) >= 36) {
    +                            selectionSupportsMultipleRanges = false;
    +                        } else {
    +                            var r2 = r1.cloneRange();
    +                            r1.setStart(textNode, 0);
    +                            r2.setEnd(textNode, 3);
    +                            r2.setStart(textNode, 2);
    +                            sel.addRange(r1);
    +                            sel.addRange(r2);
    +                            selectionSupportsMultipleRanges = (sel.rangeCount == 2);
    +                        }
    +                    }
    +
    +                    // Clean up
    +                    body.removeChild(testEl);
    +                    sel.removeAllRanges();
    +
    +                    for (i = 0; i < originalSelectionRangeCount; ++i) {
    +                        if (i == 0 && originalSelectionBackward) {
    +                            if (addRangeBackwardToNative) {
    +                                addRangeBackwardToNative(sel, originalSelectionRanges[i]);
    +                            } else {
    +                                api.warn("Rangy initialization: original selection was backwards but selection has been restored forwards because the browser does not support Selection.extend");
    +                                sel.addRange(originalSelectionRanges[i]);
    +                            }
    +                        } else {
    +                            sel.addRange(originalSelectionRanges[i]);
    +                        }
    +                    }
    +                }
    +            })();
    +        }
    +
    +        features.selectionSupportsMultipleRanges = selectionSupportsMultipleRanges;
    +        features.collapsedNonEditableSelectionsSupported = collapsedNonEditableSelectionsSupported;
    +
    +        // ControlRanges
    +        var implementsControlRange = false, testControlRange;
    +
    +        if (body && isHostMethod(body, "createControlRange")) {
    +            testControlRange = body.createControlRange();
    +            if (util.areHostProperties(testControlRange, ["item", "add"])) {
    +                implementsControlRange = true;
    +            }
    +        }
    +        features.implementsControlRange = implementsControlRange;
    +
    +        // Selection collapsedness
    +        if (selectionHasAnchorAndFocus) {
    +            selectionIsCollapsed = function(sel) {
    +                return sel.anchorNode === sel.focusNode && sel.anchorOffset === sel.focusOffset;
    +            };
    +        } else {
    +            selectionIsCollapsed = function(sel) {
    +                return sel.rangeCount ? sel.getRangeAt(sel.rangeCount - 1).collapsed : false;
    +            };
    +        }
    +
    +        function updateAnchorAndFocusFromRange(sel, range, backward) {
    +            var anchorPrefix = backward ? "end" : "start", focusPrefix = backward ? "start" : "end";
    +            sel.anchorNode = range[anchorPrefix + "Container"];
    +            sel.anchorOffset = range[anchorPrefix + "Offset"];
    +            sel.focusNode = range[focusPrefix + "Container"];
    +            sel.focusOffset = range[focusPrefix + "Offset"];
    +        }
    +
    +        function updateAnchorAndFocusFromNativeSelection(sel) {
    +            var nativeSel = sel.nativeSelection;
    +            sel.anchorNode = nativeSel.anchorNode;
    +            sel.anchorOffset = nativeSel.anchorOffset;
    +            sel.focusNode = nativeSel.focusNode;
    +            sel.focusOffset = nativeSel.focusOffset;
    +        }
    +
    +        function updateEmptySelection(sel) {
    +            sel.anchorNode = sel.focusNode = null;
    +            sel.anchorOffset = sel.focusOffset = 0;
    +            sel.rangeCount = 0;
    +            sel.isCollapsed = true;
    +            sel._ranges.length = 0;
    +        }
    +
    +        function getNativeRange(range) {
    +            var nativeRange;
    +            if (range instanceof DomRange) {
    +                nativeRange = api.createNativeRange(range.getDocument());
    +                nativeRange.setEnd(range.endContainer, range.endOffset);
    +                nativeRange.setStart(range.startContainer, range.startOffset);
    +            } else if (range instanceof WrappedRange) {
    +                nativeRange = range.nativeRange;
    +            } else if (features.implementsDomRange && (range instanceof dom.getWindow(range.startContainer).Range)) {
    +                nativeRange = range;
    +            }
    +            return nativeRange;
    +        }
    +
    +        function rangeContainsSingleElement(rangeNodes) {
    +            if (!rangeNodes.length || rangeNodes[0].nodeType != 1) {
    +                return false;
    +            }
    +            for (var i = 1, len = rangeNodes.length; i < len; ++i) {
    +                if (!dom.isAncestorOf(rangeNodes[0], rangeNodes[i])) {
    +                    return false;
    +                }
    +            }
    +            return true;
    +        }
    +
    +        function getSingleElementFromRange(range) {
    +            var nodes = range.getNodes();
    +            if (!rangeContainsSingleElement(nodes)) {
    +                throw module.createError("getSingleElementFromRange: range " + range.inspect() + " did not consist of a single element");
    +            }
    +            return nodes[0];
    +        }
    +
    +        // Simple, quick test which only needs to distinguish between a TextRange and a ControlRange
    +        function isTextRange(range) {
    +            return !!range && typeof range.text != "undefined";
    +        }
    +
    +        function updateFromTextRange(sel, range) {
    +            // Create a Range from the selected TextRange
    +            var wrappedRange = new WrappedRange(range);
    +            sel._ranges = [wrappedRange];
    +
    +            updateAnchorAndFocusFromRange(sel, wrappedRange, false);
    +            sel.rangeCount = 1;
    +            sel.isCollapsed = wrappedRange.collapsed;
    +        }
    +
    +        function updateControlSelection(sel) {
    +            // Update the wrapped selection based on what's now in the native selection
    +            sel._ranges.length = 0;
    +            if (sel.docSelection.type == "None") {
    +                updateEmptySelection(sel);
    +            } else {
    +                var controlRange = sel.docSelection.createRange();
    +                if (isTextRange(controlRange)) {
    +                    // This case (where the selection type is "Control" and calling createRange() on the selection returns
    +                    // a TextRange) can happen in IE 9. It happens, for example, when all elements in the selected
    +                    // ControlRange have been removed from the ControlRange and removed from the document.
    +                    updateFromTextRange(sel, controlRange);
    +                } else {
    +                    sel.rangeCount = controlRange.length;
    +                    var range, doc = getDocument(controlRange.item(0));
    +                    for (var i = 0; i < sel.rangeCount; ++i) {
    +                        range = api.createRange(doc);
    +                        range.selectNode(controlRange.item(i));
    +                        sel._ranges.push(range);
    +                    }
    +                    sel.isCollapsed = sel.rangeCount == 1 && sel._ranges[0].collapsed;
    +                    updateAnchorAndFocusFromRange(sel, sel._ranges[sel.rangeCount - 1], false);
    +                }
    +            }
    +        }
    +
    +        function addRangeToControlSelection(sel, range) {
    +            var controlRange = sel.docSelection.createRange();
    +            var rangeElement = getSingleElementFromRange(range);
    +
    +            // Create a new ControlRange containing all the elements in the selected ControlRange plus the element
    +            // contained by the supplied range
    +            var doc = getDocument(controlRange.item(0));
    +            var newControlRange = getBody(doc).createControlRange();
    +            for (var i = 0, len = controlRange.length; i < len; ++i) {
    +                newControlRange.add(controlRange.item(i));
    +            }
    +            try {
    +                newControlRange.add(rangeElement);
    +            } catch (ex) {
    +                throw module.createError("addRange(): Element within the specified Range could not be added to control selection (does it have layout?)");
    +            }
    +            newControlRange.select();
    +
    +            // Update the wrapped selection based on what's now in the native selection
    +            updateControlSelection(sel);
    +        }
    +
    +        var getSelectionRangeAt;
    +
    +        if (isHostMethod(testSelection, "getRangeAt")) {
    +            // try/catch is present because getRangeAt() must have thrown an error in some browser and some situation.
    +            // Unfortunately, I didn't write a comment about the specifics and am now scared to take it out. Let that be a
    +            // lesson to us all, especially me.
    +            getSelectionRangeAt = function(sel, index) {
    +                try {
    +                    return sel.getRangeAt(index);
    +                } catch (ex) {
    +                    return null;
    +                }
    +            };
    +        } else if (selectionHasAnchorAndFocus) {
    +            getSelectionRangeAt = function(sel) {
    +                var doc = getDocument(sel.anchorNode);
    +                var range = api.createRange(doc);
    +                range.setStartAndEnd(sel.anchorNode, sel.anchorOffset, sel.focusNode, sel.focusOffset);
    +
    +                // Handle the case when the selection was selected backwards (from the end to the start in the
    +                // document)
    +                if (range.collapsed !== this.isCollapsed) {
    +                    range.setStartAndEnd(sel.focusNode, sel.focusOffset, sel.anchorNode, sel.anchorOffset);
    +                }
    +
    +                return range;
    +            };
    +        }
    +
    +        function WrappedSelection(selection, docSelection, win) {
    +            this.nativeSelection = selection;
    +            this.docSelection = docSelection;
    +            this._ranges = [];
    +            this.win = win;
    +            this.refresh();
    +        }
    +
    +        WrappedSelection.prototype = api.selectionPrototype;
    +
    +        function deleteProperties(sel) {
    +            sel.win = sel.anchorNode = sel.focusNode = sel._ranges = null;
    +            sel.rangeCount = sel.anchorOffset = sel.focusOffset = 0;
    +            sel.detached = true;
    +        }
    +
    +        var cachedRangySelections = [];
    +
    +        function actOnCachedSelection(win, action) {
    +            var i = cachedRangySelections.length, cached, sel;
    +            while (i--) {
    +                cached = cachedRangySelections[i];
    +                sel = cached.selection;
    +                if (action == "deleteAll") {
    +                    deleteProperties(sel);
    +                } else if (cached.win == win) {
    +                    if (action == "delete") {
    +                        cachedRangySelections.splice(i, 1);
    +                        return true;
    +                    } else {
    +                        return sel;
    +                    }
    +                }
    +            }
    +            if (action == "deleteAll") {
    +                cachedRangySelections.length = 0;
    +            }
    +            return null;
    +        }
    +
    +        var getSelection = function(win) {
    +            // Check if the parameter is a Rangy Selection object
    +            if (win && win instanceof WrappedSelection) {
    +                win.refresh();
    +                return win;
    +            }
    +
    +            win = getWindow(win, "getNativeSelection");
    +
    +            var sel = actOnCachedSelection(win);
    +            var nativeSel = getNativeSelection(win), docSel = implementsDocSelection ? getDocSelection(win) : null;
    +            if (sel) {
    +                sel.nativeSelection = nativeSel;
    +                sel.docSelection = docSel;
    +                sel.refresh();
    +            } else {
    +                sel = new WrappedSelection(nativeSel, docSel, win);
    +                cachedRangySelections.push( { win: win, selection: sel } );
    +            }
    +            return sel;
    +        };
    +
    +        api.getSelection = getSelection;
    +
    +        api.getIframeSelection = function(iframeEl) {
    +            module.deprecationNotice("getIframeSelection()", "getSelection(iframeEl)");
    +            return api.getSelection(dom.getIframeWindow(iframeEl));
    +        };
    +
    +        var selProto = WrappedSelection.prototype;
    +
    +        function createControlSelection(sel, ranges) {
    +            // Ensure that the selection becomes of type "Control"
    +            var doc = getDocument(ranges[0].startContainer);
    +            var controlRange = getBody(doc).createControlRange();
    +            for (var i = 0, el, len = ranges.length; i < len; ++i) {
    +                el = getSingleElementFromRange(ranges[i]);
    +                try {
    +                    controlRange.add(el);
    +                } catch (ex) {
    +                    throw module.createError("setRanges(): Element within one of the specified Ranges could not be added to control selection (does it have layout?)");
    +                }
    +            }
    +            controlRange.select();
    +
    +            // Update the wrapped selection based on what's now in the native selection
    +            updateControlSelection(sel);
    +        }
    +
    +        // Selecting a range
    +        if (!useDocumentSelection && selectionHasAnchorAndFocus && util.areHostMethods(testSelection, ["removeAllRanges", "addRange"])) {
    +            selProto.removeAllRanges = function() {
    +                this.nativeSelection.removeAllRanges();
    +                updateEmptySelection(this);
    +            };
    +
    +            var addRangeBackward = function(sel, range) {
    +                addRangeBackwardToNative(sel.nativeSelection, range);
    +                sel.refresh();
    +            };
    +
    +            if (selectionHasRangeCount) {
    +                selProto.addRange = function(range, direction) {
    +                    if (implementsControlRange && implementsDocSelection && this.docSelection.type == CONTROL) {
    +                        addRangeToControlSelection(this, range);
    +                    } else {
    +                        if (isDirectionBackward(direction) && selectionHasExtend) {
    +                            addRangeBackward(this, range);
    +                        } else {
    +                            var previousRangeCount;
    +                            if (selectionSupportsMultipleRanges) {
    +                                previousRangeCount = this.rangeCount;
    +                            } else {
    +                                this.removeAllRanges();
    +                                previousRangeCount = 0;
    +                            }
    +                            // Clone the native range so that changing the selected range does not affect the selection.
    +                            // This is contrary to the spec but is the only way to achieve consistency between browsers. See
    +                            // issue 80.
    +                            this.nativeSelection.addRange(getNativeRange(range).cloneRange());
    +
    +                            // Check whether adding the range was successful
    +                            this.rangeCount = this.nativeSelection.rangeCount;
    +
    +                            if (this.rangeCount == previousRangeCount + 1) {
    +                                // The range was added successfully
    +
    +                                // Check whether the range that we added to the selection is reflected in the last range extracted from
    +                                // the selection
    +                                if (api.config.checkSelectionRanges) {
    +                                    var nativeRange = getSelectionRangeAt(this.nativeSelection, this.rangeCount - 1);
    +                                    if (nativeRange && !rangesEqual(nativeRange, range)) {
    +                                        // Happens in WebKit with, for example, a selection placed at the start of a text node
    +                                        range = new WrappedRange(nativeRange);
    +                                    }
    +                                }
    +                                this._ranges[this.rangeCount - 1] = range;
    +                                updateAnchorAndFocusFromRange(this, range, selectionIsBackward(this.nativeSelection));
    +                                this.isCollapsed = selectionIsCollapsed(this);
    +                            } else {
    +                                // The range was not added successfully. The simplest thing is to refresh
    +                                this.refresh();
    +                            }
    +                        }
    +                    }
    +                };
    +            } else {
    +                selProto.addRange = function(range, direction) {
    +                    if (isDirectionBackward(direction) && selectionHasExtend) {
    +                        addRangeBackward(this, range);
    +                    } else {
    +                        this.nativeSelection.addRange(getNativeRange(range));
    +                        this.refresh();
    +                    }
    +                };
    +            }
    +
    +            selProto.setRanges = function(ranges) {
    +                if (implementsControlRange && implementsDocSelection && ranges.length > 1) {
    +                    createControlSelection(this, ranges);
    +                } else {
    +                    this.removeAllRanges();
    +                    for (var i = 0, len = ranges.length; i < len; ++i) {
    +                        this.addRange(ranges[i]);
    +                    }
    +                }
    +            };
    +        } else if (isHostMethod(testSelection, "empty") && isHostMethod(testRange, "select") &&
    +                   implementsControlRange && useDocumentSelection) {
    +
    +            selProto.removeAllRanges = function() {
    +                // Added try/catch as fix for issue #21
    +                try {
    +                    this.docSelection.empty();
    +
    +                    // Check for empty() not working (issue #24)
    +                    if (this.docSelection.type != "None") {
    +                        // Work around failure to empty a control selection by instead selecting a TextRange and then
    +                        // calling empty()
    +                        var doc;
    +                        if (this.anchorNode) {
    +                            doc = getDocument(this.anchorNode);
    +                        } else if (this.docSelection.type == CONTROL) {
    +                            var controlRange = this.docSelection.createRange();
    +                            if (controlRange.length) {
    +                                doc = getDocument( controlRange.item(0) );
    +                            }
    +                        }
    +                        if (doc) {
    +                            var textRange = getBody(doc).createTextRange();
    +                            textRange.select();
    +                            this.docSelection.empty();
    +                        }
    +                    }
    +                } catch(ex) {}
    +                updateEmptySelection(this);
    +            };
    +
    +            selProto.addRange = function(range) {
    +                if (this.docSelection.type == CONTROL) {
    +                    addRangeToControlSelection(this, range);
    +                } else {
    +                    api.WrappedTextRange.rangeToTextRange(range).select();
    +                    this._ranges[0] = range;
    +                    this.rangeCount = 1;
    +                    this.isCollapsed = this._ranges[0].collapsed;
    +                    updateAnchorAndFocusFromRange(this, range, false);
    +                }
    +            };
    +
    +            selProto.setRanges = function(ranges) {
    +                this.removeAllRanges();
    +                var rangeCount = ranges.length;
    +                if (rangeCount > 1) {
    +                    createControlSelection(this, ranges);
    +                } else if (rangeCount) {
    +                    this.addRange(ranges[0]);
    +                }
    +            };
    +        } else {
    +            module.fail("No means of selecting a Range or TextRange was found");
    +            return false;
    +        }
    +
    +        selProto.getRangeAt = function(index) {
    +            if (index < 0 || index >= this.rangeCount) {
    +                throw new DOMException("INDEX_SIZE_ERR");
    +            } else {
    +                // Clone the range to preserve selection-range independence. See issue 80.
    +                return this._ranges[index].cloneRange();
    +            }
    +        };
    +
    +        var refreshSelection;
    +
    +        if (useDocumentSelection) {
    +            refreshSelection = function(sel) {
    +                var range;
    +                if (api.isSelectionValid(sel.win)) {
    +                    range = sel.docSelection.createRange();
    +                } else {
    +                    range = getBody(sel.win.document).createTextRange();
    +                    range.collapse(true);
    +                }
    +
    +                if (sel.docSelection.type == CONTROL) {
    +                    updateControlSelection(sel);
    +                } else if (isTextRange(range)) {
    +                    updateFromTextRange(sel, range);
    +                } else {
    +                    updateEmptySelection(sel);
    +                }
    +            };
    +        } else if (isHostMethod(testSelection, "getRangeAt") && typeof testSelection.rangeCount == NUMBER) {
    +            refreshSelection = function(sel) {
    +                if (implementsControlRange && implementsDocSelection && sel.docSelection.type == CONTROL) {
    +                    updateControlSelection(sel);
    +                } else {
    +                    sel._ranges.length = sel.rangeCount = sel.nativeSelection.rangeCount;
    +                    if (sel.rangeCount) {
    +                        for (var i = 0, len = sel.rangeCount; i < len; ++i) {
    +                            sel._ranges[i] = new api.WrappedRange(sel.nativeSelection.getRangeAt(i));
    +                        }
    +                        updateAnchorAndFocusFromRange(sel, sel._ranges[sel.rangeCount - 1], selectionIsBackward(sel.nativeSelection));
    +                        sel.isCollapsed = selectionIsCollapsed(sel);
    +                    } else {
    +                        updateEmptySelection(sel);
    +                    }
    +                }
    +            };
    +        } else if (selectionHasAnchorAndFocus && typeof testSelection.isCollapsed == BOOLEAN && typeof testRange.collapsed == BOOLEAN && features.implementsDomRange) {
    +            refreshSelection = function(sel) {
    +                var range, nativeSel = sel.nativeSelection;
    +                if (nativeSel.anchorNode) {
    +                    range = getSelectionRangeAt(nativeSel, 0);
    +                    sel._ranges = [range];
    +                    sel.rangeCount = 1;
    +                    updateAnchorAndFocusFromNativeSelection(sel);
    +                    sel.isCollapsed = selectionIsCollapsed(sel);
    +                } else {
    +                    updateEmptySelection(sel);
    +                }
    +            };
    +        } else {
    +            module.fail("No means of obtaining a Range or TextRange from the user's selection was found");
    +            return false;
    +        }
    +
    +        selProto.refresh = function(checkForChanges) {
    +            var oldRanges = checkForChanges ? this._ranges.slice(0) : null;
    +            var oldAnchorNode = this.anchorNode, oldAnchorOffset = this.anchorOffset;
    +
    +            refreshSelection(this);
    +            if (checkForChanges) {
    +                // Check the range count first
    +                var i = oldRanges.length;
    +                if (i != this._ranges.length) {
    +                    return true;
    +                }
    +
    +                // Now check the direction. Checking the anchor position is the same is enough since we're checking all the
    +                // ranges after this
    +                if (this.anchorNode != oldAnchorNode || this.anchorOffset != oldAnchorOffset) {
    +                    return true;
    +                }
    +
    +                // Finally, compare each range in turn
    +                while (i--) {
    +                    if (!rangesEqual(oldRanges[i], this._ranges[i])) {
    +                        return true;
    +                    }
    +                }
    +                return false;
    +            }
    +        };
    +
    +        // Removal of a single range
    +        var removeRangeManually = function(sel, range) {
    +            var ranges = sel.getAllRanges();
    +            sel.removeAllRanges();
    +            for (var i = 0, len = ranges.length; i < len; ++i) {
    +                if (!rangesEqual(range, ranges[i])) {
    +                    sel.addRange(ranges[i]);
    +                }
    +            }
    +            if (!sel.rangeCount) {
    +                updateEmptySelection(sel);
    +            }
    +        };
    +
    +        if (implementsControlRange && implementsDocSelection) {
    +            selProto.removeRange = function(range) {
    +                if (this.docSelection.type == CONTROL) {
    +                    var controlRange = this.docSelection.createRange();
    +                    var rangeElement = getSingleElementFromRange(range);
    +
    +                    // Create a new ControlRange containing all the elements in the selected ControlRange minus the
    +                    // element contained by the supplied range
    +                    var doc = getDocument(controlRange.item(0));
    +                    var newControlRange = getBody(doc).createControlRange();
    +                    var el, removed = false;
    +                    for (var i = 0, len = controlRange.length; i < len; ++i) {
    +                        el = controlRange.item(i);
    +                        if (el !== rangeElement || removed) {
    +                            newControlRange.add(controlRange.item(i));
    +                        } else {
    +                            removed = true;
    +                        }
    +                    }
    +                    newControlRange.select();
    +
    +                    // Update the wrapped selection based on what's now in the native selection
    +                    updateControlSelection(this);
    +                } else {
    +                    removeRangeManually(this, range);
    +                }
    +            };
    +        } else {
    +            selProto.removeRange = function(range) {
    +                removeRangeManually(this, range);
    +            };
    +        }
    +
    +        // Detecting if a selection is backward
    +        var selectionIsBackward;
    +        if (!useDocumentSelection && selectionHasAnchorAndFocus && features.implementsDomRange) {
    +            selectionIsBackward = winSelectionIsBackward;
    +
    +            selProto.isBackward = function() {
    +                return selectionIsBackward(this);
    +            };
    +        } else {
    +            selectionIsBackward = selProto.isBackward = function() {
    +                return false;
    +            };
    +        }
    +
    +        // Create an alias for backwards compatibility. From 1.3, everything is "backward" rather than "backwards"
    +        selProto.isBackwards = selProto.isBackward;
    +
    +        // Selection stringifier
    +        // This is conformant to the old HTML5 selections draft spec but differs from WebKit and Mozilla's implementation.
    +        // The current spec does not yet define this method.
    +        selProto.toString = function() {
    +            var rangeTexts = [];
    +            for (var i = 0, len = this.rangeCount; i < len; ++i) {
    +                rangeTexts[i] = "" + this._ranges[i];
    +            }
    +            return rangeTexts.join("");
    +        };
    +
    +        function assertNodeInSameDocument(sel, node) {
    +            if (sel.win.document != getDocument(node)) {
    +                throw new DOMException("WRONG_DOCUMENT_ERR");
    +            }
    +        }
    +
    +        // No current browser conforms fully to the spec for this method, so Rangy's own method is always used
    +        selProto.collapse = function(node, offset) {
    +            assertNodeInSameDocument(this, node);
    +            var range = api.createRange(node);
    +            range.collapseToPoint(node, offset);
    +            this.setSingleRange(range);
    +            this.isCollapsed = true;
    +        };
    +
    +        selProto.collapseToStart = function() {
    +            if (this.rangeCount) {
    +                var range = this._ranges[0];
    +                this.collapse(range.startContainer, range.startOffset);
    +            } else {
    +                throw new DOMException("INVALID_STATE_ERR");
    +            }
    +        };
    +
    +        selProto.collapseToEnd = function() {
    +            if (this.rangeCount) {
    +                var range = this._ranges[this.rangeCount - 1];
    +                this.collapse(range.endContainer, range.endOffset);
    +            } else {
    +                throw new DOMException("INVALID_STATE_ERR");
    +            }
    +        };
    +
    +        // The spec is very specific on how selectAllChildren should be implemented so the native implementation is
    +        // never used by Rangy.
    +        selProto.selectAllChildren = function(node) {
    +            assertNodeInSameDocument(this, node);
    +            var range = api.createRange(node);
    +            range.selectNodeContents(node);
    +            this.setSingleRange(range);
    +        };
    +
    +        selProto.deleteFromDocument = function() {
    +            // Sepcial behaviour required for IE's control selections
    +            if (implementsControlRange && implementsDocSelection && this.docSelection.type == CONTROL) {
    +                var controlRange = this.docSelection.createRange();
    +                var element;
    +                while (controlRange.length) {
    +                    element = controlRange.item(0);
    +                    controlRange.remove(element);
    +                    element.parentNode.removeChild(element);
    +                }
    +                this.refresh();
    +            } else if (this.rangeCount) {
    +                var ranges = this.getAllRanges();
    +                if (ranges.length) {
    +                    this.removeAllRanges();
    +                    for (var i = 0, len = ranges.length; i < len; ++i) {
    +                        ranges[i].deleteContents();
    +                    }
    +                    // The spec says nothing about what the selection should contain after calling deleteContents on each
    +                    // range. Firefox moves the selection to where the final selected range was, so we emulate that
    +                    this.addRange(ranges[len - 1]);
    +                }
    +            }
    +        };
    +
    +        // The following are non-standard extensions
    +        selProto.eachRange = function(func, returnValue) {
    +            for (var i = 0, len = this._ranges.length; i < len; ++i) {
    +                if ( func( this.getRangeAt(i) ) ) {
    +                    return returnValue;
    +                }
    +            }
    +        };
    +
    +        selProto.getAllRanges = function() {
    +            var ranges = [];
    +            this.eachRange(function(range) {
    +                ranges.push(range);
    +            });
    +            return ranges;
    +        };
    +
    +        selProto.setSingleRange = function(range, direction) {
    +            this.removeAllRanges();
    +            this.addRange(range, direction);
    +        };
    +
    +        selProto.callMethodOnEachRange = function(methodName, params) {
    +            var results = [];
    +            this.eachRange( function(range) {
    +                results.push( range[methodName].apply(range, params) );
    +            } );
    +            return results;
    +        };
    +        
    +        function createStartOrEndSetter(isStart) {
    +            return function(node, offset) {
    +                var range;
    +                if (this.rangeCount) {
    +                    range = this.getRangeAt(0);
    +                    range["set" + (isStart ? "Start" : "End")](node, offset);
    +                } else {
    +                    range = api.createRange(this.win.document);
    +                    range.setStartAndEnd(node, offset);
    +                }
    +                this.setSingleRange(range, this.isBackward());
    +            };
    +        }
    +
    +        selProto.setStart = createStartOrEndSetter(true);
    +        selProto.setEnd = createStartOrEndSetter(false);
    +        
    +        // Add select() method to Range prototype. Any existing selection will be removed.
    +        api.rangePrototype.select = function(direction) {
    +            getSelection( this.getDocument() ).setSingleRange(this, direction);
    +        };
    +
    +        selProto.changeEachRange = function(func) {
    +            var ranges = [];
    +            var backward = this.isBackward();
    +
    +            this.eachRange(function(range) {
    +                func(range);
    +                ranges.push(range);
    +            });
    +
    +            this.removeAllRanges();
    +            if (backward && ranges.length == 1) {
    +                this.addRange(ranges[0], "backward");
    +            } else {
    +                this.setRanges(ranges);
    +            }
    +        };
    +
    +        selProto.containsNode = function(node, allowPartial) {
    +            return this.eachRange( function(range) {
    +                return range.containsNode(node, allowPartial);
    +            }, true ) || false;
    +        };
    +
    +        selProto.getBookmark = function(containerNode) {
    +            return {
    +                backward: this.isBackward(),
    +                rangeBookmarks: this.callMethodOnEachRange("getBookmark", [containerNode])
    +            };
    +        };
    +
    +        selProto.moveToBookmark = function(bookmark) {
    +            var selRanges = [];
    +            for (var i = 0, rangeBookmark, range; rangeBookmark = bookmark.rangeBookmarks[i++]; ) {
    +                range = api.createRange(this.win);
    +                range.moveToBookmark(rangeBookmark);
    +                selRanges.push(range);
    +            }
    +            if (bookmark.backward) {
    +                this.setSingleRange(selRanges[0], "backward");
    +            } else {
    +                this.setRanges(selRanges);
    +            }
    +        };
    +
    +        selProto.toHtml = function() {
    +            var rangeHtmls = [];
    +            this.eachRange(function(range) {
    +                rangeHtmls.push( DomRange.toHtml(range) );
    +            });
    +            return rangeHtmls.join("");
    +        };
    +
    +        if (features.implementsTextRange) {
    +            selProto.getNativeTextRange = function() {
    +                var sel, textRange;
    +                if ( (sel = this.docSelection) ) {
    +                    var range = sel.createRange();
    +                    if (isTextRange(range)) {
    +                        return range;
    +                    } else {
    +                        throw module.createError("getNativeTextRange: selection is a control selection"); 
    +                    }
    +                } else if (this.rangeCount > 0) {
    +                    return api.WrappedTextRange.rangeToTextRange( this.getRangeAt(0) );
    +                } else {
    +                    throw module.createError("getNativeTextRange: selection contains no range");
    +                }
    +            };
    +        }
    +
    +        function inspect(sel) {
    +            var rangeInspects = [];
    +            var anchor = new DomPosition(sel.anchorNode, sel.anchorOffset);
    +            var focus = new DomPosition(sel.focusNode, sel.focusOffset);
    +            var name = (typeof sel.getName == "function") ? sel.getName() : "Selection";
    +
    +            if (typeof sel.rangeCount != "undefined") {
    +                for (var i = 0, len = sel.rangeCount; i < len; ++i) {
    +                    rangeInspects[i] = DomRange.inspect(sel.getRangeAt(i));
    +                }
    +            }
    +            return "[" + name + "(Ranges: " + rangeInspects.join(", ") +
    +                    ")(anchor: " + anchor.inspect() + ", focus: " + focus.inspect() + "]";
    +        }
    +
    +        selProto.getName = function() {
    +            return "WrappedSelection";
    +        };
    +
    +        selProto.inspect = function() {
    +            return inspect(this);
    +        };
    +
    +        selProto.detach = function() {
    +            actOnCachedSelection(this.win, "delete");
    +            deleteProperties(this);
    +        };
    +
    +        WrappedSelection.detachAll = function() {
    +            actOnCachedSelection(null, "deleteAll");
    +        };
    +
    +        WrappedSelection.inspect = inspect;
    +        WrappedSelection.isDirectionBackward = isDirectionBackward;
    +
    +        api.Selection = WrappedSelection;
    +
    +        api.selectionPrototype = selProto;
    +
    +        api.addShimListener(function(win) {
    +            if (typeof win.getSelection == "undefined") {
    +                win.getSelection = function() {
    +                    return getSelection(win);
    +                };
    +            }
    +            win = null;
    +        });
    +    });
    +    
    +
    +    /*----------------------------------------------------------------------------------------------------------------*/
    +
    +    return api;
    +}, this);;/**
    + * Selection save and restore module for Rangy.
    + * Saves and restores user selections using marker invisible elements in the DOM.
    + *
    + * Part of Rangy, a cross-browser JavaScript range and selection library
    + * http://code.google.com/p/rangy/
    + *
    + * Depends on Rangy core.
    + *
    + * Copyright 2014, Tim Down
    + * Licensed under the MIT license.
    + * Version: 1.3alpha.20140804
    + * Build date: 4 August 2014
    + */
    +(function(factory, global) {
    +    if (typeof define == "function" && define.amd) {
    +        // AMD. Register as an anonymous module with a dependency on Rangy.
    +        define(["rangy"], factory);
    +        /*
    +         } else if (typeof exports == "object") {
    +         // Node/CommonJS style for Browserify
    +         module.exports = factory;
    +         */
    +    } else {
    +        // No AMD or CommonJS support so we use the rangy global variable
    +        factory(global.rangy);
    +    }
    +})(function(rangy) {
    +    rangy.createModule("SaveRestore", ["WrappedRange"], function(api, module) {
    +        var dom = api.dom;
    +
    +        var markerTextChar = "\ufeff";
    +
    +        function gEBI(id, doc) {
    +            return (doc || document).getElementById(id);
    +        }
    +
    +        function insertRangeBoundaryMarker(range, atStart) {
    +            var markerId = "selectionBoundary_" + (+new Date()) + "_" + ("" + Math.random()).slice(2);
    +            var markerEl;
    +            var doc = dom.getDocument(range.startContainer);
    +
    +            // Clone the Range and collapse to the appropriate boundary point
    +            var boundaryRange = range.cloneRange();
    +            boundaryRange.collapse(atStart);
    +
    +            // Create the marker element containing a single invisible character using DOM methods and insert it
    +            markerEl = doc.createElement("span");
    +            markerEl.id = markerId;
    +            markerEl.style.lineHeight = "0";
    +            markerEl.style.display = "none";
    +            markerEl.className = "rangySelectionBoundary";
    +            markerEl.appendChild(doc.createTextNode(markerTextChar));
    +
    +            boundaryRange.insertNode(markerEl);
    +            return markerEl;
    +        }
    +
    +        function setRangeBoundary(doc, range, markerId, atStart) {
    +            var markerEl = gEBI(markerId, doc);
    +            if (markerEl) {
    +                range[atStart ? "setStartBefore" : "setEndBefore"](markerEl);
    +                markerEl.parentNode.removeChild(markerEl);
    +            } else {
    +                module.warn("Marker element has been removed. Cannot restore selection.");
    +            }
    +        }
    +
    +        function compareRanges(r1, r2) {
    +            return r2.compareBoundaryPoints(r1.START_TO_START, r1);
    +        }
    +
    +        function saveRange(range, backward) {
    +            var startEl, endEl, doc = api.DomRange.getRangeDocument(range), text = range.toString();
    +
    +            if (range.collapsed) {
    +                endEl = insertRangeBoundaryMarker(range, false);
    +                return {
    +                    document: doc,
    +                    markerId: endEl.id,
    +                    collapsed: true
    +                };
    +            } else {
    +                endEl = insertRangeBoundaryMarker(range, false);
    +                startEl = insertRangeBoundaryMarker(range, true);
    +
    +                return {
    +                    document: doc,
    +                    startMarkerId: startEl.id,
    +                    endMarkerId: endEl.id,
    +                    collapsed: false,
    +                    backward: backward,
    +                    toString: function() {
    +                        return "original text: '" + text + "', new text: '" + range.toString() + "'";
    +                    }
    +                };
    +            }
    +        }
    +
    +        function restoreRange(rangeInfo, normalize) {
    +            var doc = rangeInfo.document;
    +            if (typeof normalize == "undefined") {
    +                normalize = true;
    +            }
    +            var range = api.createRange(doc);
    +            if (rangeInfo.collapsed) {
    +                var markerEl = gEBI(rangeInfo.markerId, doc);
    +                if (markerEl) {
    +                    markerEl.style.display = "inline";
    +                    var previousNode = markerEl.previousSibling;
    +
    +                    // Workaround for issue 17
    +                    if (previousNode && previousNode.nodeType == 3) {
    +                        markerEl.parentNode.removeChild(markerEl);
    +                        range.collapseToPoint(previousNode, previousNode.length);
    +                    } else {
    +                        range.collapseBefore(markerEl);
    +                        markerEl.parentNode.removeChild(markerEl);
    +                    }
    +                } else {
    +                    module.warn("Marker element has been removed. Cannot restore selection.");
    +                }
    +            } else {
    +                setRangeBoundary(doc, range, rangeInfo.startMarkerId, true);
    +                setRangeBoundary(doc, range, rangeInfo.endMarkerId, false);
    +            }
    +
    +            if (normalize) {
    +                range.normalizeBoundaries();
    +            }
    +
    +            return range;
    +        }
    +
    +        function saveRanges(ranges, backward) {
    +            var rangeInfos = [], range, doc;
    +
    +            // Order the ranges by position within the DOM, latest first, cloning the array to leave the original untouched
    +            ranges = ranges.slice(0);
    +            ranges.sort(compareRanges);
    +
    +            for (var i = 0, len = ranges.length; i < len; ++i) {
    +                rangeInfos[i] = saveRange(ranges[i], backward);
    +            }
    +
    +            // Now that all the markers are in place and DOM manipulation over, adjust each range's boundaries to lie
    +            // between its markers
    +            for (i = len - 1; i >= 0; --i) {
    +                range = ranges[i];
    +                doc = api.DomRange.getRangeDocument(range);
    +                if (range.collapsed) {
    +                    range.collapseAfter(gEBI(rangeInfos[i].markerId, doc));
    +                } else {
    +                    range.setEndBefore(gEBI(rangeInfos[i].endMarkerId, doc));
    +                    range.setStartAfter(gEBI(rangeInfos[i].startMarkerId, doc));
    +                }
    +            }
    +
    +            return rangeInfos;
    +        }
    +
    +        function saveSelection(win) {
    +            if (!api.isSelectionValid(win)) {
    +                module.warn("Cannot save selection. This usually happens when the selection is collapsed and the selection document has lost focus.");
    +                return null;
    +            }
    +            var sel = api.getSelection(win);
    +            var ranges = sel.getAllRanges();
    +            var backward = (ranges.length == 1 && sel.isBackward());
    +
    +            var rangeInfos = saveRanges(ranges, backward);
    +
    +            // Ensure current selection is unaffected
    +            if (backward) {
    +                sel.setSingleRange(ranges[0], "backward");
    +            } else {
    +                sel.setRanges(ranges);
    +            }
    +
    +            return {
    +                win: win,
    +                rangeInfos: rangeInfos,
    +                restored: false
    +            };
    +        }
    +
    +        function restoreRanges(rangeInfos) {
    +            var ranges = [];
    +
    +            // Ranges are in reverse order of appearance in the DOM. We want to restore earliest first to avoid
    +            // normalization affecting previously restored ranges.
    +            var rangeCount = rangeInfos.length;
    +
    +            for (var i = rangeCount - 1; i >= 0; i--) {
    +                ranges[i] = restoreRange(rangeInfos[i], true);
    +            }
    +
    +            return ranges;
    +        }
    +
    +        function restoreSelection(savedSelection, preserveDirection) {
    +            if (!savedSelection.restored) {
    +                var rangeInfos = savedSelection.rangeInfos;
    +                var sel = api.getSelection(savedSelection.win);
    +                var ranges = restoreRanges(rangeInfos), rangeCount = rangeInfos.length;
    +
    +                if (rangeCount == 1 && preserveDirection && api.features.selectionHasExtend && rangeInfos[0].backward) {
    +                    sel.removeAllRanges();
    +                    sel.addRange(ranges[0], true);
    +                } else {
    +                    sel.setRanges(ranges);
    +                }
    +
    +                savedSelection.restored = true;
    +            }
    +        }
    +
    +        function removeMarkerElement(doc, markerId) {
    +            var markerEl = gEBI(markerId, doc);
    +            if (markerEl) {
    +                markerEl.parentNode.removeChild(markerEl);
    +            }
    +        }
    +
    +        function removeMarkers(savedSelection) {
    +            var rangeInfos = savedSelection.rangeInfos;
    +            for (var i = 0, len = rangeInfos.length, rangeInfo; i < len; ++i) {
    +                rangeInfo = rangeInfos[i];
    +                if (rangeInfo.collapsed) {
    +                    removeMarkerElement(savedSelection.doc, rangeInfo.markerId);
    +                } else {
    +                    removeMarkerElement(savedSelection.doc, rangeInfo.startMarkerId);
    +                    removeMarkerElement(savedSelection.doc, rangeInfo.endMarkerId);
    +                }
    +            }
    +        }
    +
    +        api.util.extend(api, {
    +            saveRange: saveRange,
    +            restoreRange: restoreRange,
    +            saveRanges: saveRanges,
    +            restoreRanges: restoreRanges,
    +            saveSelection: saveSelection,
    +            restoreSelection: restoreSelection,
    +            removeMarkerElement: removeMarkerElement,
    +            removeMarkers: removeMarkers
    +        });
    +    });
    +    
    +}, this);;/*
    +	Base.js, version 1.1a
    +	Copyright 2006-2010, Dean Edwards
    +	License: http://www.opensource.org/licenses/mit-license.php
    +*/
    +
    +var Base = function() {
    +	// dummy
    +};
    +
    +Base.extend = function(_instance, _static) { // subclass
    +	var extend = Base.prototype.extend;
    +	
    +	// build the prototype
    +	Base._prototyping = true;
    +	var proto = new this;
    +	extend.call(proto, _instance);
    +  proto.base = function() {
    +    // call this method from any other method to invoke that method's ancestor
    +  };
    +	delete Base._prototyping;
    +	
    +	// create the wrapper for the constructor function
    +	//var constructor = proto.constructor.valueOf(); //-dean
    +	var constructor = proto.constructor;
    +	var klass = proto.constructor = function() {
    +		if (!Base._prototyping) {
    +			if (this._constructing || this.constructor == klass) { // instantiation
    +				this._constructing = true;
    +				constructor.apply(this, arguments);
    +				delete this._constructing;
    +			} else if (arguments[0] != null) { // casting
    +				return (arguments[0].extend || extend).call(arguments[0], proto);
    +			}
    +		}
    +	};
    +	
    +	// build the class interface
    +	klass.ancestor = this;
    +	klass.extend = this.extend;
    +	klass.forEach = this.forEach;
    +	klass.implement = this.implement;
    +	klass.prototype = proto;
    +	klass.toString = this.toString;
    +	klass.valueOf = function(type) {
    +		//return (type == "object") ? klass : constructor; //-dean
    +		return (type == "object") ? klass : constructor.valueOf();
    +	};
    +	extend.call(klass, _static);
    +	// class initialisation
    +	if (typeof klass.init == "function") klass.init();
    +	return klass;
    +};
    +
    +Base.prototype = {	
    +	extend: function(source, value) {
    +		if (arguments.length > 1) { // extending with a name/value pair
    +			var ancestor = this[source];
    +			if (ancestor && (typeof value == "function") && // overriding a method?
    +				// the valueOf() comparison is to avoid circular references
    +				(!ancestor.valueOf || ancestor.valueOf() != value.valueOf()) &&
    +				/\bbase\b/.test(value)) {
    +				// get the underlying method
    +				var method = value.valueOf();
    +				// override
    +				value = function() {
    +					var previous = this.base || Base.prototype.base;
    +					this.base = ancestor;
    +					var returnValue = method.apply(this, arguments);
    +					this.base = previous;
    +					return returnValue;
    +				};
    +				// point to the underlying method
    +				value.valueOf = function(type) {
    +					return (type == "object") ? value : method;
    +				};
    +				value.toString = Base.toString;
    +			}
    +			this[source] = value;
    +		} else if (source) { // extending with an object literal
    +			var extend = Base.prototype.extend;
    +			// if this object has a customised extend method then use it
    +			if (!Base._prototyping && typeof this != "function") {
    +				extend = this.extend || extend;
    +			}
    +			var proto = {toSource: null};
    +			// do the "toString" and other methods manually
    +			var hidden = ["constructor", "toString", "valueOf"];
    +			// if we are prototyping then include the constructor
    +			var i = Base._prototyping ? 0 : 1;
    +			while (key = hidden[i++]) {
    +				if (source[key] != proto[key]) {
    +					extend.call(this, key, source[key]);
    +
    +				}
    +			}
    +			// copy each of the source object's properties to this object
    +			for (var key in source) {
    +				if (!proto[key]) extend.call(this, key, source[key]);
    +			}
    +		}
    +		return this;
    +	}
    +};
    +
    +// initialise
    +Base = Base.extend({
    +	constructor: function() {
    +		this.extend(arguments[0]);
    +	}
    +}, {
    +	ancestor: Object,
    +	version: "1.1",
    +	
    +	forEach: function(object, block, context) {
    +		for (var key in object) {
    +			if (this.prototype[key] === undefined) {
    +				block.call(context, object[key], key, object);
    +			}
    +		}
    +	},
    +		
    +	implement: function() {
    +		for (var i = 0; i < arguments.length; i++) {
    +			if (typeof arguments[i] == "function") {
    +				// if it's a function, call it
    +				arguments[i](this.prototype);
    +			} else {
    +				// add the interface using the extend method
    +				this.prototype.extend(arguments[i]);
    +			}
    +		}
    +		return this;
    +	},
    +	
    +	toString: function() {
    +		return String(this.valueOf());
    +	}
    +});;/**
    + * Detect browser support for specific features
    + */
    +wysihtml5.browser = (function() {
    +  var userAgent   = navigator.userAgent,
    +      testElement = document.createElement("div"),
    +      // Browser sniffing is unfortunately needed since some behaviors are impossible to feature detect
    +      isGecko     = userAgent.indexOf("Gecko")        !== -1 && userAgent.indexOf("KHTML") === -1,
    +      isWebKit    = userAgent.indexOf("AppleWebKit/") !== -1,
    +      isChrome    = userAgent.indexOf("Chrome/")      !== -1,
    +      isOpera     = userAgent.indexOf("Opera/")       !== -1;
    +
    +  function iosVersion(userAgent) {
    +    return +((/ipad|iphone|ipod/.test(userAgent) && userAgent.match(/ os (\d+).+? like mac os x/)) || [undefined, 0])[1];
    +  }
    +
    +  function androidVersion(userAgent) {
    +    return +(userAgent.match(/android (\d+)/) || [undefined, 0])[1];
    +  }
    +
    +  function isIE(version, equation) {
    +    var rv = -1,
    +        re;
    +
    +    if (navigator.appName == 'Microsoft Internet Explorer') {
    +      re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
    +    } else if (navigator.appName == 'Netscape') {
    +      re = new RegExp("Trident/.*rv:([0-9]{1,}[\.0-9]{0,})");
    +    }
    +
    +    if (re && re.exec(navigator.userAgent) != null) {
    +      rv = parseFloat(RegExp.$1);
    +    }
    +
    +    if (rv === -1) { return false; }
    +    if (!version) { return true; }
    +    if (!equation) { return version === rv; }
    +    if (equation === "<") { return version < rv; }
    +    if (equation === ">") { return version > rv; }
    +    if (equation === "<=") { return version <= rv; }
    +    if (equation === ">=") { return version >= rv; }
    +  }
    +
    +  return {
    +    // Static variable needed, publicly accessible, to be able override it in unit tests
    +    USER_AGENT: userAgent,
    +
    +    /**
    +     * Exclude browsers that are not capable of displaying and handling
    +     * contentEditable as desired:
    +     *    - iPhone, iPad (tested iOS 4.2.2) and Android (tested 2.2) refuse to make contentEditables focusable
    +     *    - IE < 8 create invalid markup and crash randomly from time to time
    +     *
    +     * @return {Boolean}
    +     */
    +    supported: function() {
    +      var userAgent                   = this.USER_AGENT.toLowerCase(),
    +          // Essential for making html elements editable
    +          hasContentEditableSupport   = "contentEditable" in testElement,
    +          // Following methods are needed in order to interact with the contentEditable area
    +          hasEditingApiSupport        = document.execCommand && document.queryCommandSupported && document.queryCommandState,
    +          // document selector apis are only supported by IE 8+, Safari 4+, Chrome and Firefox 3.5+
    +          hasQuerySelectorSupport     = document.querySelector && document.querySelectorAll,
    +          // contentEditable is unusable in mobile browsers (tested iOS 4.2.2, Android 2.2, Opera Mobile, WebOS 3.05)
    +          isIncompatibleMobileBrowser = (this.isIos() && iosVersion(userAgent) < 5) || (this.isAndroid() && androidVersion(userAgent) < 4) || userAgent.indexOf("opera mobi") !== -1 || userAgent.indexOf("hpwos/") !== -1;
    +      return hasContentEditableSupport
    +        && hasEditingApiSupport
    +        && hasQuerySelectorSupport
    +        && !isIncompatibleMobileBrowser;
    +    },
    +
    +    isTouchDevice: function() {
    +      return this.supportsEvent("touchmove");
    +    },
    +
    +    isIos: function() {
    +      return (/ipad|iphone|ipod/i).test(this.USER_AGENT);
    +    },
    +
    +    isAndroid: function() {
    +      return this.USER_AGENT.indexOf("Android") !== -1;
    +    },
    +
    +    /**
    +     * Whether the browser supports sandboxed iframes
    +     * Currently only IE 6+ offers such feature ');return b.join("")})}},fileButton:function(b,a,d){if(!(3>arguments.length)){i.call(this,a);var e=this;a.validate&&(this.validate=a.validate);var c=CKEDITOR.tools.extend({},a),f=c.onClick;c.className=(c.className?c.className+" ":"")+"cke_dialog_ui_button";c.onClick=function(c){var d=
    +a["for"];if(!f||f.call(this,c)!==false){b.getContentElement(d[0],d[1]).submit();this.disable()}};b.on("load",function(){b.getContentElement(a["for"][0],a["for"][1])._.buttons.push(e)});CKEDITOR.ui.dialog.button.call(this,b,c,d)}},html:function(){var b=/^\s*<[\w:]+\s+([^>]*)?>/,a=/^(\s*<[\w:]+(?:\s+[^>]*)?)((?:.|\r|\n)+)$/,d=/\/$/;return function(e,c,f){if(!(3>arguments.length)){var h=[],g=c.html;"<"!=g.charAt(0)&&(g=""+g+"");var k=c.focus;if(k){var j=this.focus;this.focus=function(){("function"==
    +typeof k?k:j).call(this);this.fire("focus")};c.isFocusable&&(this.isFocusable=this.isFocusable);this.keyboardFocusable=!0}CKEDITOR.ui.dialog.uiElement.call(this,e,c,h,"span",null,null,"");h=h.join("").match(b);g=g.match(a)||["","",""];d.test(g[1])&&(g[1]=g[1].slice(0,-1),g[2]="/"+g[2]);f.push([g[1]," ",h[1]||"",g[2]].join(""))}}}(),fieldset:function(b,a,d,e,c){var f=c.label;this._={children:a};CKEDITOR.ui.dialog.uiElement.call(this,b,c,e,"fieldset",null,null,function(){var a=[];f&&a.push(""+f+"");for(var b=0;ba.getChildCount()?(new CKEDITOR.dom.text(b,CKEDITOR.document)).appendTo(a):a.getChild(0).$.nodeValue=b;return this},getLabel:function(){var b=
    +CKEDITOR.document.getById(this._.labelId);return!b||1>b.getChildCount()?"":b.getChild(0).getText()},eventProcessors:o},!0);CKEDITOR.ui.dialog.button.prototype=CKEDITOR.tools.extend(new CKEDITOR.ui.dialog.uiElement,{click:function(){return!this._.disabled?this.fire("click",{dialog:this._.dialog}):!1},enable:function(){this._.disabled=!1;var b=this.getElement();b&&b.removeClass("cke_disabled")},disable:function(){this._.disabled=!0;this.getElement().addClass("cke_disabled")},isVisible:function(){return this.getElement().getFirst().isVisible()},
    +isEnabled:function(){return!this._.disabled},eventProcessors:CKEDITOR.tools.extend({},CKEDITOR.ui.dialog.uiElement.prototype.eventProcessors,{onClick:function(b,a){this.on("click",function(){a.apply(this,arguments)})}},!0),accessKeyUp:function(){this.click()},accessKeyDown:function(){this.focus()},keyboardFocusable:!0},!0);CKEDITOR.ui.dialog.textInput.prototype=CKEDITOR.tools.extend(new CKEDITOR.ui.dialog.labeledElement,{getInputElement:function(){return CKEDITOR.document.getById(this._.inputId)},
    +focus:function(){var b=this.selectParentTab();setTimeout(function(){var a=b.getInputElement();a&&a.$.focus()},0)},select:function(){var b=this.selectParentTab();setTimeout(function(){var a=b.getInputElement();a&&(a.$.focus(),a.$.select())},0)},accessKeyUp:function(){this.select()},setValue:function(b){!b&&(b="");return CKEDITOR.ui.dialog.uiElement.prototype.setValue.apply(this,arguments)},keyboardFocusable:!0},n,!0);CKEDITOR.ui.dialog.textarea.prototype=new CKEDITOR.ui.dialog.textInput;CKEDITOR.ui.dialog.select.prototype=
    +CKEDITOR.tools.extend(new CKEDITOR.ui.dialog.labeledElement,{getInputElement:function(){return this._.select.getElement()},add:function(b,a,d){var e=new CKEDITOR.dom.element("option",this.getDialog().getParentEditor().document),c=this.getInputElement().$;e.$.text=b;e.$.value=void 0===a||null===a?b:a;void 0===d||null===d?CKEDITOR.env.ie?c.add(e.$):c.add(e.$,null):c.add(e.$,d);return this},remove:function(b){this.getInputElement().$.remove(b);return this},clear:function(){for(var b=this.getInputElement().$;0<
    +b.length;)b.remove(0);return this},keyboardFocusable:!0},n,!0);CKEDITOR.ui.dialog.checkbox.prototype=CKEDITOR.tools.extend(new CKEDITOR.ui.dialog.uiElement,{getInputElement:function(){return this._.checkbox.getElement()},setValue:function(b,a){this.getInputElement().$.checked=b;!a&&this.fire("change",{value:b})},getValue:function(){return this.getInputElement().$.checked},accessKeyUp:function(){this.setValue(!this.getValue())},eventProcessors:{onChange:function(b,a){if(!CKEDITOR.env.ie||8','
    + +

    + diff --git a/public/assets/plugins/ckeditor/plugins/wsc/dialogs/tmp.html b/public/assets/plugins/ckeditor/plugins/wsc/dialogs/tmp.html new file mode 100644 index 00000000..6e9b012e --- /dev/null +++ b/public/assets/plugins/ckeditor/plugins/wsc/dialogs/tmp.html @@ -0,0 +1,115 @@ + + + + + iframe + + + + +
    + + + + + + + diff --git a/public/assets/plugins/ckeditor/plugins/wsc/dialogs/tmpFrameset.html b/public/assets/plugins/ckeditor/plugins/wsc/dialogs/tmpFrameset.html new file mode 100644 index 00000000..0d675f4d --- /dev/null +++ b/public/assets/plugins/ckeditor/plugins/wsc/dialogs/tmpFrameset.html @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + diff --git a/public/assets/plugins/ckeditor/plugins/wsc/dialogs/wsc.css b/public/assets/plugins/ckeditor/plugins/wsc/dialogs/wsc.css new file mode 100644 index 00000000..9e834f1d --- /dev/null +++ b/public/assets/plugins/ckeditor/plugins/wsc/dialogs/wsc.css @@ -0,0 +1,82 @@ +/* +Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. +For licensing, see LICENSE.html or http://ckeditor.com/license +*/ + +html, body +{ + background-color: transparent; + margin: 0px; + padding: 0px; +} + +body +{ + padding: 10px; +} + +body, td, input, select, textarea +{ + font-size: 11px; + font-family: 'Microsoft Sans Serif' , Arial, Helvetica, Verdana; +} + +.midtext +{ + padding:0px; + margin:10px; +} + +.midtext p +{ + padding:0px; + margin:10px; +} + +.Button +{ + border: #737357 1px solid; + color: #3b3b1f; + background-color: #c7c78f; +} + +.PopupTabArea +{ + color: #737357; + background-color: #e3e3c7; +} + +.PopupTitleBorder +{ + border-bottom: #d5d59d 1px solid; +} +.PopupTabEmptyArea +{ + padding-left: 10px; + border-bottom: #d5d59d 1px solid; +} + +.PopupTab, .PopupTabSelected +{ + border-right: #d5d59d 1px solid; + border-top: #d5d59d 1px solid; + border-left: #d5d59d 1px solid; + padding: 3px 5px 3px 5px; + color: #737357; +} + +.PopupTab +{ + margin-top: 1px; + border-bottom: #d5d59d 1px solid; + cursor: pointer; +} + +.PopupTabSelected +{ + font-weight: bold; + cursor: default; + padding-top: 4px; + border-bottom: #f1f1e3 1px solid; + background-color: #f1f1e3; +} diff --git a/public/assets/plugins/ckeditor/plugins/wsc/dialogs/wsc.js b/public/assets/plugins/ckeditor/plugins/wsc/dialogs/wsc.js new file mode 100644 index 00000000..22410bdb --- /dev/null +++ b/public/assets/plugins/ckeditor/plugins/wsc/dialogs/wsc.js @@ -0,0 +1,67 @@ +/* + Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. + For licensing, see LICENSE.html or http://ckeditor.com/license +*/ +(function(){function w(a){if(!a)throw"Languages-by-groups list are required for construct selectbox";var c=[],d="",f;for(f in a)for(var g in a[f]){var h=a[f][g];"en_US"==h?d=h:c.push(h)}c.sort();d&&c.unshift(d);return{getCurrentLangGroup:function(c){a:{for(var d in a)for(var f in a[d])if(f.toUpperCase()===c.toUpperCase()){c=d;break a}c=""}return c},setLangList:function(){var c={},d;for(d in a)for(var f in a[d])c[a[d][f]]=f;return c}()}}var e=function(){var a=function(a,b,f){var f=f||{},g=f.expires; +if("number"==typeof g&&g){var h=new Date;h.setTime(h.getTime()+1E3*g);g=f.expires=h}g&&g.toUTCString&&(f.expires=g.toUTCString());var b=encodeURIComponent(b),a=a+"="+b,e;for(e in f)b=f[e],a+="; "+e,!0!==b&&(a+="="+b);document.cookie=a};return{postMessage:{init:function(a){document.addEventListener?window.addEventListener("message",a,!1):window.attachEvent("onmessage",a)},send:function(a){var b=a.fn||null,f=a.id||"",g=a.target||window,h=a.message||{id:f};"[object Object]"==Object.prototype.toString.call(a.message)&& +(a.message.id||(a.message.id=f),h=a.message);a=window.JSON.stringify(h,b);g.postMessage(a,"*")}},hash:{create:function(){},parse:function(){}},cookie:{set:a,get:function(a){return(a=document.cookie.match(RegExp("(?:^|; )"+a.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g,"\\$1")+"=([^;]*)")))?decodeURIComponent(a[1]):void 0},remove:function(c){a(c,"",{expires:-1})}}}}(),a=a||{};a.TextAreaNumber=null;a.load=!0;a.cmd={SpellTab:"spell",Thesaurus:"thes",GrammTab:"grammar"};a.dialog=null;a.optionNode=null;a.selectNode= +null;a.grammerSuggest=null;a.textNode={};a.iframeMain=null;a.dataTemp="";a.div_overlay=null;a.textNodeInfo={};a.selectNode={};a.selectNodeResponce={};a.langList=null;a.langSelectbox=null;a.banner="";a.show_grammar=null;a.div_overlay_no_check=null;a.targetFromFrame={};a.onLoadOverlay=null;a.LocalizationComing={};a.OverlayPlace=null;a.LocalizationButton={ChangeTo:{instance:null,text:"Change to"},ChangeAll:{instance:null,text:"Change All"},IgnoreWord:{instance:null,text:"Ignore word"},IgnoreAllWords:{instance:null, +text:"Ignore all words"},Options:{instance:null,text:"Options",optionsDialog:{instance:null}},AddWord:{instance:null,text:"Add word"},FinishChecking:{instance:null,text:"Finish Checking"}};a.LocalizationLabel={ChangeTo:{instance:null,text:"Change to"},Suggestions:{instance:null,text:"Suggestions"}};var x=function(b){for(var c in b)b[c].instance.getElement().setText(a.LocalizationComing[c])},y=function(b){for(var c in b){if(!b[c].instance.setLabel)break;b[c].instance.setLabel(a.LocalizationComing[c])}}, +j,p;a.framesetHtml=function(b){return''};a.setIframe=function(b,c){var d=a.framesetHtml(c);return b.getElement().setHtml(d)};a.setCurrentIframe=function(b){a.setIframe(a.dialog._.contents[b].Content,b)};a.setHeightBannerFrame=function(){var b=a.dialog.getContentElement("SpellTab","banner").getElement(), +c=a.dialog.getContentElement("GrammTab","banner").getElement(),d=a.dialog.getContentElement("Thesaurus","banner").getElement();b.setStyle("height","90px");c.setStyle("height","90px");d.setStyle("height","90px")};a.setHeightFrame=function(){document.getElementById(a.iframeNumber+"_"+a.dialog._.currentTabId).style.height="240px"};a.sendData=function(b){var c=b._.currentTabId,d=b._.contents[c].Content,f,g;a.setIframe(d,c);b.parts.tabs.removeAllListeners();b.parts.tabs.on("click",function(h){h=h||window.event; +h.data.getTarget().is("a")&&c!=b._.currentTabId&&(c=b._.currentTabId,d=b._.contents[c].Content,f=a.iframeNumber+"_"+c,a.div_overlay.setEnable(),d.getElement().getChildCount()?t(a.targetFromFrame[f],a.cmd[c]):(a.setIframe(d,c),g=document.getElementById(f),a.targetFromFrame[f]=g.contentWindow))})};a.buildSelectLang=function(a){var c=new CKEDITOR.dom.element("div"),d=new CKEDITOR.dom.element("select"),a="wscLang"+a;c.addClass("cke_dialog_ui_input_select");c.setAttribute("role","presentation");c.setStyles({height:"auto", +position:"absolute",right:"0",top:"-1px",width:"160px","white-space":"normal"});d.setAttribute("id",a);d.addClass("cke_dialog_ui_input_select");d.setStyles({width:"160px"});c.append(d);return c};a.buildOptionLang=function(b,c){var d=document.getElementById("wscLang"+c),f=document.createDocumentFragment(),g,h,e=[];if(0===d.options.length){for(g in b)e.push([g,b[g]]);e.sort();for(var k=0;k
    "},{type:"html",id:"Content",label:"spellContent",html:"",setup:function(b){var b=a.iframeNumber+"_"+b._.currentTabId, +c=document.getElementById(b);a.targetFromFrame[b]=c.contentWindow}},{type:"hbox",id:"bottomGroup",style:"width:560px; margin: 0 auto;",widths:["50%","50%"],children:[{type:"hbox",id:"leftCol",align:"left",width:"50%",children:[{type:"vbox",id:"rightCol1",widths:["50%","50%"],children:[{type:"text",id:"text",label:a.LocalizationLabel.ChangeTo.text+":",labelLayout:"horizontal",labelStyle:"font: 12px/25px arial, sans-serif;",width:"140px","default":"",onShow:function(){a.textNode.SpellTab=this;a.LocalizationLabel.ChangeTo.instance= +this},onHide:function(){this.reset()}},{type:"hbox",id:"rightCol",align:"right",width:"30%",children:[{type:"vbox",id:"rightCol_col__left",children:[{type:"text",id:"labelSuggestions",label:a.LocalizationLabel.Suggestions.text+":",onShow:function(){a.LocalizationLabel.Suggestions.instance=this;this.getInputElement().hide()}},{type:"html",id:"logo",html:'WebSpellChecker.net',setup:function(){this.getElement().$.src= +a.logotype;this.getElement().getParent().setStyles({"text-align":"left"})}}]},{type:"select",id:"list_of_suggestions",labelStyle:"font: 12px/25px arial, sans-serif;",size:"6",inputStyle:"width: 140px; height: auto;",items:[["loading..."]],onShow:function(){p=this},onHide:function(){this.clear()},onChange:function(){a.textNode.SpellTab.setValue(this.getValue())}}]}]}]},{type:"hbox",id:"rightCol",align:"right",width:"50%",children:[{type:"vbox",id:"rightCol_col__left",widths:["50%","50%","50%","50%"], +children:[{type:"button",id:"ChangeTo",label:a.LocalizationButton.ChangeTo.text,title:"Change to",style:"width: 100%;",onLoad:function(){this.getElement().setAttribute("title-cmd",this.id);a.LocalizationButton.ChangeTo.instance=this},onClick:c},{type:"button",id:"ChangeAll",label:a.LocalizationButton.ChangeAll.text,title:"Change All",style:"width: 100%;",onLoad:function(){this.getElement().setAttribute("title-cmd",this.id);a.LocalizationButton.ChangeAll.instance=this},onClick:c},{type:"button",id:"AddWord", +label:a.LocalizationButton.AddWord.text,title:"Add word",style:"width: 100%;",onLoad:function(){this.getElement().setAttribute("title-cmd",this.id);a.LocalizationButton.AddWord.instance=this},onClick:c},{type:"button",id:"FinishChecking",label:a.LocalizationButton.FinishChecking.text,title:"Finish Checking",style:"width: 100%;margin-top: 9px;",onLoad:function(){this.getElement().setAttribute("title-cmd",this.id);a.LocalizationButton.FinishChecking.instance=this},onClick:c}]},{type:"vbox",id:"rightCol_col__right", +widths:["50%","50%","50%"],children:[{type:"button",id:"IgnoreWord",label:a.LocalizationButton.IgnoreWord.text,title:"Ignore word",style:"width: 100%;",onLoad:function(){this.getElement().setAttribute("title-cmd",this.id);a.LocalizationButton.IgnoreWord.instance=this},onClick:c},{type:"button",id:"IgnoreAllWords",label:a.LocalizationButton.IgnoreAllWords.text,title:"Ignore all words",style:"width: 100%;",onLoad:function(){this.getElement().setAttribute("title-cmd",this.id);a.LocalizationButton.IgnoreAllWords.instance= +this},onClick:c},{type:"button",id:"option",label:a.LocalizationButton.Options.text,title:"Option",style:"width: 100%;",onLoad:function(){a.LocalizationButton.Options.instance=this;"file:"==document.location.protocol&&this.disable()},onClick:function(){"file:"==document.location.protocol?alert("WSC: Options functionality is disabled when runing from file system"):b.openDialog("options")}}]}]}]},{type:"hbox",id:"BlockFinishChecking",style:"width:560px; margin: 0 auto;",widths:["70%","30%"],onShow:function(){this.getElement().hide()}, +onHide:l,children:[{type:"hbox",id:"leftCol",align:"left",width:"70%",children:[{type:"vbox",id:"rightCol1",setup:function(){this.getChild()[0].getElement().$.src=a.logotype;this.getChild()[0].getElement().getParent().setStyles({"text-align":"center"})},children:[{type:"html",id:"logo",html:'WebSpellChecker.net'}]}]},{type:"hbox",id:"rightCol",align:"right",width:"30%",children:[{type:"vbox", +id:"rightCol_col__left",children:[{type:"button",id:"Option_button",label:a.LocalizationButton.Options.text,title:"Option",style:"width: 100%;",onLoad:function(){this.getElement().setAttribute("title-cmd",this.id);"file:"==document.location.protocol&&this.disable()},onClick:function(){"file:"==document.location.protocol?alert("WSC: Options functionality is disabled when runing from file system"):b.openDialog("options")}},{type:"button",id:"FinishChecking",label:a.LocalizationButton.FinishChecking.text, +title:"Finish Checking",style:"width: 100%;",onLoad:function(){this.getElement().setAttribute("title-cmd",this.id)},onClick:c}]}]}]}]},{id:"GrammTab",label:"Grammar",accessKey:"G",elements:[{type:"html",id:"banner",label:"banner",style:"",html:"
    "},{type:"html",id:"Content",label:"GrammarContent",html:"",setup:function(){var b=a.iframeNumber+"_"+a.dialog._.currentTabId,c=document.getElementById(b);a.targetFromFrame[b]=c.contentWindow}},{type:"vbox",id:"bottomGroup",style:"width:560px; margin: 0 auto;", +children:[{type:"hbox",id:"leftCol",widths:["66%","34%"],children:[{type:"vbox",children:[{type:"text",id:"text",label:"Change to:",labelLayout:"horizontal",labelStyle:"font: 12px/25px arial, sans-serif;",inputStyle:"float: right; width: 200px;","default":"",onShow:function(){a.textNode.GrammTab=this},onHide:function(){this.reset()}},{type:"html",id:"html_text",html:"
    ", +onShow:function(){a.textNodeInfo.GrammTab=this}},{type:"html",id:"radio",html:"",onShow:function(){a.grammerSuggest=this}}]},{type:"vbox",children:[{type:"button",id:"ChangeTo",label:"Change to",title:"Change to",style:"width: 133px; float: right;",onLoad:function(){this.getElement().setAttribute("title-cmd",this.id)},onClick:c},{type:"button",id:"IgnoreWord",label:"Ignore word",title:"Ignore word",style:"width: 133px; float: right;",onLoad:function(){this.getElement().setAttribute("title-cmd",this.id)}, +onClick:c},{type:"button",id:"IgnoreAllWords",label:"Ignore Problem",title:"Ignore Problem",style:"width: 133px; float: right;",onLoad:function(){this.getElement().setAttribute("title-cmd",this.id)},onClick:c},{type:"button",id:"FinishChecking",label:"Finish Checking",title:"Finish Checking",style:"width: 133px; float: right; margin-top: 9px;",onLoad:function(){this.getElement().setAttribute("title-cmd",this.id)},onClick:c}]}]}]},{type:"hbox",id:"BlockFinishChecking",style:"width:560px; margin: 0 auto;", +widths:["70%","30%"],onShow:function(){this.getElement().hide()},onHide:l,children:[{type:"hbox",id:"leftCol",align:"left",width:"70%",children:[{type:"vbox",id:"rightCol1",children:[{type:"html",id:"logo",html:'WebSpellChecker.net',setup:function(){this.getElement().$.src=a.logotype;this.getElement().getParent().setStyles({"text-align":"center"})}}]}]},{type:"hbox",id:"rightCol",align:"right", +width:"30%",children:[{type:"vbox",id:"rightCol_col__left",children:[{type:"button",id:"FinishChecking",label:"Finish Checking",title:"Finish Checking",style:"width: 100%;",onLoad:function(){this.getElement().setAttribute("title-cmd",this.id)},onClick:c}]}]}]}]},{id:"Thesaurus",label:"Thesaurus",accessKey:"T",elements:[{type:"html",id:"banner",label:"banner",style:"",html:"
    "},{type:"html",id:"Content",label:"spellContent",html:"",setup:function(){var b=a.iframeNumber+"_"+a.dialog._.currentTabId, +c=document.getElementById(b);a.targetFromFrame[b]=c.contentWindow}},{type:"vbox",id:"bottomGroup",style:"width:560px; margin: -10px auto; overflow: hidden;",children:[{type:"hbox",widths:["75%","25%"],children:[{type:"vbox",children:[{type:"hbox",widths:["65%","35%"],children:[{type:"text",id:"ChangeTo",label:"Change to:",labelLayout:"horizontal",inputStyle:"width: 160px;",labelStyle:"font: 12px/25px arial, sans-serif;","default":"",onShow:function(){a.textNode.Thesaurus=this},onHide:function(){this.reset()}}, +{type:"button",id:"ChangeTo",label:"Change to",title:"Change to",style:"width: 121px; margin-top: 1px;",onLoad:function(){this.getElement().setAttribute("title-cmd",this.id)},onClick:c}]},{type:"hbox",children:[{type:"select",id:"categories",label:"Categories:",labelStyle:"font: 12px/25px arial, sans-serif;",size:"5",inputStyle:"width: 180px; height: auto;",items:[],onShow:function(){a.selectNode.categories=this},onHide:function(){this.clear()},onChange:function(){a.buildOptionSynonyms(this.getValue())}}, +{type:"select",id:"synonyms",label:"Synonyms:",labelStyle:"font: 12px/25px arial, sans-serif;",size:"5",inputStyle:"width: 180px; height: auto;",items:[],onShow:function(){a.selectNode.synonyms=this;a.textNode.Thesaurus.setValue(this.getValue())},onHide:function(){this.clear()},onChange:function(){a.textNode.Thesaurus.setValue(this.getValue())}}]}]},{type:"vbox",width:"120px",style:"margin-top:46px;",children:[{type:"html",id:"logotype",label:"WebSpellChecker.net",html:'WebSpellChecker.net', +setup:function(){this.getElement().$.src=a.logotype;this.getElement().getParent().setStyles({"text-align":"center"})}},{type:"button",id:"FinishChecking",label:"Finish Checking",title:"Finish Checking",style:"width: 121px; float: right; margin-top: 9px;",onLoad:function(){this.getElement().setAttribute("title-cmd",this.id)},onClick:c}]}]}]},{type:"hbox",id:"BlockFinishChecking",style:"width:560px; margin: 0 auto;",widths:["70%","30%"],onShow:function(){this.getElement().hide()},children:[{type:"hbox", +id:"leftCol",align:"left",width:"70%",children:[{type:"vbox",id:"rightCol1",children:[{type:"html",id:"logo",html:'WebSpellChecker.net',setup:function(){this.getElement().$.src=a.logotype;this.getElement().getParent().setStyles({"text-align":"center"})}}]}]},{type:"hbox",id:"rightCol",align:"right",width:"30%",children:[{type:"vbox",id:"rightCol_col__left",children:[{type:"button",id:"FinishChecking", +label:"Finish Checking",title:"Finish Checking",style:"width: 100%;",onLoad:function(){this.getElement().setAttribute("title-cmd",this.id)},onClick:c}]}]}]}]}]}});CKEDITOR.dialog.add("options",function(){var b=null,c={},d={},f=null,g=null;e.cookie.get("udn");e.cookie.get("osp");var h=function(){g=this.getElement().getAttribute("title-cmd");var a=[];a[0]=d.IgnoreAllCapsWords;a[1]=d.IgnoreWordsNumbers;a[2]=d.IgnoreMixedCaseWords;a[3]=d.IgnoreDomainNames;a=a.toString().replace(/,/g,"");e.cookie.set("osp", +a);e.cookie.set("udnCmd",g?g:"ignore");"delete"!=g&&(a="",""!==j.getValue()&&(a=j.getValue()),e.cookie.set("udn",a));e.postMessage.send({id:"options_dic_send"})},i=function(){f.getElement().setHtml(a.LocalizationComing.error);f.getElement().show()};return{title:a.LocalizationComing.Options,minWidth:430,minHeight:130,resizable:CKEDITOR.DIALOG_RESIZE_NONE,contents:[{id:"OptionsTab",label:"Options",accessKey:"O",elements:[{type:"hbox",id:"options_error",children:[{type:"html",style:"display: block;text-align: center;white-space: normal!important; font-size: 12px;color:red", +html:"
    ",onShow:function(){f=this}}]},{type:"vbox",id:"Options_content",children:[{type:"hbox",id:"Options_manager",widths:["52%","48%"],children:[{type:"fieldset",label:"Spell Checking Options",style:"border: none;margin-top: 13px;padding: 10px 0 10px 10px",onShow:function(){this.getInputElement().$.children[0].innerHTML=a.LocalizationComing.SpellCheckingOptions},children:[{type:"vbox",id:"Options_checkbox",children:[{type:"checkbox",id:"IgnoreAllCapsWords",label:"Ignore All-Caps Words", +labelStyle:"margin-left: 5px; font: 12px/16px arial, sans-serif;display: inline-block;white-space: normal;",style:"float:left; min-height: 16px;","default":"",onClick:function(){d[this.id]=!this.getValue()?0:1}},{type:"checkbox",id:"IgnoreWordsNumbers",label:"Ignore Words with Numbers",labelStyle:"margin-left: 5px; font: 12px/16px arial, sans-serif;display: inline-block;white-space: normal;",style:"float:left; min-height: 16px;","default":"",onClick:function(){d[this.id]=!this.getValue()?0:1}},{type:"checkbox", +id:"IgnoreMixedCaseWords",label:"Ignore Mixed-Case Words",labelStyle:"margin-left: 5px; font: 12px/16px arial, sans-serif;display: inline-block;white-space: normal;",style:"float:left; min-height: 16px;","default":"",onClick:function(){d[this.id]=!this.getValue()?0:1}},{type:"checkbox",id:"IgnoreDomainNames",label:"Ignore Domain Names",labelStyle:"margin-left: 5px; font: 12px/16px arial, sans-serif;display: inline-block;white-space: normal;",style:"float:left; min-height: 16px;","default":"",onClick:function(){d[this.id]= +!this.getValue()?0:1}}]}]},{type:"vbox",id:"Options_DictionaryName",children:[{type:"text",id:"DictionaryName",style:"margin-bottom: 10px",label:"Dictionary Name:",labelLayout:"vertical",labelStyle:"font: 12px/25px arial, sans-serif;","default":"",onLoad:function(){j=this;this.setValue(a.userDictionaryName?a.userDictionaryName:(e.cookie.get("udn"),this.getValue()))},onShow:function(){j=this;this.setValue(!e.cookie.get("udn")?this.getValue():e.cookie.get("udn"));this.setLabel(a.LocalizationComing.DictionaryName)}, +onHide:function(){this.reset()}},{type:"hbox",id:"Options_buttons",children:[{type:"vbox",id:"Options_leftCol_col",widths:["50%","50%"],children:[{type:"button",id:"create",label:"Create",title:"Create",style:"width: 100%;",onLoad:function(){this.getElement().setAttribute("title-cmd",this.id)},onShow:function(){this.getElement().setText(a.LocalizationComing.Create)},onClick:h},{type:"button",id:"restore",label:"Restore",title:"Restore",style:"width: 100%;",onLoad:function(){this.getElement().setAttribute("title-cmd", +this.id)},onShow:function(){this.getElement().setText(a.LocalizationComing.Restore)},onClick:h}]},{type:"vbox",id:"Options_rightCol_col",widths:["50%","50%"],children:[{type:"button",id:"rename",label:"Rename",title:"Rename",style:"width: 100%;",onLoad:function(){this.getElement().setAttribute("title-cmd",this.id)},onShow:function(){this.getElement().setText(a.LocalizationComing.Rename)},onClick:h},{type:"button",id:"delete",label:"Remove",title:"Remove",style:"width: 100%;",onLoad:function(){this.getElement().setAttribute("title-cmd", +this.id)},onShow:function(){this.getElement().setText(a.LocalizationComing.Remove)},onClick:h}]}]}]}]},{type:"hbox",id:"Options_text",children:[{type:"html",style:"text-align: justify;margin-top: 15px;white-space: normal!important; font-size: 12px;color:#777;",html:"
    "+a.LocalizationComing.OptionsTextIntro+"
    ",onShow:function(){this.getElement().setText(a.LocalizationComing.OptionsTextIntro)}}]}]}]}],buttons:[CKEDITOR.dialog.okButton,CKEDITOR.dialog.cancelButton],onOk:function(){var a=[]; +a[0]=d.IgnoreAllCapsWords;a[1]=d.IgnoreWordsNumbers;a[2]=d.IgnoreMixedCaseWords;a[3]=d.IgnoreDomainNames;a=a.toString().replace(/,/g,"");e.cookie.set("osp",a);e.cookie.set("udn",j.getValue());e.postMessage.send({id:"options_checkbox_send"});f.getElement().hide();f.getElement().setHtml(" ")},onLoad:function(){b=this;e.postMessage.init(i);c.IgnoreAllCapsWords=b.getContentElement("OptionsTab","IgnoreAllCapsWords");c.IgnoreWordsNumbers=b.getContentElement("OptionsTab","IgnoreWordsNumbers");c.IgnoreMixedCaseWords= +b.getContentElement("OptionsTab","IgnoreMixedCaseWords");c.IgnoreDomainNames=b.getContentElement("OptionsTab","IgnoreDomainNames")},onShow:function(){var b=e.cookie.get("osp").split("");d.IgnoreAllCapsWords=b[0];d.IgnoreWordsNumbers=b[1];d.IgnoreMixedCaseWords=b[2];d.IgnoreDomainNames=b[3];!parseInt(d.IgnoreAllCapsWords,10)?c.IgnoreAllCapsWords.setValue("",!1):c.IgnoreAllCapsWords.setValue("checked",!1);!parseInt(d.IgnoreWordsNumbers,10)?c.IgnoreWordsNumbers.setValue("",!1):c.IgnoreWordsNumbers.setValue("checked", +!1);!parseInt(d.IgnoreMixedCaseWords,10)?c.IgnoreMixedCaseWords.setValue("",!1):c.IgnoreMixedCaseWords.setValue("checked",!1);!parseInt(d.IgnoreDomainNames,10)?c.IgnoreDomainNames.setValue("",!1):c.IgnoreDomainNames.setValue("checked",!1);d.IgnoreAllCapsWords=!c.IgnoreAllCapsWords.getValue()?0:1;d.IgnoreWordsNumbers=!c.IgnoreWordsNumbers.getValue()?0:1;d.IgnoreMixedCaseWords=!c.IgnoreMixedCaseWords.getValue()?0:1;d.IgnoreDomainNames=!c.IgnoreDomainNames.getValue()?0:1;c.IgnoreAllCapsWords.getElement().$.lastChild.innerHTML= +a.LocalizationComing.IgnoreAllCapsWords;c.IgnoreWordsNumbers.getElement().$.lastChild.innerHTML=a.LocalizationComing.IgnoreWordsWithNumbers;c.IgnoreMixedCaseWords.getElement().$.lastChild.innerHTML=a.LocalizationComing.IgnoreMixedCaseWords;c.IgnoreDomainNames.getElement().$.lastChild.innerHTML=a.LocalizationComing.IgnoreDomainNames}}});CKEDITOR.dialog.on("resize",function(b){var b=b.data,c=b.dialog,d=CKEDITOR.document.getById(a.iframeNumber+"_"+c._.currentTabId);"checkspell"==c._.name&&(a.bnr?d&& +d.setSize("height",b.height-310):d&&d.setSize("height",b.height-220))});CKEDITOR.on("dialogDefinition",function(b){var c=b.data.definition;a.onLoadOverlay=new q({opacity:"1",background:"#fff",target:c.dialog.parts.tabs.getParent().$});a.onLoadOverlay.setEnable();c.dialog.on("show",function(){});c.dialog.on("cancel",function(){c.dialog.getParentEditor().config.wsc_onClose.call(this.document.getWindow().getFrame());a.div_overlay.setDisable();return!1},this,null,-1)})})(); \ No newline at end of file diff --git a/public/assets/plugins/ckeditor/plugins/wsc/dialogs/wsc_ie.js b/public/assets/plugins/ckeditor/plugins/wsc/dialogs/wsc_ie.js new file mode 100644 index 00000000..6b39b006 --- /dev/null +++ b/public/assets/plugins/ckeditor/plugins/wsc/dialogs/wsc_ie.js @@ -0,0 +1,11 @@ +/* + Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. + For licensing, see LICENSE.html or http://ckeditor.com/license +*/ +CKEDITOR.dialog.add("checkspell",function(a){function c(a,c){var d=0;return function(){"function"==typeof window.doSpell?("undefined"!=typeof e&&window.clearInterval(e),j(a)):180==d++&&window._cancelOnError(c)}}function j(c){var f=new window._SP_FCK_LangCompare,b=CKEDITOR.getUrl(a.plugins.wsc.path+"dialogs/"),e=b+"tmpFrameset.html";window.gFCKPluginName="wsc";f.setDefaulLangCode(a.config.defaultLanguage);window.doSpell({ctrl:g,lang:a.config.wsc_lang||f.getSPLangCode(a.langCode),intLang:a.config.wsc_uiLang|| +f.getSPLangCode(a.langCode),winType:d,onCancel:function(){c.hide()},onFinish:function(b){a.focus();c.getParentEditor().setData(b.value);c.hide()},staticFrame:e,framesetPath:e,iframePath:b+"ciframe.html",schemaURI:b+"wsc.css",userDictionaryName:a.config.wsc_userDictionaryName,customDictionaryName:a.config.wsc_customDictionaryIds&&a.config.wsc_customDictionaryIds.split(","),domainName:a.config.wsc_domainName});CKEDITOR.document.getById(h).setStyle("display","none");CKEDITOR.document.getById(d).setStyle("display", +"block")}var b=CKEDITOR.tools.getNextNumber(),d="cke_frame_"+b,g="cke_data_"+b,h="cke_error_"+b,e,b=document.location.protocol||"http:",i=a.lang.wsc.notAvailable,k='', +l=a.config.wsc_customLoaderScript||b+"//loader.webspellchecker.net/sproxy_fck/sproxy.php?plugin=fck2&customerid="+a.config.wsc_customerId+"&cmd=script&doc=wsc&schema=22";a.config.wsc_customLoaderScript&&(i+='

    '+a.lang.wsc.errorLoading.replace(/%s/g,a.config.wsc_customLoaderScript)+"

    ");window._cancelOnError=function(c){if("undefined"==typeof window.WSC_Error){CKEDITOR.document.getById(d).setStyle("display", +"none");var b=CKEDITOR.document.getById(h);b.setStyle("display","block");b.setHtml(c||a.lang.wsc.notAvailable)}};return{title:a.config.wsc_dialogTitle||a.lang.wsc.title,minWidth:485,minHeight:380,buttons:[CKEDITOR.dialog.cancelButton],onShow:function(){var b=this.getContentElement("general","content").getElement();b.setHtml(k);b.getChild(2).setStyle("height",this._.contentSize.height+"px");"function"!=typeof window.doSpell&&CKEDITOR.document.getHead().append(CKEDITOR.document.createElement("script", +{attributes:{type:"text/javascript",src:l}}));b=a.getData();CKEDITOR.document.getById(g).setValue(b);e=window.setInterval(c(this,i),250)},onHide:function(){window.ooo=void 0;window.int_framsetLoaded=void 0;window.framesetLoaded=void 0;window.is_window_opened=!1},contents:[{id:"general",label:a.config.wsc_dialogTitle||a.lang.wsc.title,padding:0,elements:[{type:"html",id:"content",html:""}]}]}}); +CKEDITOR.dialog.on("resize",function(a){var a=a.data,c=a.dialog;"checkspell"==c._.name&&((c=(c=c.getContentElement("general","content").getElement())&&c.getChild(2))&&c.setSize("height",a.height),c&&c.setSize("width",a.width))}); \ No newline at end of file diff --git a/public/assets/plugins/ckeditor/skins/moono/dialog.css b/public/assets/plugins/ckeditor/skins/moono/dialog.css new file mode 100644 index 00000000..29bbaf9f --- /dev/null +++ b/public/assets/plugins/ckeditor/skins/moono/dialog.css @@ -0,0 +1,5 @@ +/* +Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. +For licensing, see LICENSE.md or http://ckeditor.com/license +*/ +.cke_dialog{visibility:visible}.cke_dialog_body{z-index:1;background:#eaeaea;border:1px solid #b2b2b2;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_browser_gecko19 .cke_dialog_body{position:relative}.cke_dialog strong{font-weight:bold}.cke_dialog_title{font-weight:bold;font-size:13px;cursor:move;position:relative;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #999;padding:6px 10px;-moz-border-radius:2px 2px 0 0;-webkit-border-radius:2px 2px 0 0;border-radius:2px 2px 0 0;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_dialog_contents{background-color:#fff;overflow:auto;padding:15px 10px 5px 10px;margin-top:30px;border-top:1px solid #bfbfbf;-moz-border-radius:0 0 3px 3px;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px}.cke_dialog_contents_body{overflow:auto;padding:17px 10px 5px 10px;margin-top:22px}.cke_dialog_footer{text-align:right;position:relative;border:0;outline:1px solid #bfbfbf;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;-moz-border-radius:0 0 2px 2px;-webkit-border-radius:0 0 2px 2px;border-radius:0 0 2px 2px;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#cfd1cf));background-image:-moz-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-webkit-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-o-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-ms-linear-gradient(top,#ebebeb,#cfd1cf);background-image:linear-gradient(top,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_rtl .cke_dialog_footer{text-align:left}.cke_hc .cke_dialog_footer{outline:0;border-top:1px solid #fff}.cke_dialog .cke_resizer{margin-top:22px}.cke_dialog .cke_resizer_rtl{margin-left:5px}.cke_dialog .cke_resizer_ltr{margin-right:5px}.cke_dialog_tabs{height:24px;display:inline-block;margin:5px 0 0;position:absolute;z-index:2;left:10px}.cke_rtl .cke_dialog_tabs{right:10px}a.cke_dialog_tab{height:16px;padding:4px 8px;margin-right:3px;display:inline-block;cursor:pointer;line-height:16px;outline:0;color:#595959;border:1px solid #bfbfbf;-moz-border-radius:3px 3px 0 0;-webkit-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;background:#d4d4d4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fafafa),to(#ededed));background-image:-moz-linear-gradient(top,#fafafa,#ededed);background-image:-webkit-linear-gradient(top,#fafafa,#ededed);background-image:-o-linear-gradient(top,#fafafa,#ededed);background-image:-ms-linear-gradient(top,#fafafa,#ededed);background-image:linear-gradient(top,#fafafa,#ededed);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#fafafa',endColorstr='#ededed')}.cke_rtl a.cke_dialog_tab{margin-right:0;margin-left:3px}a.cke_dialog_tab:hover{background:#ebebeb;background:-moz-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#ebebeb),color-stop(100%,#dfdfdf));background:-webkit-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-o-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-ms-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:linear-gradient(to bottom,#ebebeb 0,#dfdfdf 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ebebeb',endColorstr='#dfdfdf',GradientType=0)}a.cke_dialog_tab_selected{background:#fff;color:#383838;border-bottom-color:#fff;cursor:default;filter:none}a.cke_dialog_tab_selected:hover{background:#ededed;background:-moz-linear-gradient(top,#ededed 0,#fff 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#ededed),color-stop(100%,#fff));background:-webkit-linear-gradient(top,#ededed 0,#fff 100%);background:-o-linear-gradient(top,#ededed 0,#fff 100%);background:-ms-linear-gradient(top,#ededed 0,#fff 100%);background:linear-gradient(to bottom,#ededed 0,#fff 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ededed',endColorstr='#ffffff',GradientType=0)}.cke_hc a.cke_dialog_tab:hover,.cke_hc a.cke_dialog_tab_selected{border:3px solid;padding:2px 6px}a.cke_dialog_tab_disabled{color:#bababa;cursor:default}.cke_single_page .cke_dialog_tabs{display:none}.cke_single_page .cke_dialog_contents{padding-top:5px;margin-top:0;border-top:0}.cke_dialog_close_button{background-image:url(images/close.png);background-repeat:no-repeat;background-position:0 0;position:absolute;cursor:pointer;text-align:center;height:20px;width:20px;top:5px;z-index:5}.cke_hidpi .cke_dialog_close_button{background-image:url(images/hidpi/close.png);background-size:16px}.cke_dialog_close_button span{display:none}.cke_hc .cke_dialog_close_button span{display:inline;cursor:pointer;font-weight:bold;position:relative;top:3px}.cke_ltr .cke_dialog_close_button{right:5px}.cke_rtl .cke_dialog_close_button{left:6px}.cke_dialog_close_button{top:4px}div.cke_disabled .cke_dialog_ui_labeled_content div *{background-color:#ddd;cursor:default}.cke_dialog_ui_vbox table,.cke_dialog_ui_hbox table{margin:auto}.cke_dialog_ui_vbox_child{padding:5px 0}.cke_dialog_ui_hbox{width:100%}.cke_dialog_ui_hbox_first,.cke_dialog_ui_hbox_child,.cke_dialog_ui_hbox_last{vertical-align:top}.cke_ltr .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_ui_hbox_child{padding-right:10px}.cke_rtl .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_ui_hbox_child{padding-left:10px}.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-right:5px}.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-left:5px;padding-right:0}.cke_hc div.cke_dialog_ui_input_text,.cke_hc div.cke_dialog_ui_input_password,.cke_hc div.cke_dialog_ui_input_textarea,.cke_hc div.cke_dialog_ui_input_select,.cke_hc div.cke_dialog_ui_input_file{border:1px solid}textarea.cke_dialog_ui_input_textarea{overflow:auto;resize:none}input.cke_dialog_ui_input_text,input.cke_dialog_ui_input_password,textarea.cke_dialog_ui_input_textarea{background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:4px 6px;outline:0;width:100%;*width:95%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}input.cke_dialog_ui_input_text:hover,input.cke_dialog_ui_input_password:hover,textarea.cke_dialog_ui_input_textarea:hover{border:1px solid #aeb3b9;border-top-color:#a0a6ad}input.cke_dialog_ui_input_text:focus,input.cke_dialog_ui_input_password:focus,textarea.cke_dialog_ui_input_textarea:focus,select.cke_dialog_ui_input_select:focus{outline:0;border:1px solid #139ff7;border-top-color:#1392e9}a.cke_dialog_ui_button{display:inline-block;*display:inline;*zoom:1;padding:3px 0;margin:0;text-align:center;color:#333;vertical-align:middle;cursor:pointer;border:1px solid #b6b6b6;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}span.cke_dialog_ui_button{padding:0 12px}a.cke_dialog_ui_button:hover{border-color:#9e9e9e;background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}a.cke_dialog_ui_button:focus,a.cke_dialog_ui_button:active{border-color:#969696;outline:0;-moz-box-shadow:0 0 6px rgba(0,0,0,.4) inset;-webkit-box-shadow:0 0 6px rgba(0,0,0,.4) inset;box-shadow:0 0 6px rgba(0,0,0,.4) inset}.cke_hc a.cke_dialog_ui_button:hover,.cke_hc a.cke_dialog_ui_button:focus,.cke_hc a.cke_dialog_ui_button:active{border:3px solid;padding-top:1px;padding-bottom:1px}.cke_hc a.cke_dialog_ui_button:hover span,.cke_hc a.cke_dialog_ui_button:focus span,.cke_hc a.cke_dialog_ui_button:active span{padding-left:10px;padding-right:10px}.cke_dialog_footer_buttons a.cke_dialog_ui_button span{color:inherit;font-size:12px;font-weight:bold;line-height:20px}a.cke_dialog_ui_button_ok{color:#fff;text-shadow:0 -1px 0 #55830c;border-color:#62a60a #62a60a #4d9200;background:#69b10b;background-image:-webkit-gradient(linear,0 0,0 100%,from(#9ad717),to(#69b10b));background-image:-webkit-linear-gradient(top,#9ad717,#69b10b);background-image:-o-linear-gradient(top,#9ad717,#69b10b);background-image:linear-gradient(to bottom,#9ad717,#69b10b);background-image:-moz-linear-gradient(top,#9ad717,#69b10b);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#9ad717',endColorstr='#69b10b')}a.cke_dialog_ui_button_ok:hover{border-color:#5b9909 #5b9909 #478500;background:#88be14;background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#88be14),color-stop(100%,#5d9c0a));background:-webkit-linear-gradient(top,#88be14 0,#5d9c0a 100%);background:-o-linear-gradient(top,#88be14 0,#5d9c0a 100%);background:linear-gradient(to bottom,#88be14 0,#5d9c0a 100%);background:-moz-linear-gradient(top,#88be14 0,#5d9c0a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#88be14',endColorstr='#5d9c0a',GradientType=0)}a.cke_dialog_ui_button span{text-shadow:0 1px 0 #fff}a.cke_dialog_ui_button_ok span{text-shadow:0 -1px 0 #55830c}span.cke_dialog_ui_button{cursor:pointer}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active,a.cke_dialog_ui_button_cancel:focus,a.cke_dialog_ui_button_cancel:active{border-width:2px;padding:2px 0}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active{border-color:#568c0a}a.cke_dialog_ui_button_ok:focus span,a.cke_dialog_ui_button_ok:active span,a.cke_dialog_ui_button_cancel:focus span,a.cke_dialog_ui_button_cancel:active span{padding:0 11px}.cke_dialog_footer_buttons{display:inline-table;margin:5px;width:auto;position:relative;vertical-align:middle}div.cke_dialog_ui_input_select{display:table}select.cke_dialog_ui_input_select{height:24px;line-height:24px;background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:2px 6px;outline:0;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}.cke_dialog_ui_input_file{width:100%;height:25px}.cke_hc .cke_dialog_ui_labeled_content input:focus,.cke_hc .cke_dialog_ui_labeled_content select:focus,.cke_hc .cke_dialog_ui_labeled_content textarea:focus{outline:1px dotted}.cke_dialog .cke_dark_background{background-color:#dedede}.cke_dialog .cke_light_background{background-color:#ebebeb}.cke_dialog .cke_centered{text-align:center}.cke_dialog a.cke_btn_reset{float:right;background:url(images/refresh.png) top left no-repeat;width:16px;height:16px;border:1px none;font-size:1px}.cke_hidpi .cke_dialog a.cke_btn_reset{background-size:16px;background-image:url(images/hidpi/refresh.png)}.cke_rtl .cke_dialog a.cke_btn_reset{float:left}.cke_dialog a.cke_btn_locked,.cke_dialog a.cke_btn_unlocked{float:left;width:16px;height:16px;background-repeat:no-repeat;border:none 1px;font-size:1px}.cke_dialog a.cke_btn_locked .cke_icon{display:none}.cke_rtl .cke_dialog a.cke_btn_locked,.cke_rtl .cke_dialog a.cke_btn_unlocked{float:right}.cke_dialog a.cke_btn_locked{background-image:url(images/lock.png)}.cke_dialog a.cke_btn_unlocked{background-image:url(images/lock-open.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked,.cke_hidpi .cke_dialog a.cke_btn_locked{background-size:16px}.cke_hidpi .cke_dialog a.cke_btn_locked{background-image:url(images/hidpi/lock.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked{background-image:url(images/hidpi/lock-open.png)}.cke_dialog .cke_btn_over{border:outset 1px;cursor:pointer}.cke_dialog .ImagePreviewBox{border:2px ridge black;overflow:scroll;height:200px;width:300px;padding:2px;background-color:white}.cke_dialog .ImagePreviewBox table td{white-space:normal}.cke_dialog .ImagePreviewLoader{position:absolute;white-space:normal;overflow:hidden;height:160px;width:230px;margin:2px;padding:2px;opacity:.9;filter:alpha(opacity = 90);background-color:#e4e4e4}.cke_dialog .FlashPreviewBox{white-space:normal;border:2px ridge black;overflow:auto;height:160px;width:390px;padding:2px;background-color:white}.cke_dialog .cke_pastetext{width:346px;height:170px}.cke_dialog .cke_pastetext textarea{width:340px;height:170px;resize:none}.cke_dialog iframe.cke_pasteframe{width:346px;height:130px;background-color:white;border:1px solid #aeb3b9;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}.cke_dialog .cke_hand{cursor:pointer}.cke_disabled{color:#a0a0a0}.cke_dialog_body .cke_label{display:none}.cke_dialog_body label{display:inline;margin-bottom:auto;cursor:default}.cke_dialog_body label.cke_required{font-weight:bold}a.cke_smile{overflow:hidden;display:block;text-align:center;padding:.3em 0}a.cke_smile img{vertical-align:middle}a.cke_specialchar{cursor:inherit;display:block;height:1.25em;padding:.2em .3em;text-align:center}a.cke_smile,a.cke_specialchar{border:1px solid transparent}a.cke_smile:hover,a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:hover,a.cke_specialchar:focus,a.cke_specialchar:active{background:#fff;outline:0}a.cke_smile:hover,a.cke_specialchar:hover{border-color:#888}a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:focus,a.cke_specialchar:active{border-color:#139ff7}.cke_dialog_contents a.colorChooser{display:block;margin-top:6px;margin-left:10px;width:80px}.cke_rtl .cke_dialog_contents a.colorChooser{margin-right:10px}.cke_dialog_ui_checkbox_input:focus,.cke_dialog_ui_radio_input:focus,.cke_btn_over{outline:1px dotted #696969}.cke_iframe_shim{display:block;position:absolute;top:0;left:0;z-index:-1;filter:alpha(opacity = 0);width:100%;height:100%} \ No newline at end of file diff --git a/public/assets/plugins/ckeditor/skins/moono/dialog_ie.css b/public/assets/plugins/ckeditor/skins/moono/dialog_ie.css new file mode 100644 index 00000000..153b05cb --- /dev/null +++ b/public/assets/plugins/ckeditor/skins/moono/dialog_ie.css @@ -0,0 +1,5 @@ +/* +Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. +For licensing, see LICENSE.md or http://ckeditor.com/license +*/ +.cke_dialog{visibility:visible}.cke_dialog_body{z-index:1;background:#eaeaea;border:1px solid #b2b2b2;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_browser_gecko19 .cke_dialog_body{position:relative}.cke_dialog strong{font-weight:bold}.cke_dialog_title{font-weight:bold;font-size:13px;cursor:move;position:relative;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #999;padding:6px 10px;-moz-border-radius:2px 2px 0 0;-webkit-border-radius:2px 2px 0 0;border-radius:2px 2px 0 0;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_dialog_contents{background-color:#fff;overflow:auto;padding:15px 10px 5px 10px;margin-top:30px;border-top:1px solid #bfbfbf;-moz-border-radius:0 0 3px 3px;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px}.cke_dialog_contents_body{overflow:auto;padding:17px 10px 5px 10px;margin-top:22px}.cke_dialog_footer{text-align:right;position:relative;border:0;outline:1px solid #bfbfbf;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;-moz-border-radius:0 0 2px 2px;-webkit-border-radius:0 0 2px 2px;border-radius:0 0 2px 2px;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#cfd1cf));background-image:-moz-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-webkit-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-o-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-ms-linear-gradient(top,#ebebeb,#cfd1cf);background-image:linear-gradient(top,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_rtl .cke_dialog_footer{text-align:left}.cke_hc .cke_dialog_footer{outline:0;border-top:1px solid #fff}.cke_dialog .cke_resizer{margin-top:22px}.cke_dialog .cke_resizer_rtl{margin-left:5px}.cke_dialog .cke_resizer_ltr{margin-right:5px}.cke_dialog_tabs{height:24px;display:inline-block;margin:5px 0 0;position:absolute;z-index:2;left:10px}.cke_rtl .cke_dialog_tabs{right:10px}a.cke_dialog_tab{height:16px;padding:4px 8px;margin-right:3px;display:inline-block;cursor:pointer;line-height:16px;outline:0;color:#595959;border:1px solid #bfbfbf;-moz-border-radius:3px 3px 0 0;-webkit-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;background:#d4d4d4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fafafa),to(#ededed));background-image:-moz-linear-gradient(top,#fafafa,#ededed);background-image:-webkit-linear-gradient(top,#fafafa,#ededed);background-image:-o-linear-gradient(top,#fafafa,#ededed);background-image:-ms-linear-gradient(top,#fafafa,#ededed);background-image:linear-gradient(top,#fafafa,#ededed);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#fafafa',endColorstr='#ededed')}.cke_rtl a.cke_dialog_tab{margin-right:0;margin-left:3px}a.cke_dialog_tab:hover{background:#ebebeb;background:-moz-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#ebebeb),color-stop(100%,#dfdfdf));background:-webkit-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-o-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-ms-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:linear-gradient(to bottom,#ebebeb 0,#dfdfdf 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ebebeb',endColorstr='#dfdfdf',GradientType=0)}a.cke_dialog_tab_selected{background:#fff;color:#383838;border-bottom-color:#fff;cursor:default;filter:none}a.cke_dialog_tab_selected:hover{background:#ededed;background:-moz-linear-gradient(top,#ededed 0,#fff 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#ededed),color-stop(100%,#fff));background:-webkit-linear-gradient(top,#ededed 0,#fff 100%);background:-o-linear-gradient(top,#ededed 0,#fff 100%);background:-ms-linear-gradient(top,#ededed 0,#fff 100%);background:linear-gradient(to bottom,#ededed 0,#fff 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ededed',endColorstr='#ffffff',GradientType=0)}.cke_hc a.cke_dialog_tab:hover,.cke_hc a.cke_dialog_tab_selected{border:3px solid;padding:2px 6px}a.cke_dialog_tab_disabled{color:#bababa;cursor:default}.cke_single_page .cke_dialog_tabs{display:none}.cke_single_page .cke_dialog_contents{padding-top:5px;margin-top:0;border-top:0}.cke_dialog_close_button{background-image:url(images/close.png);background-repeat:no-repeat;background-position:0 0;position:absolute;cursor:pointer;text-align:center;height:20px;width:20px;top:5px;z-index:5}.cke_hidpi .cke_dialog_close_button{background-image:url(images/hidpi/close.png);background-size:16px}.cke_dialog_close_button span{display:none}.cke_hc .cke_dialog_close_button span{display:inline;cursor:pointer;font-weight:bold;position:relative;top:3px}.cke_ltr .cke_dialog_close_button{right:5px}.cke_rtl .cke_dialog_close_button{left:6px}.cke_dialog_close_button{top:4px}div.cke_disabled .cke_dialog_ui_labeled_content div *{background-color:#ddd;cursor:default}.cke_dialog_ui_vbox table,.cke_dialog_ui_hbox table{margin:auto}.cke_dialog_ui_vbox_child{padding:5px 0}.cke_dialog_ui_hbox{width:100%}.cke_dialog_ui_hbox_first,.cke_dialog_ui_hbox_child,.cke_dialog_ui_hbox_last{vertical-align:top}.cke_ltr .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_ui_hbox_child{padding-right:10px}.cke_rtl .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_ui_hbox_child{padding-left:10px}.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-right:5px}.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-left:5px;padding-right:0}.cke_hc div.cke_dialog_ui_input_text,.cke_hc div.cke_dialog_ui_input_password,.cke_hc div.cke_dialog_ui_input_textarea,.cke_hc div.cke_dialog_ui_input_select,.cke_hc div.cke_dialog_ui_input_file{border:1px solid}textarea.cke_dialog_ui_input_textarea{overflow:auto;resize:none}input.cke_dialog_ui_input_text,input.cke_dialog_ui_input_password,textarea.cke_dialog_ui_input_textarea{background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:4px 6px;outline:0;width:100%;*width:95%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}input.cke_dialog_ui_input_text:hover,input.cke_dialog_ui_input_password:hover,textarea.cke_dialog_ui_input_textarea:hover{border:1px solid #aeb3b9;border-top-color:#a0a6ad}input.cke_dialog_ui_input_text:focus,input.cke_dialog_ui_input_password:focus,textarea.cke_dialog_ui_input_textarea:focus,select.cke_dialog_ui_input_select:focus{outline:0;border:1px solid #139ff7;border-top-color:#1392e9}a.cke_dialog_ui_button{display:inline-block;*display:inline;*zoom:1;padding:3px 0;margin:0;text-align:center;color:#333;vertical-align:middle;cursor:pointer;border:1px solid #b6b6b6;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}span.cke_dialog_ui_button{padding:0 12px}a.cke_dialog_ui_button:hover{border-color:#9e9e9e;background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}a.cke_dialog_ui_button:focus,a.cke_dialog_ui_button:active{border-color:#969696;outline:0;-moz-box-shadow:0 0 6px rgba(0,0,0,.4) inset;-webkit-box-shadow:0 0 6px rgba(0,0,0,.4) inset;box-shadow:0 0 6px rgba(0,0,0,.4) inset}.cke_hc a.cke_dialog_ui_button:hover,.cke_hc a.cke_dialog_ui_button:focus,.cke_hc a.cke_dialog_ui_button:active{border:3px solid;padding-top:1px;padding-bottom:1px}.cke_hc a.cke_dialog_ui_button:hover span,.cke_hc a.cke_dialog_ui_button:focus span,.cke_hc a.cke_dialog_ui_button:active span{padding-left:10px;padding-right:10px}.cke_dialog_footer_buttons a.cke_dialog_ui_button span{color:inherit;font-size:12px;font-weight:bold;line-height:20px}a.cke_dialog_ui_button_ok{color:#fff;text-shadow:0 -1px 0 #55830c;border-color:#62a60a #62a60a #4d9200;background:#69b10b;background-image:-webkit-gradient(linear,0 0,0 100%,from(#9ad717),to(#69b10b));background-image:-webkit-linear-gradient(top,#9ad717,#69b10b);background-image:-o-linear-gradient(top,#9ad717,#69b10b);background-image:linear-gradient(to bottom,#9ad717,#69b10b);background-image:-moz-linear-gradient(top,#9ad717,#69b10b);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#9ad717',endColorstr='#69b10b')}a.cke_dialog_ui_button_ok:hover{border-color:#5b9909 #5b9909 #478500;background:#88be14;background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#88be14),color-stop(100%,#5d9c0a));background:-webkit-linear-gradient(top,#88be14 0,#5d9c0a 100%);background:-o-linear-gradient(top,#88be14 0,#5d9c0a 100%);background:linear-gradient(to bottom,#88be14 0,#5d9c0a 100%);background:-moz-linear-gradient(top,#88be14 0,#5d9c0a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#88be14',endColorstr='#5d9c0a',GradientType=0)}a.cke_dialog_ui_button span{text-shadow:0 1px 0 #fff}a.cke_dialog_ui_button_ok span{text-shadow:0 -1px 0 #55830c}span.cke_dialog_ui_button{cursor:pointer}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active,a.cke_dialog_ui_button_cancel:focus,a.cke_dialog_ui_button_cancel:active{border-width:2px;padding:2px 0}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active{border-color:#568c0a}a.cke_dialog_ui_button_ok:focus span,a.cke_dialog_ui_button_ok:active span,a.cke_dialog_ui_button_cancel:focus span,a.cke_dialog_ui_button_cancel:active span{padding:0 11px}.cke_dialog_footer_buttons{display:inline-table;margin:5px;width:auto;position:relative;vertical-align:middle}div.cke_dialog_ui_input_select{display:table}select.cke_dialog_ui_input_select{height:24px;line-height:24px;background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:2px 6px;outline:0;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}.cke_dialog_ui_input_file{width:100%;height:25px}.cke_hc .cke_dialog_ui_labeled_content input:focus,.cke_hc .cke_dialog_ui_labeled_content select:focus,.cke_hc .cke_dialog_ui_labeled_content textarea:focus{outline:1px dotted}.cke_dialog .cke_dark_background{background-color:#dedede}.cke_dialog .cke_light_background{background-color:#ebebeb}.cke_dialog .cke_centered{text-align:center}.cke_dialog a.cke_btn_reset{float:right;background:url(images/refresh.png) top left no-repeat;width:16px;height:16px;border:1px none;font-size:1px}.cke_hidpi .cke_dialog a.cke_btn_reset{background-size:16px;background-image:url(images/hidpi/refresh.png)}.cke_rtl .cke_dialog a.cke_btn_reset{float:left}.cke_dialog a.cke_btn_locked,.cke_dialog a.cke_btn_unlocked{float:left;width:16px;height:16px;background-repeat:no-repeat;border:none 1px;font-size:1px}.cke_dialog a.cke_btn_locked .cke_icon{display:none}.cke_rtl .cke_dialog a.cke_btn_locked,.cke_rtl .cke_dialog a.cke_btn_unlocked{float:right}.cke_dialog a.cke_btn_locked{background-image:url(images/lock.png)}.cke_dialog a.cke_btn_unlocked{background-image:url(images/lock-open.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked,.cke_hidpi .cke_dialog a.cke_btn_locked{background-size:16px}.cke_hidpi .cke_dialog a.cke_btn_locked{background-image:url(images/hidpi/lock.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked{background-image:url(images/hidpi/lock-open.png)}.cke_dialog .cke_btn_over{border:outset 1px;cursor:pointer}.cke_dialog .ImagePreviewBox{border:2px ridge black;overflow:scroll;height:200px;width:300px;padding:2px;background-color:white}.cke_dialog .ImagePreviewBox table td{white-space:normal}.cke_dialog .ImagePreviewLoader{position:absolute;white-space:normal;overflow:hidden;height:160px;width:230px;margin:2px;padding:2px;opacity:.9;filter:alpha(opacity = 90);background-color:#e4e4e4}.cke_dialog .FlashPreviewBox{white-space:normal;border:2px ridge black;overflow:auto;height:160px;width:390px;padding:2px;background-color:white}.cke_dialog .cke_pastetext{width:346px;height:170px}.cke_dialog .cke_pastetext textarea{width:340px;height:170px;resize:none}.cke_dialog iframe.cke_pasteframe{width:346px;height:130px;background-color:white;border:1px solid #aeb3b9;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}.cke_dialog .cke_hand{cursor:pointer}.cke_disabled{color:#a0a0a0}.cke_dialog_body .cke_label{display:none}.cke_dialog_body label{display:inline;margin-bottom:auto;cursor:default}.cke_dialog_body label.cke_required{font-weight:bold}a.cke_smile{overflow:hidden;display:block;text-align:center;padding:.3em 0}a.cke_smile img{vertical-align:middle}a.cke_specialchar{cursor:inherit;display:block;height:1.25em;padding:.2em .3em;text-align:center}a.cke_smile,a.cke_specialchar{border:1px solid transparent}a.cke_smile:hover,a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:hover,a.cke_specialchar:focus,a.cke_specialchar:active{background:#fff;outline:0}a.cke_smile:hover,a.cke_specialchar:hover{border-color:#888}a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:focus,a.cke_specialchar:active{border-color:#139ff7}.cke_dialog_contents a.colorChooser{display:block;margin-top:6px;margin-left:10px;width:80px}.cke_rtl .cke_dialog_contents a.colorChooser{margin-right:10px}.cke_dialog_ui_checkbox_input:focus,.cke_dialog_ui_radio_input:focus,.cke_btn_over{outline:1px dotted #696969}.cke_iframe_shim{display:block;position:absolute;top:0;left:0;z-index:-1;filter:alpha(opacity = 0);width:100%;height:100%}.cke_rtl input.cke_dialog_ui_input_text,.cke_rtl input.cke_dialog_ui_input_password{padding-right:2px}.cke_rtl div.cke_dialog_ui_input_text,.cke_rtl div.cke_dialog_ui_input_password{padding-left:2px}.cke_rtl div.cke_dialog_ui_input_text{padding-right:1px}.cke_rtl .cke_dialog_ui_vbox_child,.cke_rtl .cke_dialog_ui_hbox_child,.cke_rtl .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_ui_hbox_last{padding-right:2px!important}.cke_hc .cke_dialog_title,.cke_hc .cke_dialog_footer,.cke_hc a.cke_dialog_tab,.cke_hc a.cke_dialog_ui_button,.cke_hc a.cke_dialog_ui_button:hover,.cke_hc a.cke_dialog_ui_button_ok,.cke_hc a.cke_dialog_ui_button_ok:hover{filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.cke_hc div.cke_dialog_ui_input_text,.cke_hc div.cke_dialog_ui_input_password,.cke_hc div.cke_dialog_ui_input_textarea,.cke_hc div.cke_dialog_ui_input_select,.cke_hc div.cke_dialog_ui_input_file{border:0} \ No newline at end of file diff --git a/public/assets/plugins/ckeditor/skins/moono/dialog_ie7.css b/public/assets/plugins/ckeditor/skins/moono/dialog_ie7.css new file mode 100644 index 00000000..459e72b8 --- /dev/null +++ b/public/assets/plugins/ckeditor/skins/moono/dialog_ie7.css @@ -0,0 +1,5 @@ +/* +Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. +For licensing, see LICENSE.md or http://ckeditor.com/license +*/ +.cke_dialog{visibility:visible}.cke_dialog_body{z-index:1;background:#eaeaea;border:1px solid #b2b2b2;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_browser_gecko19 .cke_dialog_body{position:relative}.cke_dialog strong{font-weight:bold}.cke_dialog_title{font-weight:bold;font-size:13px;cursor:move;position:relative;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #999;padding:6px 10px;-moz-border-radius:2px 2px 0 0;-webkit-border-radius:2px 2px 0 0;border-radius:2px 2px 0 0;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_dialog_contents{background-color:#fff;overflow:auto;padding:15px 10px 5px 10px;margin-top:30px;border-top:1px solid #bfbfbf;-moz-border-radius:0 0 3px 3px;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px}.cke_dialog_contents_body{overflow:auto;padding:17px 10px 5px 10px;margin-top:22px}.cke_dialog_footer{text-align:right;position:relative;border:0;outline:1px solid #bfbfbf;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;-moz-border-radius:0 0 2px 2px;-webkit-border-radius:0 0 2px 2px;border-radius:0 0 2px 2px;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#cfd1cf));background-image:-moz-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-webkit-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-o-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-ms-linear-gradient(top,#ebebeb,#cfd1cf);background-image:linear-gradient(top,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_rtl .cke_dialog_footer{text-align:left}.cke_hc .cke_dialog_footer{outline:0;border-top:1px solid #fff}.cke_dialog .cke_resizer{margin-top:22px}.cke_dialog .cke_resizer_rtl{margin-left:5px}.cke_dialog .cke_resizer_ltr{margin-right:5px}.cke_dialog_tabs{height:24px;display:inline-block;margin:5px 0 0;position:absolute;z-index:2;left:10px}.cke_rtl .cke_dialog_tabs{right:10px}a.cke_dialog_tab{height:16px;padding:4px 8px;margin-right:3px;display:inline-block;cursor:pointer;line-height:16px;outline:0;color:#595959;border:1px solid #bfbfbf;-moz-border-radius:3px 3px 0 0;-webkit-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;background:#d4d4d4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fafafa),to(#ededed));background-image:-moz-linear-gradient(top,#fafafa,#ededed);background-image:-webkit-linear-gradient(top,#fafafa,#ededed);background-image:-o-linear-gradient(top,#fafafa,#ededed);background-image:-ms-linear-gradient(top,#fafafa,#ededed);background-image:linear-gradient(top,#fafafa,#ededed);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#fafafa',endColorstr='#ededed')}.cke_rtl a.cke_dialog_tab{margin-right:0;margin-left:3px}a.cke_dialog_tab:hover{background:#ebebeb;background:-moz-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#ebebeb),color-stop(100%,#dfdfdf));background:-webkit-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-o-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-ms-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:linear-gradient(to bottom,#ebebeb 0,#dfdfdf 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ebebeb',endColorstr='#dfdfdf',GradientType=0)}a.cke_dialog_tab_selected{background:#fff;color:#383838;border-bottom-color:#fff;cursor:default;filter:none}a.cke_dialog_tab_selected:hover{background:#ededed;background:-moz-linear-gradient(top,#ededed 0,#fff 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#ededed),color-stop(100%,#fff));background:-webkit-linear-gradient(top,#ededed 0,#fff 100%);background:-o-linear-gradient(top,#ededed 0,#fff 100%);background:-ms-linear-gradient(top,#ededed 0,#fff 100%);background:linear-gradient(to bottom,#ededed 0,#fff 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ededed',endColorstr='#ffffff',GradientType=0)}.cke_hc a.cke_dialog_tab:hover,.cke_hc a.cke_dialog_tab_selected{border:3px solid;padding:2px 6px}a.cke_dialog_tab_disabled{color:#bababa;cursor:default}.cke_single_page .cke_dialog_tabs{display:none}.cke_single_page .cke_dialog_contents{padding-top:5px;margin-top:0;border-top:0}.cke_dialog_close_button{background-image:url(images/close.png);background-repeat:no-repeat;background-position:0 0;position:absolute;cursor:pointer;text-align:center;height:20px;width:20px;top:5px;z-index:5}.cke_hidpi .cke_dialog_close_button{background-image:url(images/hidpi/close.png);background-size:16px}.cke_dialog_close_button span{display:none}.cke_hc .cke_dialog_close_button span{display:inline;cursor:pointer;font-weight:bold;position:relative;top:3px}.cke_ltr .cke_dialog_close_button{right:5px}.cke_rtl .cke_dialog_close_button{left:6px}.cke_dialog_close_button{top:4px}div.cke_disabled .cke_dialog_ui_labeled_content div *{background-color:#ddd;cursor:default}.cke_dialog_ui_vbox table,.cke_dialog_ui_hbox table{margin:auto}.cke_dialog_ui_vbox_child{padding:5px 0}.cke_dialog_ui_hbox{width:100%}.cke_dialog_ui_hbox_first,.cke_dialog_ui_hbox_child,.cke_dialog_ui_hbox_last{vertical-align:top}.cke_ltr .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_ui_hbox_child{padding-right:10px}.cke_rtl .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_ui_hbox_child{padding-left:10px}.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-right:5px}.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-left:5px;padding-right:0}.cke_hc div.cke_dialog_ui_input_text,.cke_hc div.cke_dialog_ui_input_password,.cke_hc div.cke_dialog_ui_input_textarea,.cke_hc div.cke_dialog_ui_input_select,.cke_hc div.cke_dialog_ui_input_file{border:1px solid}textarea.cke_dialog_ui_input_textarea{overflow:auto;resize:none}input.cke_dialog_ui_input_text,input.cke_dialog_ui_input_password,textarea.cke_dialog_ui_input_textarea{background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:4px 6px;outline:0;width:100%;*width:95%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}input.cke_dialog_ui_input_text:hover,input.cke_dialog_ui_input_password:hover,textarea.cke_dialog_ui_input_textarea:hover{border:1px solid #aeb3b9;border-top-color:#a0a6ad}input.cke_dialog_ui_input_text:focus,input.cke_dialog_ui_input_password:focus,textarea.cke_dialog_ui_input_textarea:focus,select.cke_dialog_ui_input_select:focus{outline:0;border:1px solid #139ff7;border-top-color:#1392e9}a.cke_dialog_ui_button{display:inline-block;*display:inline;*zoom:1;padding:3px 0;margin:0;text-align:center;color:#333;vertical-align:middle;cursor:pointer;border:1px solid #b6b6b6;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}span.cke_dialog_ui_button{padding:0 12px}a.cke_dialog_ui_button:hover{border-color:#9e9e9e;background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}a.cke_dialog_ui_button:focus,a.cke_dialog_ui_button:active{border-color:#969696;outline:0;-moz-box-shadow:0 0 6px rgba(0,0,0,.4) inset;-webkit-box-shadow:0 0 6px rgba(0,0,0,.4) inset;box-shadow:0 0 6px rgba(0,0,0,.4) inset}.cke_hc a.cke_dialog_ui_button:hover,.cke_hc a.cke_dialog_ui_button:focus,.cke_hc a.cke_dialog_ui_button:active{border:3px solid;padding-top:1px;padding-bottom:1px}.cke_hc a.cke_dialog_ui_button:hover span,.cke_hc a.cke_dialog_ui_button:focus span,.cke_hc a.cke_dialog_ui_button:active span{padding-left:10px;padding-right:10px}.cke_dialog_footer_buttons a.cke_dialog_ui_button span{color:inherit;font-size:12px;font-weight:bold;line-height:20px}a.cke_dialog_ui_button_ok{color:#fff;text-shadow:0 -1px 0 #55830c;border-color:#62a60a #62a60a #4d9200;background:#69b10b;background-image:-webkit-gradient(linear,0 0,0 100%,from(#9ad717),to(#69b10b));background-image:-webkit-linear-gradient(top,#9ad717,#69b10b);background-image:-o-linear-gradient(top,#9ad717,#69b10b);background-image:linear-gradient(to bottom,#9ad717,#69b10b);background-image:-moz-linear-gradient(top,#9ad717,#69b10b);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#9ad717',endColorstr='#69b10b')}a.cke_dialog_ui_button_ok:hover{border-color:#5b9909 #5b9909 #478500;background:#88be14;background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#88be14),color-stop(100%,#5d9c0a));background:-webkit-linear-gradient(top,#88be14 0,#5d9c0a 100%);background:-o-linear-gradient(top,#88be14 0,#5d9c0a 100%);background:linear-gradient(to bottom,#88be14 0,#5d9c0a 100%);background:-moz-linear-gradient(top,#88be14 0,#5d9c0a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#88be14',endColorstr='#5d9c0a',GradientType=0)}a.cke_dialog_ui_button span{text-shadow:0 1px 0 #fff}a.cke_dialog_ui_button_ok span{text-shadow:0 -1px 0 #55830c}span.cke_dialog_ui_button{cursor:pointer}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active,a.cke_dialog_ui_button_cancel:focus,a.cke_dialog_ui_button_cancel:active{border-width:2px;padding:2px 0}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active{border-color:#568c0a}a.cke_dialog_ui_button_ok:focus span,a.cke_dialog_ui_button_ok:active span,a.cke_dialog_ui_button_cancel:focus span,a.cke_dialog_ui_button_cancel:active span{padding:0 11px}.cke_dialog_footer_buttons{display:inline-table;margin:5px;width:auto;position:relative;vertical-align:middle}div.cke_dialog_ui_input_select{display:table}select.cke_dialog_ui_input_select{height:24px;line-height:24px;background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:2px 6px;outline:0;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}.cke_dialog_ui_input_file{width:100%;height:25px}.cke_hc .cke_dialog_ui_labeled_content input:focus,.cke_hc .cke_dialog_ui_labeled_content select:focus,.cke_hc .cke_dialog_ui_labeled_content textarea:focus{outline:1px dotted}.cke_dialog .cke_dark_background{background-color:#dedede}.cke_dialog .cke_light_background{background-color:#ebebeb}.cke_dialog .cke_centered{text-align:center}.cke_dialog a.cke_btn_reset{float:right;background:url(images/refresh.png) top left no-repeat;width:16px;height:16px;border:1px none;font-size:1px}.cke_hidpi .cke_dialog a.cke_btn_reset{background-size:16px;background-image:url(images/hidpi/refresh.png)}.cke_rtl .cke_dialog a.cke_btn_reset{float:left}.cke_dialog a.cke_btn_locked,.cke_dialog a.cke_btn_unlocked{float:left;width:16px;height:16px;background-repeat:no-repeat;border:none 1px;font-size:1px}.cke_dialog a.cke_btn_locked .cke_icon{display:none}.cke_rtl .cke_dialog a.cke_btn_locked,.cke_rtl .cke_dialog a.cke_btn_unlocked{float:right}.cke_dialog a.cke_btn_locked{background-image:url(images/lock.png)}.cke_dialog a.cke_btn_unlocked{background-image:url(images/lock-open.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked,.cke_hidpi .cke_dialog a.cke_btn_locked{background-size:16px}.cke_hidpi .cke_dialog a.cke_btn_locked{background-image:url(images/hidpi/lock.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked{background-image:url(images/hidpi/lock-open.png)}.cke_dialog .cke_btn_over{border:outset 1px;cursor:pointer}.cke_dialog .ImagePreviewBox{border:2px ridge black;overflow:scroll;height:200px;width:300px;padding:2px;background-color:white}.cke_dialog .ImagePreviewBox table td{white-space:normal}.cke_dialog .ImagePreviewLoader{position:absolute;white-space:normal;overflow:hidden;height:160px;width:230px;margin:2px;padding:2px;opacity:.9;filter:alpha(opacity = 90);background-color:#e4e4e4}.cke_dialog .FlashPreviewBox{white-space:normal;border:2px ridge black;overflow:auto;height:160px;width:390px;padding:2px;background-color:white}.cke_dialog .cke_pastetext{width:346px;height:170px}.cke_dialog .cke_pastetext textarea{width:340px;height:170px;resize:none}.cke_dialog iframe.cke_pasteframe{width:346px;height:130px;background-color:white;border:1px solid #aeb3b9;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}.cke_dialog .cke_hand{cursor:pointer}.cke_disabled{color:#a0a0a0}.cke_dialog_body .cke_label{display:none}.cke_dialog_body label{display:inline;margin-bottom:auto;cursor:default}.cke_dialog_body label.cke_required{font-weight:bold}a.cke_smile{overflow:hidden;display:block;text-align:center;padding:.3em 0}a.cke_smile img{vertical-align:middle}a.cke_specialchar{cursor:inherit;display:block;height:1.25em;padding:.2em .3em;text-align:center}a.cke_smile,a.cke_specialchar{border:1px solid transparent}a.cke_smile:hover,a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:hover,a.cke_specialchar:focus,a.cke_specialchar:active{background:#fff;outline:0}a.cke_smile:hover,a.cke_specialchar:hover{border-color:#888}a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:focus,a.cke_specialchar:active{border-color:#139ff7}.cke_dialog_contents a.colorChooser{display:block;margin-top:6px;margin-left:10px;width:80px}.cke_rtl .cke_dialog_contents a.colorChooser{margin-right:10px}.cke_dialog_ui_checkbox_input:focus,.cke_dialog_ui_radio_input:focus,.cke_btn_over{outline:1px dotted #696969}.cke_iframe_shim{display:block;position:absolute;top:0;left:0;z-index:-1;filter:alpha(opacity = 0);width:100%;height:100%}.cke_rtl input.cke_dialog_ui_input_text,.cke_rtl input.cke_dialog_ui_input_password{padding-right:2px}.cke_rtl div.cke_dialog_ui_input_text,.cke_rtl div.cke_dialog_ui_input_password{padding-left:2px}.cke_rtl div.cke_dialog_ui_input_text{padding-right:1px}.cke_rtl .cke_dialog_ui_vbox_child,.cke_rtl .cke_dialog_ui_hbox_child,.cke_rtl .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_ui_hbox_last{padding-right:2px!important}.cke_hc .cke_dialog_title,.cke_hc .cke_dialog_footer,.cke_hc a.cke_dialog_tab,.cke_hc a.cke_dialog_ui_button,.cke_hc a.cke_dialog_ui_button:hover,.cke_hc a.cke_dialog_ui_button_ok,.cke_hc a.cke_dialog_ui_button_ok:hover{filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.cke_hc div.cke_dialog_ui_input_text,.cke_hc div.cke_dialog_ui_input_password,.cke_hc div.cke_dialog_ui_input_textarea,.cke_hc div.cke_dialog_ui_input_select,.cke_hc div.cke_dialog_ui_input_file{border:0}.cke_dialog_title{zoom:1}.cke_dialog_footer{border-top:1px solid #bfbfbf}.cke_dialog_footer_buttons{position:static}.cke_dialog_footer_buttons a.cke_dialog_ui_button{vertical-align:top}.cke_dialog .cke_resizer_ltr{padding-left:4px}.cke_dialog .cke_resizer_rtl{padding-right:4px}.cke_dialog_ui_input_text,.cke_dialog_ui_input_password,.cke_dialog_ui_input_textarea,.cke_dialog_ui_input_select{padding:0!important}.cke_dialog_ui_checkbox_input,.cke_dialog_ui_ratio_input,.cke_btn_reset,.cke_btn_locked,.cke_btn_unlocked{border:1px solid transparent!important} \ No newline at end of file diff --git a/public/assets/plugins/ckeditor/skins/moono/dialog_ie8.css b/public/assets/plugins/ckeditor/skins/moono/dialog_ie8.css new file mode 100644 index 00000000..74e9fa88 --- /dev/null +++ b/public/assets/plugins/ckeditor/skins/moono/dialog_ie8.css @@ -0,0 +1,5 @@ +/* +Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. +For licensing, see LICENSE.md or http://ckeditor.com/license +*/ +.cke_dialog{visibility:visible}.cke_dialog_body{z-index:1;background:#eaeaea;border:1px solid #b2b2b2;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_browser_gecko19 .cke_dialog_body{position:relative}.cke_dialog strong{font-weight:bold}.cke_dialog_title{font-weight:bold;font-size:13px;cursor:move;position:relative;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #999;padding:6px 10px;-moz-border-radius:2px 2px 0 0;-webkit-border-radius:2px 2px 0 0;border-radius:2px 2px 0 0;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_dialog_contents{background-color:#fff;overflow:auto;padding:15px 10px 5px 10px;margin-top:30px;border-top:1px solid #bfbfbf;-moz-border-radius:0 0 3px 3px;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px}.cke_dialog_contents_body{overflow:auto;padding:17px 10px 5px 10px;margin-top:22px}.cke_dialog_footer{text-align:right;position:relative;border:0;outline:1px solid #bfbfbf;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;-moz-border-radius:0 0 2px 2px;-webkit-border-radius:0 0 2px 2px;border-radius:0 0 2px 2px;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#cfd1cf));background-image:-moz-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-webkit-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-o-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-ms-linear-gradient(top,#ebebeb,#cfd1cf);background-image:linear-gradient(top,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_rtl .cke_dialog_footer{text-align:left}.cke_hc .cke_dialog_footer{outline:0;border-top:1px solid #fff}.cke_dialog .cke_resizer{margin-top:22px}.cke_dialog .cke_resizer_rtl{margin-left:5px}.cke_dialog .cke_resizer_ltr{margin-right:5px}.cke_dialog_tabs{height:24px;display:inline-block;margin:5px 0 0;position:absolute;z-index:2;left:10px}.cke_rtl .cke_dialog_tabs{right:10px}a.cke_dialog_tab{height:16px;padding:4px 8px;margin-right:3px;display:inline-block;cursor:pointer;line-height:16px;outline:0;color:#595959;border:1px solid #bfbfbf;-moz-border-radius:3px 3px 0 0;-webkit-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;background:#d4d4d4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fafafa),to(#ededed));background-image:-moz-linear-gradient(top,#fafafa,#ededed);background-image:-webkit-linear-gradient(top,#fafafa,#ededed);background-image:-o-linear-gradient(top,#fafafa,#ededed);background-image:-ms-linear-gradient(top,#fafafa,#ededed);background-image:linear-gradient(top,#fafafa,#ededed);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#fafafa',endColorstr='#ededed')}.cke_rtl a.cke_dialog_tab{margin-right:0;margin-left:3px}a.cke_dialog_tab:hover{background:#ebebeb;background:-moz-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#ebebeb),color-stop(100%,#dfdfdf));background:-webkit-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-o-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-ms-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:linear-gradient(to bottom,#ebebeb 0,#dfdfdf 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ebebeb',endColorstr='#dfdfdf',GradientType=0)}a.cke_dialog_tab_selected{background:#fff;color:#383838;border-bottom-color:#fff;cursor:default;filter:none}a.cke_dialog_tab_selected:hover{background:#ededed;background:-moz-linear-gradient(top,#ededed 0,#fff 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#ededed),color-stop(100%,#fff));background:-webkit-linear-gradient(top,#ededed 0,#fff 100%);background:-o-linear-gradient(top,#ededed 0,#fff 100%);background:-ms-linear-gradient(top,#ededed 0,#fff 100%);background:linear-gradient(to bottom,#ededed 0,#fff 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ededed',endColorstr='#ffffff',GradientType=0)}.cke_hc a.cke_dialog_tab:hover,.cke_hc a.cke_dialog_tab_selected{border:3px solid;padding:2px 6px}a.cke_dialog_tab_disabled{color:#bababa;cursor:default}.cke_single_page .cke_dialog_tabs{display:none}.cke_single_page .cke_dialog_contents{padding-top:5px;margin-top:0;border-top:0}.cke_dialog_close_button{background-image:url(images/close.png);background-repeat:no-repeat;background-position:0 0;position:absolute;cursor:pointer;text-align:center;height:20px;width:20px;top:5px;z-index:5}.cke_hidpi .cke_dialog_close_button{background-image:url(images/hidpi/close.png);background-size:16px}.cke_dialog_close_button span{display:none}.cke_hc .cke_dialog_close_button span{display:inline;cursor:pointer;font-weight:bold;position:relative;top:3px}.cke_ltr .cke_dialog_close_button{right:5px}.cke_rtl .cke_dialog_close_button{left:6px}.cke_dialog_close_button{top:4px}div.cke_disabled .cke_dialog_ui_labeled_content div *{background-color:#ddd;cursor:default}.cke_dialog_ui_vbox table,.cke_dialog_ui_hbox table{margin:auto}.cke_dialog_ui_vbox_child{padding:5px 0}.cke_dialog_ui_hbox{width:100%}.cke_dialog_ui_hbox_first,.cke_dialog_ui_hbox_child,.cke_dialog_ui_hbox_last{vertical-align:top}.cke_ltr .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_ui_hbox_child{padding-right:10px}.cke_rtl .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_ui_hbox_child{padding-left:10px}.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-right:5px}.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-left:5px;padding-right:0}.cke_hc div.cke_dialog_ui_input_text,.cke_hc div.cke_dialog_ui_input_password,.cke_hc div.cke_dialog_ui_input_textarea,.cke_hc div.cke_dialog_ui_input_select,.cke_hc div.cke_dialog_ui_input_file{border:1px solid}textarea.cke_dialog_ui_input_textarea{overflow:auto;resize:none}input.cke_dialog_ui_input_text,input.cke_dialog_ui_input_password,textarea.cke_dialog_ui_input_textarea{background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:4px 6px;outline:0;width:100%;*width:95%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}input.cke_dialog_ui_input_text:hover,input.cke_dialog_ui_input_password:hover,textarea.cke_dialog_ui_input_textarea:hover{border:1px solid #aeb3b9;border-top-color:#a0a6ad}input.cke_dialog_ui_input_text:focus,input.cke_dialog_ui_input_password:focus,textarea.cke_dialog_ui_input_textarea:focus,select.cke_dialog_ui_input_select:focus{outline:0;border:1px solid #139ff7;border-top-color:#1392e9}a.cke_dialog_ui_button{display:inline-block;*display:inline;*zoom:1;padding:3px 0;margin:0;text-align:center;color:#333;vertical-align:middle;cursor:pointer;border:1px solid #b6b6b6;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}span.cke_dialog_ui_button{padding:0 12px}a.cke_dialog_ui_button:hover{border-color:#9e9e9e;background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}a.cke_dialog_ui_button:focus,a.cke_dialog_ui_button:active{border-color:#969696;outline:0;-moz-box-shadow:0 0 6px rgba(0,0,0,.4) inset;-webkit-box-shadow:0 0 6px rgba(0,0,0,.4) inset;box-shadow:0 0 6px rgba(0,0,0,.4) inset}.cke_hc a.cke_dialog_ui_button:hover,.cke_hc a.cke_dialog_ui_button:focus,.cke_hc a.cke_dialog_ui_button:active{border:3px solid;padding-top:1px;padding-bottom:1px}.cke_hc a.cke_dialog_ui_button:hover span,.cke_hc a.cke_dialog_ui_button:focus span,.cke_hc a.cke_dialog_ui_button:active span{padding-left:10px;padding-right:10px}.cke_dialog_footer_buttons a.cke_dialog_ui_button span{color:inherit;font-size:12px;font-weight:bold;line-height:20px}a.cke_dialog_ui_button_ok{color:#fff;text-shadow:0 -1px 0 #55830c;border-color:#62a60a #62a60a #4d9200;background:#69b10b;background-image:-webkit-gradient(linear,0 0,0 100%,from(#9ad717),to(#69b10b));background-image:-webkit-linear-gradient(top,#9ad717,#69b10b);background-image:-o-linear-gradient(top,#9ad717,#69b10b);background-image:linear-gradient(to bottom,#9ad717,#69b10b);background-image:-moz-linear-gradient(top,#9ad717,#69b10b);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#9ad717',endColorstr='#69b10b')}a.cke_dialog_ui_button_ok:hover{border-color:#5b9909 #5b9909 #478500;background:#88be14;background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#88be14),color-stop(100%,#5d9c0a));background:-webkit-linear-gradient(top,#88be14 0,#5d9c0a 100%);background:-o-linear-gradient(top,#88be14 0,#5d9c0a 100%);background:linear-gradient(to bottom,#88be14 0,#5d9c0a 100%);background:-moz-linear-gradient(top,#88be14 0,#5d9c0a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#88be14',endColorstr='#5d9c0a',GradientType=0)}a.cke_dialog_ui_button span{text-shadow:0 1px 0 #fff}a.cke_dialog_ui_button_ok span{text-shadow:0 -1px 0 #55830c}span.cke_dialog_ui_button{cursor:pointer}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active,a.cke_dialog_ui_button_cancel:focus,a.cke_dialog_ui_button_cancel:active{border-width:2px;padding:2px 0}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active{border-color:#568c0a}a.cke_dialog_ui_button_ok:focus span,a.cke_dialog_ui_button_ok:active span,a.cke_dialog_ui_button_cancel:focus span,a.cke_dialog_ui_button_cancel:active span{padding:0 11px}.cke_dialog_footer_buttons{display:inline-table;margin:5px;width:auto;position:relative;vertical-align:middle}div.cke_dialog_ui_input_select{display:table}select.cke_dialog_ui_input_select{height:24px;line-height:24px;background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:2px 6px;outline:0;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}.cke_dialog_ui_input_file{width:100%;height:25px}.cke_hc .cke_dialog_ui_labeled_content input:focus,.cke_hc .cke_dialog_ui_labeled_content select:focus,.cke_hc .cke_dialog_ui_labeled_content textarea:focus{outline:1px dotted}.cke_dialog .cke_dark_background{background-color:#dedede}.cke_dialog .cke_light_background{background-color:#ebebeb}.cke_dialog .cke_centered{text-align:center}.cke_dialog a.cke_btn_reset{float:right;background:url(images/refresh.png) top left no-repeat;width:16px;height:16px;border:1px none;font-size:1px}.cke_hidpi .cke_dialog a.cke_btn_reset{background-size:16px;background-image:url(images/hidpi/refresh.png)}.cke_rtl .cke_dialog a.cke_btn_reset{float:left}.cke_dialog a.cke_btn_locked,.cke_dialog a.cke_btn_unlocked{float:left;width:16px;height:16px;background-repeat:no-repeat;border:none 1px;font-size:1px}.cke_dialog a.cke_btn_locked .cke_icon{display:none}.cke_rtl .cke_dialog a.cke_btn_locked,.cke_rtl .cke_dialog a.cke_btn_unlocked{float:right}.cke_dialog a.cke_btn_locked{background-image:url(images/lock.png)}.cke_dialog a.cke_btn_unlocked{background-image:url(images/lock-open.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked,.cke_hidpi .cke_dialog a.cke_btn_locked{background-size:16px}.cke_hidpi .cke_dialog a.cke_btn_locked{background-image:url(images/hidpi/lock.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked{background-image:url(images/hidpi/lock-open.png)}.cke_dialog .cke_btn_over{border:outset 1px;cursor:pointer}.cke_dialog .ImagePreviewBox{border:2px ridge black;overflow:scroll;height:200px;width:300px;padding:2px;background-color:white}.cke_dialog .ImagePreviewBox table td{white-space:normal}.cke_dialog .ImagePreviewLoader{position:absolute;white-space:normal;overflow:hidden;height:160px;width:230px;margin:2px;padding:2px;opacity:.9;filter:alpha(opacity = 90);background-color:#e4e4e4}.cke_dialog .FlashPreviewBox{white-space:normal;border:2px ridge black;overflow:auto;height:160px;width:390px;padding:2px;background-color:white}.cke_dialog .cke_pastetext{width:346px;height:170px}.cke_dialog .cke_pastetext textarea{width:340px;height:170px;resize:none}.cke_dialog iframe.cke_pasteframe{width:346px;height:130px;background-color:white;border:1px solid #aeb3b9;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}.cke_dialog .cke_hand{cursor:pointer}.cke_disabled{color:#a0a0a0}.cke_dialog_body .cke_label{display:none}.cke_dialog_body label{display:inline;margin-bottom:auto;cursor:default}.cke_dialog_body label.cke_required{font-weight:bold}a.cke_smile{overflow:hidden;display:block;text-align:center;padding:.3em 0}a.cke_smile img{vertical-align:middle}a.cke_specialchar{cursor:inherit;display:block;height:1.25em;padding:.2em .3em;text-align:center}a.cke_smile,a.cke_specialchar{border:1px solid transparent}a.cke_smile:hover,a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:hover,a.cke_specialchar:focus,a.cke_specialchar:active{background:#fff;outline:0}a.cke_smile:hover,a.cke_specialchar:hover{border-color:#888}a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:focus,a.cke_specialchar:active{border-color:#139ff7}.cke_dialog_contents a.colorChooser{display:block;margin-top:6px;margin-left:10px;width:80px}.cke_rtl .cke_dialog_contents a.colorChooser{margin-right:10px}.cke_dialog_ui_checkbox_input:focus,.cke_dialog_ui_radio_input:focus,.cke_btn_over{outline:1px dotted #696969}.cke_iframe_shim{display:block;position:absolute;top:0;left:0;z-index:-1;filter:alpha(opacity = 0);width:100%;height:100%}.cke_rtl input.cke_dialog_ui_input_text,.cke_rtl input.cke_dialog_ui_input_password{padding-right:2px}.cke_rtl div.cke_dialog_ui_input_text,.cke_rtl div.cke_dialog_ui_input_password{padding-left:2px}.cke_rtl div.cke_dialog_ui_input_text{padding-right:1px}.cke_rtl .cke_dialog_ui_vbox_child,.cke_rtl .cke_dialog_ui_hbox_child,.cke_rtl .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_ui_hbox_last{padding-right:2px!important}.cke_hc .cke_dialog_title,.cke_hc .cke_dialog_footer,.cke_hc a.cke_dialog_tab,.cke_hc a.cke_dialog_ui_button,.cke_hc a.cke_dialog_ui_button:hover,.cke_hc a.cke_dialog_ui_button_ok,.cke_hc a.cke_dialog_ui_button_ok:hover{filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.cke_hc div.cke_dialog_ui_input_text,.cke_hc div.cke_dialog_ui_input_password,.cke_hc div.cke_dialog_ui_input_textarea,.cke_hc div.cke_dialog_ui_input_select,.cke_hc div.cke_dialog_ui_input_file{border:0}a.cke_dialog_ui_button_ok:focus span,a.cke_dialog_ui_button_ok:active span,a.cke_dialog_ui_button_cancel:focus span,a.cke_dialog_ui_button_cancel:active span{display:block} \ No newline at end of file diff --git a/public/assets/plugins/ckeditor/skins/moono/dialog_iequirks.css b/public/assets/plugins/ckeditor/skins/moono/dialog_iequirks.css new file mode 100644 index 00000000..1c8e0558 --- /dev/null +++ b/public/assets/plugins/ckeditor/skins/moono/dialog_iequirks.css @@ -0,0 +1,5 @@ +/* +Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. +For licensing, see LICENSE.md or http://ckeditor.com/license +*/ +.cke_dialog{visibility:visible}.cke_dialog_body{z-index:1;background:#eaeaea;border:1px solid #b2b2b2;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_browser_gecko19 .cke_dialog_body{position:relative}.cke_dialog strong{font-weight:bold}.cke_dialog_title{font-weight:bold;font-size:13px;cursor:move;position:relative;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #999;padding:6px 10px;-moz-border-radius:2px 2px 0 0;-webkit-border-radius:2px 2px 0 0;border-radius:2px 2px 0 0;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_dialog_contents{background-color:#fff;overflow:auto;padding:15px 10px 5px 10px;margin-top:30px;border-top:1px solid #bfbfbf;-moz-border-radius:0 0 3px 3px;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px}.cke_dialog_contents_body{overflow:auto;padding:17px 10px 5px 10px;margin-top:22px}.cke_dialog_footer{text-align:right;position:relative;border:0;outline:1px solid #bfbfbf;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;-moz-border-radius:0 0 2px 2px;-webkit-border-radius:0 0 2px 2px;border-radius:0 0 2px 2px;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#cfd1cf));background-image:-moz-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-webkit-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-o-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-ms-linear-gradient(top,#ebebeb,#cfd1cf);background-image:linear-gradient(top,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_rtl .cke_dialog_footer{text-align:left}.cke_hc .cke_dialog_footer{outline:0;border-top:1px solid #fff}.cke_dialog .cke_resizer{margin-top:22px}.cke_dialog .cke_resizer_rtl{margin-left:5px}.cke_dialog .cke_resizer_ltr{margin-right:5px}.cke_dialog_tabs{height:24px;display:inline-block;margin:5px 0 0;position:absolute;z-index:2;left:10px}.cke_rtl .cke_dialog_tabs{right:10px}a.cke_dialog_tab{height:16px;padding:4px 8px;margin-right:3px;display:inline-block;cursor:pointer;line-height:16px;outline:0;color:#595959;border:1px solid #bfbfbf;-moz-border-radius:3px 3px 0 0;-webkit-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;background:#d4d4d4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fafafa),to(#ededed));background-image:-moz-linear-gradient(top,#fafafa,#ededed);background-image:-webkit-linear-gradient(top,#fafafa,#ededed);background-image:-o-linear-gradient(top,#fafafa,#ededed);background-image:-ms-linear-gradient(top,#fafafa,#ededed);background-image:linear-gradient(top,#fafafa,#ededed);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#fafafa',endColorstr='#ededed')}.cke_rtl a.cke_dialog_tab{margin-right:0;margin-left:3px}a.cke_dialog_tab:hover{background:#ebebeb;background:-moz-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#ebebeb),color-stop(100%,#dfdfdf));background:-webkit-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-o-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-ms-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:linear-gradient(to bottom,#ebebeb 0,#dfdfdf 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ebebeb',endColorstr='#dfdfdf',GradientType=0)}a.cke_dialog_tab_selected{background:#fff;color:#383838;border-bottom-color:#fff;cursor:default;filter:none}a.cke_dialog_tab_selected:hover{background:#ededed;background:-moz-linear-gradient(top,#ededed 0,#fff 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#ededed),color-stop(100%,#fff));background:-webkit-linear-gradient(top,#ededed 0,#fff 100%);background:-o-linear-gradient(top,#ededed 0,#fff 100%);background:-ms-linear-gradient(top,#ededed 0,#fff 100%);background:linear-gradient(to bottom,#ededed 0,#fff 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ededed',endColorstr='#ffffff',GradientType=0)}.cke_hc a.cke_dialog_tab:hover,.cke_hc a.cke_dialog_tab_selected{border:3px solid;padding:2px 6px}a.cke_dialog_tab_disabled{color:#bababa;cursor:default}.cke_single_page .cke_dialog_tabs{display:none}.cke_single_page .cke_dialog_contents{padding-top:5px;margin-top:0;border-top:0}.cke_dialog_close_button{background-image:url(images/close.png);background-repeat:no-repeat;background-position:0 0;position:absolute;cursor:pointer;text-align:center;height:20px;width:20px;top:5px;z-index:5}.cke_hidpi .cke_dialog_close_button{background-image:url(images/hidpi/close.png);background-size:16px}.cke_dialog_close_button span{display:none}.cke_hc .cke_dialog_close_button span{display:inline;cursor:pointer;font-weight:bold;position:relative;top:3px}.cke_ltr .cke_dialog_close_button{right:5px}.cke_rtl .cke_dialog_close_button{left:6px}.cke_dialog_close_button{top:4px}div.cke_disabled .cke_dialog_ui_labeled_content div *{background-color:#ddd;cursor:default}.cke_dialog_ui_vbox table,.cke_dialog_ui_hbox table{margin:auto}.cke_dialog_ui_vbox_child{padding:5px 0}.cke_dialog_ui_hbox{width:100%}.cke_dialog_ui_hbox_first,.cke_dialog_ui_hbox_child,.cke_dialog_ui_hbox_last{vertical-align:top}.cke_ltr .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_ui_hbox_child{padding-right:10px}.cke_rtl .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_ui_hbox_child{padding-left:10px}.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-right:5px}.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-left:5px;padding-right:0}.cke_hc div.cke_dialog_ui_input_text,.cke_hc div.cke_dialog_ui_input_password,.cke_hc div.cke_dialog_ui_input_textarea,.cke_hc div.cke_dialog_ui_input_select,.cke_hc div.cke_dialog_ui_input_file{border:1px solid}textarea.cke_dialog_ui_input_textarea{overflow:auto;resize:none}input.cke_dialog_ui_input_text,input.cke_dialog_ui_input_password,textarea.cke_dialog_ui_input_textarea{background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:4px 6px;outline:0;width:100%;*width:95%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}input.cke_dialog_ui_input_text:hover,input.cke_dialog_ui_input_password:hover,textarea.cke_dialog_ui_input_textarea:hover{border:1px solid #aeb3b9;border-top-color:#a0a6ad}input.cke_dialog_ui_input_text:focus,input.cke_dialog_ui_input_password:focus,textarea.cke_dialog_ui_input_textarea:focus,select.cke_dialog_ui_input_select:focus{outline:0;border:1px solid #139ff7;border-top-color:#1392e9}a.cke_dialog_ui_button{display:inline-block;*display:inline;*zoom:1;padding:3px 0;margin:0;text-align:center;color:#333;vertical-align:middle;cursor:pointer;border:1px solid #b6b6b6;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}span.cke_dialog_ui_button{padding:0 12px}a.cke_dialog_ui_button:hover{border-color:#9e9e9e;background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}a.cke_dialog_ui_button:focus,a.cke_dialog_ui_button:active{border-color:#969696;outline:0;-moz-box-shadow:0 0 6px rgba(0,0,0,.4) inset;-webkit-box-shadow:0 0 6px rgba(0,0,0,.4) inset;box-shadow:0 0 6px rgba(0,0,0,.4) inset}.cke_hc a.cke_dialog_ui_button:hover,.cke_hc a.cke_dialog_ui_button:focus,.cke_hc a.cke_dialog_ui_button:active{border:3px solid;padding-top:1px;padding-bottom:1px}.cke_hc a.cke_dialog_ui_button:hover span,.cke_hc a.cke_dialog_ui_button:focus span,.cke_hc a.cke_dialog_ui_button:active span{padding-left:10px;padding-right:10px}.cke_dialog_footer_buttons a.cke_dialog_ui_button span{color:inherit;font-size:12px;font-weight:bold;line-height:20px}a.cke_dialog_ui_button_ok{color:#fff;text-shadow:0 -1px 0 #55830c;border-color:#62a60a #62a60a #4d9200;background:#69b10b;background-image:-webkit-gradient(linear,0 0,0 100%,from(#9ad717),to(#69b10b));background-image:-webkit-linear-gradient(top,#9ad717,#69b10b);background-image:-o-linear-gradient(top,#9ad717,#69b10b);background-image:linear-gradient(to bottom,#9ad717,#69b10b);background-image:-moz-linear-gradient(top,#9ad717,#69b10b);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#9ad717',endColorstr='#69b10b')}a.cke_dialog_ui_button_ok:hover{border-color:#5b9909 #5b9909 #478500;background:#88be14;background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#88be14),color-stop(100%,#5d9c0a));background:-webkit-linear-gradient(top,#88be14 0,#5d9c0a 100%);background:-o-linear-gradient(top,#88be14 0,#5d9c0a 100%);background:linear-gradient(to bottom,#88be14 0,#5d9c0a 100%);background:-moz-linear-gradient(top,#88be14 0,#5d9c0a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#88be14',endColorstr='#5d9c0a',GradientType=0)}a.cke_dialog_ui_button span{text-shadow:0 1px 0 #fff}a.cke_dialog_ui_button_ok span{text-shadow:0 -1px 0 #55830c}span.cke_dialog_ui_button{cursor:pointer}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active,a.cke_dialog_ui_button_cancel:focus,a.cke_dialog_ui_button_cancel:active{border-width:2px;padding:2px 0}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active{border-color:#568c0a}a.cke_dialog_ui_button_ok:focus span,a.cke_dialog_ui_button_ok:active span,a.cke_dialog_ui_button_cancel:focus span,a.cke_dialog_ui_button_cancel:active span{padding:0 11px}.cke_dialog_footer_buttons{display:inline-table;margin:5px;width:auto;position:relative;vertical-align:middle}div.cke_dialog_ui_input_select{display:table}select.cke_dialog_ui_input_select{height:24px;line-height:24px;background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:2px 6px;outline:0;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}.cke_dialog_ui_input_file{width:100%;height:25px}.cke_hc .cke_dialog_ui_labeled_content input:focus,.cke_hc .cke_dialog_ui_labeled_content select:focus,.cke_hc .cke_dialog_ui_labeled_content textarea:focus{outline:1px dotted}.cke_dialog .cke_dark_background{background-color:#dedede}.cke_dialog .cke_light_background{background-color:#ebebeb}.cke_dialog .cke_centered{text-align:center}.cke_dialog a.cke_btn_reset{float:right;background:url(images/refresh.png) top left no-repeat;width:16px;height:16px;border:1px none;font-size:1px}.cke_hidpi .cke_dialog a.cke_btn_reset{background-size:16px;background-image:url(images/hidpi/refresh.png)}.cke_rtl .cke_dialog a.cke_btn_reset{float:left}.cke_dialog a.cke_btn_locked,.cke_dialog a.cke_btn_unlocked{float:left;width:16px;height:16px;background-repeat:no-repeat;border:none 1px;font-size:1px}.cke_dialog a.cke_btn_locked .cke_icon{display:none}.cke_rtl .cke_dialog a.cke_btn_locked,.cke_rtl .cke_dialog a.cke_btn_unlocked{float:right}.cke_dialog a.cke_btn_locked{background-image:url(images/lock.png)}.cke_dialog a.cke_btn_unlocked{background-image:url(images/lock-open.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked,.cke_hidpi .cke_dialog a.cke_btn_locked{background-size:16px}.cke_hidpi .cke_dialog a.cke_btn_locked{background-image:url(images/hidpi/lock.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked{background-image:url(images/hidpi/lock-open.png)}.cke_dialog .cke_btn_over{border:outset 1px;cursor:pointer}.cke_dialog .ImagePreviewBox{border:2px ridge black;overflow:scroll;height:200px;width:300px;padding:2px;background-color:white}.cke_dialog .ImagePreviewBox table td{white-space:normal}.cke_dialog .ImagePreviewLoader{position:absolute;white-space:normal;overflow:hidden;height:160px;width:230px;margin:2px;padding:2px;opacity:.9;filter:alpha(opacity = 90);background-color:#e4e4e4}.cke_dialog .FlashPreviewBox{white-space:normal;border:2px ridge black;overflow:auto;height:160px;width:390px;padding:2px;background-color:white}.cke_dialog .cke_pastetext{width:346px;height:170px}.cke_dialog .cke_pastetext textarea{width:340px;height:170px;resize:none}.cke_dialog iframe.cke_pasteframe{width:346px;height:130px;background-color:white;border:1px solid #aeb3b9;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}.cke_dialog .cke_hand{cursor:pointer}.cke_disabled{color:#a0a0a0}.cke_dialog_body .cke_label{display:none}.cke_dialog_body label{display:inline;margin-bottom:auto;cursor:default}.cke_dialog_body label.cke_required{font-weight:bold}a.cke_smile{overflow:hidden;display:block;text-align:center;padding:.3em 0}a.cke_smile img{vertical-align:middle}a.cke_specialchar{cursor:inherit;display:block;height:1.25em;padding:.2em .3em;text-align:center}a.cke_smile,a.cke_specialchar{border:1px solid transparent}a.cke_smile:hover,a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:hover,a.cke_specialchar:focus,a.cke_specialchar:active{background:#fff;outline:0}a.cke_smile:hover,a.cke_specialchar:hover{border-color:#888}a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:focus,a.cke_specialchar:active{border-color:#139ff7}.cke_dialog_contents a.colorChooser{display:block;margin-top:6px;margin-left:10px;width:80px}.cke_rtl .cke_dialog_contents a.colorChooser{margin-right:10px}.cke_dialog_ui_checkbox_input:focus,.cke_dialog_ui_radio_input:focus,.cke_btn_over{outline:1px dotted #696969}.cke_iframe_shim{display:block;position:absolute;top:0;left:0;z-index:-1;filter:alpha(opacity = 0);width:100%;height:100%}.cke_rtl input.cke_dialog_ui_input_text,.cke_rtl input.cke_dialog_ui_input_password{padding-right:2px}.cke_rtl div.cke_dialog_ui_input_text,.cke_rtl div.cke_dialog_ui_input_password{padding-left:2px}.cke_rtl div.cke_dialog_ui_input_text{padding-right:1px}.cke_rtl .cke_dialog_ui_vbox_child,.cke_rtl .cke_dialog_ui_hbox_child,.cke_rtl .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_ui_hbox_last{padding-right:2px!important}.cke_hc .cke_dialog_title,.cke_hc .cke_dialog_footer,.cke_hc a.cke_dialog_tab,.cke_hc a.cke_dialog_ui_button,.cke_hc a.cke_dialog_ui_button:hover,.cke_hc a.cke_dialog_ui_button_ok,.cke_hc a.cke_dialog_ui_button_ok:hover{filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.cke_hc div.cke_dialog_ui_input_text,.cke_hc div.cke_dialog_ui_input_password,.cke_hc div.cke_dialog_ui_input_textarea,.cke_hc div.cke_dialog_ui_input_select,.cke_hc div.cke_dialog_ui_input_file{border:0}.cke_dialog_footer{filter:""} \ No newline at end of file diff --git a/public/assets/plugins/ckeditor/skins/moono/dialog_opera.css b/public/assets/plugins/ckeditor/skins/moono/dialog_opera.css new file mode 100644 index 00000000..742ce731 --- /dev/null +++ b/public/assets/plugins/ckeditor/skins/moono/dialog_opera.css @@ -0,0 +1,5 @@ +/* +Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. +For licensing, see LICENSE.md or http://ckeditor.com/license +*/ +.cke_dialog{visibility:visible}.cke_dialog_body{z-index:1;background:#eaeaea;border:1px solid #b2b2b2;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_browser_gecko19 .cke_dialog_body{position:relative}.cke_dialog strong{font-weight:bold}.cke_dialog_title{font-weight:bold;font-size:13px;cursor:move;position:relative;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #999;padding:6px 10px;-moz-border-radius:2px 2px 0 0;-webkit-border-radius:2px 2px 0 0;border-radius:2px 2px 0 0;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_dialog_contents{background-color:#fff;overflow:auto;padding:15px 10px 5px 10px;margin-top:30px;border-top:1px solid #bfbfbf;-moz-border-radius:0 0 3px 3px;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px}.cke_dialog_contents_body{overflow:auto;padding:17px 10px 5px 10px;margin-top:22px}.cke_dialog_footer{text-align:right;position:relative;border:0;outline:1px solid #bfbfbf;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;-moz-border-radius:0 0 2px 2px;-webkit-border-radius:0 0 2px 2px;border-radius:0 0 2px 2px;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#cfd1cf));background-image:-moz-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-webkit-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-o-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-ms-linear-gradient(top,#ebebeb,#cfd1cf);background-image:linear-gradient(top,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_rtl .cke_dialog_footer{text-align:left}.cke_hc .cke_dialog_footer{outline:0;border-top:1px solid #fff}.cke_dialog .cke_resizer{margin-top:22px}.cke_dialog .cke_resizer_rtl{margin-left:5px}.cke_dialog .cke_resizer_ltr{margin-right:5px}.cke_dialog_tabs{height:24px;display:inline-block;margin:5px 0 0;position:absolute;z-index:2;left:10px}.cke_rtl .cke_dialog_tabs{right:10px}a.cke_dialog_tab{height:16px;padding:4px 8px;margin-right:3px;display:inline-block;cursor:pointer;line-height:16px;outline:0;color:#595959;border:1px solid #bfbfbf;-moz-border-radius:3px 3px 0 0;-webkit-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;background:#d4d4d4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fafafa),to(#ededed));background-image:-moz-linear-gradient(top,#fafafa,#ededed);background-image:-webkit-linear-gradient(top,#fafafa,#ededed);background-image:-o-linear-gradient(top,#fafafa,#ededed);background-image:-ms-linear-gradient(top,#fafafa,#ededed);background-image:linear-gradient(top,#fafafa,#ededed);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#fafafa',endColorstr='#ededed')}.cke_rtl a.cke_dialog_tab{margin-right:0;margin-left:3px}a.cke_dialog_tab:hover{background:#ebebeb;background:-moz-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#ebebeb),color-stop(100%,#dfdfdf));background:-webkit-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-o-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-ms-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:linear-gradient(to bottom,#ebebeb 0,#dfdfdf 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ebebeb',endColorstr='#dfdfdf',GradientType=0)}a.cke_dialog_tab_selected{background:#fff;color:#383838;border-bottom-color:#fff;cursor:default;filter:none}a.cke_dialog_tab_selected:hover{background:#ededed;background:-moz-linear-gradient(top,#ededed 0,#fff 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#ededed),color-stop(100%,#fff));background:-webkit-linear-gradient(top,#ededed 0,#fff 100%);background:-o-linear-gradient(top,#ededed 0,#fff 100%);background:-ms-linear-gradient(top,#ededed 0,#fff 100%);background:linear-gradient(to bottom,#ededed 0,#fff 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ededed',endColorstr='#ffffff',GradientType=0)}.cke_hc a.cke_dialog_tab:hover,.cke_hc a.cke_dialog_tab_selected{border:3px solid;padding:2px 6px}a.cke_dialog_tab_disabled{color:#bababa;cursor:default}.cke_single_page .cke_dialog_tabs{display:none}.cke_single_page .cke_dialog_contents{padding-top:5px;margin-top:0;border-top:0}.cke_dialog_close_button{background-image:url(images/close.png);background-repeat:no-repeat;background-position:0 0;position:absolute;cursor:pointer;text-align:center;height:20px;width:20px;top:5px;z-index:5}.cke_hidpi .cke_dialog_close_button{background-image:url(images/hidpi/close.png);background-size:16px}.cke_dialog_close_button span{display:none}.cke_hc .cke_dialog_close_button span{display:inline;cursor:pointer;font-weight:bold;position:relative;top:3px}.cke_ltr .cke_dialog_close_button{right:5px}.cke_rtl .cke_dialog_close_button{left:6px}.cke_dialog_close_button{top:4px}div.cke_disabled .cke_dialog_ui_labeled_content div *{background-color:#ddd;cursor:default}.cke_dialog_ui_vbox table,.cke_dialog_ui_hbox table{margin:auto}.cke_dialog_ui_vbox_child{padding:5px 0}.cke_dialog_ui_hbox{width:100%}.cke_dialog_ui_hbox_first,.cke_dialog_ui_hbox_child,.cke_dialog_ui_hbox_last{vertical-align:top}.cke_ltr .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_ui_hbox_child{padding-right:10px}.cke_rtl .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_ui_hbox_child{padding-left:10px}.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-right:5px}.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-left:5px;padding-right:0}.cke_hc div.cke_dialog_ui_input_text,.cke_hc div.cke_dialog_ui_input_password,.cke_hc div.cke_dialog_ui_input_textarea,.cke_hc div.cke_dialog_ui_input_select,.cke_hc div.cke_dialog_ui_input_file{border:1px solid}textarea.cke_dialog_ui_input_textarea{overflow:auto;resize:none}input.cke_dialog_ui_input_text,input.cke_dialog_ui_input_password,textarea.cke_dialog_ui_input_textarea{background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:4px 6px;outline:0;width:100%;*width:95%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}input.cke_dialog_ui_input_text:hover,input.cke_dialog_ui_input_password:hover,textarea.cke_dialog_ui_input_textarea:hover{border:1px solid #aeb3b9;border-top-color:#a0a6ad}input.cke_dialog_ui_input_text:focus,input.cke_dialog_ui_input_password:focus,textarea.cke_dialog_ui_input_textarea:focus,select.cke_dialog_ui_input_select:focus{outline:0;border:1px solid #139ff7;border-top-color:#1392e9}a.cke_dialog_ui_button{display:inline-block;*display:inline;*zoom:1;padding:3px 0;margin:0;text-align:center;color:#333;vertical-align:middle;cursor:pointer;border:1px solid #b6b6b6;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}span.cke_dialog_ui_button{padding:0 12px}a.cke_dialog_ui_button:hover{border-color:#9e9e9e;background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}a.cke_dialog_ui_button:focus,a.cke_dialog_ui_button:active{border-color:#969696;outline:0;-moz-box-shadow:0 0 6px rgba(0,0,0,.4) inset;-webkit-box-shadow:0 0 6px rgba(0,0,0,.4) inset;box-shadow:0 0 6px rgba(0,0,0,.4) inset}.cke_hc a.cke_dialog_ui_button:hover,.cke_hc a.cke_dialog_ui_button:focus,.cke_hc a.cke_dialog_ui_button:active{border:3px solid;padding-top:1px;padding-bottom:1px}.cke_hc a.cke_dialog_ui_button:hover span,.cke_hc a.cke_dialog_ui_button:focus span,.cke_hc a.cke_dialog_ui_button:active span{padding-left:10px;padding-right:10px}.cke_dialog_footer_buttons a.cke_dialog_ui_button span{color:inherit;font-size:12px;font-weight:bold;line-height:20px}a.cke_dialog_ui_button_ok{color:#fff;text-shadow:0 -1px 0 #55830c;border-color:#62a60a #62a60a #4d9200;background:#69b10b;background-image:-webkit-gradient(linear,0 0,0 100%,from(#9ad717),to(#69b10b));background-image:-webkit-linear-gradient(top,#9ad717,#69b10b);background-image:-o-linear-gradient(top,#9ad717,#69b10b);background-image:linear-gradient(to bottom,#9ad717,#69b10b);background-image:-moz-linear-gradient(top,#9ad717,#69b10b);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#9ad717',endColorstr='#69b10b')}a.cke_dialog_ui_button_ok:hover{border-color:#5b9909 #5b9909 #478500;background:#88be14;background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#88be14),color-stop(100%,#5d9c0a));background:-webkit-linear-gradient(top,#88be14 0,#5d9c0a 100%);background:-o-linear-gradient(top,#88be14 0,#5d9c0a 100%);background:linear-gradient(to bottom,#88be14 0,#5d9c0a 100%);background:-moz-linear-gradient(top,#88be14 0,#5d9c0a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#88be14',endColorstr='#5d9c0a',GradientType=0)}a.cke_dialog_ui_button span{text-shadow:0 1px 0 #fff}a.cke_dialog_ui_button_ok span{text-shadow:0 -1px 0 #55830c}span.cke_dialog_ui_button{cursor:pointer}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active,a.cke_dialog_ui_button_cancel:focus,a.cke_dialog_ui_button_cancel:active{border-width:2px;padding:2px 0}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active{border-color:#568c0a}a.cke_dialog_ui_button_ok:focus span,a.cke_dialog_ui_button_ok:active span,a.cke_dialog_ui_button_cancel:focus span,a.cke_dialog_ui_button_cancel:active span{padding:0 11px}.cke_dialog_footer_buttons{display:inline-table;margin:5px;width:auto;position:relative;vertical-align:middle}div.cke_dialog_ui_input_select{display:table}select.cke_dialog_ui_input_select{height:24px;line-height:24px;background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:2px 6px;outline:0;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}.cke_dialog_ui_input_file{width:100%;height:25px}.cke_hc .cke_dialog_ui_labeled_content input:focus,.cke_hc .cke_dialog_ui_labeled_content select:focus,.cke_hc .cke_dialog_ui_labeled_content textarea:focus{outline:1px dotted}.cke_dialog .cke_dark_background{background-color:#dedede}.cke_dialog .cke_light_background{background-color:#ebebeb}.cke_dialog .cke_centered{text-align:center}.cke_dialog a.cke_btn_reset{float:right;background:url(images/refresh.png) top left no-repeat;width:16px;height:16px;border:1px none;font-size:1px}.cke_hidpi .cke_dialog a.cke_btn_reset{background-size:16px;background-image:url(images/hidpi/refresh.png)}.cke_rtl .cke_dialog a.cke_btn_reset{float:left}.cke_dialog a.cke_btn_locked,.cke_dialog a.cke_btn_unlocked{float:left;width:16px;height:16px;background-repeat:no-repeat;border:none 1px;font-size:1px}.cke_dialog a.cke_btn_locked .cke_icon{display:none}.cke_rtl .cke_dialog a.cke_btn_locked,.cke_rtl .cke_dialog a.cke_btn_unlocked{float:right}.cke_dialog a.cke_btn_locked{background-image:url(images/lock.png)}.cke_dialog a.cke_btn_unlocked{background-image:url(images/lock-open.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked,.cke_hidpi .cke_dialog a.cke_btn_locked{background-size:16px}.cke_hidpi .cke_dialog a.cke_btn_locked{background-image:url(images/hidpi/lock.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked{background-image:url(images/hidpi/lock-open.png)}.cke_dialog .cke_btn_over{border:outset 1px;cursor:pointer}.cke_dialog .ImagePreviewBox{border:2px ridge black;overflow:scroll;height:200px;width:300px;padding:2px;background-color:white}.cke_dialog .ImagePreviewBox table td{white-space:normal}.cke_dialog .ImagePreviewLoader{position:absolute;white-space:normal;overflow:hidden;height:160px;width:230px;margin:2px;padding:2px;opacity:.9;filter:alpha(opacity = 90);background-color:#e4e4e4}.cke_dialog .FlashPreviewBox{white-space:normal;border:2px ridge black;overflow:auto;height:160px;width:390px;padding:2px;background-color:white}.cke_dialog .cke_pastetext{width:346px;height:170px}.cke_dialog .cke_pastetext textarea{width:340px;height:170px;resize:none}.cke_dialog iframe.cke_pasteframe{width:346px;height:130px;background-color:white;border:1px solid #aeb3b9;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}.cke_dialog .cke_hand{cursor:pointer}.cke_disabled{color:#a0a0a0}.cke_dialog_body .cke_label{display:none}.cke_dialog_body label{display:inline;margin-bottom:auto;cursor:default}.cke_dialog_body label.cke_required{font-weight:bold}a.cke_smile{overflow:hidden;display:block;text-align:center;padding:.3em 0}a.cke_smile img{vertical-align:middle}a.cke_specialchar{cursor:inherit;display:block;height:1.25em;padding:.2em .3em;text-align:center}a.cke_smile,a.cke_specialchar{border:1px solid transparent}a.cke_smile:hover,a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:hover,a.cke_specialchar:focus,a.cke_specialchar:active{background:#fff;outline:0}a.cke_smile:hover,a.cke_specialchar:hover{border-color:#888}a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:focus,a.cke_specialchar:active{border-color:#139ff7}.cke_dialog_contents a.colorChooser{display:block;margin-top:6px;margin-left:10px;width:80px}.cke_rtl .cke_dialog_contents a.colorChooser{margin-right:10px}.cke_dialog_ui_checkbox_input:focus,.cke_dialog_ui_radio_input:focus,.cke_btn_over{outline:1px dotted #696969}.cke_iframe_shim{display:block;position:absolute;top:0;left:0;z-index:-1;filter:alpha(opacity = 0);width:100%;height:100%}.cke_dialog_footer{display:block;height:38px}.cke_ltr .cke_dialog_footer>*{float:right}.cke_rtl .cke_dialog_footer>*{float:left} \ No newline at end of file diff --git a/public/assets/plugins/ckeditor/skins/moono/editor.css b/public/assets/plugins/ckeditor/skins/moono/editor.css new file mode 100644 index 00000000..2df84822 --- /dev/null +++ b/public/assets/plugins/ckeditor/skins/moono/editor.css @@ -0,0 +1,5 @@ +/* +Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. +For licensing, see LICENSE.md or http://ckeditor.com/license +*/ +.cke_reset{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;position:static;-webkit-transition:none;-moz-transition:none;-ms-transition:none;transition:none}.cke_reset_all,.cke_reset_all *{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;position:static;-webkit-transition:none;-moz-transition:none;-ms-transition:none;transition:none;border-collapse:collapse;font:normal normal normal 12px Arial,Helvetica,Tahoma,Verdana,Sans-Serif;color:#000;text-align:left;white-space:nowrap;cursor:auto}.cke_reset_all .cke_rtl *{text-align:right}.cke_reset_all iframe{vertical-align:inherit}.cke_reset_all textarea{white-space:pre}.cke_reset_all textarea,.cke_reset_all input[type="text"],.cke_reset_all input[type="password"]{cursor:text}.cke_reset_all textarea[disabled],.cke_reset_all input[type="text"][disabled],.cke_reset_all input[type="password"][disabled]{cursor:default}.cke_reset_all fieldset{padding:10px;border:2px groove #e0dfe3}.cke_reset_all select{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}.cke_chrome{display:block;border:1px solid #b6b6b6;padding:0;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_inner{display:block;-webkit-touch-callout:none;background:#fff;padding:0}.cke_float{border:0}.cke_float .cke_inner{padding-bottom:0}.cke_top,.cke_contents,.cke_bottom{display:block;overflow:hidden}.cke_top{border-bottom:1px solid #b6b6b6;padding:6px 8px 2px;white-space:normal;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_float .cke_top{border:1px solid #b6b6b6;border-bottom-color:#999}.cke_bottom{padding:6px 8px 2px;position:relative;border-top:1px solid #bfbfbf;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#cfd1cf));background-image:-moz-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-webkit-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-o-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-ms-linear-gradient(top,#ebebeb,#cfd1cf);background-image:linear-gradient(top,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_browser_ios .cke_contents{overflow-y:auto;-webkit-overflow-scrolling:touch}.cke_resizer{width:0;height:0;overflow:hidden;width:0;height:0;overflow:hidden;border-width:10px 10px 0 0;border-color:transparent #666 transparent transparent;border-style:dashed solid dashed dashed;font-size:0;vertical-align:bottom;margin-top:6px;margin-bottom:2px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.3);-webkit-box-shadow:0 1px 0 rgba(255,255,255,.3);box-shadow:0 1px 0 rgba(255,255,255,.3)}.cke_hc .cke_resizer{font-size:15px;width:auto;height:auto;border-width:0}.cke_resizer_ltr{cursor:se-resize;float:right;margin-right:-4px}.cke_resizer_rtl{border-width:10px 0 0 10px;border-color:transparent transparent transparent #a5a5a5;border-style:dashed dashed dashed solid;cursor:sw-resize;float:left;margin-left:-4px;right:auto}.cke_wysiwyg_div{display:block;height:100%;overflow:auto;padding:0 8px;outline-style:none;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.cke_panel{visibility:visible;width:120px;height:100px;overflow:hidden;background-color:#fff;border:1px solid #b6b6b6;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_menu_panel{padding:0;margin:0}.cke_combopanel{width:150px;height:170px}.cke_panel_frame{width:100%;height:100%;font-size:12px;overflow:auto;overflow-x:hidden}.cke_panel_container{overflow-y:auto;overflow-x:hidden}.cke_panel_list{list-style-type:none;margin:3px;padding:0;white-space:nowrap}.cke_panel_listItem{margin:0;padding-bottom:1px}.cke_panel_listItem a{padding:3px 4px;display:block;border:1px solid #fff;color:inherit!important;text-decoration:none;overflow:hidden;text-overflow:ellipsis;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px}* html .cke_panel_listItem a{width:100%;color:#000}*:first-child+html .cke_panel_listItem a{color:#000}.cke_panel_listItem.cke_selected a{border:1px solid #dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_panel_listItem a:hover,.cke_panel_listItem a:focus,.cke_panel_listItem a:active{border-color:#dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_hc .cke_panel_listItem a{border-style:none}.cke_hc .cke_panel_listItem a:hover,.cke_hc .cke_panel_listItem a:focus,.cke_hc .cke_panel_listItem a:active{border:2px solid;padding:1px 2px}.cke_panel_grouptitle{font-size:11px;font-weight:bold;white-space:nowrap;margin:0;padding:4px 6px;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #b6b6b6;-moz-border-radius:2px 2px 0 0;-webkit-border-radius:2px 2px 0 0;border-radius:2px 2px 0 0;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_panel_listItem p,.cke_panel_listItem h1,.cke_panel_listItem h2,.cke_panel_listItem h3,.cke_panel_listItem h4,.cke_panel_listItem h5,.cke_panel_listItem h6,.cke_panel_listItem pre{margin-top:0;margin-bottom:0}.cke_colorblock{padding:3px;font-size:11px;font-family:'Microsoft Sans Serif',Tahoma,Arial,Verdana,Sans-Serif}.cke_colorblock,.cke_colorblock a{text-decoration:none;color:#000}span.cke_colorbox{width:10px;height:10px;border:#808080 1px solid;float:left}.cke_rtl span.cke_colorbox{float:right}a.cke_colorbox{border:#fff 1px solid;padding:2px;float:left;width:12px;height:12px}.cke_rtl a.cke_colorbox{float:right}a:hover.cke_colorbox,a:focus.cke_colorbox,a:active.cke_colorbox{border:#b6b6b6 1px solid;background-color:#e5e5e5}a.cke_colorauto,a.cke_colormore{border:#fff 1px solid;padding:2px;display:block;cursor:pointer}a:hover.cke_colorauto,a:hover.cke_colormore,a:focus.cke_colorauto,a:focus.cke_colormore,a:active.cke_colorauto,a:active.cke_colormore{border:#b6b6b6 1px solid;background-color:#e5e5e5}.cke_toolbar{float:left}.cke_rtl .cke_toolbar{float:right}.cke_toolgroup{float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_hc .cke_toolgroup{border:0;margin-right:10px;margin-bottom:10px}.cke_rtl .cke_toolgroup *:first-child{-moz-border-radius:0 2px 2px 0;-webkit-border-radius:0 2px 2px 0;border-radius:0 2px 2px 0}.cke_rtl .cke_toolgroup *:last-child{-moz-border-radius:2px 0 0 2px;-webkit-border-radius:2px 0 0 2px;border-radius:2px 0 0 2px}.cke_rtl .cke_toolgroup{float:right;margin-left:6px;margin-right:0}a.cke_button{display:inline-block;height:18px;padding:4px 6px;outline:0;cursor:default;float:left;border:0}.cke_rtl .cke_button{float:right}.cke_hc .cke_button{border:1px solid black;padding:3px 5px;margin:-2px 4px 0 -2px}.cke_button_on{-moz-box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);background:#b5b5b5;background-image:-webkit-gradient(linear,left top,left bottom,from(#aaa),to(#cacaca));background-image:-moz-linear-gradient(top,#aaa,#cacaca);background-image:-webkit-linear-gradient(top,#aaa,#cacaca);background-image:-o-linear-gradient(top,#aaa,#cacaca);background-image:-ms-linear-gradient(top,#aaa,#cacaca);background-image:linear-gradient(top,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc a.cke_button_disabled:hover,.cke_hc a.cke_button_disabled:focus,.cke_hc a.cke_button_disabled:active{border-width:3px;padding:1px 3px}.cke_button_disabled .cke_button_icon{opacity:.3}.cke_hc .cke_button_disabled{opacity:.5}a.cke_button_on:hover,a.cke_button_on:focus,a.cke_button_on:active{-moz-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}a.cke_button_off:hover,a.cke_button_off:focus,a.cke_button_off:active,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{-moz-box-shadow:0 0 1px rgba(0,0,0,.3) inset;-webkit-box-shadow:0 0 1px rgba(0,0,0,.3) inset;box-shadow:0 0 1px rgba(0,0,0,.3) inset;background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_button_icon{cursor:inherit;background-repeat:no-repeat;margin-top:1px;width:16px;height:16px;float:left;display:inline-block}.cke_rtl .cke_button_icon{float:right}.cke_hc .cke_button_icon{display:none}.cke_button_label{display:none;padding-left:3px;margin-top:1px;line-height:17px;vertical-align:middle;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5)}.cke_rtl .cke_button_label{padding-right:3px;padding-left:0;float:right}.cke_hc .cke_button_label{padding:0;display:inline-block;font-size:12px}.cke_button_arrow{display:inline-block;margin:8px 0 0 1px;width:0;height:0;cursor:default;vertical-align:top;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_rtl .cke_button_arrow{margin-right:5px;margin-left:0}.cke_hc .cke_button_arrow{font-size:10px;margin:3px -2px 0 3px;width:auto;border:0}.cke_toolbar_separator{float:left;background-color:#c0c0c0;background-color:rgba(0,0,0,.2);margin:5px 2px 0;height:18px;width:1px;-webkit-box-shadow:1px 0 1px rgba(255,255,255,.5);-moz-box-shadow:1px 0 1px rgba(255,255,255,.5);box-shadow:1px 0 1px rgba(255,255,255,.5)}.cke_rtl .cke_toolbar_separator{float:right;-webkit-box-shadow:-1px 0 1px rgba(255,255,255,.1);-moz-box-shadow:-1px 0 1px rgba(255,255,255,.1);box-shadow:-1px 0 1px rgba(255,255,255,.1)}.cke_hc .cke_toolbar_separator{width:0;border-left:1px solid;margin:1px 5px 0 0}.cke_toolbar_break{display:block;clear:left}.cke_rtl .cke_toolbar_break{clear:right}.cke_toolbox_collapser{width:12px;height:11px;float:right;margin:11px 0 0;font-size:0;cursor:default;text-align:center;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_toolbox_collapser:hover{background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_toolbox_collapser.cke_toolbox_collapser_min{margin:0 2px 4px}.cke_rtl .cke_toolbox_collapser{float:left}.cke_toolbox_collapser .cke_arrow{display:inline-block;height:0;width:0;font-size:0;margin-top:1px;border-left:3px solid transparent;border-right:3px solid transparent;border-bottom:3px solid #474747;border-top:3px solid transparent}.cke_toolbox_collapser.cke_toolbox_collapser_min .cke_arrow{margin-top:4px;border-bottom-color:transparent;border-top-color:#474747}.cke_hc .cke_toolbox_collapser .cke_arrow{font-size:8px;width:auto;border:0;margin-top:0;margin-right:2px}.cke_menubutton{display:block}.cke_menuitem span{cursor:default}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#d3d3d3;display:block}.cke_hc .cke_menubutton{padding:2px}.cke_hc .cke_menubutton:hover,.cke_hc .cke_menubutton:focus,.cke_hc .cke_menubutton:active{border:2px solid;padding:0}.cke_menubutton_inner{display:table-row}.cke_menubutton_icon,.cke_menubutton_label,.cke_menuarrow{display:table-cell}.cke_menubutton_icon{background-color:#d7d8d7;opacity:.70;filter:alpha(opacity=70);padding:4px}.cke_hc .cke_menubutton_icon{height:16px;width:0;padding:4px 0}.cke_menubutton:hover .cke_menubutton_icon,.cke_menubutton:focus .cke_menubutton_icon,.cke_menubutton:active .cke_menubutton_icon{background-color:#d0d2d0}.cke_menubutton_disabled:hover .cke_menubutton_icon,.cke_menubutton_disabled:focus .cke_menubutton_icon,.cke_menubutton_disabled:active .cke_menubutton_icon{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_label{padding:0 5px;background-color:transparent;width:100%;vertical-align:middle}.cke_menubutton_disabled .cke_menubutton_label{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_on{border:1px solid #dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_menubutton_on .cke_menubutton_icon{padding-right:3px}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#eff0ef}.cke_panel_frame .cke_menubutton_label{display:none}.cke_menuseparator{background-color:#d3d3d3;height:1px;filter:alpha(opacity=70);opacity:.70}.cke_menuarrow{background-image:url(images/arrow.png);background-position:0 10px;background-repeat:no-repeat;padding:0 5px}.cke_rtl .cke_menuarrow{background-position:5px -13px;background-repeat:no-repeat}.cke_menuarrow span{display:none}.cke_hc .cke_menuarrow span{vertical-align:middle;display:inline}.cke_combo{display:inline-block;float:left}.cke_rtl .cke_combo{float:right}.cke_hc .cke_combo{margin-top:-2px}.cke_combo_label{display:none;float:left;line-height:26px;vertical-align:top;margin-right:5px}.cke_rtl .cke_combo_label{float:right;margin-left:5px;margin-right:0}.cke_combo_button{display:inline-block;float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_combo_off a.cke_combo_button:hover,.cke_combo_off a.cke_combo_button:focus{background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc');outline:0}.cke_combo_off a.cke_combo_button:active,.cke_combo_on a.cke_combo_button{border:1px solid #777;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;background:#b5b5b5;background-image:-webkit-gradient(linear,left top,left bottom,from(#aaa),to(#cacaca));background-image:-moz-linear-gradient(top,#aaa,#cacaca);background-image:-webkit-linear-gradient(top,#aaa,#cacaca);background-image:-o-linear-gradient(top,#aaa,#cacaca);background-image:-ms-linear-gradient(top,#aaa,#cacaca);background-image:linear-gradient(top,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_combo_on a.cke_combo_button:hover,.cke_combo_on a.cke_combo_button:focus,.cke_combo_on a.cke_combo_button:active{-moz-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}.cke_rtl .cke_combo_button{float:right;margin-left:5px;margin-right:0}.cke_hc a.cke_combo_button{padding:3px}.cke_hc .cke_combo_on a.cke_combo_button,.cke_hc .cke_combo_off a.cke_combo_button:hover,.cke_hc .cke_combo_off a.cke_combo_button:focus,.cke_hc .cke_combo_off a.cke_combo_button:active{border-width:3px;padding:1px}.cke_combo_text{line-height:26px;padding-left:10px;text-overflow:ellipsis;overflow:hidden;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5);width:60px}.cke_rtl .cke_combo_text{float:right;text-align:right;padding-left:0;padding-right:10px}.cke_hc .cke_combo_text{line-height:18px;font-size:12px}.cke_combo_open{cursor:default;display:inline-block;font-size:0;height:19px;line-height:17px;margin:1px 7px 1px;width:5px}.cke_hc .cke_combo_open{height:12px}.cke_combo_arrow{margin:11px 0 0;float:left;height:0;width:0;font-size:0;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_hc .cke_combo_arrow{font-size:10px;width:auto;border:0;margin-top:3px}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{opacity:.3}.cke_path{float:left;margin:-2px 0 2px}.cke_path_item,.cke_path_empty{display:inline-block;float:left;padding:3px 4px;margin-right:2px;cursor:default;text-decoration:none;outline:0;border:0;color:#4c4c4c;text-shadow:0 1px 0 #fff;font-weight:bold;font-size:11px}.cke_rtl .cke_path,.cke_rtl .cke_path_item,.cke_rtl .cke_path_empty{float:right}a.cke_path_item:hover,a.cke_path_item:focus,a.cke_path_item:active{background-color:#bfbfbf;color:#333;text-shadow:0 1px 0 rgba(255,255,255,.5);-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-moz-box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5);-webkit-box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5);box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5)}.cke_hc a.cke_path_item:hover,.cke_hc a.cke_path_item:focus,.cke_hc a.cke_path_item:active{border:2px solid;padding:1px 2px}.cke_button__source_label,.cke_button__sourcedialog_label{display:inline}.cke_combo__fontsize .cke_combo_text{width:30px}.cke_combopanel__fontsize{width:120px}.cke_source{font-family:'Courier New',Monospace;font-size:small;background-color:#fff;white-space:pre}.cke_wysiwyg_frame,.cke_wysiwyg_div{background-color:#fff}.cke_chrome{visibility:inherit}.cke_voice_label{display:none}legend.cke_voice_label{display:none}.cke_button__about_icon {background: url(icons.png) no-repeat 0 -0px !important;}.cke_button__bold_icon {background: url(icons.png) no-repeat 0 -24px !important;}.cke_button__italic_icon {background: url(icons.png) no-repeat 0 -48px !important;}.cke_button__strike_icon {background: url(icons.png) no-repeat 0 -72px !important;}.cke_button__subscript_icon {background: url(icons.png) no-repeat 0 -96px !important;}.cke_button__superscript_icon {background: url(icons.png) no-repeat 0 -120px !important;}.cke_button__underline_icon {background: url(icons.png) no-repeat 0 -144px !important;}.cke_button__blockquote_icon {background: url(icons.png) no-repeat 0 -168px !important;}.cke_rtl .cke_button__copy_icon, .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons.png) no-repeat 0 -192px !important;}.cke_ltr .cke_button__copy_icon {background: url(icons.png) no-repeat 0 -216px !important;}.cke_rtl .cke_button__cut_icon, .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons.png) no-repeat 0 -240px !important;}.cke_ltr .cke_button__cut_icon {background: url(icons.png) no-repeat 0 -264px !important;}.cke_rtl .cke_button__paste_icon, .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons.png) no-repeat 0 -288px !important;}.cke_ltr .cke_button__paste_icon {background: url(icons.png) no-repeat 0 -312px !important;}.cke_button__horizontalrule_icon {background: url(icons.png) no-repeat 0 -336px !important;}.cke_button__image_icon {background: url(icons.png) no-repeat 0 -360px !important;}.cke_rtl .cke_button__indent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons.png) no-repeat 0 -384px !important;}.cke_ltr .cke_button__indent_icon {background: url(icons.png) no-repeat 0 -408px !important;}.cke_rtl .cke_button__outdent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons.png) no-repeat 0 -432px !important;}.cke_ltr .cke_button__outdent_icon {background: url(icons.png) no-repeat 0 -456px !important;}.cke_rtl .cke_button__anchor_icon, .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons.png) no-repeat 0 -480px !important;}.cke_ltr .cke_button__anchor_icon {background: url(icons.png) no-repeat 0 -504px !important;}.cke_button__link_icon {background: url(icons.png) no-repeat 0 -528px !important;}.cke_button__unlink_icon {background: url(icons.png) no-repeat 0 -552px !important;}.cke_rtl .cke_button__bulletedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons.png) no-repeat 0 -576px !important;}.cke_ltr .cke_button__bulletedlist_icon {background: url(icons.png) no-repeat 0 -600px !important;}.cke_rtl .cke_button__numberedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons.png) no-repeat 0 -624px !important;}.cke_ltr .cke_button__numberedlist_icon {background: url(icons.png) no-repeat 0 -648px !important;}.cke_button__maximize_icon {background: url(icons.png) no-repeat 0 -672px !important;}.cke_rtl .cke_button__pastetext_icon, .cke_mixed_dir_content .cke_rtl .cke_button__pastetext_icon {background: url(icons.png) no-repeat 0 -696px !important;}.cke_ltr .cke_button__pastetext_icon {background: url(icons.png) no-repeat 0 -720px !important;}.cke_rtl .cke_button__pastefromword_icon, .cke_mixed_dir_content .cke_rtl .cke_button__pastefromword_icon {background: url(icons.png) no-repeat 0 -744px !important;}.cke_ltr .cke_button__pastefromword_icon {background: url(icons.png) no-repeat 0 -768px !important;}.cke_button__removeformat_icon {background: url(icons.png) no-repeat 0 -792px !important;}.cke_rtl .cke_button__source_icon, .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons.png) no-repeat 0 -816px !important;}.cke_ltr .cke_button__source_icon {background: url(icons.png) no-repeat 0 -840px !important;}.cke_button__specialchar_icon {background: url(icons.png) no-repeat 0 -864px !important;}.cke_button__scayt_icon {background: url(icons.png) no-repeat 0 -888px !important;}.cke_button__table_icon {background: url(icons.png) no-repeat 0 -912px !important;}.cke_rtl .cke_button__redo_icon, .cke_mixed_dir_content .cke_rtl .cke_button__redo_icon {background: url(icons.png) no-repeat 0 -936px !important;}.cke_ltr .cke_button__redo_icon {background: url(icons.png) no-repeat 0 -960px !important;}.cke_rtl .cke_button__undo_icon, .cke_mixed_dir_content .cke_rtl .cke_button__undo_icon {background: url(icons.png) no-repeat 0 -984px !important;}.cke_ltr .cke_button__undo_icon {background: url(icons.png) no-repeat 0 -1008px !important;}.cke_button__spellchecker_icon {background: url(icons.png) no-repeat 0 -1032px !important;}.cke_hidpi .cke_button__about_icon {background: url(icons_hidpi.png) no-repeat 0 -0px !important;background-size: 16px !important;}.cke_hidpi .cke_button__bold_icon {background: url(icons_hidpi.png) no-repeat 0 -24px !important;background-size: 16px !important;}.cke_hidpi .cke_button__italic_icon {background: url(icons_hidpi.png) no-repeat 0 -48px !important;background-size: 16px !important;}.cke_hidpi .cke_button__strike_icon {background: url(icons_hidpi.png) no-repeat 0 -72px !important;background-size: 16px !important;}.cke_hidpi .cke_button__subscript_icon {background: url(icons_hidpi.png) no-repeat 0 -96px !important;background-size: 16px !important;}.cke_hidpi .cke_button__superscript_icon {background: url(icons_hidpi.png) no-repeat 0 -120px !important;background-size: 16px !important;}.cke_hidpi .cke_button__underline_icon {background: url(icons_hidpi.png) no-repeat 0 -144px !important;background-size: 16px !important;}.cke_hidpi .cke_button__blockquote_icon {background: url(icons_hidpi.png) no-repeat 0 -168px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__copy_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons_hidpi.png) no-repeat 0 -192px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__copy_icon,.cke_ltr.cke_hidpi .cke_button__copy_icon {background: url(icons_hidpi.png) no-repeat 0 -216px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__cut_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons_hidpi.png) no-repeat 0 -240px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__cut_icon,.cke_ltr.cke_hidpi .cke_button__cut_icon {background: url(icons_hidpi.png) no-repeat 0 -264px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__paste_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons_hidpi.png) no-repeat 0 -288px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__paste_icon,.cke_ltr.cke_hidpi .cke_button__paste_icon {background: url(icons_hidpi.png) no-repeat 0 -312px !important;background-size: 16px !important;}.cke_hidpi .cke_button__horizontalrule_icon {background: url(icons_hidpi.png) no-repeat 0 -336px !important;background-size: 16px !important;}.cke_hidpi .cke_button__image_icon {background: url(icons_hidpi.png) no-repeat 0 -360px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__indent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons_hidpi.png) no-repeat 0 -384px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__indent_icon,.cke_ltr.cke_hidpi .cke_button__indent_icon {background: url(icons_hidpi.png) no-repeat 0 -408px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__outdent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons_hidpi.png) no-repeat 0 -432px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__outdent_icon,.cke_ltr.cke_hidpi .cke_button__outdent_icon {background: url(icons_hidpi.png) no-repeat 0 -456px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__anchor_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons_hidpi.png) no-repeat 0 -480px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__anchor_icon,.cke_ltr.cke_hidpi .cke_button__anchor_icon {background: url(icons_hidpi.png) no-repeat 0 -504px !important;background-size: 16px !important;}.cke_hidpi .cke_button__link_icon {background: url(icons_hidpi.png) no-repeat 0 -528px !important;background-size: 16px !important;}.cke_hidpi .cke_button__unlink_icon {background: url(icons_hidpi.png) no-repeat 0 -552px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__bulletedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -576px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__bulletedlist_icon,.cke_ltr.cke_hidpi .cke_button__bulletedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -600px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__numberedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -624px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__numberedlist_icon,.cke_ltr.cke_hidpi .cke_button__numberedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -648px !important;background-size: 16px !important;}.cke_hidpi .cke_button__maximize_icon {background: url(icons_hidpi.png) no-repeat 0 -672px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__pastetext_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__pastetext_icon {background: url(icons_hidpi.png) no-repeat 0 -696px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__pastetext_icon,.cke_ltr.cke_hidpi .cke_button__pastetext_icon {background: url(icons_hidpi.png) no-repeat 0 -720px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__pastefromword_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__pastefromword_icon {background: url(icons_hidpi.png) no-repeat 0 -744px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__pastefromword_icon,.cke_ltr.cke_hidpi .cke_button__pastefromword_icon {background: url(icons_hidpi.png) no-repeat 0 -768px !important;background-size: 16px !important;}.cke_hidpi .cke_button__removeformat_icon {background: url(icons_hidpi.png) no-repeat 0 -792px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__source_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons_hidpi.png) no-repeat 0 -816px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__source_icon,.cke_ltr.cke_hidpi .cke_button__source_icon {background: url(icons_hidpi.png) no-repeat 0 -840px !important;background-size: 16px !important;}.cke_hidpi .cke_button__specialchar_icon {background: url(icons_hidpi.png) no-repeat 0 -864px !important;background-size: 16px !important;}.cke_hidpi .cke_button__scayt_icon {background: url(icons_hidpi.png) no-repeat 0 -888px !important;background-size: 16px !important;}.cke_hidpi .cke_button__table_icon {background: url(icons_hidpi.png) no-repeat 0 -912px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__redo_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__redo_icon {background: url(icons_hidpi.png) no-repeat 0 -936px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__redo_icon,.cke_ltr.cke_hidpi .cke_button__redo_icon {background: url(icons_hidpi.png) no-repeat 0 -960px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__undo_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__undo_icon {background: url(icons_hidpi.png) no-repeat 0 -984px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__undo_icon,.cke_ltr.cke_hidpi .cke_button__undo_icon {background: url(icons_hidpi.png) no-repeat 0 -1008px !important;background-size: 16px !important;}.cke_hidpi .cke_button__spellchecker_icon {background: url(icons_hidpi.png) no-repeat 0 -1032px !important;background-size: 16px !important;} \ No newline at end of file diff --git a/public/assets/plugins/ckeditor/skins/moono/editor_gecko.css b/public/assets/plugins/ckeditor/skins/moono/editor_gecko.css new file mode 100644 index 00000000..ecb7990a --- /dev/null +++ b/public/assets/plugins/ckeditor/skins/moono/editor_gecko.css @@ -0,0 +1,5 @@ +/* +Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. +For licensing, see LICENSE.md or http://ckeditor.com/license +*/ +.cke_reset{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;position:static;-webkit-transition:none;-moz-transition:none;-ms-transition:none;transition:none}.cke_reset_all,.cke_reset_all *{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;position:static;-webkit-transition:none;-moz-transition:none;-ms-transition:none;transition:none;border-collapse:collapse;font:normal normal normal 12px Arial,Helvetica,Tahoma,Verdana,Sans-Serif;color:#000;text-align:left;white-space:nowrap;cursor:auto}.cke_reset_all .cke_rtl *{text-align:right}.cke_reset_all iframe{vertical-align:inherit}.cke_reset_all textarea{white-space:pre}.cke_reset_all textarea,.cke_reset_all input[type="text"],.cke_reset_all input[type="password"]{cursor:text}.cke_reset_all textarea[disabled],.cke_reset_all input[type="text"][disabled],.cke_reset_all input[type="password"][disabled]{cursor:default}.cke_reset_all fieldset{padding:10px;border:2px groove #e0dfe3}.cke_reset_all select{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}.cke_chrome{display:block;border:1px solid #b6b6b6;padding:0;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_inner{display:block;-webkit-touch-callout:none;background:#fff;padding:0}.cke_float{border:0}.cke_float .cke_inner{padding-bottom:0}.cke_top,.cke_contents,.cke_bottom{display:block;overflow:hidden}.cke_top{border-bottom:1px solid #b6b6b6;padding:6px 8px 2px;white-space:normal;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_float .cke_top{border:1px solid #b6b6b6;border-bottom-color:#999}.cke_bottom{padding:6px 8px 2px;position:relative;border-top:1px solid #bfbfbf;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#cfd1cf));background-image:-moz-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-webkit-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-o-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-ms-linear-gradient(top,#ebebeb,#cfd1cf);background-image:linear-gradient(top,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_browser_ios .cke_contents{overflow-y:auto;-webkit-overflow-scrolling:touch}.cke_resizer{width:0;height:0;overflow:hidden;width:0;height:0;overflow:hidden;border-width:10px 10px 0 0;border-color:transparent #666 transparent transparent;border-style:dashed solid dashed dashed;font-size:0;vertical-align:bottom;margin-top:6px;margin-bottom:2px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.3);-webkit-box-shadow:0 1px 0 rgba(255,255,255,.3);box-shadow:0 1px 0 rgba(255,255,255,.3)}.cke_hc .cke_resizer{font-size:15px;width:auto;height:auto;border-width:0}.cke_resizer_ltr{cursor:se-resize;float:right;margin-right:-4px}.cke_resizer_rtl{border-width:10px 0 0 10px;border-color:transparent transparent transparent #a5a5a5;border-style:dashed dashed dashed solid;cursor:sw-resize;float:left;margin-left:-4px;right:auto}.cke_wysiwyg_div{display:block;height:100%;overflow:auto;padding:0 8px;outline-style:none;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.cke_panel{visibility:visible;width:120px;height:100px;overflow:hidden;background-color:#fff;border:1px solid #b6b6b6;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_menu_panel{padding:0;margin:0}.cke_combopanel{width:150px;height:170px}.cke_panel_frame{width:100%;height:100%;font-size:12px;overflow:auto;overflow-x:hidden}.cke_panel_container{overflow-y:auto;overflow-x:hidden}.cke_panel_list{list-style-type:none;margin:3px;padding:0;white-space:nowrap}.cke_panel_listItem{margin:0;padding-bottom:1px}.cke_panel_listItem a{padding:3px 4px;display:block;border:1px solid #fff;color:inherit!important;text-decoration:none;overflow:hidden;text-overflow:ellipsis;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px}* html .cke_panel_listItem a{width:100%;color:#000}*:first-child+html .cke_panel_listItem a{color:#000}.cke_panel_listItem.cke_selected a{border:1px solid #dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_panel_listItem a:hover,.cke_panel_listItem a:focus,.cke_panel_listItem a:active{border-color:#dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_hc .cke_panel_listItem a{border-style:none}.cke_hc .cke_panel_listItem a:hover,.cke_hc .cke_panel_listItem a:focus,.cke_hc .cke_panel_listItem a:active{border:2px solid;padding:1px 2px}.cke_panel_grouptitle{font-size:11px;font-weight:bold;white-space:nowrap;margin:0;padding:4px 6px;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #b6b6b6;-moz-border-radius:2px 2px 0 0;-webkit-border-radius:2px 2px 0 0;border-radius:2px 2px 0 0;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_panel_listItem p,.cke_panel_listItem h1,.cke_panel_listItem h2,.cke_panel_listItem h3,.cke_panel_listItem h4,.cke_panel_listItem h5,.cke_panel_listItem h6,.cke_panel_listItem pre{margin-top:0;margin-bottom:0}.cke_colorblock{padding:3px;font-size:11px;font-family:'Microsoft Sans Serif',Tahoma,Arial,Verdana,Sans-Serif}.cke_colorblock,.cke_colorblock a{text-decoration:none;color:#000}span.cke_colorbox{width:10px;height:10px;border:#808080 1px solid;float:left}.cke_rtl span.cke_colorbox{float:right}a.cke_colorbox{border:#fff 1px solid;padding:2px;float:left;width:12px;height:12px}.cke_rtl a.cke_colorbox{float:right}a:hover.cke_colorbox,a:focus.cke_colorbox,a:active.cke_colorbox{border:#b6b6b6 1px solid;background-color:#e5e5e5}a.cke_colorauto,a.cke_colormore{border:#fff 1px solid;padding:2px;display:block;cursor:pointer}a:hover.cke_colorauto,a:hover.cke_colormore,a:focus.cke_colorauto,a:focus.cke_colormore,a:active.cke_colorauto,a:active.cke_colormore{border:#b6b6b6 1px solid;background-color:#e5e5e5}.cke_toolbar{float:left}.cke_rtl .cke_toolbar{float:right}.cke_toolgroup{float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_hc .cke_toolgroup{border:0;margin-right:10px;margin-bottom:10px}.cke_rtl .cke_toolgroup *:first-child{-moz-border-radius:0 2px 2px 0;-webkit-border-radius:0 2px 2px 0;border-radius:0 2px 2px 0}.cke_rtl .cke_toolgroup *:last-child{-moz-border-radius:2px 0 0 2px;-webkit-border-radius:2px 0 0 2px;border-radius:2px 0 0 2px}.cke_rtl .cke_toolgroup{float:right;margin-left:6px;margin-right:0}a.cke_button{display:inline-block;height:18px;padding:4px 6px;outline:0;cursor:default;float:left;border:0}.cke_rtl .cke_button{float:right}.cke_hc .cke_button{border:1px solid black;padding:3px 5px;margin:-2px 4px 0 -2px}.cke_button_on{-moz-box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);background:#b5b5b5;background-image:-webkit-gradient(linear,left top,left bottom,from(#aaa),to(#cacaca));background-image:-moz-linear-gradient(top,#aaa,#cacaca);background-image:-webkit-linear-gradient(top,#aaa,#cacaca);background-image:-o-linear-gradient(top,#aaa,#cacaca);background-image:-ms-linear-gradient(top,#aaa,#cacaca);background-image:linear-gradient(top,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc a.cke_button_disabled:hover,.cke_hc a.cke_button_disabled:focus,.cke_hc a.cke_button_disabled:active{border-width:3px;padding:1px 3px}.cke_button_disabled .cke_button_icon{opacity:.3}.cke_hc .cke_button_disabled{opacity:.5}a.cke_button_on:hover,a.cke_button_on:focus,a.cke_button_on:active{-moz-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}a.cke_button_off:hover,a.cke_button_off:focus,a.cke_button_off:active,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{-moz-box-shadow:0 0 1px rgba(0,0,0,.3) inset;-webkit-box-shadow:0 0 1px rgba(0,0,0,.3) inset;box-shadow:0 0 1px rgba(0,0,0,.3) inset;background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_button_icon{cursor:inherit;background-repeat:no-repeat;margin-top:1px;width:16px;height:16px;float:left;display:inline-block}.cke_rtl .cke_button_icon{float:right}.cke_hc .cke_button_icon{display:none}.cke_button_label{display:none;padding-left:3px;margin-top:1px;line-height:17px;vertical-align:middle;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5)}.cke_rtl .cke_button_label{padding-right:3px;padding-left:0;float:right}.cke_hc .cke_button_label{padding:0;display:inline-block;font-size:12px}.cke_button_arrow{display:inline-block;margin:8px 0 0 1px;width:0;height:0;cursor:default;vertical-align:top;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_rtl .cke_button_arrow{margin-right:5px;margin-left:0}.cke_hc .cke_button_arrow{font-size:10px;margin:3px -2px 0 3px;width:auto;border:0}.cke_toolbar_separator{float:left;background-color:#c0c0c0;background-color:rgba(0,0,0,.2);margin:5px 2px 0;height:18px;width:1px;-webkit-box-shadow:1px 0 1px rgba(255,255,255,.5);-moz-box-shadow:1px 0 1px rgba(255,255,255,.5);box-shadow:1px 0 1px rgba(255,255,255,.5)}.cke_rtl .cke_toolbar_separator{float:right;-webkit-box-shadow:-1px 0 1px rgba(255,255,255,.1);-moz-box-shadow:-1px 0 1px rgba(255,255,255,.1);box-shadow:-1px 0 1px rgba(255,255,255,.1)}.cke_hc .cke_toolbar_separator{width:0;border-left:1px solid;margin:1px 5px 0 0}.cke_toolbar_break{display:block;clear:left}.cke_rtl .cke_toolbar_break{clear:right}.cke_toolbox_collapser{width:12px;height:11px;float:right;margin:11px 0 0;font-size:0;cursor:default;text-align:center;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_toolbox_collapser:hover{background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_toolbox_collapser.cke_toolbox_collapser_min{margin:0 2px 4px}.cke_rtl .cke_toolbox_collapser{float:left}.cke_toolbox_collapser .cke_arrow{display:inline-block;height:0;width:0;font-size:0;margin-top:1px;border-left:3px solid transparent;border-right:3px solid transparent;border-bottom:3px solid #474747;border-top:3px solid transparent}.cke_toolbox_collapser.cke_toolbox_collapser_min .cke_arrow{margin-top:4px;border-bottom-color:transparent;border-top-color:#474747}.cke_hc .cke_toolbox_collapser .cke_arrow{font-size:8px;width:auto;border:0;margin-top:0;margin-right:2px}.cke_menubutton{display:block}.cke_menuitem span{cursor:default}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#d3d3d3;display:block}.cke_hc .cke_menubutton{padding:2px}.cke_hc .cke_menubutton:hover,.cke_hc .cke_menubutton:focus,.cke_hc .cke_menubutton:active{border:2px solid;padding:0}.cke_menubutton_inner{display:table-row}.cke_menubutton_icon,.cke_menubutton_label,.cke_menuarrow{display:table-cell}.cke_menubutton_icon{background-color:#d7d8d7;opacity:.70;filter:alpha(opacity=70);padding:4px}.cke_hc .cke_menubutton_icon{height:16px;width:0;padding:4px 0}.cke_menubutton:hover .cke_menubutton_icon,.cke_menubutton:focus .cke_menubutton_icon,.cke_menubutton:active .cke_menubutton_icon{background-color:#d0d2d0}.cke_menubutton_disabled:hover .cke_menubutton_icon,.cke_menubutton_disabled:focus .cke_menubutton_icon,.cke_menubutton_disabled:active .cke_menubutton_icon{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_label{padding:0 5px;background-color:transparent;width:100%;vertical-align:middle}.cke_menubutton_disabled .cke_menubutton_label{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_on{border:1px solid #dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_menubutton_on .cke_menubutton_icon{padding-right:3px}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#eff0ef}.cke_panel_frame .cke_menubutton_label{display:none}.cke_menuseparator{background-color:#d3d3d3;height:1px;filter:alpha(opacity=70);opacity:.70}.cke_menuarrow{background-image:url(images/arrow.png);background-position:0 10px;background-repeat:no-repeat;padding:0 5px}.cke_rtl .cke_menuarrow{background-position:5px -13px;background-repeat:no-repeat}.cke_menuarrow span{display:none}.cke_hc .cke_menuarrow span{vertical-align:middle;display:inline}.cke_combo{display:inline-block;float:left}.cke_rtl .cke_combo{float:right}.cke_hc .cke_combo{margin-top:-2px}.cke_combo_label{display:none;float:left;line-height:26px;vertical-align:top;margin-right:5px}.cke_rtl .cke_combo_label{float:right;margin-left:5px;margin-right:0}.cke_combo_button{display:inline-block;float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_combo_off a.cke_combo_button:hover,.cke_combo_off a.cke_combo_button:focus{background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc');outline:0}.cke_combo_off a.cke_combo_button:active,.cke_combo_on a.cke_combo_button{border:1px solid #777;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;background:#b5b5b5;background-image:-webkit-gradient(linear,left top,left bottom,from(#aaa),to(#cacaca));background-image:-moz-linear-gradient(top,#aaa,#cacaca);background-image:-webkit-linear-gradient(top,#aaa,#cacaca);background-image:-o-linear-gradient(top,#aaa,#cacaca);background-image:-ms-linear-gradient(top,#aaa,#cacaca);background-image:linear-gradient(top,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_combo_on a.cke_combo_button:hover,.cke_combo_on a.cke_combo_button:focus,.cke_combo_on a.cke_combo_button:active{-moz-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}.cke_rtl .cke_combo_button{float:right;margin-left:5px;margin-right:0}.cke_hc a.cke_combo_button{padding:3px}.cke_hc .cke_combo_on a.cke_combo_button,.cke_hc .cke_combo_off a.cke_combo_button:hover,.cke_hc .cke_combo_off a.cke_combo_button:focus,.cke_hc .cke_combo_off a.cke_combo_button:active{border-width:3px;padding:1px}.cke_combo_text{line-height:26px;padding-left:10px;text-overflow:ellipsis;overflow:hidden;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5);width:60px}.cke_rtl .cke_combo_text{float:right;text-align:right;padding-left:0;padding-right:10px}.cke_hc .cke_combo_text{line-height:18px;font-size:12px}.cke_combo_open{cursor:default;display:inline-block;font-size:0;height:19px;line-height:17px;margin:1px 7px 1px;width:5px}.cke_hc .cke_combo_open{height:12px}.cke_combo_arrow{margin:11px 0 0;float:left;height:0;width:0;font-size:0;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_hc .cke_combo_arrow{font-size:10px;width:auto;border:0;margin-top:3px}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{opacity:.3}.cke_path{float:left;margin:-2px 0 2px}.cke_path_item,.cke_path_empty{display:inline-block;float:left;padding:3px 4px;margin-right:2px;cursor:default;text-decoration:none;outline:0;border:0;color:#4c4c4c;text-shadow:0 1px 0 #fff;font-weight:bold;font-size:11px}.cke_rtl .cke_path,.cke_rtl .cke_path_item,.cke_rtl .cke_path_empty{float:right}a.cke_path_item:hover,a.cke_path_item:focus,a.cke_path_item:active{background-color:#bfbfbf;color:#333;text-shadow:0 1px 0 rgba(255,255,255,.5);-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-moz-box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5);-webkit-box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5);box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5)}.cke_hc a.cke_path_item:hover,.cke_hc a.cke_path_item:focus,.cke_hc a.cke_path_item:active{border:2px solid;padding:1px 2px}.cke_button__source_label,.cke_button__sourcedialog_label{display:inline}.cke_combo__fontsize .cke_combo_text{width:30px}.cke_combopanel__fontsize{width:120px}.cke_source{font-family:'Courier New',Monospace;font-size:small;background-color:#fff;white-space:pre}.cke_wysiwyg_frame,.cke_wysiwyg_div{background-color:#fff}.cke_chrome{visibility:inherit}.cke_voice_label{display:none}legend.cke_voice_label{display:none}.cke_bottom{padding-bottom:3px}.cke_combo_text{margin-bottom:-1px;margin-top:1px}.cke_button__about_icon {background: url(icons.png) no-repeat 0 -0px !important;}.cke_button__bold_icon {background: url(icons.png) no-repeat 0 -24px !important;}.cke_button__italic_icon {background: url(icons.png) no-repeat 0 -48px !important;}.cke_button__strike_icon {background: url(icons.png) no-repeat 0 -72px !important;}.cke_button__subscript_icon {background: url(icons.png) no-repeat 0 -96px !important;}.cke_button__superscript_icon {background: url(icons.png) no-repeat 0 -120px !important;}.cke_button__underline_icon {background: url(icons.png) no-repeat 0 -144px !important;}.cke_button__blockquote_icon {background: url(icons.png) no-repeat 0 -168px !important;}.cke_rtl .cke_button__copy_icon, .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons.png) no-repeat 0 -192px !important;}.cke_ltr .cke_button__copy_icon {background: url(icons.png) no-repeat 0 -216px !important;}.cke_rtl .cke_button__cut_icon, .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons.png) no-repeat 0 -240px !important;}.cke_ltr .cke_button__cut_icon {background: url(icons.png) no-repeat 0 -264px !important;}.cke_rtl .cke_button__paste_icon, .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons.png) no-repeat 0 -288px !important;}.cke_ltr .cke_button__paste_icon {background: url(icons.png) no-repeat 0 -312px !important;}.cke_button__horizontalrule_icon {background: url(icons.png) no-repeat 0 -336px !important;}.cke_button__image_icon {background: url(icons.png) no-repeat 0 -360px !important;}.cke_rtl .cke_button__indent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons.png) no-repeat 0 -384px !important;}.cke_ltr .cke_button__indent_icon {background: url(icons.png) no-repeat 0 -408px !important;}.cke_rtl .cke_button__outdent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons.png) no-repeat 0 -432px !important;}.cke_ltr .cke_button__outdent_icon {background: url(icons.png) no-repeat 0 -456px !important;}.cke_rtl .cke_button__anchor_icon, .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons.png) no-repeat 0 -480px !important;}.cke_ltr .cke_button__anchor_icon {background: url(icons.png) no-repeat 0 -504px !important;}.cke_button__link_icon {background: url(icons.png) no-repeat 0 -528px !important;}.cke_button__unlink_icon {background: url(icons.png) no-repeat 0 -552px !important;}.cke_rtl .cke_button__bulletedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons.png) no-repeat 0 -576px !important;}.cke_ltr .cke_button__bulletedlist_icon {background: url(icons.png) no-repeat 0 -600px !important;}.cke_rtl .cke_button__numberedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons.png) no-repeat 0 -624px !important;}.cke_ltr .cke_button__numberedlist_icon {background: url(icons.png) no-repeat 0 -648px !important;}.cke_button__maximize_icon {background: url(icons.png) no-repeat 0 -672px !important;}.cke_rtl .cke_button__pastetext_icon, .cke_mixed_dir_content .cke_rtl .cke_button__pastetext_icon {background: url(icons.png) no-repeat 0 -696px !important;}.cke_ltr .cke_button__pastetext_icon {background: url(icons.png) no-repeat 0 -720px !important;}.cke_rtl .cke_button__pastefromword_icon, .cke_mixed_dir_content .cke_rtl .cke_button__pastefromword_icon {background: url(icons.png) no-repeat 0 -744px !important;}.cke_ltr .cke_button__pastefromword_icon {background: url(icons.png) no-repeat 0 -768px !important;}.cke_button__removeformat_icon {background: url(icons.png) no-repeat 0 -792px !important;}.cke_rtl .cke_button__source_icon, .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons.png) no-repeat 0 -816px !important;}.cke_ltr .cke_button__source_icon {background: url(icons.png) no-repeat 0 -840px !important;}.cke_button__specialchar_icon {background: url(icons.png) no-repeat 0 -864px !important;}.cke_button__scayt_icon {background: url(icons.png) no-repeat 0 -888px !important;}.cke_button__table_icon {background: url(icons.png) no-repeat 0 -912px !important;}.cke_rtl .cke_button__redo_icon, .cke_mixed_dir_content .cke_rtl .cke_button__redo_icon {background: url(icons.png) no-repeat 0 -936px !important;}.cke_ltr .cke_button__redo_icon {background: url(icons.png) no-repeat 0 -960px !important;}.cke_rtl .cke_button__undo_icon, .cke_mixed_dir_content .cke_rtl .cke_button__undo_icon {background: url(icons.png) no-repeat 0 -984px !important;}.cke_ltr .cke_button__undo_icon {background: url(icons.png) no-repeat 0 -1008px !important;}.cke_button__spellchecker_icon {background: url(icons.png) no-repeat 0 -1032px !important;}.cke_hidpi .cke_button__about_icon {background: url(icons_hidpi.png) no-repeat 0 -0px !important;background-size: 16px !important;}.cke_hidpi .cke_button__bold_icon {background: url(icons_hidpi.png) no-repeat 0 -24px !important;background-size: 16px !important;}.cke_hidpi .cke_button__italic_icon {background: url(icons_hidpi.png) no-repeat 0 -48px !important;background-size: 16px !important;}.cke_hidpi .cke_button__strike_icon {background: url(icons_hidpi.png) no-repeat 0 -72px !important;background-size: 16px !important;}.cke_hidpi .cke_button__subscript_icon {background: url(icons_hidpi.png) no-repeat 0 -96px !important;background-size: 16px !important;}.cke_hidpi .cke_button__superscript_icon {background: url(icons_hidpi.png) no-repeat 0 -120px !important;background-size: 16px !important;}.cke_hidpi .cke_button__underline_icon {background: url(icons_hidpi.png) no-repeat 0 -144px !important;background-size: 16px !important;}.cke_hidpi .cke_button__blockquote_icon {background: url(icons_hidpi.png) no-repeat 0 -168px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__copy_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons_hidpi.png) no-repeat 0 -192px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__copy_icon,.cke_ltr.cke_hidpi .cke_button__copy_icon {background: url(icons_hidpi.png) no-repeat 0 -216px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__cut_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons_hidpi.png) no-repeat 0 -240px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__cut_icon,.cke_ltr.cke_hidpi .cke_button__cut_icon {background: url(icons_hidpi.png) no-repeat 0 -264px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__paste_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons_hidpi.png) no-repeat 0 -288px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__paste_icon,.cke_ltr.cke_hidpi .cke_button__paste_icon {background: url(icons_hidpi.png) no-repeat 0 -312px !important;background-size: 16px !important;}.cke_hidpi .cke_button__horizontalrule_icon {background: url(icons_hidpi.png) no-repeat 0 -336px !important;background-size: 16px !important;}.cke_hidpi .cke_button__image_icon {background: url(icons_hidpi.png) no-repeat 0 -360px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__indent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons_hidpi.png) no-repeat 0 -384px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__indent_icon,.cke_ltr.cke_hidpi .cke_button__indent_icon {background: url(icons_hidpi.png) no-repeat 0 -408px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__outdent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons_hidpi.png) no-repeat 0 -432px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__outdent_icon,.cke_ltr.cke_hidpi .cke_button__outdent_icon {background: url(icons_hidpi.png) no-repeat 0 -456px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__anchor_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons_hidpi.png) no-repeat 0 -480px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__anchor_icon,.cke_ltr.cke_hidpi .cke_button__anchor_icon {background: url(icons_hidpi.png) no-repeat 0 -504px !important;background-size: 16px !important;}.cke_hidpi .cke_button__link_icon {background: url(icons_hidpi.png) no-repeat 0 -528px !important;background-size: 16px !important;}.cke_hidpi .cke_button__unlink_icon {background: url(icons_hidpi.png) no-repeat 0 -552px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__bulletedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -576px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__bulletedlist_icon,.cke_ltr.cke_hidpi .cke_button__bulletedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -600px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__numberedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -624px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__numberedlist_icon,.cke_ltr.cke_hidpi .cke_button__numberedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -648px !important;background-size: 16px !important;}.cke_hidpi .cke_button__maximize_icon {background: url(icons_hidpi.png) no-repeat 0 -672px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__pastetext_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__pastetext_icon {background: url(icons_hidpi.png) no-repeat 0 -696px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__pastetext_icon,.cke_ltr.cke_hidpi .cke_button__pastetext_icon {background: url(icons_hidpi.png) no-repeat 0 -720px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__pastefromword_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__pastefromword_icon {background: url(icons_hidpi.png) no-repeat 0 -744px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__pastefromword_icon,.cke_ltr.cke_hidpi .cke_button__pastefromword_icon {background: url(icons_hidpi.png) no-repeat 0 -768px !important;background-size: 16px !important;}.cke_hidpi .cke_button__removeformat_icon {background: url(icons_hidpi.png) no-repeat 0 -792px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__source_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons_hidpi.png) no-repeat 0 -816px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__source_icon,.cke_ltr.cke_hidpi .cke_button__source_icon {background: url(icons_hidpi.png) no-repeat 0 -840px !important;background-size: 16px !important;}.cke_hidpi .cke_button__specialchar_icon {background: url(icons_hidpi.png) no-repeat 0 -864px !important;background-size: 16px !important;}.cke_hidpi .cke_button__scayt_icon {background: url(icons_hidpi.png) no-repeat 0 -888px !important;background-size: 16px !important;}.cke_hidpi .cke_button__table_icon {background: url(icons_hidpi.png) no-repeat 0 -912px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__redo_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__redo_icon {background: url(icons_hidpi.png) no-repeat 0 -936px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__redo_icon,.cke_ltr.cke_hidpi .cke_button__redo_icon {background: url(icons_hidpi.png) no-repeat 0 -960px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__undo_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__undo_icon {background: url(icons_hidpi.png) no-repeat 0 -984px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__undo_icon,.cke_ltr.cke_hidpi .cke_button__undo_icon {background: url(icons_hidpi.png) no-repeat 0 -1008px !important;background-size: 16px !important;}.cke_hidpi .cke_button__spellchecker_icon {background: url(icons_hidpi.png) no-repeat 0 -1032px !important;background-size: 16px !important;} \ No newline at end of file diff --git a/public/assets/plugins/ckeditor/skins/moono/editor_ie.css b/public/assets/plugins/ckeditor/skins/moono/editor_ie.css new file mode 100644 index 00000000..332d7795 --- /dev/null +++ b/public/assets/plugins/ckeditor/skins/moono/editor_ie.css @@ -0,0 +1,5 @@ +/* +Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. +For licensing, see LICENSE.md or http://ckeditor.com/license +*/ +.cke_reset{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;position:static;-webkit-transition:none;-moz-transition:none;-ms-transition:none;transition:none}.cke_reset_all,.cke_reset_all *{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;position:static;-webkit-transition:none;-moz-transition:none;-ms-transition:none;transition:none;border-collapse:collapse;font:normal normal normal 12px Arial,Helvetica,Tahoma,Verdana,Sans-Serif;color:#000;text-align:left;white-space:nowrap;cursor:auto}.cke_reset_all .cke_rtl *{text-align:right}.cke_reset_all iframe{vertical-align:inherit}.cke_reset_all textarea{white-space:pre}.cke_reset_all textarea,.cke_reset_all input[type="text"],.cke_reset_all input[type="password"]{cursor:text}.cke_reset_all textarea[disabled],.cke_reset_all input[type="text"][disabled],.cke_reset_all input[type="password"][disabled]{cursor:default}.cke_reset_all fieldset{padding:10px;border:2px groove #e0dfe3}.cke_reset_all select{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}.cke_chrome{display:block;border:1px solid #b6b6b6;padding:0;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_inner{display:block;-webkit-touch-callout:none;background:#fff;padding:0}.cke_float{border:0}.cke_float .cke_inner{padding-bottom:0}.cke_top,.cke_contents,.cke_bottom{display:block;overflow:hidden}.cke_top{border-bottom:1px solid #b6b6b6;padding:6px 8px 2px;white-space:normal;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_float .cke_top{border:1px solid #b6b6b6;border-bottom-color:#999}.cke_bottom{padding:6px 8px 2px;position:relative;border-top:1px solid #bfbfbf;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#cfd1cf));background-image:-moz-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-webkit-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-o-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-ms-linear-gradient(top,#ebebeb,#cfd1cf);background-image:linear-gradient(top,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_browser_ios .cke_contents{overflow-y:auto;-webkit-overflow-scrolling:touch}.cke_resizer{width:0;height:0;overflow:hidden;width:0;height:0;overflow:hidden;border-width:10px 10px 0 0;border-color:transparent #666 transparent transparent;border-style:dashed solid dashed dashed;font-size:0;vertical-align:bottom;margin-top:6px;margin-bottom:2px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.3);-webkit-box-shadow:0 1px 0 rgba(255,255,255,.3);box-shadow:0 1px 0 rgba(255,255,255,.3)}.cke_hc .cke_resizer{font-size:15px;width:auto;height:auto;border-width:0}.cke_resizer_ltr{cursor:se-resize;float:right;margin-right:-4px}.cke_resizer_rtl{border-width:10px 0 0 10px;border-color:transparent transparent transparent #a5a5a5;border-style:dashed dashed dashed solid;cursor:sw-resize;float:left;margin-left:-4px;right:auto}.cke_wysiwyg_div{display:block;height:100%;overflow:auto;padding:0 8px;outline-style:none;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.cke_panel{visibility:visible;width:120px;height:100px;overflow:hidden;background-color:#fff;border:1px solid #b6b6b6;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_menu_panel{padding:0;margin:0}.cke_combopanel{width:150px;height:170px}.cke_panel_frame{width:100%;height:100%;font-size:12px;overflow:auto;overflow-x:hidden}.cke_panel_container{overflow-y:auto;overflow-x:hidden}.cke_panel_list{list-style-type:none;margin:3px;padding:0;white-space:nowrap}.cke_panel_listItem{margin:0;padding-bottom:1px}.cke_panel_listItem a{padding:3px 4px;display:block;border:1px solid #fff;color:inherit!important;text-decoration:none;overflow:hidden;text-overflow:ellipsis;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px}* html .cke_panel_listItem a{width:100%;color:#000}*:first-child+html .cke_panel_listItem a{color:#000}.cke_panel_listItem.cke_selected a{border:1px solid #dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_panel_listItem a:hover,.cke_panel_listItem a:focus,.cke_panel_listItem a:active{border-color:#dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_hc .cke_panel_listItem a{border-style:none}.cke_hc .cke_panel_listItem a:hover,.cke_hc .cke_panel_listItem a:focus,.cke_hc .cke_panel_listItem a:active{border:2px solid;padding:1px 2px}.cke_panel_grouptitle{font-size:11px;font-weight:bold;white-space:nowrap;margin:0;padding:4px 6px;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #b6b6b6;-moz-border-radius:2px 2px 0 0;-webkit-border-radius:2px 2px 0 0;border-radius:2px 2px 0 0;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_panel_listItem p,.cke_panel_listItem h1,.cke_panel_listItem h2,.cke_panel_listItem h3,.cke_panel_listItem h4,.cke_panel_listItem h5,.cke_panel_listItem h6,.cke_panel_listItem pre{margin-top:0;margin-bottom:0}.cke_colorblock{padding:3px;font-size:11px;font-family:'Microsoft Sans Serif',Tahoma,Arial,Verdana,Sans-Serif}.cke_colorblock,.cke_colorblock a{text-decoration:none;color:#000}span.cke_colorbox{width:10px;height:10px;border:#808080 1px solid;float:left}.cke_rtl span.cke_colorbox{float:right}a.cke_colorbox{border:#fff 1px solid;padding:2px;float:left;width:12px;height:12px}.cke_rtl a.cke_colorbox{float:right}a:hover.cke_colorbox,a:focus.cke_colorbox,a:active.cke_colorbox{border:#b6b6b6 1px solid;background-color:#e5e5e5}a.cke_colorauto,a.cke_colormore{border:#fff 1px solid;padding:2px;display:block;cursor:pointer}a:hover.cke_colorauto,a:hover.cke_colormore,a:focus.cke_colorauto,a:focus.cke_colormore,a:active.cke_colorauto,a:active.cke_colormore{border:#b6b6b6 1px solid;background-color:#e5e5e5}.cke_toolbar{float:left}.cke_rtl .cke_toolbar{float:right}.cke_toolgroup{float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_hc .cke_toolgroup{border:0;margin-right:10px;margin-bottom:10px}.cke_rtl .cke_toolgroup *:first-child{-moz-border-radius:0 2px 2px 0;-webkit-border-radius:0 2px 2px 0;border-radius:0 2px 2px 0}.cke_rtl .cke_toolgroup *:last-child{-moz-border-radius:2px 0 0 2px;-webkit-border-radius:2px 0 0 2px;border-radius:2px 0 0 2px}.cke_rtl .cke_toolgroup{float:right;margin-left:6px;margin-right:0}a.cke_button{display:inline-block;height:18px;padding:4px 6px;outline:0;cursor:default;float:left;border:0}.cke_rtl .cke_button{float:right}.cke_hc .cke_button{border:1px solid black;padding:3px 5px;margin:-2px 4px 0 -2px}.cke_button_on{-moz-box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);background:#b5b5b5;background-image:-webkit-gradient(linear,left top,left bottom,from(#aaa),to(#cacaca));background-image:-moz-linear-gradient(top,#aaa,#cacaca);background-image:-webkit-linear-gradient(top,#aaa,#cacaca);background-image:-o-linear-gradient(top,#aaa,#cacaca);background-image:-ms-linear-gradient(top,#aaa,#cacaca);background-image:linear-gradient(top,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc a.cke_button_disabled:hover,.cke_hc a.cke_button_disabled:focus,.cke_hc a.cke_button_disabled:active{border-width:3px;padding:1px 3px}.cke_button_disabled .cke_button_icon{opacity:.3}.cke_hc .cke_button_disabled{opacity:.5}a.cke_button_on:hover,a.cke_button_on:focus,a.cke_button_on:active{-moz-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}a.cke_button_off:hover,a.cke_button_off:focus,a.cke_button_off:active,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{-moz-box-shadow:0 0 1px rgba(0,0,0,.3) inset;-webkit-box-shadow:0 0 1px rgba(0,0,0,.3) inset;box-shadow:0 0 1px rgba(0,0,0,.3) inset;background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_button_icon{cursor:inherit;background-repeat:no-repeat;margin-top:1px;width:16px;height:16px;float:left;display:inline-block}.cke_rtl .cke_button_icon{float:right}.cke_hc .cke_button_icon{display:none}.cke_button_label{display:none;padding-left:3px;margin-top:1px;line-height:17px;vertical-align:middle;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5)}.cke_rtl .cke_button_label{padding-right:3px;padding-left:0;float:right}.cke_hc .cke_button_label{padding:0;display:inline-block;font-size:12px}.cke_button_arrow{display:inline-block;margin:8px 0 0 1px;width:0;height:0;cursor:default;vertical-align:top;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_rtl .cke_button_arrow{margin-right:5px;margin-left:0}.cke_hc .cke_button_arrow{font-size:10px;margin:3px -2px 0 3px;width:auto;border:0}.cke_toolbar_separator{float:left;background-color:#c0c0c0;background-color:rgba(0,0,0,.2);margin:5px 2px 0;height:18px;width:1px;-webkit-box-shadow:1px 0 1px rgba(255,255,255,.5);-moz-box-shadow:1px 0 1px rgba(255,255,255,.5);box-shadow:1px 0 1px rgba(255,255,255,.5)}.cke_rtl .cke_toolbar_separator{float:right;-webkit-box-shadow:-1px 0 1px rgba(255,255,255,.1);-moz-box-shadow:-1px 0 1px rgba(255,255,255,.1);box-shadow:-1px 0 1px rgba(255,255,255,.1)}.cke_hc .cke_toolbar_separator{width:0;border-left:1px solid;margin:1px 5px 0 0}.cke_toolbar_break{display:block;clear:left}.cke_rtl .cke_toolbar_break{clear:right}.cke_toolbox_collapser{width:12px;height:11px;float:right;margin:11px 0 0;font-size:0;cursor:default;text-align:center;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_toolbox_collapser:hover{background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_toolbox_collapser.cke_toolbox_collapser_min{margin:0 2px 4px}.cke_rtl .cke_toolbox_collapser{float:left}.cke_toolbox_collapser .cke_arrow{display:inline-block;height:0;width:0;font-size:0;margin-top:1px;border-left:3px solid transparent;border-right:3px solid transparent;border-bottom:3px solid #474747;border-top:3px solid transparent}.cke_toolbox_collapser.cke_toolbox_collapser_min .cke_arrow{margin-top:4px;border-bottom-color:transparent;border-top-color:#474747}.cke_hc .cke_toolbox_collapser .cke_arrow{font-size:8px;width:auto;border:0;margin-top:0;margin-right:2px}.cke_menubutton{display:block}.cke_menuitem span{cursor:default}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#d3d3d3;display:block}.cke_hc .cke_menubutton{padding:2px}.cke_hc .cke_menubutton:hover,.cke_hc .cke_menubutton:focus,.cke_hc .cke_menubutton:active{border:2px solid;padding:0}.cke_menubutton_inner{display:table-row}.cke_menubutton_icon,.cke_menubutton_label,.cke_menuarrow{display:table-cell}.cke_menubutton_icon{background-color:#d7d8d7;opacity:.70;filter:alpha(opacity=70);padding:4px}.cke_hc .cke_menubutton_icon{height:16px;width:0;padding:4px 0}.cke_menubutton:hover .cke_menubutton_icon,.cke_menubutton:focus .cke_menubutton_icon,.cke_menubutton:active .cke_menubutton_icon{background-color:#d0d2d0}.cke_menubutton_disabled:hover .cke_menubutton_icon,.cke_menubutton_disabled:focus .cke_menubutton_icon,.cke_menubutton_disabled:active .cke_menubutton_icon{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_label{padding:0 5px;background-color:transparent;width:100%;vertical-align:middle}.cke_menubutton_disabled .cke_menubutton_label{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_on{border:1px solid #dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_menubutton_on .cke_menubutton_icon{padding-right:3px}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#eff0ef}.cke_panel_frame .cke_menubutton_label{display:none}.cke_menuseparator{background-color:#d3d3d3;height:1px;filter:alpha(opacity=70);opacity:.70}.cke_menuarrow{background-image:url(images/arrow.png);background-position:0 10px;background-repeat:no-repeat;padding:0 5px}.cke_rtl .cke_menuarrow{background-position:5px -13px;background-repeat:no-repeat}.cke_menuarrow span{display:none}.cke_hc .cke_menuarrow span{vertical-align:middle;display:inline}.cke_combo{display:inline-block;float:left}.cke_rtl .cke_combo{float:right}.cke_hc .cke_combo{margin-top:-2px}.cke_combo_label{display:none;float:left;line-height:26px;vertical-align:top;margin-right:5px}.cke_rtl .cke_combo_label{float:right;margin-left:5px;margin-right:0}.cke_combo_button{display:inline-block;float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_combo_off a.cke_combo_button:hover,.cke_combo_off a.cke_combo_button:focus{background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc');outline:0}.cke_combo_off a.cke_combo_button:active,.cke_combo_on a.cke_combo_button{border:1px solid #777;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;background:#b5b5b5;background-image:-webkit-gradient(linear,left top,left bottom,from(#aaa),to(#cacaca));background-image:-moz-linear-gradient(top,#aaa,#cacaca);background-image:-webkit-linear-gradient(top,#aaa,#cacaca);background-image:-o-linear-gradient(top,#aaa,#cacaca);background-image:-ms-linear-gradient(top,#aaa,#cacaca);background-image:linear-gradient(top,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_combo_on a.cke_combo_button:hover,.cke_combo_on a.cke_combo_button:focus,.cke_combo_on a.cke_combo_button:active{-moz-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}.cke_rtl .cke_combo_button{float:right;margin-left:5px;margin-right:0}.cke_hc a.cke_combo_button{padding:3px}.cke_hc .cke_combo_on a.cke_combo_button,.cke_hc .cke_combo_off a.cke_combo_button:hover,.cke_hc .cke_combo_off a.cke_combo_button:focus,.cke_hc .cke_combo_off a.cke_combo_button:active{border-width:3px;padding:1px}.cke_combo_text{line-height:26px;padding-left:10px;text-overflow:ellipsis;overflow:hidden;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5);width:60px}.cke_rtl .cke_combo_text{float:right;text-align:right;padding-left:0;padding-right:10px}.cke_hc .cke_combo_text{line-height:18px;font-size:12px}.cke_combo_open{cursor:default;display:inline-block;font-size:0;height:19px;line-height:17px;margin:1px 7px 1px;width:5px}.cke_hc .cke_combo_open{height:12px}.cke_combo_arrow{margin:11px 0 0;float:left;height:0;width:0;font-size:0;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_hc .cke_combo_arrow{font-size:10px;width:auto;border:0;margin-top:3px}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{opacity:.3}.cke_path{float:left;margin:-2px 0 2px}.cke_path_item,.cke_path_empty{display:inline-block;float:left;padding:3px 4px;margin-right:2px;cursor:default;text-decoration:none;outline:0;border:0;color:#4c4c4c;text-shadow:0 1px 0 #fff;font-weight:bold;font-size:11px}.cke_rtl .cke_path,.cke_rtl .cke_path_item,.cke_rtl .cke_path_empty{float:right}a.cke_path_item:hover,a.cke_path_item:focus,a.cke_path_item:active{background-color:#bfbfbf;color:#333;text-shadow:0 1px 0 rgba(255,255,255,.5);-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-moz-box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5);-webkit-box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5);box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5)}.cke_hc a.cke_path_item:hover,.cke_hc a.cke_path_item:focus,.cke_hc a.cke_path_item:active{border:2px solid;padding:1px 2px}.cke_button__source_label,.cke_button__sourcedialog_label{display:inline}.cke_combo__fontsize .cke_combo_text{width:30px}.cke_combopanel__fontsize{width:120px}.cke_source{font-family:'Courier New',Monospace;font-size:small;background-color:#fff;white-space:pre}.cke_wysiwyg_frame,.cke_wysiwyg_div{background-color:#fff}.cke_chrome{visibility:inherit}.cke_voice_label{display:none}legend.cke_voice_label{display:none}a.cke_button_disabled,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{filter:alpha(opacity = 30)}.cke_button_disabled .cke_button_icon{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#00ffffff,endColorstr=#00ffffff)}.cke_button_off:hover,.cke_button_off:focus,.cke_button_off:active{filter:alpha(opacity = 100)}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{filter:alpha(opacity = 30)}.cke_toolbox_collapser{border:1px solid #a6a6a6}.cke_toolbox_collapser .cke_arrow{margin-top:1px}.cke_hc .cke_top,.cke_hc .cke_bottom,.cke_hc .cke_combo_button,.cke_hc a.cke_combo_button:hover,.cke_hc a.cke_combo_button:focus,.cke_hc .cke_toolgroup,.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc .cke_toolbox_collapser,.cke_hc .cke_toolbox_collapser:hover,.cke_hc .cke_panel_grouptitle{filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.cke_button__about_icon {background: url(icons.png) no-repeat 0 -0px !important;}.cke_button__bold_icon {background: url(icons.png) no-repeat 0 -24px !important;}.cke_button__italic_icon {background: url(icons.png) no-repeat 0 -48px !important;}.cke_button__strike_icon {background: url(icons.png) no-repeat 0 -72px !important;}.cke_button__subscript_icon {background: url(icons.png) no-repeat 0 -96px !important;}.cke_button__superscript_icon {background: url(icons.png) no-repeat 0 -120px !important;}.cke_button__underline_icon {background: url(icons.png) no-repeat 0 -144px !important;}.cke_button__blockquote_icon {background: url(icons.png) no-repeat 0 -168px !important;}.cke_rtl .cke_button__copy_icon, .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons.png) no-repeat 0 -192px !important;}.cke_ltr .cke_button__copy_icon {background: url(icons.png) no-repeat 0 -216px !important;}.cke_rtl .cke_button__cut_icon, .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons.png) no-repeat 0 -240px !important;}.cke_ltr .cke_button__cut_icon {background: url(icons.png) no-repeat 0 -264px !important;}.cke_rtl .cke_button__paste_icon, .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons.png) no-repeat 0 -288px !important;}.cke_ltr .cke_button__paste_icon {background: url(icons.png) no-repeat 0 -312px !important;}.cke_button__horizontalrule_icon {background: url(icons.png) no-repeat 0 -336px !important;}.cke_button__image_icon {background: url(icons.png) no-repeat 0 -360px !important;}.cke_rtl .cke_button__indent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons.png) no-repeat 0 -384px !important;}.cke_ltr .cke_button__indent_icon {background: url(icons.png) no-repeat 0 -408px !important;}.cke_rtl .cke_button__outdent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons.png) no-repeat 0 -432px !important;}.cke_ltr .cke_button__outdent_icon {background: url(icons.png) no-repeat 0 -456px !important;}.cke_rtl .cke_button__anchor_icon, .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons.png) no-repeat 0 -480px !important;}.cke_ltr .cke_button__anchor_icon {background: url(icons.png) no-repeat 0 -504px !important;}.cke_button__link_icon {background: url(icons.png) no-repeat 0 -528px !important;}.cke_button__unlink_icon {background: url(icons.png) no-repeat 0 -552px !important;}.cke_rtl .cke_button__bulletedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons.png) no-repeat 0 -576px !important;}.cke_ltr .cke_button__bulletedlist_icon {background: url(icons.png) no-repeat 0 -600px !important;}.cke_rtl .cke_button__numberedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons.png) no-repeat 0 -624px !important;}.cke_ltr .cke_button__numberedlist_icon {background: url(icons.png) no-repeat 0 -648px !important;}.cke_button__maximize_icon {background: url(icons.png) no-repeat 0 -672px !important;}.cke_rtl .cke_button__pastetext_icon, .cke_mixed_dir_content .cke_rtl .cke_button__pastetext_icon {background: url(icons.png) no-repeat 0 -696px !important;}.cke_ltr .cke_button__pastetext_icon {background: url(icons.png) no-repeat 0 -720px !important;}.cke_rtl .cke_button__pastefromword_icon, .cke_mixed_dir_content .cke_rtl .cke_button__pastefromword_icon {background: url(icons.png) no-repeat 0 -744px !important;}.cke_ltr .cke_button__pastefromword_icon {background: url(icons.png) no-repeat 0 -768px !important;}.cke_button__removeformat_icon {background: url(icons.png) no-repeat 0 -792px !important;}.cke_rtl .cke_button__source_icon, .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons.png) no-repeat 0 -816px !important;}.cke_ltr .cke_button__source_icon {background: url(icons.png) no-repeat 0 -840px !important;}.cke_button__specialchar_icon {background: url(icons.png) no-repeat 0 -864px !important;}.cke_button__scayt_icon {background: url(icons.png) no-repeat 0 -888px !important;}.cke_button__table_icon {background: url(icons.png) no-repeat 0 -912px !important;}.cke_rtl .cke_button__redo_icon, .cke_mixed_dir_content .cke_rtl .cke_button__redo_icon {background: url(icons.png) no-repeat 0 -936px !important;}.cke_ltr .cke_button__redo_icon {background: url(icons.png) no-repeat 0 -960px !important;}.cke_rtl .cke_button__undo_icon, .cke_mixed_dir_content .cke_rtl .cke_button__undo_icon {background: url(icons.png) no-repeat 0 -984px !important;}.cke_ltr .cke_button__undo_icon {background: url(icons.png) no-repeat 0 -1008px !important;}.cke_button__spellchecker_icon {background: url(icons.png) no-repeat 0 -1032px !important;}.cke_hidpi .cke_button__about_icon {background: url(icons_hidpi.png) no-repeat 0 -0px !important;background-size: 16px !important;}.cke_hidpi .cke_button__bold_icon {background: url(icons_hidpi.png) no-repeat 0 -24px !important;background-size: 16px !important;}.cke_hidpi .cke_button__italic_icon {background: url(icons_hidpi.png) no-repeat 0 -48px !important;background-size: 16px !important;}.cke_hidpi .cke_button__strike_icon {background: url(icons_hidpi.png) no-repeat 0 -72px !important;background-size: 16px !important;}.cke_hidpi .cke_button__subscript_icon {background: url(icons_hidpi.png) no-repeat 0 -96px !important;background-size: 16px !important;}.cke_hidpi .cke_button__superscript_icon {background: url(icons_hidpi.png) no-repeat 0 -120px !important;background-size: 16px !important;}.cke_hidpi .cke_button__underline_icon {background: url(icons_hidpi.png) no-repeat 0 -144px !important;background-size: 16px !important;}.cke_hidpi .cke_button__blockquote_icon {background: url(icons_hidpi.png) no-repeat 0 -168px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__copy_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons_hidpi.png) no-repeat 0 -192px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__copy_icon,.cke_ltr.cke_hidpi .cke_button__copy_icon {background: url(icons_hidpi.png) no-repeat 0 -216px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__cut_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons_hidpi.png) no-repeat 0 -240px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__cut_icon,.cke_ltr.cke_hidpi .cke_button__cut_icon {background: url(icons_hidpi.png) no-repeat 0 -264px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__paste_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons_hidpi.png) no-repeat 0 -288px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__paste_icon,.cke_ltr.cke_hidpi .cke_button__paste_icon {background: url(icons_hidpi.png) no-repeat 0 -312px !important;background-size: 16px !important;}.cke_hidpi .cke_button__horizontalrule_icon {background: url(icons_hidpi.png) no-repeat 0 -336px !important;background-size: 16px !important;}.cke_hidpi .cke_button__image_icon {background: url(icons_hidpi.png) no-repeat 0 -360px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__indent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons_hidpi.png) no-repeat 0 -384px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__indent_icon,.cke_ltr.cke_hidpi .cke_button__indent_icon {background: url(icons_hidpi.png) no-repeat 0 -408px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__outdent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons_hidpi.png) no-repeat 0 -432px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__outdent_icon,.cke_ltr.cke_hidpi .cke_button__outdent_icon {background: url(icons_hidpi.png) no-repeat 0 -456px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__anchor_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons_hidpi.png) no-repeat 0 -480px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__anchor_icon,.cke_ltr.cke_hidpi .cke_button__anchor_icon {background: url(icons_hidpi.png) no-repeat 0 -504px !important;background-size: 16px !important;}.cke_hidpi .cke_button__link_icon {background: url(icons_hidpi.png) no-repeat 0 -528px !important;background-size: 16px !important;}.cke_hidpi .cke_button__unlink_icon {background: url(icons_hidpi.png) no-repeat 0 -552px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__bulletedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -576px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__bulletedlist_icon,.cke_ltr.cke_hidpi .cke_button__bulletedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -600px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__numberedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -624px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__numberedlist_icon,.cke_ltr.cke_hidpi .cke_button__numberedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -648px !important;background-size: 16px !important;}.cke_hidpi .cke_button__maximize_icon {background: url(icons_hidpi.png) no-repeat 0 -672px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__pastetext_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__pastetext_icon {background: url(icons_hidpi.png) no-repeat 0 -696px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__pastetext_icon,.cke_ltr.cke_hidpi .cke_button__pastetext_icon {background: url(icons_hidpi.png) no-repeat 0 -720px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__pastefromword_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__pastefromword_icon {background: url(icons_hidpi.png) no-repeat 0 -744px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__pastefromword_icon,.cke_ltr.cke_hidpi .cke_button__pastefromword_icon {background: url(icons_hidpi.png) no-repeat 0 -768px !important;background-size: 16px !important;}.cke_hidpi .cke_button__removeformat_icon {background: url(icons_hidpi.png) no-repeat 0 -792px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__source_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons_hidpi.png) no-repeat 0 -816px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__source_icon,.cke_ltr.cke_hidpi .cke_button__source_icon {background: url(icons_hidpi.png) no-repeat 0 -840px !important;background-size: 16px !important;}.cke_hidpi .cke_button__specialchar_icon {background: url(icons_hidpi.png) no-repeat 0 -864px !important;background-size: 16px !important;}.cke_hidpi .cke_button__scayt_icon {background: url(icons_hidpi.png) no-repeat 0 -888px !important;background-size: 16px !important;}.cke_hidpi .cke_button__table_icon {background: url(icons_hidpi.png) no-repeat 0 -912px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__redo_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__redo_icon {background: url(icons_hidpi.png) no-repeat 0 -936px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__redo_icon,.cke_ltr.cke_hidpi .cke_button__redo_icon {background: url(icons_hidpi.png) no-repeat 0 -960px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__undo_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__undo_icon {background: url(icons_hidpi.png) no-repeat 0 -984px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__undo_icon,.cke_ltr.cke_hidpi .cke_button__undo_icon {background: url(icons_hidpi.png) no-repeat 0 -1008px !important;background-size: 16px !important;}.cke_hidpi .cke_button__spellchecker_icon {background: url(icons_hidpi.png) no-repeat 0 -1032px !important;background-size: 16px !important;} \ No newline at end of file diff --git a/public/assets/plugins/ckeditor/skins/moono/editor_ie7.css b/public/assets/plugins/ckeditor/skins/moono/editor_ie7.css new file mode 100644 index 00000000..9bfeaa78 --- /dev/null +++ b/public/assets/plugins/ckeditor/skins/moono/editor_ie7.css @@ -0,0 +1,5 @@ +/* +Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. +For licensing, see LICENSE.md or http://ckeditor.com/license +*/ +.cke_reset{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;position:static;-webkit-transition:none;-moz-transition:none;-ms-transition:none;transition:none}.cke_reset_all,.cke_reset_all *{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;position:static;-webkit-transition:none;-moz-transition:none;-ms-transition:none;transition:none;border-collapse:collapse;font:normal normal normal 12px Arial,Helvetica,Tahoma,Verdana,Sans-Serif;color:#000;text-align:left;white-space:nowrap;cursor:auto}.cke_reset_all .cke_rtl *{text-align:right}.cke_reset_all iframe{vertical-align:inherit}.cke_reset_all textarea{white-space:pre}.cke_reset_all textarea,.cke_reset_all input[type="text"],.cke_reset_all input[type="password"]{cursor:text}.cke_reset_all textarea[disabled],.cke_reset_all input[type="text"][disabled],.cke_reset_all input[type="password"][disabled]{cursor:default}.cke_reset_all fieldset{padding:10px;border:2px groove #e0dfe3}.cke_reset_all select{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}.cke_chrome{display:block;border:1px solid #b6b6b6;padding:0;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_inner{display:block;-webkit-touch-callout:none;background:#fff;padding:0}.cke_float{border:0}.cke_float .cke_inner{padding-bottom:0}.cke_top,.cke_contents,.cke_bottom{display:block;overflow:hidden}.cke_top{border-bottom:1px solid #b6b6b6;padding:6px 8px 2px;white-space:normal;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_float .cke_top{border:1px solid #b6b6b6;border-bottom-color:#999}.cke_bottom{padding:6px 8px 2px;position:relative;border-top:1px solid #bfbfbf;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#cfd1cf));background-image:-moz-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-webkit-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-o-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-ms-linear-gradient(top,#ebebeb,#cfd1cf);background-image:linear-gradient(top,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_browser_ios .cke_contents{overflow-y:auto;-webkit-overflow-scrolling:touch}.cke_resizer{width:0;height:0;overflow:hidden;width:0;height:0;overflow:hidden;border-width:10px 10px 0 0;border-color:transparent #666 transparent transparent;border-style:dashed solid dashed dashed;font-size:0;vertical-align:bottom;margin-top:6px;margin-bottom:2px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.3);-webkit-box-shadow:0 1px 0 rgba(255,255,255,.3);box-shadow:0 1px 0 rgba(255,255,255,.3)}.cke_hc .cke_resizer{font-size:15px;width:auto;height:auto;border-width:0}.cke_resizer_ltr{cursor:se-resize;float:right;margin-right:-4px}.cke_resizer_rtl{border-width:10px 0 0 10px;border-color:transparent transparent transparent #a5a5a5;border-style:dashed dashed dashed solid;cursor:sw-resize;float:left;margin-left:-4px;right:auto}.cke_wysiwyg_div{display:block;height:100%;overflow:auto;padding:0 8px;outline-style:none;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.cke_panel{visibility:visible;width:120px;height:100px;overflow:hidden;background-color:#fff;border:1px solid #b6b6b6;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_menu_panel{padding:0;margin:0}.cke_combopanel{width:150px;height:170px}.cke_panel_frame{width:100%;height:100%;font-size:12px;overflow:auto;overflow-x:hidden}.cke_panel_container{overflow-y:auto;overflow-x:hidden}.cke_panel_list{list-style-type:none;margin:3px;padding:0;white-space:nowrap}.cke_panel_listItem{margin:0;padding-bottom:1px}.cke_panel_listItem a{padding:3px 4px;display:block;border:1px solid #fff;color:inherit!important;text-decoration:none;overflow:hidden;text-overflow:ellipsis;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px}* html .cke_panel_listItem a{width:100%;color:#000}*:first-child+html .cke_panel_listItem a{color:#000}.cke_panel_listItem.cke_selected a{border:1px solid #dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_panel_listItem a:hover,.cke_panel_listItem a:focus,.cke_panel_listItem a:active{border-color:#dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_hc .cke_panel_listItem a{border-style:none}.cke_hc .cke_panel_listItem a:hover,.cke_hc .cke_panel_listItem a:focus,.cke_hc .cke_panel_listItem a:active{border:2px solid;padding:1px 2px}.cke_panel_grouptitle{font-size:11px;font-weight:bold;white-space:nowrap;margin:0;padding:4px 6px;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #b6b6b6;-moz-border-radius:2px 2px 0 0;-webkit-border-radius:2px 2px 0 0;border-radius:2px 2px 0 0;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_panel_listItem p,.cke_panel_listItem h1,.cke_panel_listItem h2,.cke_panel_listItem h3,.cke_panel_listItem h4,.cke_panel_listItem h5,.cke_panel_listItem h6,.cke_panel_listItem pre{margin-top:0;margin-bottom:0}.cke_colorblock{padding:3px;font-size:11px;font-family:'Microsoft Sans Serif',Tahoma,Arial,Verdana,Sans-Serif}.cke_colorblock,.cke_colorblock a{text-decoration:none;color:#000}span.cke_colorbox{width:10px;height:10px;border:#808080 1px solid;float:left}.cke_rtl span.cke_colorbox{float:right}a.cke_colorbox{border:#fff 1px solid;padding:2px;float:left;width:12px;height:12px}.cke_rtl a.cke_colorbox{float:right}a:hover.cke_colorbox,a:focus.cke_colorbox,a:active.cke_colorbox{border:#b6b6b6 1px solid;background-color:#e5e5e5}a.cke_colorauto,a.cke_colormore{border:#fff 1px solid;padding:2px;display:block;cursor:pointer}a:hover.cke_colorauto,a:hover.cke_colormore,a:focus.cke_colorauto,a:focus.cke_colormore,a:active.cke_colorauto,a:active.cke_colormore{border:#b6b6b6 1px solid;background-color:#e5e5e5}.cke_toolbar{float:left}.cke_rtl .cke_toolbar{float:right}.cke_toolgroup{float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_hc .cke_toolgroup{border:0;margin-right:10px;margin-bottom:10px}.cke_rtl .cke_toolgroup *:first-child{-moz-border-radius:0 2px 2px 0;-webkit-border-radius:0 2px 2px 0;border-radius:0 2px 2px 0}.cke_rtl .cke_toolgroup *:last-child{-moz-border-radius:2px 0 0 2px;-webkit-border-radius:2px 0 0 2px;border-radius:2px 0 0 2px}.cke_rtl .cke_toolgroup{float:right;margin-left:6px;margin-right:0}a.cke_button{display:inline-block;height:18px;padding:4px 6px;outline:0;cursor:default;float:left;border:0}.cke_rtl .cke_button{float:right}.cke_hc .cke_button{border:1px solid black;padding:3px 5px;margin:-2px 4px 0 -2px}.cke_button_on{-moz-box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);background:#b5b5b5;background-image:-webkit-gradient(linear,left top,left bottom,from(#aaa),to(#cacaca));background-image:-moz-linear-gradient(top,#aaa,#cacaca);background-image:-webkit-linear-gradient(top,#aaa,#cacaca);background-image:-o-linear-gradient(top,#aaa,#cacaca);background-image:-ms-linear-gradient(top,#aaa,#cacaca);background-image:linear-gradient(top,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc a.cke_button_disabled:hover,.cke_hc a.cke_button_disabled:focus,.cke_hc a.cke_button_disabled:active{border-width:3px;padding:1px 3px}.cke_button_disabled .cke_button_icon{opacity:.3}.cke_hc .cke_button_disabled{opacity:.5}a.cke_button_on:hover,a.cke_button_on:focus,a.cke_button_on:active{-moz-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}a.cke_button_off:hover,a.cke_button_off:focus,a.cke_button_off:active,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{-moz-box-shadow:0 0 1px rgba(0,0,0,.3) inset;-webkit-box-shadow:0 0 1px rgba(0,0,0,.3) inset;box-shadow:0 0 1px rgba(0,0,0,.3) inset;background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_button_icon{cursor:inherit;background-repeat:no-repeat;margin-top:1px;width:16px;height:16px;float:left;display:inline-block}.cke_rtl .cke_button_icon{float:right}.cke_hc .cke_button_icon{display:none}.cke_button_label{display:none;padding-left:3px;margin-top:1px;line-height:17px;vertical-align:middle;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5)}.cke_rtl .cke_button_label{padding-right:3px;padding-left:0;float:right}.cke_hc .cke_button_label{padding:0;display:inline-block;font-size:12px}.cke_button_arrow{display:inline-block;margin:8px 0 0 1px;width:0;height:0;cursor:default;vertical-align:top;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_rtl .cke_button_arrow{margin-right:5px;margin-left:0}.cke_hc .cke_button_arrow{font-size:10px;margin:3px -2px 0 3px;width:auto;border:0}.cke_toolbar_separator{float:left;background-color:#c0c0c0;background-color:rgba(0,0,0,.2);margin:5px 2px 0;height:18px;width:1px;-webkit-box-shadow:1px 0 1px rgba(255,255,255,.5);-moz-box-shadow:1px 0 1px rgba(255,255,255,.5);box-shadow:1px 0 1px rgba(255,255,255,.5)}.cke_rtl .cke_toolbar_separator{float:right;-webkit-box-shadow:-1px 0 1px rgba(255,255,255,.1);-moz-box-shadow:-1px 0 1px rgba(255,255,255,.1);box-shadow:-1px 0 1px rgba(255,255,255,.1)}.cke_hc .cke_toolbar_separator{width:0;border-left:1px solid;margin:1px 5px 0 0}.cke_toolbar_break{display:block;clear:left}.cke_rtl .cke_toolbar_break{clear:right}.cke_toolbox_collapser{width:12px;height:11px;float:right;margin:11px 0 0;font-size:0;cursor:default;text-align:center;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_toolbox_collapser:hover{background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_toolbox_collapser.cke_toolbox_collapser_min{margin:0 2px 4px}.cke_rtl .cke_toolbox_collapser{float:left}.cke_toolbox_collapser .cke_arrow{display:inline-block;height:0;width:0;font-size:0;margin-top:1px;border-left:3px solid transparent;border-right:3px solid transparent;border-bottom:3px solid #474747;border-top:3px solid transparent}.cke_toolbox_collapser.cke_toolbox_collapser_min .cke_arrow{margin-top:4px;border-bottom-color:transparent;border-top-color:#474747}.cke_hc .cke_toolbox_collapser .cke_arrow{font-size:8px;width:auto;border:0;margin-top:0;margin-right:2px}.cke_menubutton{display:block}.cke_menuitem span{cursor:default}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#d3d3d3;display:block}.cke_hc .cke_menubutton{padding:2px}.cke_hc .cke_menubutton:hover,.cke_hc .cke_menubutton:focus,.cke_hc .cke_menubutton:active{border:2px solid;padding:0}.cke_menubutton_inner{display:table-row}.cke_menubutton_icon,.cke_menubutton_label,.cke_menuarrow{display:table-cell}.cke_menubutton_icon{background-color:#d7d8d7;opacity:.70;filter:alpha(opacity=70);padding:4px}.cke_hc .cke_menubutton_icon{height:16px;width:0;padding:4px 0}.cke_menubutton:hover .cke_menubutton_icon,.cke_menubutton:focus .cke_menubutton_icon,.cke_menubutton:active .cke_menubutton_icon{background-color:#d0d2d0}.cke_menubutton_disabled:hover .cke_menubutton_icon,.cke_menubutton_disabled:focus .cke_menubutton_icon,.cke_menubutton_disabled:active .cke_menubutton_icon{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_label{padding:0 5px;background-color:transparent;width:100%;vertical-align:middle}.cke_menubutton_disabled .cke_menubutton_label{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_on{border:1px solid #dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_menubutton_on .cke_menubutton_icon{padding-right:3px}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#eff0ef}.cke_panel_frame .cke_menubutton_label{display:none}.cke_menuseparator{background-color:#d3d3d3;height:1px;filter:alpha(opacity=70);opacity:.70}.cke_menuarrow{background-image:url(images/arrow.png);background-position:0 10px;background-repeat:no-repeat;padding:0 5px}.cke_rtl .cke_menuarrow{background-position:5px -13px;background-repeat:no-repeat}.cke_menuarrow span{display:none}.cke_hc .cke_menuarrow span{vertical-align:middle;display:inline}.cke_combo{display:inline-block;float:left}.cke_rtl .cke_combo{float:right}.cke_hc .cke_combo{margin-top:-2px}.cke_combo_label{display:none;float:left;line-height:26px;vertical-align:top;margin-right:5px}.cke_rtl .cke_combo_label{float:right;margin-left:5px;margin-right:0}.cke_combo_button{display:inline-block;float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_combo_off a.cke_combo_button:hover,.cke_combo_off a.cke_combo_button:focus{background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc');outline:0}.cke_combo_off a.cke_combo_button:active,.cke_combo_on a.cke_combo_button{border:1px solid #777;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;background:#b5b5b5;background-image:-webkit-gradient(linear,left top,left bottom,from(#aaa),to(#cacaca));background-image:-moz-linear-gradient(top,#aaa,#cacaca);background-image:-webkit-linear-gradient(top,#aaa,#cacaca);background-image:-o-linear-gradient(top,#aaa,#cacaca);background-image:-ms-linear-gradient(top,#aaa,#cacaca);background-image:linear-gradient(top,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_combo_on a.cke_combo_button:hover,.cke_combo_on a.cke_combo_button:focus,.cke_combo_on a.cke_combo_button:active{-moz-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}.cke_rtl .cke_combo_button{float:right;margin-left:5px;margin-right:0}.cke_hc a.cke_combo_button{padding:3px}.cke_hc .cke_combo_on a.cke_combo_button,.cke_hc .cke_combo_off a.cke_combo_button:hover,.cke_hc .cke_combo_off a.cke_combo_button:focus,.cke_hc .cke_combo_off a.cke_combo_button:active{border-width:3px;padding:1px}.cke_combo_text{line-height:26px;padding-left:10px;text-overflow:ellipsis;overflow:hidden;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5);width:60px}.cke_rtl .cke_combo_text{float:right;text-align:right;padding-left:0;padding-right:10px}.cke_hc .cke_combo_text{line-height:18px;font-size:12px}.cke_combo_open{cursor:default;display:inline-block;font-size:0;height:19px;line-height:17px;margin:1px 7px 1px;width:5px}.cke_hc .cke_combo_open{height:12px}.cke_combo_arrow{margin:11px 0 0;float:left;height:0;width:0;font-size:0;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_hc .cke_combo_arrow{font-size:10px;width:auto;border:0;margin-top:3px}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{opacity:.3}.cke_path{float:left;margin:-2px 0 2px}.cke_path_item,.cke_path_empty{display:inline-block;float:left;padding:3px 4px;margin-right:2px;cursor:default;text-decoration:none;outline:0;border:0;color:#4c4c4c;text-shadow:0 1px 0 #fff;font-weight:bold;font-size:11px}.cke_rtl .cke_path,.cke_rtl .cke_path_item,.cke_rtl .cke_path_empty{float:right}a.cke_path_item:hover,a.cke_path_item:focus,a.cke_path_item:active{background-color:#bfbfbf;color:#333;text-shadow:0 1px 0 rgba(255,255,255,.5);-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-moz-box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5);-webkit-box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5);box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5)}.cke_hc a.cke_path_item:hover,.cke_hc a.cke_path_item:focus,.cke_hc a.cke_path_item:active{border:2px solid;padding:1px 2px}.cke_button__source_label,.cke_button__sourcedialog_label{display:inline}.cke_combo__fontsize .cke_combo_text{width:30px}.cke_combopanel__fontsize{width:120px}.cke_source{font-family:'Courier New',Monospace;font-size:small;background-color:#fff;white-space:pre}.cke_wysiwyg_frame,.cke_wysiwyg_div{background-color:#fff}.cke_chrome{visibility:inherit}.cke_voice_label{display:none}legend.cke_voice_label{display:none}a.cke_button_disabled,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{filter:alpha(opacity = 30)}.cke_button_disabled .cke_button_icon{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#00ffffff,endColorstr=#00ffffff)}.cke_button_off:hover,.cke_button_off:focus,.cke_button_off:active{filter:alpha(opacity = 100)}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{filter:alpha(opacity = 30)}.cke_toolbox_collapser{border:1px solid #a6a6a6}.cke_toolbox_collapser .cke_arrow{margin-top:1px}.cke_hc .cke_top,.cke_hc .cke_bottom,.cke_hc .cke_combo_button,.cke_hc a.cke_combo_button:hover,.cke_hc a.cke_combo_button:focus,.cke_hc .cke_toolgroup,.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc .cke_toolbox_collapser,.cke_hc .cke_toolbox_collapser:hover,.cke_hc .cke_panel_grouptitle{filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.cke_rtl .cke_toolgroup,.cke_rtl .cke_toolbar_separator,.cke_rtl .cke_button,.cke_rtl .cke_button *,.cke_rtl .cke_combo,.cke_rtl .cke_combo *,.cke_rtl .cke_path_item,.cke_rtl .cke_path_item *,.cke_rtl .cke_path_empty{float:none}.cke_rtl .cke_toolgroup,.cke_rtl .cke_toolbar_separator,.cke_rtl .cke_combo_button,.cke_rtl .cke_combo_button *,.cke_rtl .cke_button,.cke_rtl .cke_button_icon,{display:inline-block;vertical-align:top}.cke_toolbox{display:inline-block;padding-bottom:5px;height:100%}.cke_rtl .cke_toolbox{padding-bottom:0}.cke_toolbar{margin-bottom:5px}.cke_rtl .cke_toolbar{margin-bottom:0}.cke_toolgroup{height:26px}.cke_toolgroup,.cke_combo{position:relative}a.cke_button{float:none;vertical-align:top}.cke_toolbar_separator{display:inline-block;float:none;vertical-align:top;background-color:#c0c0c0}.cke_toolbox_collapser .cke_arrow{margin-top:0}.cke_toolbox_collapser .cke_arrow{border-width:4px}.cke_toolbox_collapser.cke_toolbox_collapser_min .cke_arrow{border-width:3px}.cke_rtl .cke_button_arrow{padding-top:8px;margin-right:2px}.cke_rtl .cke_combo_inlinelabel{display:table-cell;vertical-align:middle}.cke_menubutton{display:block;height:24px}.cke_menubutton_inner{display:block;position:relative}.cke_menubutton_icon{height:16px;width:16px}.cke_menubutton_icon,.cke_menubutton_label,.cke_menuarrow{display:inline-block}.cke_menubutton_label{width:auto;vertical-align:top;line-height:24px;height:24px;margin:0 10px 0 0}.cke_menuarrow{width:5px;height:6px;padding:0;position:absolute;right:8px;top:10px;background-position:0 0}.cke_rtl .cke_menubutton_icon{position:absolute;right:0;top:0}.cke_rtl .cke_menubutton_label{float:right;clear:both;margin:0 24px 0 10px}.cke_hc .cke_rtl .cke_menubutton_label{margin-right:0}.cke_rtl .cke_menuarrow{left:8px;right:auto;background-position:0 -24px}.cke_hc .cke_menuarrow{top:5px;padding:0 5px}.cke_rtl input.cke_dialog_ui_input_text,.cke_rtl input.cke_dialog_ui_input_password{position:relative}.cke_wysiwyg_div{padding-top:0!important;padding-bottom:0!important}.cke_button__about_icon {background: url(icons.png) no-repeat 0 -0px !important;}.cke_button__bold_icon {background: url(icons.png) no-repeat 0 -24px !important;}.cke_button__italic_icon {background: url(icons.png) no-repeat 0 -48px !important;}.cke_button__strike_icon {background: url(icons.png) no-repeat 0 -72px !important;}.cke_button__subscript_icon {background: url(icons.png) no-repeat 0 -96px !important;}.cke_button__superscript_icon {background: url(icons.png) no-repeat 0 -120px !important;}.cke_button__underline_icon {background: url(icons.png) no-repeat 0 -144px !important;}.cke_button__blockquote_icon {background: url(icons.png) no-repeat 0 -168px !important;}.cke_rtl .cke_button__copy_icon, .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons.png) no-repeat 0 -192px !important;}.cke_ltr .cke_button__copy_icon {background: url(icons.png) no-repeat 0 -216px !important;}.cke_rtl .cke_button__cut_icon, .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons.png) no-repeat 0 -240px !important;}.cke_ltr .cke_button__cut_icon {background: url(icons.png) no-repeat 0 -264px !important;}.cke_rtl .cke_button__paste_icon, .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons.png) no-repeat 0 -288px !important;}.cke_ltr .cke_button__paste_icon {background: url(icons.png) no-repeat 0 -312px !important;}.cke_button__horizontalrule_icon {background: url(icons.png) no-repeat 0 -336px !important;}.cke_button__image_icon {background: url(icons.png) no-repeat 0 -360px !important;}.cke_rtl .cke_button__indent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons.png) no-repeat 0 -384px !important;}.cke_ltr .cke_button__indent_icon {background: url(icons.png) no-repeat 0 -408px !important;}.cke_rtl .cke_button__outdent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons.png) no-repeat 0 -432px !important;}.cke_ltr .cke_button__outdent_icon {background: url(icons.png) no-repeat 0 -456px !important;}.cke_rtl .cke_button__anchor_icon, .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons.png) no-repeat 0 -480px !important;}.cke_ltr .cke_button__anchor_icon {background: url(icons.png) no-repeat 0 -504px !important;}.cke_button__link_icon {background: url(icons.png) no-repeat 0 -528px !important;}.cke_button__unlink_icon {background: url(icons.png) no-repeat 0 -552px !important;}.cke_rtl .cke_button__bulletedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons.png) no-repeat 0 -576px !important;}.cke_ltr .cke_button__bulletedlist_icon {background: url(icons.png) no-repeat 0 -600px !important;}.cke_rtl .cke_button__numberedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons.png) no-repeat 0 -624px !important;}.cke_ltr .cke_button__numberedlist_icon {background: url(icons.png) no-repeat 0 -648px !important;}.cke_button__maximize_icon {background: url(icons.png) no-repeat 0 -672px !important;}.cke_rtl .cke_button__pastetext_icon, .cke_mixed_dir_content .cke_rtl .cke_button__pastetext_icon {background: url(icons.png) no-repeat 0 -696px !important;}.cke_ltr .cke_button__pastetext_icon {background: url(icons.png) no-repeat 0 -720px !important;}.cke_rtl .cke_button__pastefromword_icon, .cke_mixed_dir_content .cke_rtl .cke_button__pastefromword_icon {background: url(icons.png) no-repeat 0 -744px !important;}.cke_ltr .cke_button__pastefromword_icon {background: url(icons.png) no-repeat 0 -768px !important;}.cke_button__removeformat_icon {background: url(icons.png) no-repeat 0 -792px !important;}.cke_rtl .cke_button__source_icon, .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons.png) no-repeat 0 -816px !important;}.cke_ltr .cke_button__source_icon {background: url(icons.png) no-repeat 0 -840px !important;}.cke_button__specialchar_icon {background: url(icons.png) no-repeat 0 -864px !important;}.cke_button__scayt_icon {background: url(icons.png) no-repeat 0 -888px !important;}.cke_button__table_icon {background: url(icons.png) no-repeat 0 -912px !important;}.cke_rtl .cke_button__redo_icon, .cke_mixed_dir_content .cke_rtl .cke_button__redo_icon {background: url(icons.png) no-repeat 0 -936px !important;}.cke_ltr .cke_button__redo_icon {background: url(icons.png) no-repeat 0 -960px !important;}.cke_rtl .cke_button__undo_icon, .cke_mixed_dir_content .cke_rtl .cke_button__undo_icon {background: url(icons.png) no-repeat 0 -984px !important;}.cke_ltr .cke_button__undo_icon {background: url(icons.png) no-repeat 0 -1008px !important;}.cke_button__spellchecker_icon {background: url(icons.png) no-repeat 0 -1032px !important;}.cke_hidpi .cke_button__about_icon {background: url(icons_hidpi.png) no-repeat 0 -0px !important;background-size: 16px !important;}.cke_hidpi .cke_button__bold_icon {background: url(icons_hidpi.png) no-repeat 0 -24px !important;background-size: 16px !important;}.cke_hidpi .cke_button__italic_icon {background: url(icons_hidpi.png) no-repeat 0 -48px !important;background-size: 16px !important;}.cke_hidpi .cke_button__strike_icon {background: url(icons_hidpi.png) no-repeat 0 -72px !important;background-size: 16px !important;}.cke_hidpi .cke_button__subscript_icon {background: url(icons_hidpi.png) no-repeat 0 -96px !important;background-size: 16px !important;}.cke_hidpi .cke_button__superscript_icon {background: url(icons_hidpi.png) no-repeat 0 -120px !important;background-size: 16px !important;}.cke_hidpi .cke_button__underline_icon {background: url(icons_hidpi.png) no-repeat 0 -144px !important;background-size: 16px !important;}.cke_hidpi .cke_button__blockquote_icon {background: url(icons_hidpi.png) no-repeat 0 -168px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__copy_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons_hidpi.png) no-repeat 0 -192px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__copy_icon,.cke_ltr.cke_hidpi .cke_button__copy_icon {background: url(icons_hidpi.png) no-repeat 0 -216px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__cut_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons_hidpi.png) no-repeat 0 -240px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__cut_icon,.cke_ltr.cke_hidpi .cke_button__cut_icon {background: url(icons_hidpi.png) no-repeat 0 -264px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__paste_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons_hidpi.png) no-repeat 0 -288px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__paste_icon,.cke_ltr.cke_hidpi .cke_button__paste_icon {background: url(icons_hidpi.png) no-repeat 0 -312px !important;background-size: 16px !important;}.cke_hidpi .cke_button__horizontalrule_icon {background: url(icons_hidpi.png) no-repeat 0 -336px !important;background-size: 16px !important;}.cke_hidpi .cke_button__image_icon {background: url(icons_hidpi.png) no-repeat 0 -360px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__indent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons_hidpi.png) no-repeat 0 -384px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__indent_icon,.cke_ltr.cke_hidpi .cke_button__indent_icon {background: url(icons_hidpi.png) no-repeat 0 -408px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__outdent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons_hidpi.png) no-repeat 0 -432px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__outdent_icon,.cke_ltr.cke_hidpi .cke_button__outdent_icon {background: url(icons_hidpi.png) no-repeat 0 -456px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__anchor_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons_hidpi.png) no-repeat 0 -480px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__anchor_icon,.cke_ltr.cke_hidpi .cke_button__anchor_icon {background: url(icons_hidpi.png) no-repeat 0 -504px !important;background-size: 16px !important;}.cke_hidpi .cke_button__link_icon {background: url(icons_hidpi.png) no-repeat 0 -528px !important;background-size: 16px !important;}.cke_hidpi .cke_button__unlink_icon {background: url(icons_hidpi.png) no-repeat 0 -552px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__bulletedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -576px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__bulletedlist_icon,.cke_ltr.cke_hidpi .cke_button__bulletedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -600px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__numberedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -624px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__numberedlist_icon,.cke_ltr.cke_hidpi .cke_button__numberedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -648px !important;background-size: 16px !important;}.cke_hidpi .cke_button__maximize_icon {background: url(icons_hidpi.png) no-repeat 0 -672px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__pastetext_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__pastetext_icon {background: url(icons_hidpi.png) no-repeat 0 -696px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__pastetext_icon,.cke_ltr.cke_hidpi .cke_button__pastetext_icon {background: url(icons_hidpi.png) no-repeat 0 -720px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__pastefromword_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__pastefromword_icon {background: url(icons_hidpi.png) no-repeat 0 -744px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__pastefromword_icon,.cke_ltr.cke_hidpi .cke_button__pastefromword_icon {background: url(icons_hidpi.png) no-repeat 0 -768px !important;background-size: 16px !important;}.cke_hidpi .cke_button__removeformat_icon {background: url(icons_hidpi.png) no-repeat 0 -792px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__source_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons_hidpi.png) no-repeat 0 -816px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__source_icon,.cke_ltr.cke_hidpi .cke_button__source_icon {background: url(icons_hidpi.png) no-repeat 0 -840px !important;background-size: 16px !important;}.cke_hidpi .cke_button__specialchar_icon {background: url(icons_hidpi.png) no-repeat 0 -864px !important;background-size: 16px !important;}.cke_hidpi .cke_button__scayt_icon {background: url(icons_hidpi.png) no-repeat 0 -888px !important;background-size: 16px !important;}.cke_hidpi .cke_button__table_icon {background: url(icons_hidpi.png) no-repeat 0 -912px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__redo_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__redo_icon {background: url(icons_hidpi.png) no-repeat 0 -936px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__redo_icon,.cke_ltr.cke_hidpi .cke_button__redo_icon {background: url(icons_hidpi.png) no-repeat 0 -960px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__undo_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__undo_icon {background: url(icons_hidpi.png) no-repeat 0 -984px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__undo_icon,.cke_ltr.cke_hidpi .cke_button__undo_icon {background: url(icons_hidpi.png) no-repeat 0 -1008px !important;background-size: 16px !important;}.cke_hidpi .cke_button__spellchecker_icon {background: url(icons_hidpi.png) no-repeat 0 -1032px !important;background-size: 16px !important;} \ No newline at end of file diff --git a/public/assets/plugins/ckeditor/skins/moono/editor_ie8.css b/public/assets/plugins/ckeditor/skins/moono/editor_ie8.css new file mode 100644 index 00000000..955ec8d2 --- /dev/null +++ b/public/assets/plugins/ckeditor/skins/moono/editor_ie8.css @@ -0,0 +1,5 @@ +/* +Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. +For licensing, see LICENSE.md or http://ckeditor.com/license +*/ +.cke_reset{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;position:static;-webkit-transition:none;-moz-transition:none;-ms-transition:none;transition:none}.cke_reset_all,.cke_reset_all *{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;position:static;-webkit-transition:none;-moz-transition:none;-ms-transition:none;transition:none;border-collapse:collapse;font:normal normal normal 12px Arial,Helvetica,Tahoma,Verdana,Sans-Serif;color:#000;text-align:left;white-space:nowrap;cursor:auto}.cke_reset_all .cke_rtl *{text-align:right}.cke_reset_all iframe{vertical-align:inherit}.cke_reset_all textarea{white-space:pre}.cke_reset_all textarea,.cke_reset_all input[type="text"],.cke_reset_all input[type="password"]{cursor:text}.cke_reset_all textarea[disabled],.cke_reset_all input[type="text"][disabled],.cke_reset_all input[type="password"][disabled]{cursor:default}.cke_reset_all fieldset{padding:10px;border:2px groove #e0dfe3}.cke_reset_all select{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}.cke_chrome{display:block;border:1px solid #b6b6b6;padding:0;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_inner{display:block;-webkit-touch-callout:none;background:#fff;padding:0}.cke_float{border:0}.cke_float .cke_inner{padding-bottom:0}.cke_top,.cke_contents,.cke_bottom{display:block;overflow:hidden}.cke_top{border-bottom:1px solid #b6b6b6;padding:6px 8px 2px;white-space:normal;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_float .cke_top{border:1px solid #b6b6b6;border-bottom-color:#999}.cke_bottom{padding:6px 8px 2px;position:relative;border-top:1px solid #bfbfbf;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#cfd1cf));background-image:-moz-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-webkit-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-o-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-ms-linear-gradient(top,#ebebeb,#cfd1cf);background-image:linear-gradient(top,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_browser_ios .cke_contents{overflow-y:auto;-webkit-overflow-scrolling:touch}.cke_resizer{width:0;height:0;overflow:hidden;width:0;height:0;overflow:hidden;border-width:10px 10px 0 0;border-color:transparent #666 transparent transparent;border-style:dashed solid dashed dashed;font-size:0;vertical-align:bottom;margin-top:6px;margin-bottom:2px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.3);-webkit-box-shadow:0 1px 0 rgba(255,255,255,.3);box-shadow:0 1px 0 rgba(255,255,255,.3)}.cke_hc .cke_resizer{font-size:15px;width:auto;height:auto;border-width:0}.cke_resizer_ltr{cursor:se-resize;float:right;margin-right:-4px}.cke_resizer_rtl{border-width:10px 0 0 10px;border-color:transparent transparent transparent #a5a5a5;border-style:dashed dashed dashed solid;cursor:sw-resize;float:left;margin-left:-4px;right:auto}.cke_wysiwyg_div{display:block;height:100%;overflow:auto;padding:0 8px;outline-style:none;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.cke_panel{visibility:visible;width:120px;height:100px;overflow:hidden;background-color:#fff;border:1px solid #b6b6b6;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_menu_panel{padding:0;margin:0}.cke_combopanel{width:150px;height:170px}.cke_panel_frame{width:100%;height:100%;font-size:12px;overflow:auto;overflow-x:hidden}.cke_panel_container{overflow-y:auto;overflow-x:hidden}.cke_panel_list{list-style-type:none;margin:3px;padding:0;white-space:nowrap}.cke_panel_listItem{margin:0;padding-bottom:1px}.cke_panel_listItem a{padding:3px 4px;display:block;border:1px solid #fff;color:inherit!important;text-decoration:none;overflow:hidden;text-overflow:ellipsis;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px}* html .cke_panel_listItem a{width:100%;color:#000}*:first-child+html .cke_panel_listItem a{color:#000}.cke_panel_listItem.cke_selected a{border:1px solid #dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_panel_listItem a:hover,.cke_panel_listItem a:focus,.cke_panel_listItem a:active{border-color:#dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_hc .cke_panel_listItem a{border-style:none}.cke_hc .cke_panel_listItem a:hover,.cke_hc .cke_panel_listItem a:focus,.cke_hc .cke_panel_listItem a:active{border:2px solid;padding:1px 2px}.cke_panel_grouptitle{font-size:11px;font-weight:bold;white-space:nowrap;margin:0;padding:4px 6px;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #b6b6b6;-moz-border-radius:2px 2px 0 0;-webkit-border-radius:2px 2px 0 0;border-radius:2px 2px 0 0;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_panel_listItem p,.cke_panel_listItem h1,.cke_panel_listItem h2,.cke_panel_listItem h3,.cke_panel_listItem h4,.cke_panel_listItem h5,.cke_panel_listItem h6,.cke_panel_listItem pre{margin-top:0;margin-bottom:0}.cke_colorblock{padding:3px;font-size:11px;font-family:'Microsoft Sans Serif',Tahoma,Arial,Verdana,Sans-Serif}.cke_colorblock,.cke_colorblock a{text-decoration:none;color:#000}span.cke_colorbox{width:10px;height:10px;border:#808080 1px solid;float:left}.cke_rtl span.cke_colorbox{float:right}a.cke_colorbox{border:#fff 1px solid;padding:2px;float:left;width:12px;height:12px}.cke_rtl a.cke_colorbox{float:right}a:hover.cke_colorbox,a:focus.cke_colorbox,a:active.cke_colorbox{border:#b6b6b6 1px solid;background-color:#e5e5e5}a.cke_colorauto,a.cke_colormore{border:#fff 1px solid;padding:2px;display:block;cursor:pointer}a:hover.cke_colorauto,a:hover.cke_colormore,a:focus.cke_colorauto,a:focus.cke_colormore,a:active.cke_colorauto,a:active.cke_colormore{border:#b6b6b6 1px solid;background-color:#e5e5e5}.cke_toolbar{float:left}.cke_rtl .cke_toolbar{float:right}.cke_toolgroup{float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_hc .cke_toolgroup{border:0;margin-right:10px;margin-bottom:10px}.cke_rtl .cke_toolgroup *:first-child{-moz-border-radius:0 2px 2px 0;-webkit-border-radius:0 2px 2px 0;border-radius:0 2px 2px 0}.cke_rtl .cke_toolgroup *:last-child{-moz-border-radius:2px 0 0 2px;-webkit-border-radius:2px 0 0 2px;border-radius:2px 0 0 2px}.cke_rtl .cke_toolgroup{float:right;margin-left:6px;margin-right:0}a.cke_button{display:inline-block;height:18px;padding:4px 6px;outline:0;cursor:default;float:left;border:0}.cke_rtl .cke_button{float:right}.cke_hc .cke_button{border:1px solid black;padding:3px 5px;margin:-2px 4px 0 -2px}.cke_button_on{-moz-box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);background:#b5b5b5;background-image:-webkit-gradient(linear,left top,left bottom,from(#aaa),to(#cacaca));background-image:-moz-linear-gradient(top,#aaa,#cacaca);background-image:-webkit-linear-gradient(top,#aaa,#cacaca);background-image:-o-linear-gradient(top,#aaa,#cacaca);background-image:-ms-linear-gradient(top,#aaa,#cacaca);background-image:linear-gradient(top,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc a.cke_button_disabled:hover,.cke_hc a.cke_button_disabled:focus,.cke_hc a.cke_button_disabled:active{border-width:3px;padding:1px 3px}.cke_button_disabled .cke_button_icon{opacity:.3}.cke_hc .cke_button_disabled{opacity:.5}a.cke_button_on:hover,a.cke_button_on:focus,a.cke_button_on:active{-moz-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}a.cke_button_off:hover,a.cke_button_off:focus,a.cke_button_off:active,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{-moz-box-shadow:0 0 1px rgba(0,0,0,.3) inset;-webkit-box-shadow:0 0 1px rgba(0,0,0,.3) inset;box-shadow:0 0 1px rgba(0,0,0,.3) inset;background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_button_icon{cursor:inherit;background-repeat:no-repeat;margin-top:1px;width:16px;height:16px;float:left;display:inline-block}.cke_rtl .cke_button_icon{float:right}.cke_hc .cke_button_icon{display:none}.cke_button_label{display:none;padding-left:3px;margin-top:1px;line-height:17px;vertical-align:middle;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5)}.cke_rtl .cke_button_label{padding-right:3px;padding-left:0;float:right}.cke_hc .cke_button_label{padding:0;display:inline-block;font-size:12px}.cke_button_arrow{display:inline-block;margin:8px 0 0 1px;width:0;height:0;cursor:default;vertical-align:top;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_rtl .cke_button_arrow{margin-right:5px;margin-left:0}.cke_hc .cke_button_arrow{font-size:10px;margin:3px -2px 0 3px;width:auto;border:0}.cke_toolbar_separator{float:left;background-color:#c0c0c0;background-color:rgba(0,0,0,.2);margin:5px 2px 0;height:18px;width:1px;-webkit-box-shadow:1px 0 1px rgba(255,255,255,.5);-moz-box-shadow:1px 0 1px rgba(255,255,255,.5);box-shadow:1px 0 1px rgba(255,255,255,.5)}.cke_rtl .cke_toolbar_separator{float:right;-webkit-box-shadow:-1px 0 1px rgba(255,255,255,.1);-moz-box-shadow:-1px 0 1px rgba(255,255,255,.1);box-shadow:-1px 0 1px rgba(255,255,255,.1)}.cke_hc .cke_toolbar_separator{width:0;border-left:1px solid;margin:1px 5px 0 0}.cke_toolbar_break{display:block;clear:left}.cke_rtl .cke_toolbar_break{clear:right}.cke_toolbox_collapser{width:12px;height:11px;float:right;margin:11px 0 0;font-size:0;cursor:default;text-align:center;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_toolbox_collapser:hover{background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_toolbox_collapser.cke_toolbox_collapser_min{margin:0 2px 4px}.cke_rtl .cke_toolbox_collapser{float:left}.cke_toolbox_collapser .cke_arrow{display:inline-block;height:0;width:0;font-size:0;margin-top:1px;border-left:3px solid transparent;border-right:3px solid transparent;border-bottom:3px solid #474747;border-top:3px solid transparent}.cke_toolbox_collapser.cke_toolbox_collapser_min .cke_arrow{margin-top:4px;border-bottom-color:transparent;border-top-color:#474747}.cke_hc .cke_toolbox_collapser .cke_arrow{font-size:8px;width:auto;border:0;margin-top:0;margin-right:2px}.cke_menubutton{display:block}.cke_menuitem span{cursor:default}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#d3d3d3;display:block}.cke_hc .cke_menubutton{padding:2px}.cke_hc .cke_menubutton:hover,.cke_hc .cke_menubutton:focus,.cke_hc .cke_menubutton:active{border:2px solid;padding:0}.cke_menubutton_inner{display:table-row}.cke_menubutton_icon,.cke_menubutton_label,.cke_menuarrow{display:table-cell}.cke_menubutton_icon{background-color:#d7d8d7;opacity:.70;filter:alpha(opacity=70);padding:4px}.cke_hc .cke_menubutton_icon{height:16px;width:0;padding:4px 0}.cke_menubutton:hover .cke_menubutton_icon,.cke_menubutton:focus .cke_menubutton_icon,.cke_menubutton:active .cke_menubutton_icon{background-color:#d0d2d0}.cke_menubutton_disabled:hover .cke_menubutton_icon,.cke_menubutton_disabled:focus .cke_menubutton_icon,.cke_menubutton_disabled:active .cke_menubutton_icon{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_label{padding:0 5px;background-color:transparent;width:100%;vertical-align:middle}.cke_menubutton_disabled .cke_menubutton_label{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_on{border:1px solid #dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_menubutton_on .cke_menubutton_icon{padding-right:3px}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#eff0ef}.cke_panel_frame .cke_menubutton_label{display:none}.cke_menuseparator{background-color:#d3d3d3;height:1px;filter:alpha(opacity=70);opacity:.70}.cke_menuarrow{background-image:url(images/arrow.png);background-position:0 10px;background-repeat:no-repeat;padding:0 5px}.cke_rtl .cke_menuarrow{background-position:5px -13px;background-repeat:no-repeat}.cke_menuarrow span{display:none}.cke_hc .cke_menuarrow span{vertical-align:middle;display:inline}.cke_combo{display:inline-block;float:left}.cke_rtl .cke_combo{float:right}.cke_hc .cke_combo{margin-top:-2px}.cke_combo_label{display:none;float:left;line-height:26px;vertical-align:top;margin-right:5px}.cke_rtl .cke_combo_label{float:right;margin-left:5px;margin-right:0}.cke_combo_button{display:inline-block;float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_combo_off a.cke_combo_button:hover,.cke_combo_off a.cke_combo_button:focus{background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc');outline:0}.cke_combo_off a.cke_combo_button:active,.cke_combo_on a.cke_combo_button{border:1px solid #777;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;background:#b5b5b5;background-image:-webkit-gradient(linear,left top,left bottom,from(#aaa),to(#cacaca));background-image:-moz-linear-gradient(top,#aaa,#cacaca);background-image:-webkit-linear-gradient(top,#aaa,#cacaca);background-image:-o-linear-gradient(top,#aaa,#cacaca);background-image:-ms-linear-gradient(top,#aaa,#cacaca);background-image:linear-gradient(top,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_combo_on a.cke_combo_button:hover,.cke_combo_on a.cke_combo_button:focus,.cke_combo_on a.cke_combo_button:active{-moz-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}.cke_rtl .cke_combo_button{float:right;margin-left:5px;margin-right:0}.cke_hc a.cke_combo_button{padding:3px}.cke_hc .cke_combo_on a.cke_combo_button,.cke_hc .cke_combo_off a.cke_combo_button:hover,.cke_hc .cke_combo_off a.cke_combo_button:focus,.cke_hc .cke_combo_off a.cke_combo_button:active{border-width:3px;padding:1px}.cke_combo_text{line-height:26px;padding-left:10px;text-overflow:ellipsis;overflow:hidden;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5);width:60px}.cke_rtl .cke_combo_text{float:right;text-align:right;padding-left:0;padding-right:10px}.cke_hc .cke_combo_text{line-height:18px;font-size:12px}.cke_combo_open{cursor:default;display:inline-block;font-size:0;height:19px;line-height:17px;margin:1px 7px 1px;width:5px}.cke_hc .cke_combo_open{height:12px}.cke_combo_arrow{margin:11px 0 0;float:left;height:0;width:0;font-size:0;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_hc .cke_combo_arrow{font-size:10px;width:auto;border:0;margin-top:3px}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{opacity:.3}.cke_path{float:left;margin:-2px 0 2px}.cke_path_item,.cke_path_empty{display:inline-block;float:left;padding:3px 4px;margin-right:2px;cursor:default;text-decoration:none;outline:0;border:0;color:#4c4c4c;text-shadow:0 1px 0 #fff;font-weight:bold;font-size:11px}.cke_rtl .cke_path,.cke_rtl .cke_path_item,.cke_rtl .cke_path_empty{float:right}a.cke_path_item:hover,a.cke_path_item:focus,a.cke_path_item:active{background-color:#bfbfbf;color:#333;text-shadow:0 1px 0 rgba(255,255,255,.5);-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-moz-box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5);-webkit-box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5);box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5)}.cke_hc a.cke_path_item:hover,.cke_hc a.cke_path_item:focus,.cke_hc a.cke_path_item:active{border:2px solid;padding:1px 2px}.cke_button__source_label,.cke_button__sourcedialog_label{display:inline}.cke_combo__fontsize .cke_combo_text{width:30px}.cke_combopanel__fontsize{width:120px}.cke_source{font-family:'Courier New',Monospace;font-size:small;background-color:#fff;white-space:pre}.cke_wysiwyg_frame,.cke_wysiwyg_div{background-color:#fff}.cke_chrome{visibility:inherit}.cke_voice_label{display:none}legend.cke_voice_label{display:none}a.cke_button_disabled,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{filter:alpha(opacity = 30)}.cke_button_disabled .cke_button_icon{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#00ffffff,endColorstr=#00ffffff)}.cke_button_off:hover,.cke_button_off:focus,.cke_button_off:active{filter:alpha(opacity = 100)}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{filter:alpha(opacity = 30)}.cke_toolbox_collapser{border:1px solid #a6a6a6}.cke_toolbox_collapser .cke_arrow{margin-top:1px}.cke_hc .cke_top,.cke_hc .cke_bottom,.cke_hc .cke_combo_button,.cke_hc a.cke_combo_button:hover,.cke_hc a.cke_combo_button:focus,.cke_hc .cke_toolgroup,.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc .cke_toolbox_collapser,.cke_hc .cke_toolbox_collapser:hover,.cke_hc .cke_panel_grouptitle{filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.cke_toolbox_collapser .cke_arrow{border-width:4px}.cke_toolbox_collapser.cke_toolbox_collapser_min .cke_arrow{border-width:3px}.cke_toolbox_collapser .cke_arrow{margin-top:0}.cke_button__about_icon {background: url(icons.png) no-repeat 0 -0px !important;}.cke_button__bold_icon {background: url(icons.png) no-repeat 0 -24px !important;}.cke_button__italic_icon {background: url(icons.png) no-repeat 0 -48px !important;}.cke_button__strike_icon {background: url(icons.png) no-repeat 0 -72px !important;}.cke_button__subscript_icon {background: url(icons.png) no-repeat 0 -96px !important;}.cke_button__superscript_icon {background: url(icons.png) no-repeat 0 -120px !important;}.cke_button__underline_icon {background: url(icons.png) no-repeat 0 -144px !important;}.cke_button__blockquote_icon {background: url(icons.png) no-repeat 0 -168px !important;}.cke_rtl .cke_button__copy_icon, .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons.png) no-repeat 0 -192px !important;}.cke_ltr .cke_button__copy_icon {background: url(icons.png) no-repeat 0 -216px !important;}.cke_rtl .cke_button__cut_icon, .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons.png) no-repeat 0 -240px !important;}.cke_ltr .cke_button__cut_icon {background: url(icons.png) no-repeat 0 -264px !important;}.cke_rtl .cke_button__paste_icon, .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons.png) no-repeat 0 -288px !important;}.cke_ltr .cke_button__paste_icon {background: url(icons.png) no-repeat 0 -312px !important;}.cke_button__horizontalrule_icon {background: url(icons.png) no-repeat 0 -336px !important;}.cke_button__image_icon {background: url(icons.png) no-repeat 0 -360px !important;}.cke_rtl .cke_button__indent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons.png) no-repeat 0 -384px !important;}.cke_ltr .cke_button__indent_icon {background: url(icons.png) no-repeat 0 -408px !important;}.cke_rtl .cke_button__outdent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons.png) no-repeat 0 -432px !important;}.cke_ltr .cke_button__outdent_icon {background: url(icons.png) no-repeat 0 -456px !important;}.cke_rtl .cke_button__anchor_icon, .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons.png) no-repeat 0 -480px !important;}.cke_ltr .cke_button__anchor_icon {background: url(icons.png) no-repeat 0 -504px !important;}.cke_button__link_icon {background: url(icons.png) no-repeat 0 -528px !important;}.cke_button__unlink_icon {background: url(icons.png) no-repeat 0 -552px !important;}.cke_rtl .cke_button__bulletedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons.png) no-repeat 0 -576px !important;}.cke_ltr .cke_button__bulletedlist_icon {background: url(icons.png) no-repeat 0 -600px !important;}.cke_rtl .cke_button__numberedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons.png) no-repeat 0 -624px !important;}.cke_ltr .cke_button__numberedlist_icon {background: url(icons.png) no-repeat 0 -648px !important;}.cke_button__maximize_icon {background: url(icons.png) no-repeat 0 -672px !important;}.cke_rtl .cke_button__pastetext_icon, .cke_mixed_dir_content .cke_rtl .cke_button__pastetext_icon {background: url(icons.png) no-repeat 0 -696px !important;}.cke_ltr .cke_button__pastetext_icon {background: url(icons.png) no-repeat 0 -720px !important;}.cke_rtl .cke_button__pastefromword_icon, .cke_mixed_dir_content .cke_rtl .cke_button__pastefromword_icon {background: url(icons.png) no-repeat 0 -744px !important;}.cke_ltr .cke_button__pastefromword_icon {background: url(icons.png) no-repeat 0 -768px !important;}.cke_button__removeformat_icon {background: url(icons.png) no-repeat 0 -792px !important;}.cke_rtl .cke_button__source_icon, .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons.png) no-repeat 0 -816px !important;}.cke_ltr .cke_button__source_icon {background: url(icons.png) no-repeat 0 -840px !important;}.cke_button__specialchar_icon {background: url(icons.png) no-repeat 0 -864px !important;}.cke_button__scayt_icon {background: url(icons.png) no-repeat 0 -888px !important;}.cke_button__table_icon {background: url(icons.png) no-repeat 0 -912px !important;}.cke_rtl .cke_button__redo_icon, .cke_mixed_dir_content .cke_rtl .cke_button__redo_icon {background: url(icons.png) no-repeat 0 -936px !important;}.cke_ltr .cke_button__redo_icon {background: url(icons.png) no-repeat 0 -960px !important;}.cke_rtl .cke_button__undo_icon, .cke_mixed_dir_content .cke_rtl .cke_button__undo_icon {background: url(icons.png) no-repeat 0 -984px !important;}.cke_ltr .cke_button__undo_icon {background: url(icons.png) no-repeat 0 -1008px !important;}.cke_button__spellchecker_icon {background: url(icons.png) no-repeat 0 -1032px !important;}.cke_hidpi .cke_button__about_icon {background: url(icons_hidpi.png) no-repeat 0 -0px !important;background-size: 16px !important;}.cke_hidpi .cke_button__bold_icon {background: url(icons_hidpi.png) no-repeat 0 -24px !important;background-size: 16px !important;}.cke_hidpi .cke_button__italic_icon {background: url(icons_hidpi.png) no-repeat 0 -48px !important;background-size: 16px !important;}.cke_hidpi .cke_button__strike_icon {background: url(icons_hidpi.png) no-repeat 0 -72px !important;background-size: 16px !important;}.cke_hidpi .cke_button__subscript_icon {background: url(icons_hidpi.png) no-repeat 0 -96px !important;background-size: 16px !important;}.cke_hidpi .cke_button__superscript_icon {background: url(icons_hidpi.png) no-repeat 0 -120px !important;background-size: 16px !important;}.cke_hidpi .cke_button__underline_icon {background: url(icons_hidpi.png) no-repeat 0 -144px !important;background-size: 16px !important;}.cke_hidpi .cke_button__blockquote_icon {background: url(icons_hidpi.png) no-repeat 0 -168px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__copy_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons_hidpi.png) no-repeat 0 -192px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__copy_icon,.cke_ltr.cke_hidpi .cke_button__copy_icon {background: url(icons_hidpi.png) no-repeat 0 -216px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__cut_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons_hidpi.png) no-repeat 0 -240px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__cut_icon,.cke_ltr.cke_hidpi .cke_button__cut_icon {background: url(icons_hidpi.png) no-repeat 0 -264px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__paste_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons_hidpi.png) no-repeat 0 -288px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__paste_icon,.cke_ltr.cke_hidpi .cke_button__paste_icon {background: url(icons_hidpi.png) no-repeat 0 -312px !important;background-size: 16px !important;}.cke_hidpi .cke_button__horizontalrule_icon {background: url(icons_hidpi.png) no-repeat 0 -336px !important;background-size: 16px !important;}.cke_hidpi .cke_button__image_icon {background: url(icons_hidpi.png) no-repeat 0 -360px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__indent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons_hidpi.png) no-repeat 0 -384px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__indent_icon,.cke_ltr.cke_hidpi .cke_button__indent_icon {background: url(icons_hidpi.png) no-repeat 0 -408px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__outdent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons_hidpi.png) no-repeat 0 -432px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__outdent_icon,.cke_ltr.cke_hidpi .cke_button__outdent_icon {background: url(icons_hidpi.png) no-repeat 0 -456px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__anchor_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons_hidpi.png) no-repeat 0 -480px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__anchor_icon,.cke_ltr.cke_hidpi .cke_button__anchor_icon {background: url(icons_hidpi.png) no-repeat 0 -504px !important;background-size: 16px !important;}.cke_hidpi .cke_button__link_icon {background: url(icons_hidpi.png) no-repeat 0 -528px !important;background-size: 16px !important;}.cke_hidpi .cke_button__unlink_icon {background: url(icons_hidpi.png) no-repeat 0 -552px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__bulletedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -576px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__bulletedlist_icon,.cke_ltr.cke_hidpi .cke_button__bulletedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -600px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__numberedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -624px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__numberedlist_icon,.cke_ltr.cke_hidpi .cke_button__numberedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -648px !important;background-size: 16px !important;}.cke_hidpi .cke_button__maximize_icon {background: url(icons_hidpi.png) no-repeat 0 -672px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__pastetext_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__pastetext_icon {background: url(icons_hidpi.png) no-repeat 0 -696px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__pastetext_icon,.cke_ltr.cke_hidpi .cke_button__pastetext_icon {background: url(icons_hidpi.png) no-repeat 0 -720px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__pastefromword_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__pastefromword_icon {background: url(icons_hidpi.png) no-repeat 0 -744px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__pastefromword_icon,.cke_ltr.cke_hidpi .cke_button__pastefromword_icon {background: url(icons_hidpi.png) no-repeat 0 -768px !important;background-size: 16px !important;}.cke_hidpi .cke_button__removeformat_icon {background: url(icons_hidpi.png) no-repeat 0 -792px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__source_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons_hidpi.png) no-repeat 0 -816px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__source_icon,.cke_ltr.cke_hidpi .cke_button__source_icon {background: url(icons_hidpi.png) no-repeat 0 -840px !important;background-size: 16px !important;}.cke_hidpi .cke_button__specialchar_icon {background: url(icons_hidpi.png) no-repeat 0 -864px !important;background-size: 16px !important;}.cke_hidpi .cke_button__scayt_icon {background: url(icons_hidpi.png) no-repeat 0 -888px !important;background-size: 16px !important;}.cke_hidpi .cke_button__table_icon {background: url(icons_hidpi.png) no-repeat 0 -912px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__redo_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__redo_icon {background: url(icons_hidpi.png) no-repeat 0 -936px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__redo_icon,.cke_ltr.cke_hidpi .cke_button__redo_icon {background: url(icons_hidpi.png) no-repeat 0 -960px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__undo_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__undo_icon {background: url(icons_hidpi.png) no-repeat 0 -984px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__undo_icon,.cke_ltr.cke_hidpi .cke_button__undo_icon {background: url(icons_hidpi.png) no-repeat 0 -1008px !important;background-size: 16px !important;}.cke_hidpi .cke_button__spellchecker_icon {background: url(icons_hidpi.png) no-repeat 0 -1032px !important;background-size: 16px !important;} \ No newline at end of file diff --git a/public/assets/plugins/ckeditor/skins/moono/editor_iequirks.css b/public/assets/plugins/ckeditor/skins/moono/editor_iequirks.css new file mode 100644 index 00000000..009d08c5 --- /dev/null +++ b/public/assets/plugins/ckeditor/skins/moono/editor_iequirks.css @@ -0,0 +1,5 @@ +/* +Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. +For licensing, see LICENSE.md or http://ckeditor.com/license +*/ +.cke_reset{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;position:static;-webkit-transition:none;-moz-transition:none;-ms-transition:none;transition:none}.cke_reset_all,.cke_reset_all *{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;position:static;-webkit-transition:none;-moz-transition:none;-ms-transition:none;transition:none;border-collapse:collapse;font:normal normal normal 12px Arial,Helvetica,Tahoma,Verdana,Sans-Serif;color:#000;text-align:left;white-space:nowrap;cursor:auto}.cke_reset_all .cke_rtl *{text-align:right}.cke_reset_all iframe{vertical-align:inherit}.cke_reset_all textarea{white-space:pre}.cke_reset_all textarea,.cke_reset_all input[type="text"],.cke_reset_all input[type="password"]{cursor:text}.cke_reset_all textarea[disabled],.cke_reset_all input[type="text"][disabled],.cke_reset_all input[type="password"][disabled]{cursor:default}.cke_reset_all fieldset{padding:10px;border:2px groove #e0dfe3}.cke_reset_all select{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}.cke_chrome{display:block;border:1px solid #b6b6b6;padding:0;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_inner{display:block;-webkit-touch-callout:none;background:#fff;padding:0}.cke_float{border:0}.cke_float .cke_inner{padding-bottom:0}.cke_top,.cke_contents,.cke_bottom{display:block;overflow:hidden}.cke_top{border-bottom:1px solid #b6b6b6;padding:6px 8px 2px;white-space:normal;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_float .cke_top{border:1px solid #b6b6b6;border-bottom-color:#999}.cke_bottom{padding:6px 8px 2px;position:relative;border-top:1px solid #bfbfbf;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#cfd1cf));background-image:-moz-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-webkit-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-o-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-ms-linear-gradient(top,#ebebeb,#cfd1cf);background-image:linear-gradient(top,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_browser_ios .cke_contents{overflow-y:auto;-webkit-overflow-scrolling:touch}.cke_resizer{width:0;height:0;overflow:hidden;width:0;height:0;overflow:hidden;border-width:10px 10px 0 0;border-color:transparent #666 transparent transparent;border-style:dashed solid dashed dashed;font-size:0;vertical-align:bottom;margin-top:6px;margin-bottom:2px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.3);-webkit-box-shadow:0 1px 0 rgba(255,255,255,.3);box-shadow:0 1px 0 rgba(255,255,255,.3)}.cke_hc .cke_resizer{font-size:15px;width:auto;height:auto;border-width:0}.cke_resizer_ltr{cursor:se-resize;float:right;margin-right:-4px}.cke_resizer_rtl{border-width:10px 0 0 10px;border-color:transparent transparent transparent #a5a5a5;border-style:dashed dashed dashed solid;cursor:sw-resize;float:left;margin-left:-4px;right:auto}.cke_wysiwyg_div{display:block;height:100%;overflow:auto;padding:0 8px;outline-style:none;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.cke_panel{visibility:visible;width:120px;height:100px;overflow:hidden;background-color:#fff;border:1px solid #b6b6b6;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_menu_panel{padding:0;margin:0}.cke_combopanel{width:150px;height:170px}.cke_panel_frame{width:100%;height:100%;font-size:12px;overflow:auto;overflow-x:hidden}.cke_panel_container{overflow-y:auto;overflow-x:hidden}.cke_panel_list{list-style-type:none;margin:3px;padding:0;white-space:nowrap}.cke_panel_listItem{margin:0;padding-bottom:1px}.cke_panel_listItem a{padding:3px 4px;display:block;border:1px solid #fff;color:inherit!important;text-decoration:none;overflow:hidden;text-overflow:ellipsis;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px}* html .cke_panel_listItem a{width:100%;color:#000}*:first-child+html .cke_panel_listItem a{color:#000}.cke_panel_listItem.cke_selected a{border:1px solid #dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_panel_listItem a:hover,.cke_panel_listItem a:focus,.cke_panel_listItem a:active{border-color:#dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_hc .cke_panel_listItem a{border-style:none}.cke_hc .cke_panel_listItem a:hover,.cke_hc .cke_panel_listItem a:focus,.cke_hc .cke_panel_listItem a:active{border:2px solid;padding:1px 2px}.cke_panel_grouptitle{font-size:11px;font-weight:bold;white-space:nowrap;margin:0;padding:4px 6px;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #b6b6b6;-moz-border-radius:2px 2px 0 0;-webkit-border-radius:2px 2px 0 0;border-radius:2px 2px 0 0;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_panel_listItem p,.cke_panel_listItem h1,.cke_panel_listItem h2,.cke_panel_listItem h3,.cke_panel_listItem h4,.cke_panel_listItem h5,.cke_panel_listItem h6,.cke_panel_listItem pre{margin-top:0;margin-bottom:0}.cke_colorblock{padding:3px;font-size:11px;font-family:'Microsoft Sans Serif',Tahoma,Arial,Verdana,Sans-Serif}.cke_colorblock,.cke_colorblock a{text-decoration:none;color:#000}span.cke_colorbox{width:10px;height:10px;border:#808080 1px solid;float:left}.cke_rtl span.cke_colorbox{float:right}a.cke_colorbox{border:#fff 1px solid;padding:2px;float:left;width:12px;height:12px}.cke_rtl a.cke_colorbox{float:right}a:hover.cke_colorbox,a:focus.cke_colorbox,a:active.cke_colorbox{border:#b6b6b6 1px solid;background-color:#e5e5e5}a.cke_colorauto,a.cke_colormore{border:#fff 1px solid;padding:2px;display:block;cursor:pointer}a:hover.cke_colorauto,a:hover.cke_colormore,a:focus.cke_colorauto,a:focus.cke_colormore,a:active.cke_colorauto,a:active.cke_colormore{border:#b6b6b6 1px solid;background-color:#e5e5e5}.cke_toolbar{float:left}.cke_rtl .cke_toolbar{float:right}.cke_toolgroup{float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_hc .cke_toolgroup{border:0;margin-right:10px;margin-bottom:10px}.cke_rtl .cke_toolgroup *:first-child{-moz-border-radius:0 2px 2px 0;-webkit-border-radius:0 2px 2px 0;border-radius:0 2px 2px 0}.cke_rtl .cke_toolgroup *:last-child{-moz-border-radius:2px 0 0 2px;-webkit-border-radius:2px 0 0 2px;border-radius:2px 0 0 2px}.cke_rtl .cke_toolgroup{float:right;margin-left:6px;margin-right:0}a.cke_button{display:inline-block;height:18px;padding:4px 6px;outline:0;cursor:default;float:left;border:0}.cke_rtl .cke_button{float:right}.cke_hc .cke_button{border:1px solid black;padding:3px 5px;margin:-2px 4px 0 -2px}.cke_button_on{-moz-box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);background:#b5b5b5;background-image:-webkit-gradient(linear,left top,left bottom,from(#aaa),to(#cacaca));background-image:-moz-linear-gradient(top,#aaa,#cacaca);background-image:-webkit-linear-gradient(top,#aaa,#cacaca);background-image:-o-linear-gradient(top,#aaa,#cacaca);background-image:-ms-linear-gradient(top,#aaa,#cacaca);background-image:linear-gradient(top,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc a.cke_button_disabled:hover,.cke_hc a.cke_button_disabled:focus,.cke_hc a.cke_button_disabled:active{border-width:3px;padding:1px 3px}.cke_button_disabled .cke_button_icon{opacity:.3}.cke_hc .cke_button_disabled{opacity:.5}a.cke_button_on:hover,a.cke_button_on:focus,a.cke_button_on:active{-moz-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}a.cke_button_off:hover,a.cke_button_off:focus,a.cke_button_off:active,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{-moz-box-shadow:0 0 1px rgba(0,0,0,.3) inset;-webkit-box-shadow:0 0 1px rgba(0,0,0,.3) inset;box-shadow:0 0 1px rgba(0,0,0,.3) inset;background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_button_icon{cursor:inherit;background-repeat:no-repeat;margin-top:1px;width:16px;height:16px;float:left;display:inline-block}.cke_rtl .cke_button_icon{float:right}.cke_hc .cke_button_icon{display:none}.cke_button_label{display:none;padding-left:3px;margin-top:1px;line-height:17px;vertical-align:middle;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5)}.cke_rtl .cke_button_label{padding-right:3px;padding-left:0;float:right}.cke_hc .cke_button_label{padding:0;display:inline-block;font-size:12px}.cke_button_arrow{display:inline-block;margin:8px 0 0 1px;width:0;height:0;cursor:default;vertical-align:top;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_rtl .cke_button_arrow{margin-right:5px;margin-left:0}.cke_hc .cke_button_arrow{font-size:10px;margin:3px -2px 0 3px;width:auto;border:0}.cke_toolbar_separator{float:left;background-color:#c0c0c0;background-color:rgba(0,0,0,.2);margin:5px 2px 0;height:18px;width:1px;-webkit-box-shadow:1px 0 1px rgba(255,255,255,.5);-moz-box-shadow:1px 0 1px rgba(255,255,255,.5);box-shadow:1px 0 1px rgba(255,255,255,.5)}.cke_rtl .cke_toolbar_separator{float:right;-webkit-box-shadow:-1px 0 1px rgba(255,255,255,.1);-moz-box-shadow:-1px 0 1px rgba(255,255,255,.1);box-shadow:-1px 0 1px rgba(255,255,255,.1)}.cke_hc .cke_toolbar_separator{width:0;border-left:1px solid;margin:1px 5px 0 0}.cke_toolbar_break{display:block;clear:left}.cke_rtl .cke_toolbar_break{clear:right}.cke_toolbox_collapser{width:12px;height:11px;float:right;margin:11px 0 0;font-size:0;cursor:default;text-align:center;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_toolbox_collapser:hover{background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_toolbox_collapser.cke_toolbox_collapser_min{margin:0 2px 4px}.cke_rtl .cke_toolbox_collapser{float:left}.cke_toolbox_collapser .cke_arrow{display:inline-block;height:0;width:0;font-size:0;margin-top:1px;border-left:3px solid transparent;border-right:3px solid transparent;border-bottom:3px solid #474747;border-top:3px solid transparent}.cke_toolbox_collapser.cke_toolbox_collapser_min .cke_arrow{margin-top:4px;border-bottom-color:transparent;border-top-color:#474747}.cke_hc .cke_toolbox_collapser .cke_arrow{font-size:8px;width:auto;border:0;margin-top:0;margin-right:2px}.cke_menubutton{display:block}.cke_menuitem span{cursor:default}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#d3d3d3;display:block}.cke_hc .cke_menubutton{padding:2px}.cke_hc .cke_menubutton:hover,.cke_hc .cke_menubutton:focus,.cke_hc .cke_menubutton:active{border:2px solid;padding:0}.cke_menubutton_inner{display:table-row}.cke_menubutton_icon,.cke_menubutton_label,.cke_menuarrow{display:table-cell}.cke_menubutton_icon{background-color:#d7d8d7;opacity:.70;filter:alpha(opacity=70);padding:4px}.cke_hc .cke_menubutton_icon{height:16px;width:0;padding:4px 0}.cke_menubutton:hover .cke_menubutton_icon,.cke_menubutton:focus .cke_menubutton_icon,.cke_menubutton:active .cke_menubutton_icon{background-color:#d0d2d0}.cke_menubutton_disabled:hover .cke_menubutton_icon,.cke_menubutton_disabled:focus .cke_menubutton_icon,.cke_menubutton_disabled:active .cke_menubutton_icon{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_label{padding:0 5px;background-color:transparent;width:100%;vertical-align:middle}.cke_menubutton_disabled .cke_menubutton_label{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_on{border:1px solid #dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_menubutton_on .cke_menubutton_icon{padding-right:3px}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#eff0ef}.cke_panel_frame .cke_menubutton_label{display:none}.cke_menuseparator{background-color:#d3d3d3;height:1px;filter:alpha(opacity=70);opacity:.70}.cke_menuarrow{background-image:url(images/arrow.png);background-position:0 10px;background-repeat:no-repeat;padding:0 5px}.cke_rtl .cke_menuarrow{background-position:5px -13px;background-repeat:no-repeat}.cke_menuarrow span{display:none}.cke_hc .cke_menuarrow span{vertical-align:middle;display:inline}.cke_combo{display:inline-block;float:left}.cke_rtl .cke_combo{float:right}.cke_hc .cke_combo{margin-top:-2px}.cke_combo_label{display:none;float:left;line-height:26px;vertical-align:top;margin-right:5px}.cke_rtl .cke_combo_label{float:right;margin-left:5px;margin-right:0}.cke_combo_button{display:inline-block;float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_combo_off a.cke_combo_button:hover,.cke_combo_off a.cke_combo_button:focus{background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc');outline:0}.cke_combo_off a.cke_combo_button:active,.cke_combo_on a.cke_combo_button{border:1px solid #777;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;background:#b5b5b5;background-image:-webkit-gradient(linear,left top,left bottom,from(#aaa),to(#cacaca));background-image:-moz-linear-gradient(top,#aaa,#cacaca);background-image:-webkit-linear-gradient(top,#aaa,#cacaca);background-image:-o-linear-gradient(top,#aaa,#cacaca);background-image:-ms-linear-gradient(top,#aaa,#cacaca);background-image:linear-gradient(top,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_combo_on a.cke_combo_button:hover,.cke_combo_on a.cke_combo_button:focus,.cke_combo_on a.cke_combo_button:active{-moz-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}.cke_rtl .cke_combo_button{float:right;margin-left:5px;margin-right:0}.cke_hc a.cke_combo_button{padding:3px}.cke_hc .cke_combo_on a.cke_combo_button,.cke_hc .cke_combo_off a.cke_combo_button:hover,.cke_hc .cke_combo_off a.cke_combo_button:focus,.cke_hc .cke_combo_off a.cke_combo_button:active{border-width:3px;padding:1px}.cke_combo_text{line-height:26px;padding-left:10px;text-overflow:ellipsis;overflow:hidden;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5);width:60px}.cke_rtl .cke_combo_text{float:right;text-align:right;padding-left:0;padding-right:10px}.cke_hc .cke_combo_text{line-height:18px;font-size:12px}.cke_combo_open{cursor:default;display:inline-block;font-size:0;height:19px;line-height:17px;margin:1px 7px 1px;width:5px}.cke_hc .cke_combo_open{height:12px}.cke_combo_arrow{margin:11px 0 0;float:left;height:0;width:0;font-size:0;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_hc .cke_combo_arrow{font-size:10px;width:auto;border:0;margin-top:3px}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{opacity:.3}.cke_path{float:left;margin:-2px 0 2px}.cke_path_item,.cke_path_empty{display:inline-block;float:left;padding:3px 4px;margin-right:2px;cursor:default;text-decoration:none;outline:0;border:0;color:#4c4c4c;text-shadow:0 1px 0 #fff;font-weight:bold;font-size:11px}.cke_rtl .cke_path,.cke_rtl .cke_path_item,.cke_rtl .cke_path_empty{float:right}a.cke_path_item:hover,a.cke_path_item:focus,a.cke_path_item:active{background-color:#bfbfbf;color:#333;text-shadow:0 1px 0 rgba(255,255,255,.5);-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-moz-box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5);-webkit-box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5);box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5)}.cke_hc a.cke_path_item:hover,.cke_hc a.cke_path_item:focus,.cke_hc a.cke_path_item:active{border:2px solid;padding:1px 2px}.cke_button__source_label,.cke_button__sourcedialog_label{display:inline}.cke_combo__fontsize .cke_combo_text{width:30px}.cke_combopanel__fontsize{width:120px}.cke_source{font-family:'Courier New',Monospace;font-size:small;background-color:#fff;white-space:pre}.cke_wysiwyg_frame,.cke_wysiwyg_div{background-color:#fff}.cke_chrome{visibility:inherit}.cke_voice_label{display:none}legend.cke_voice_label{display:none}a.cke_button_disabled,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{filter:alpha(opacity = 30)}.cke_button_disabled .cke_button_icon{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#00ffffff,endColorstr=#00ffffff)}.cke_button_off:hover,.cke_button_off:focus,.cke_button_off:active{filter:alpha(opacity = 100)}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{filter:alpha(opacity = 30)}.cke_toolbox_collapser{border:1px solid #a6a6a6}.cke_toolbox_collapser .cke_arrow{margin-top:1px}.cke_hc .cke_top,.cke_hc .cke_bottom,.cke_hc .cke_combo_button,.cke_hc a.cke_combo_button:hover,.cke_hc a.cke_combo_button:focus,.cke_hc .cke_toolgroup,.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc .cke_toolbox_collapser,.cke_hc .cke_toolbox_collapser:hover,.cke_hc .cke_panel_grouptitle{filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.cke_top,.cke_contents,.cke_bottom{width:100%}.cke_button_arrow{font-size:0}.cke_rtl .cke_toolgroup,.cke_rtl .cke_toolbar_separator,.cke_rtl .cke_button,.cke_rtl .cke_button *,.cke_rtl .cke_combo,.cke_rtl .cke_combo *,.cke_rtl .cke_path_item,.cke_rtl .cke_path_item *,.cke_rtl .cke_path_empty{float:none}.cke_rtl .cke_toolgroup,.cke_rtl .cke_toolbar_separator,.cke_rtl .cke_combo_button,.cke_rtl .cke_combo_button *,.cke_rtl .cke_button,.cke_rtl .cke_button_icon,{display:inline-block;vertical-align:top}.cke_rtl .cke_button_icon{float:none}.cke_resizer{width:10px}.cke_source{white-space:normal}.cke_bottom{position:static}.cke_colorbox{font-size:0}.cke_button__about_icon {background: url(icons.png) no-repeat 0 -0px !important;}.cke_button__bold_icon {background: url(icons.png) no-repeat 0 -24px !important;}.cke_button__italic_icon {background: url(icons.png) no-repeat 0 -48px !important;}.cke_button__strike_icon {background: url(icons.png) no-repeat 0 -72px !important;}.cke_button__subscript_icon {background: url(icons.png) no-repeat 0 -96px !important;}.cke_button__superscript_icon {background: url(icons.png) no-repeat 0 -120px !important;}.cke_button__underline_icon {background: url(icons.png) no-repeat 0 -144px !important;}.cke_button__blockquote_icon {background: url(icons.png) no-repeat 0 -168px !important;}.cke_rtl .cke_button__copy_icon, .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons.png) no-repeat 0 -192px !important;}.cke_ltr .cke_button__copy_icon {background: url(icons.png) no-repeat 0 -216px !important;}.cke_rtl .cke_button__cut_icon, .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons.png) no-repeat 0 -240px !important;}.cke_ltr .cke_button__cut_icon {background: url(icons.png) no-repeat 0 -264px !important;}.cke_rtl .cke_button__paste_icon, .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons.png) no-repeat 0 -288px !important;}.cke_ltr .cke_button__paste_icon {background: url(icons.png) no-repeat 0 -312px !important;}.cke_button__horizontalrule_icon {background: url(icons.png) no-repeat 0 -336px !important;}.cke_button__image_icon {background: url(icons.png) no-repeat 0 -360px !important;}.cke_rtl .cke_button__indent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons.png) no-repeat 0 -384px !important;}.cke_ltr .cke_button__indent_icon {background: url(icons.png) no-repeat 0 -408px !important;}.cke_rtl .cke_button__outdent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons.png) no-repeat 0 -432px !important;}.cke_ltr .cke_button__outdent_icon {background: url(icons.png) no-repeat 0 -456px !important;}.cke_rtl .cke_button__anchor_icon, .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons.png) no-repeat 0 -480px !important;}.cke_ltr .cke_button__anchor_icon {background: url(icons.png) no-repeat 0 -504px !important;}.cke_button__link_icon {background: url(icons.png) no-repeat 0 -528px !important;}.cke_button__unlink_icon {background: url(icons.png) no-repeat 0 -552px !important;}.cke_rtl .cke_button__bulletedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons.png) no-repeat 0 -576px !important;}.cke_ltr .cke_button__bulletedlist_icon {background: url(icons.png) no-repeat 0 -600px !important;}.cke_rtl .cke_button__numberedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons.png) no-repeat 0 -624px !important;}.cke_ltr .cke_button__numberedlist_icon {background: url(icons.png) no-repeat 0 -648px !important;}.cke_button__maximize_icon {background: url(icons.png) no-repeat 0 -672px !important;}.cke_rtl .cke_button__pastetext_icon, .cke_mixed_dir_content .cke_rtl .cke_button__pastetext_icon {background: url(icons.png) no-repeat 0 -696px !important;}.cke_ltr .cke_button__pastetext_icon {background: url(icons.png) no-repeat 0 -720px !important;}.cke_rtl .cke_button__pastefromword_icon, .cke_mixed_dir_content .cke_rtl .cke_button__pastefromword_icon {background: url(icons.png) no-repeat 0 -744px !important;}.cke_ltr .cke_button__pastefromword_icon {background: url(icons.png) no-repeat 0 -768px !important;}.cke_button__removeformat_icon {background: url(icons.png) no-repeat 0 -792px !important;}.cke_rtl .cke_button__source_icon, .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons.png) no-repeat 0 -816px !important;}.cke_ltr .cke_button__source_icon {background: url(icons.png) no-repeat 0 -840px !important;}.cke_button__specialchar_icon {background: url(icons.png) no-repeat 0 -864px !important;}.cke_button__scayt_icon {background: url(icons.png) no-repeat 0 -888px !important;}.cke_button__table_icon {background: url(icons.png) no-repeat 0 -912px !important;}.cke_rtl .cke_button__redo_icon, .cke_mixed_dir_content .cke_rtl .cke_button__redo_icon {background: url(icons.png) no-repeat 0 -936px !important;}.cke_ltr .cke_button__redo_icon {background: url(icons.png) no-repeat 0 -960px !important;}.cke_rtl .cke_button__undo_icon, .cke_mixed_dir_content .cke_rtl .cke_button__undo_icon {background: url(icons.png) no-repeat 0 -984px !important;}.cke_ltr .cke_button__undo_icon {background: url(icons.png) no-repeat 0 -1008px !important;}.cke_button__spellchecker_icon {background: url(icons.png) no-repeat 0 -1032px !important;}.cke_hidpi .cke_button__about_icon {background: url(icons_hidpi.png) no-repeat 0 -0px !important;background-size: 16px !important;}.cke_hidpi .cke_button__bold_icon {background: url(icons_hidpi.png) no-repeat 0 -24px !important;background-size: 16px !important;}.cke_hidpi .cke_button__italic_icon {background: url(icons_hidpi.png) no-repeat 0 -48px !important;background-size: 16px !important;}.cke_hidpi .cke_button__strike_icon {background: url(icons_hidpi.png) no-repeat 0 -72px !important;background-size: 16px !important;}.cke_hidpi .cke_button__subscript_icon {background: url(icons_hidpi.png) no-repeat 0 -96px !important;background-size: 16px !important;}.cke_hidpi .cke_button__superscript_icon {background: url(icons_hidpi.png) no-repeat 0 -120px !important;background-size: 16px !important;}.cke_hidpi .cke_button__underline_icon {background: url(icons_hidpi.png) no-repeat 0 -144px !important;background-size: 16px !important;}.cke_hidpi .cke_button__blockquote_icon {background: url(icons_hidpi.png) no-repeat 0 -168px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__copy_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons_hidpi.png) no-repeat 0 -192px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__copy_icon,.cke_ltr.cke_hidpi .cke_button__copy_icon {background: url(icons_hidpi.png) no-repeat 0 -216px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__cut_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons_hidpi.png) no-repeat 0 -240px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__cut_icon,.cke_ltr.cke_hidpi .cke_button__cut_icon {background: url(icons_hidpi.png) no-repeat 0 -264px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__paste_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons_hidpi.png) no-repeat 0 -288px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__paste_icon,.cke_ltr.cke_hidpi .cke_button__paste_icon {background: url(icons_hidpi.png) no-repeat 0 -312px !important;background-size: 16px !important;}.cke_hidpi .cke_button__horizontalrule_icon {background: url(icons_hidpi.png) no-repeat 0 -336px !important;background-size: 16px !important;}.cke_hidpi .cke_button__image_icon {background: url(icons_hidpi.png) no-repeat 0 -360px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__indent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons_hidpi.png) no-repeat 0 -384px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__indent_icon,.cke_ltr.cke_hidpi .cke_button__indent_icon {background: url(icons_hidpi.png) no-repeat 0 -408px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__outdent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons_hidpi.png) no-repeat 0 -432px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__outdent_icon,.cke_ltr.cke_hidpi .cke_button__outdent_icon {background: url(icons_hidpi.png) no-repeat 0 -456px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__anchor_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons_hidpi.png) no-repeat 0 -480px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__anchor_icon,.cke_ltr.cke_hidpi .cke_button__anchor_icon {background: url(icons_hidpi.png) no-repeat 0 -504px !important;background-size: 16px !important;}.cke_hidpi .cke_button__link_icon {background: url(icons_hidpi.png) no-repeat 0 -528px !important;background-size: 16px !important;}.cke_hidpi .cke_button__unlink_icon {background: url(icons_hidpi.png) no-repeat 0 -552px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__bulletedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -576px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__bulletedlist_icon,.cke_ltr.cke_hidpi .cke_button__bulletedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -600px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__numberedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -624px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__numberedlist_icon,.cke_ltr.cke_hidpi .cke_button__numberedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -648px !important;background-size: 16px !important;}.cke_hidpi .cke_button__maximize_icon {background: url(icons_hidpi.png) no-repeat 0 -672px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__pastetext_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__pastetext_icon {background: url(icons_hidpi.png) no-repeat 0 -696px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__pastetext_icon,.cke_ltr.cke_hidpi .cke_button__pastetext_icon {background: url(icons_hidpi.png) no-repeat 0 -720px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__pastefromword_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__pastefromword_icon {background: url(icons_hidpi.png) no-repeat 0 -744px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__pastefromword_icon,.cke_ltr.cke_hidpi .cke_button__pastefromword_icon {background: url(icons_hidpi.png) no-repeat 0 -768px !important;background-size: 16px !important;}.cke_hidpi .cke_button__removeformat_icon {background: url(icons_hidpi.png) no-repeat 0 -792px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__source_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons_hidpi.png) no-repeat 0 -816px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__source_icon,.cke_ltr.cke_hidpi .cke_button__source_icon {background: url(icons_hidpi.png) no-repeat 0 -840px !important;background-size: 16px !important;}.cke_hidpi .cke_button__specialchar_icon {background: url(icons_hidpi.png) no-repeat 0 -864px !important;background-size: 16px !important;}.cke_hidpi .cke_button__scayt_icon {background: url(icons_hidpi.png) no-repeat 0 -888px !important;background-size: 16px !important;}.cke_hidpi .cke_button__table_icon {background: url(icons_hidpi.png) no-repeat 0 -912px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__redo_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__redo_icon {background: url(icons_hidpi.png) no-repeat 0 -936px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__redo_icon,.cke_ltr.cke_hidpi .cke_button__redo_icon {background: url(icons_hidpi.png) no-repeat 0 -960px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__undo_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__undo_icon {background: url(icons_hidpi.png) no-repeat 0 -984px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__undo_icon,.cke_ltr.cke_hidpi .cke_button__undo_icon {background: url(icons_hidpi.png) no-repeat 0 -1008px !important;background-size: 16px !important;}.cke_hidpi .cke_button__spellchecker_icon {background: url(icons_hidpi.png) no-repeat 0 -1032px !important;background-size: 16px !important;} \ No newline at end of file diff --git a/public/assets/plugins/ckeditor/skins/moono/icons.png b/public/assets/plugins/ckeditor/skins/moono/icons.png new file mode 100644 index 00000000..c71008d7 Binary files /dev/null and b/public/assets/plugins/ckeditor/skins/moono/icons.png differ diff --git a/public/assets/plugins/ckeditor/skins/moono/icons_hidpi.png b/public/assets/plugins/ckeditor/skins/moono/icons_hidpi.png new file mode 100644 index 00000000..0466c2bc Binary files /dev/null and b/public/assets/plugins/ckeditor/skins/moono/icons_hidpi.png differ diff --git a/public/assets/plugins/ckeditor/skins/moono/images/arrow.png b/public/assets/plugins/ckeditor/skins/moono/images/arrow.png new file mode 100644 index 00000000..0d1eb39c Binary files /dev/null and b/public/assets/plugins/ckeditor/skins/moono/images/arrow.png differ diff --git a/public/assets/plugins/ckeditor/skins/moono/images/close.png b/public/assets/plugins/ckeditor/skins/moono/images/close.png new file mode 100644 index 00000000..04b9c97d Binary files /dev/null and b/public/assets/plugins/ckeditor/skins/moono/images/close.png differ diff --git a/public/assets/plugins/ckeditor/skins/moono/images/hidpi/close.png b/public/assets/plugins/ckeditor/skins/moono/images/hidpi/close.png new file mode 100644 index 00000000..8abca8e9 Binary files /dev/null and b/public/assets/plugins/ckeditor/skins/moono/images/hidpi/close.png differ diff --git a/public/assets/plugins/ckeditor/skins/moono/images/hidpi/lock-open.png b/public/assets/plugins/ckeditor/skins/moono/images/hidpi/lock-open.png new file mode 100644 index 00000000..aa5e740e Binary files /dev/null and b/public/assets/plugins/ckeditor/skins/moono/images/hidpi/lock-open.png differ diff --git a/public/assets/plugins/ckeditor/skins/moono/images/hidpi/lock.png b/public/assets/plugins/ckeditor/skins/moono/images/hidpi/lock.png new file mode 100644 index 00000000..5404b063 Binary files /dev/null and b/public/assets/plugins/ckeditor/skins/moono/images/hidpi/lock.png differ diff --git a/public/assets/plugins/ckeditor/skins/moono/images/hidpi/refresh.png b/public/assets/plugins/ckeditor/skins/moono/images/hidpi/refresh.png new file mode 100644 index 00000000..1ebef344 Binary files /dev/null and b/public/assets/plugins/ckeditor/skins/moono/images/hidpi/refresh.png differ diff --git a/public/assets/plugins/ckeditor/skins/moono/images/lock-open.png b/public/assets/plugins/ckeditor/skins/moono/images/lock-open.png new file mode 100644 index 00000000..3b256c06 Binary files /dev/null and b/public/assets/plugins/ckeditor/skins/moono/images/lock-open.png differ diff --git a/public/assets/plugins/ckeditor/skins/moono/images/lock.png b/public/assets/plugins/ckeditor/skins/moono/images/lock.png new file mode 100644 index 00000000..c127f9eb Binary files /dev/null and b/public/assets/plugins/ckeditor/skins/moono/images/lock.png differ diff --git a/public/assets/plugins/ckeditor/skins/moono/images/refresh.png b/public/assets/plugins/ckeditor/skins/moono/images/refresh.png new file mode 100644 index 00000000..a1a061c5 Binary files /dev/null and b/public/assets/plugins/ckeditor/skins/moono/images/refresh.png differ diff --git a/public/assets/plugins/ckeditor/skins/moono/readme.md b/public/assets/plugins/ckeditor/skins/moono/readme.md new file mode 100644 index 00000000..0fa4c1ac --- /dev/null +++ b/public/assets/plugins/ckeditor/skins/moono/readme.md @@ -0,0 +1,51 @@ +"Moono" Skin +==================== + +This skin has been chosen for the **default skin** of CKEditor 4.x, elected from the CKEditor +[skin contest](http://ckeditor.com/blog/new_ckeditor_4_skin) and further shaped by +the CKEditor team. "Moono" is maintained by the core developers. + +For more information about skins, please check the [CKEditor Skin SDK](http://docs.cksource.com/CKEditor_4.x/Skin_SDK) +documentation. + +Features +------------------- +"Moono" is a monochromatic skin, which offers a modern look coupled with gradients and transparency. +It comes with the following features: + +- Chameleon feature with brightness, +- high-contrast compatibility, +- graphics source provided in SVG. + +Directory Structure +------------------- + +CSS parts: +- **editor.css**: the main CSS file. It's simply loading several other files, for easier maintenance, +- **mainui.css**: the file contains styles of entire editor outline structures, +- **toolbar.css**: the file contains styles of the editor toolbar space (top), +- **richcombo.css**: the file contains styles of the rich combo ui elements on toolbar, +- **panel.css**: the file contains styles of the rich combo drop-down, it's not loaded +until the first panel open up, +- **elementspath.css**: the file contains styles of the editor elements path bar (bottom), +- **menu.css**: the file contains styles of all editor menus including context menu and button drop-down, +it's not loaded until the first menu open up, +- **dialog.css**: the CSS files for the dialog UI, it's not loaded until the first dialog open, +- **reset.css**: the file defines the basis of style resets among all editor UI spaces, +- **preset.css**: the file defines the default styles of some UI elements reflecting the skin preference, +- **editor_XYZ.css** and **dialog_XYZ.css**: browser specific CSS hacks. + +Other parts: +- **skin.js**: the only JavaScript part of the skin that registers the skin, its browser specific files and its icons and defines the Chameleon feature, +- **icons/**: contains all skin defined icons, +- **images/**: contains a fill general used images, +- **dev/**: contains SVG source of the skin icons. + +License +------- + +Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. + +Licensed under the terms of any of the following licenses at your choice: [GPL](http://www.gnu.org/licenses/gpl.html), [LGPL](http://www.gnu.org/licenses/lgpl.html) and [MPL](http://www.mozilla.org/MPL/MPL-1.1.html). + +See LICENSE.md for more information. diff --git a/public/assets/plugins/ckeditor/styles.js b/public/assets/plugins/ckeditor/styles.js new file mode 100644 index 00000000..b58e0bda --- /dev/null +++ b/public/assets/plugins/ckeditor/styles.js @@ -0,0 +1,111 @@ +/** + * Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md or http://ckeditor.com/license + */ + +// This file contains style definitions that can be used by CKEditor plugins. +// +// The most common use for it is the "stylescombo" plugin, which shows a combo +// in the editor toolbar, containing all styles. Other plugins instead, like +// the div plugin, use a subset of the styles on their feature. +// +// If you don't have plugins that depend on this file, you can simply ignore it. +// Otherwise it is strongly recommended to customize this file to match your +// website requirements and design properly. + +CKEDITOR.stylesSet.add( 'default', [ + /* Block Styles */ + + // These styles are already available in the "Format" combo ("format" plugin), + // so they are not needed here by default. You may enable them to avoid + // placing the "Format" combo in the toolbar, maintaining the same features. + /* + { name: 'Paragraph', element: 'p' }, + { name: 'Heading 1', element: 'h1' }, + { name: 'Heading 2', element: 'h2' }, + { name: 'Heading 3', element: 'h3' }, + { name: 'Heading 4', element: 'h4' }, + { name: 'Heading 5', element: 'h5' }, + { name: 'Heading 6', element: 'h6' }, + { name: 'Preformatted Text',element: 'pre' }, + { name: 'Address', element: 'address' }, + */ + + { name: 'Italic Title', element: 'h2', styles: { 'font-style': 'italic' } }, + { name: 'Subtitle', element: 'h3', styles: { 'color': '#aaa', 'font-style': 'italic' } }, + { + name: 'Special Container', + element: 'div', + styles: { + padding: '5px 10px', + background: '#eee', + border: '1px solid #ccc' + } + }, + + /* Inline Styles */ + + // These are core styles available as toolbar buttons. You may opt enabling + // some of them in the Styles combo, removing them from the toolbar. + // (This requires the "stylescombo" plugin) + /* + { name: 'Strong', element: 'strong', overrides: 'b' }, + { name: 'Emphasis', element: 'em' , overrides: 'i' }, + { name: 'Underline', element: 'u' }, + { name: 'Strikethrough', element: 'strike' }, + { name: 'Subscript', element: 'sub' }, + { name: 'Superscript', element: 'sup' }, + */ + + { name: 'Marker', element: 'span', attributes: { 'class': 'marker' } }, + + { name: 'Big', element: 'big' }, + { name: 'Small', element: 'small' }, + { name: 'Typewriter', element: 'tt' }, + + { name: 'Computer Code', element: 'code' }, + { name: 'Keyboard Phrase', element: 'kbd' }, + { name: 'Sample Text', element: 'samp' }, + { name: 'Variable', element: 'var' }, + + { name: 'Deleted Text', element: 'del' }, + { name: 'Inserted Text', element: 'ins' }, + + { name: 'Cited Work', element: 'cite' }, + { name: 'Inline Quotation', element: 'q' }, + + { name: 'Language: RTL', element: 'span', attributes: { 'dir': 'rtl' } }, + { name: 'Language: LTR', element: 'span', attributes: { 'dir': 'ltr' } }, + + /* Object Styles */ + + { + name: 'Styled image (left)', + element: 'img', + attributes: { 'class': 'left' } + }, + + { + name: 'Styled image (right)', + element: 'img', + attributes: { 'class': 'right' } + }, + + { + name: 'Compact table', + element: 'table', + attributes: { + cellpadding: '5', + cellspacing: '0', + border: '1', + bordercolor: '#ccc' + }, + styles: { + 'border-collapse': 'collapse' + } + }, + + { name: 'Borderless Table', element: 'table', styles: { 'border-style': 'hidden', 'background-color': '#E6E6FA' } }, + { name: 'Square Bulleted List', element: 'ul', styles: { 'list-style-type': 'square' } } +]); + diff --git a/public/assets/css/colorpicker/bootstrap-colorpicker.css b/public/assets/plugins/colorpicker/bootstrap-colorpicker.css old mode 100755 new mode 100644 similarity index 89% rename from public/assets/css/colorpicker/bootstrap-colorpicker.css rename to public/assets/plugins/colorpicker/bootstrap-colorpicker.css index 8252394f..ba4365e2 --- a/public/assets/css/colorpicker/bootstrap-colorpicker.css +++ b/public/assets/plugins/colorpicker/bootstrap-colorpicker.css @@ -13,7 +13,7 @@ width: 100px; height: 100px; cursor: crosshair; - background-image: url("../../img/bootstrap-colorpicker/saturation.png"); + background-image: url("img/saturation.png"); } .colorpicker-saturation i { @@ -64,12 +64,12 @@ } .colorpicker-hue { - background-image: url("../../img/bootstrap-colorpicker/hue.png"); + background-image: url("img/hue.png"); } .colorpicker-alpha { display: none; - background-image: url("../../img/bootstrap-colorpicker/alpha.png"); + background-image: url("img/alpha.png"); } .colorpicker { @@ -135,7 +135,7 @@ height: 10px; margin-top: 5px; clear: both; - background-image: url("../../img/bootstrap-colorpicker/alpha.png"); + background-image: url("img/alpha.png"); background-position: 0 100%; } @@ -194,11 +194,11 @@ } .colorpicker.colorpicker-horizontal .colorpicker-hue { - background-image: url("../../img/bootstrap-colorpicker/hue-horizontal.png"); + background-image: url("img/hue-horizontal.png"); } .colorpicker.colorpicker-horizontal .colorpicker-alpha { - background-image: url("../../img/bootstrap-colorpicker/alpha-horizontal.png"); + background-image: url("img/alpha-horizontal.png"); } .colorpicker.colorpicker-hidden { diff --git a/public/assets/js/plugins/colorpicker/bootstrap-colorpicker.js b/public/assets/plugins/colorpicker/bootstrap-colorpicker.js old mode 100755 new mode 100644 similarity index 100% rename from public/assets/js/plugins/colorpicker/bootstrap-colorpicker.js rename to public/assets/plugins/colorpicker/bootstrap-colorpicker.js diff --git a/public/assets/plugins/colorpicker/bootstrap-colorpicker.min.css b/public/assets/plugins/colorpicker/bootstrap-colorpicker.min.css new file mode 100644 index 00000000..16a2d1a0 --- /dev/null +++ b/public/assets/plugins/colorpicker/bootstrap-colorpicker.min.css @@ -0,0 +1,9 @@ +/*! + * Bootstrap Colorpicker + * http://mjolnic.github.io/bootstrap-colorpicker/ + * + * Originally written by (c) 2012 Stefan Petre + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0.txt + * + */.colorpicker-saturation{float:left;width:100px;height:100px;cursor:crosshair;background-image:url("img/saturation.png")}.colorpicker-saturation i{position:absolute;top:0;left:0;display:block;width:5px;height:5px;margin:-4px 0 0 -4px;border:1px solid #000;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.colorpicker-saturation i b{display:block;width:5px;height:5px;border:1px solid #fff;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.colorpicker-hue,.colorpicker-alpha{float:left;width:15px;height:100px;margin-bottom:4px;margin-left:4px;cursor:row-resize}.colorpicker-hue i,.colorpicker-alpha i{position:absolute;top:0;left:0;display:block;width:100%;height:1px;margin-top:-1px;background:#000;border-top:1px solid #fff}.colorpicker-hue{background-image:url("img/hue.png")}.colorpicker-alpha{display:none;background-image:url("img/alpha.png")}.colorpicker{top:0;left:0;z-index:2500;min-width:130px;padding:4px;margin-top:1px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*zoom:1}.colorpicker:before,.colorpicker:after{display:table;line-height:0;content:""}.colorpicker:after{clear:both}.colorpicker:before{position:absolute;top:-7px;left:6px;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:''}.colorpicker:after{position:absolute;top:-6px;left:7px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''}.colorpicker div{position:relative}.colorpicker.colorpicker-with-alpha{min-width:140px}.colorpicker.colorpicker-with-alpha .colorpicker-alpha{display:block}.colorpicker-color{height:10px;margin-top:5px;clear:both;background-image:url("img/alpha.png");background-position:0 100%}.colorpicker-color div{height:10px}.colorpicker-element .input-group-addon i{display:block;width:16px;height:16px;cursor:pointer}.colorpicker.colorpicker-inline{position:relative;display:inline-block;float:none}.colorpicker.colorpicker-horizontal{width:110px;height:auto;min-width:110px}.colorpicker.colorpicker-horizontal .colorpicker-saturation{margin-bottom:4px}.colorpicker.colorpicker-horizontal .colorpicker-color{width:100px}.colorpicker.colorpicker-horizontal .colorpicker-hue,.colorpicker.colorpicker-horizontal .colorpicker-alpha{float:left;width:100px;height:15px;margin-bottom:4px;margin-left:0;cursor:col-resize}.colorpicker.colorpicker-horizontal .colorpicker-hue i,.colorpicker.colorpicker-horizontal .colorpicker-alpha i{position:absolute;top:0;left:0;display:block;width:1px;height:15px;margin-top:0;background:#fff;border:0}.colorpicker.colorpicker-horizontal .colorpicker-hue{background-image:url("img/hue-horizontal.png")}.colorpicker.colorpicker-horizontal .colorpicker-alpha{background-image:url("img/alpha-horizontal.png")}.colorpicker.colorpicker-hidden{display:none}.colorpicker.colorpicker-visible{display:block}.colorpicker-inline.colorpicker-visible{display:inline-block} \ No newline at end of file diff --git a/public/assets/js/plugins/colorpicker/bootstrap-colorpicker.min.js b/public/assets/plugins/colorpicker/bootstrap-colorpicker.min.js old mode 100755 new mode 100644 similarity index 100% rename from public/assets/js/plugins/colorpicker/bootstrap-colorpicker.min.js rename to public/assets/plugins/colorpicker/bootstrap-colorpicker.min.js diff --git a/public/assets/plugins/colorpicker/img/alpha-horizontal.png b/public/assets/plugins/colorpicker/img/alpha-horizontal.png new file mode 100644 index 00000000..d0a65c08 Binary files /dev/null and b/public/assets/plugins/colorpicker/img/alpha-horizontal.png differ diff --git a/public/assets/plugins/colorpicker/img/alpha.png b/public/assets/plugins/colorpicker/img/alpha.png new file mode 100644 index 00000000..38043f1c Binary files /dev/null and b/public/assets/plugins/colorpicker/img/alpha.png differ diff --git a/public/assets/plugins/colorpicker/img/hue-horizontal.png b/public/assets/plugins/colorpicker/img/hue-horizontal.png new file mode 100644 index 00000000..a0d9add8 Binary files /dev/null and b/public/assets/plugins/colorpicker/img/hue-horizontal.png differ diff --git a/public/assets/plugins/colorpicker/img/hue.png b/public/assets/plugins/colorpicker/img/hue.png new file mode 100644 index 00000000..d89560e9 Binary files /dev/null and b/public/assets/plugins/colorpicker/img/hue.png differ diff --git a/public/assets/plugins/colorpicker/img/saturation.png b/public/assets/plugins/colorpicker/img/saturation.png new file mode 100644 index 00000000..594ae50e Binary files /dev/null and b/public/assets/plugins/colorpicker/img/saturation.png differ diff --git a/public/assets/plugins/datatables/dataTables.bootstrap.css b/public/assets/plugins/datatables/dataTables.bootstrap.css new file mode 100644 index 00000000..2ccacaff --- /dev/null +++ b/public/assets/plugins/datatables/dataTables.bootstrap.css @@ -0,0 +1,372 @@ +div.dataTables_length label { + font-weight: normal; + text-align: left; + white-space: nowrap; +} + +div.dataTables_length select { + width: 75px; + display: inline-block; +} + +div.dataTables_filter { + text-align: right; +} + +div.dataTables_filter label { + font-weight: normal; + white-space: nowrap; + text-align: left; +} + +div.dataTables_filter input { + margin-left: 0.5em; + display: inline-block; + width: auto; +} + +div.dataTables_info { + padding-top: 8px; + white-space: nowrap; +} + +div.dataTables_paginate { + margin: 0; + white-space: nowrap; + text-align: right; +} + +div.dataTables_paginate ul.pagination { + margin: 2px 0; + white-space: nowrap; +} + +@media screen and (max-width: 767px) { + div.dataTables_wrapper > div.row > div, + div.dataTables_length, + div.dataTables_filter, + div.dataTables_info, + div.dataTables_paginate { + text-align: center; + } + + div.DTTT { + margin-bottom: 0.5em; + } +} + + +table.dataTable td, +table.dataTable th { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; +} + + +table.dataTable { + clear: both; + margin-top: 6px !important; + margin-bottom: 6px !important; + max-width: none !important; +} + +table.dataTable thead .sorting, +table.dataTable thead .sorting_asc, +table.dataTable thead .sorting_desc, +table.dataTable thead .sorting_asc_disabled, +table.dataTable thead .sorting_desc_disabled { + cursor: pointer; + position: relative; +} + +table.dataTable thead .sorting:after, +table.dataTable thead .sorting_asc:after, +table.dataTable thead .sorting_desc:after { + position: absolute; + top: 8px; + right: 8px; + display: block; + font-family: 'Glyphicons Halflings'; + opacity: 0.5; +} +table.dataTable thead .sorting:after { + opacity: 0.2; + content: "\e150"; /* sort */ +} +table.dataTable thead .sorting_asc:after { + content: "\e155"; /* sort-by-attributes */ +} +table.dataTable thead .sorting_desc:after { + content: "\e156"; /* sort-by-attributes-alt */ +} +div.dataTables_scrollBody table.dataTable thead .sorting:after, +div.dataTables_scrollBody table.dataTable thead .sorting_asc:after, +div.dataTables_scrollBody table.dataTable thead .sorting_desc:after { + display: none; +} + +table.dataTable thead .sorting_asc_disabled:after, +table.dataTable thead .sorting_desc_disabled:after { + color: #eee; +} + +table.dataTable thead > tr > th { + padding-right: 30px; +} + +table.dataTable th:active { + outline: none; +} + + +/* Condensed */ +table.dataTable.table-condensed thead > tr > th { + padding-right: 20px; +} + +table.dataTable.table-condensed thead .sorting:after, +table.dataTable.table-condensed thead .sorting_asc:after, +table.dataTable.table-condensed thead .sorting_desc:after { + top: 6px; + right: 6px; +} + +/* Scrolling */ +div.dataTables_scrollHead table { + margin-bottom: 0 !important; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} + +div.dataTables_scrollHead table thead tr:last-child th:first-child, +div.dataTables_scrollHead table thead tr:last-child td:first-child { + border-bottom-left-radius: 0 !important; + border-bottom-right-radius: 0 !important; +} + +div.dataTables_scrollBody table { + border-top: none; + margin-top: 0 !important; + margin-bottom: 0 !important; +} + +div.dataTables_scrollBody tbody tr:first-child th, +div.dataTables_scrollBody tbody tr:first-child td { + border-top: none; +} + +div.dataTables_scrollFoot table { + margin-top: 0 !important; + border-top: none; +} + +/* Frustratingly the border-collapse:collapse used by Bootstrap makes the column + width calculations when using scrolling impossible to align columns. We have + to use separate + */ +table.table-bordered.dataTable { + border-collapse: separate !important; +} +table.table-bordered thead th, +table.table-bordered thead td { + border-left-width: 0; + border-top-width: 0; +} +table.table-bordered tbody th, +table.table-bordered tbody td { + border-left-width: 0; + border-bottom-width: 0; +} +table.table-bordered tfoot th, +table.table-bordered tfoot td { + border-left-width: 0; + border-bottom-width: 0; +} +table.table-bordered th:last-child, +table.table-bordered td:last-child { + border-right-width: 0; +} +div.dataTables_scrollHead table.table-bordered { + border-bottom-width: 0; +} + + + + +/* + * TableTools styles + */ +.table.dataTable tbody tr.active td, +.table.dataTable tbody tr.active th { + background-color: #08C; + color: white; +} + +.table.dataTable tbody tr.active:hover td, +.table.dataTable tbody tr.active:hover th { + background-color: #0075b0 !important; +} + +.table.dataTable tbody tr.active th > a, +.table.dataTable tbody tr.active td > a { + color: white; +} + +.table-striped.dataTable tbody tr.active:nth-child(odd) td, +.table-striped.dataTable tbody tr.active:nth-child(odd) th { + background-color: #017ebc; +} + +table.DTTT_selectable tbody tr { + cursor: pointer; +} + +div.DTTT .btn:hover { + text-decoration: none !important; +} + +ul.DTTT_dropdown.dropdown-menu { + z-index: 2003; +} + +ul.DTTT_dropdown.dropdown-menu a { + color: #333 !important; /* needed only when demo_page.css is included */ +} + +ul.DTTT_dropdown.dropdown-menu li { + position: relative; +} + +ul.DTTT_dropdown.dropdown-menu li:hover a { + background-color: #0088cc; + color: white !important; +} + +div.DTTT_collection_background { + z-index: 2002; +} + +/* TableTools information display */ +div.DTTT_print_info { + position: fixed; + top: 50%; + left: 50%; + width: 400px; + height: 150px; + margin-left: -200px; + margin-top: -75px; + text-align: center; + color: #333; + padding: 10px 30px; + opacity: 0.95; + + background-color: white; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 6px; + + -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.5); + box-shadow: 0 3px 7px rgba(0, 0, 0, 0.5); +} + +div.DTTT_print_info h6 { + font-weight: normal; + font-size: 28px; + line-height: 28px; + margin: 1em; +} + +div.DTTT_print_info p { + font-size: 14px; + line-height: 20px; +} + +div.dataTables_processing { + position: absolute; + top: 50%; + left: 50%; + width: 100%; + height: 60px; + margin-left: -50%; + margin-top: -25px; + padding-top: 20px; + padding-bottom: 20px; + text-align: center; + font-size: 1.2em; + background-color: white; + background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255,255,255,0)), color-stop(25%, rgba(255,255,255,0.9)), color-stop(75%, rgba(255,255,255,0.9)), color-stop(100%, rgba(255,255,255,0))); + background: -webkit-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%); + background: -moz-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%); + background: -ms-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%); + background: -o-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%); + background: linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%); +} + + + +/* + * FixedColumns styles + */ +div.DTFC_LeftHeadWrapper table, +div.DTFC_LeftFootWrapper table, +div.DTFC_RightHeadWrapper table, +div.DTFC_RightFootWrapper table, +table.DTFC_Cloned tr.even { + background-color: white; + margin-bottom: 0; +} + +div.DTFC_RightHeadWrapper table , +div.DTFC_LeftHeadWrapper table { + border-bottom: none !important; + margin-bottom: 0 !important; + border-top-right-radius: 0 !important; + border-bottom-left-radius: 0 !important; + border-bottom-right-radius: 0 !important; +} + +div.DTFC_RightHeadWrapper table thead tr:last-child th:first-child, +div.DTFC_RightHeadWrapper table thead tr:last-child td:first-child, +div.DTFC_LeftHeadWrapper table thead tr:last-child th:first-child, +div.DTFC_LeftHeadWrapper table thead tr:last-child td:first-child { + border-bottom-left-radius: 0 !important; + border-bottom-right-radius: 0 !important; +} + +div.DTFC_RightBodyWrapper table, +div.DTFC_LeftBodyWrapper table { + border-top: none; + margin: 0 !important; +} + +div.DTFC_RightBodyWrapper tbody tr:first-child th, +div.DTFC_RightBodyWrapper tbody tr:first-child td, +div.DTFC_LeftBodyWrapper tbody tr:first-child th, +div.DTFC_LeftBodyWrapper tbody tr:first-child td { + border-top: none; +} + +div.DTFC_RightFootWrapper table, +div.DTFC_LeftFootWrapper table { + border-top: none; + margin-top: 0 !important; +} + + +div.DTFC_LeftBodyWrapper table.dataTable thead .sorting:after, +div.DTFC_LeftBodyWrapper table.dataTable thead .sorting_asc:after, +div.DTFC_LeftBodyWrapper table.dataTable thead .sorting_desc:after, +div.DTFC_RightBodyWrapper table.dataTable thead .sorting:after, +div.DTFC_RightBodyWrapper table.dataTable thead .sorting_asc:after, +div.DTFC_RightBodyWrapper table.dataTable thead .sorting_desc:after { + display: none; +} + + +/* + * FixedHeader styles + */ +div.FixedHeader_Cloned table { + margin: 0 !important +} + diff --git a/public/assets/plugins/datatables/dataTables.bootstrap.js b/public/assets/plugins/datatables/dataTables.bootstrap.js new file mode 100644 index 00000000..dcc561fc --- /dev/null +++ b/public/assets/plugins/datatables/dataTables.bootstrap.js @@ -0,0 +1,206 @@ +/*! DataTables Bootstrap 3 integration + * ©2011-2014 SpryMedia Ltd - datatables.net/license + */ + +/** + * DataTables integration for Bootstrap 3. This requires Bootstrap 3 and + * DataTables 1.10 or newer. + * + * This file sets the defaults and adds options to DataTables to style its + * controls using Bootstrap. See http://datatables.net/manual/styling/bootstrap + * for further information. + */ +(function(window, document, undefined){ + +var factory = function( $, DataTable ) { +"use strict"; + + +/* Set the defaults for DataTables initialisation */ +$.extend( true, DataTable.defaults, { + dom: + "<'row'<'col-sm-6'l><'col-sm-6'f>>" + + "<'row'<'col-sm-12'tr>>" + + "<'row'<'col-sm-5'i><'col-sm-7'p>>", + renderer: 'bootstrap' +} ); + + +/* Default class modification */ +$.extend( DataTable.ext.classes, { + sWrapper: "dataTables_wrapper form-inline dt-bootstrap", + sFilterInput: "form-control input-sm", + sLengthSelect: "form-control input-sm" +} ); + + +/* Bootstrap paging button renderer */ +DataTable.ext.renderer.pageButton.bootstrap = function ( settings, host, idx, buttons, page, pages ) { + var api = new DataTable.Api( settings ); + var classes = settings.oClasses; + var lang = settings.oLanguage.oPaginate; + var btnDisplay, btnClass, counter=0; + + var attach = function( container, buttons ) { + var i, ien, node, button; + var clickHandler = function ( e ) { + e.preventDefault(); + if ( !$(e.currentTarget).hasClass('disabled') ) { + api.page( e.data.action ).draw( false ); + } + }; + + for ( i=0, ien=buttons.length ; i 0 ? + '' : ' disabled'); + break; + + case 'previous': + btnDisplay = lang.sPrevious; + btnClass = button + (page > 0 ? + '' : ' disabled'); + break; + + case 'next': + btnDisplay = lang.sNext; + btnClass = button + (page < pages-1 ? + '' : ' disabled'); + break; + + case 'last': + btnDisplay = lang.sLast; + btnClass = button + (page < pages-1 ? + '' : ' disabled'); + break; + + default: + btnDisplay = button + 1; + btnClass = page === button ? + 'active' : ''; + break; + } + + if ( btnDisplay ) { + node = $('
  • ', { + 'class': classes.sPageButton+' '+btnClass, + 'id': idx === 0 && typeof button === 'string' ? + settings.sTableId +'_'+ button : + null + } ) + .append( $('', { + 'href': '#', + 'aria-controls': settings.sTableId, + 'data-dt-idx': counter, + 'tabindex': settings.iTabIndex + } ) + .html( btnDisplay ) + ) + .appendTo( container ); + + settings.oApi._fnBindAction( + node, {action: button}, clickHandler + ); + + counter++; + } + } + } + }; + + // IE9 throws an 'unknown error' if document.activeElement is used + // inside an iframe or frame. + var activeEl; + + try { + // Because this approach is destroying and recreating the paging + // elements, focus is lost on the select button which is bad for + // accessibility. So we want to restore focus once the draw has + // completed + activeEl = $(document.activeElement).data('dt-idx'); + } + catch (e) {} + + attach( + $(host).empty().html('
      ').children('ul'), + buttons + ); + + if ( activeEl ) { + $(host).find( '[data-dt-idx='+activeEl+']' ).focus(); + } +}; + + +/* + * TableTools Bootstrap compatibility + * Required TableTools 2.1+ + */ +if ( DataTable.TableTools ) { + // Set the classes that TableTools uses to something suitable for Bootstrap + $.extend( true, DataTable.TableTools.classes, { + "container": "DTTT btn-group", + "buttons": { + "normal": "btn btn-default", + "disabled": "disabled" + }, + "collection": { + "container": "DTTT_dropdown dropdown-menu", + "buttons": { + "normal": "", + "disabled": "disabled" + } + }, + "print": { + "info": "DTTT_print_info" + }, + "select": { + "row": "active" + } + } ); + + // Have the collection use a bootstrap compatible drop down + $.extend( true, DataTable.TableTools.DEFAULTS.oTags, { + "collection": { + "container": "ul", + "button": "li", + "liner": "a" + } + } ); +} + +}; // /factory + + +// Define as an AMD module if possible +if ( typeof define === 'function' && define.amd ) { + define( ['jquery', 'datatables'], factory ); +} +else if ( typeof exports === 'object' ) { + // Node/CommonJS + factory( require('jquery'), require('datatables') ); +} +else if ( jQuery ) { + // Otherwise simply initialise as normal, stopping multiple evaluation + factory( jQuery, jQuery.fn.dataTable ); +} + + +})(window, document); + diff --git a/public/assets/plugins/datatables/dataTables.bootstrap.min.js b/public/assets/plugins/datatables/dataTables.bootstrap.min.js new file mode 100644 index 00000000..85f7d062 --- /dev/null +++ b/public/assets/plugins/datatables/dataTables.bootstrap.min.js @@ -0,0 +1,8 @@ +/*! + DataTables Bootstrap 3 integration + ©2011-2014 SpryMedia Ltd - datatables.net/license +*/ +(function(l,q){var e=function(b,c){b.extend(!0,c.defaults,{dom:"<'row'<'col-sm-6'l><'col-sm-6'f>><'row'<'col-sm-12'tr>><'row'<'col-sm-5'i><'col-sm-7'p>>",renderer:"bootstrap"});b.extend(c.ext.classes,{sWrapper:"dataTables_wrapper form-inline dt-bootstrap",sFilterInput:"form-control input-sm",sLengthSelect:"form-control input-sm"});c.ext.renderer.pageButton.bootstrap=function(g,e,r,s,i,m){var t=new c.Api(g),u=g.oClasses,j=g.oLanguage.oPaginate,d,f,n=0,p=function(c,e){var k,h,o,a,l=function(a){a.preventDefault(); +b(a.currentTarget).hasClass("disabled")||t.page(a.data.action).draw(!1)};k=0;for(h=e.length;k",{"class":u.sPageButton+" "+ +f,id:0===r&&"string"===typeof a?g.sTableId+"_"+a:null}).append(b("",{href:"#","aria-controls":g.sTableId,"data-dt-idx":n,tabindex:g.iTabIndex}).html(d)).appendTo(c),g.oApi._fnBindAction(o,{action:a},l),n++)}},h;try{h=b(q.activeElement).data("dt-idx")}catch(l){}p(b(e).empty().html('
        ').children("ul"),s);h&&b(e).find("[data-dt-idx="+h+"]").focus()};c.TableTools&&(b.extend(!0,c.TableTools.classes,{container:"DTTT btn-group",buttons:{normal:"btn btn-default",disabled:"disabled"}, +collection:{container:"DTTT_dropdown dropdown-menu",buttons:{normal:"",disabled:"disabled"}},print:{info:"DTTT_print_info"},select:{row:"active"}}),b.extend(!0,c.TableTools.DEFAULTS.oTags,{collection:{container:"ul",button:"li",liner:"a"}}))};"function"===typeof define&&define.amd?define(["jquery","datatables"],e):"object"===typeof exports?e(require("jquery"),require("datatables")):jQuery&&e(jQuery,jQuery.fn.dataTable)})(window,document); diff --git a/public/assets/plugins/datatables/extensions/AutoFill/Readme.txt b/public/assets/plugins/datatables/extensions/AutoFill/Readme.txt new file mode 100644 index 00000000..017d1d0d --- /dev/null +++ b/public/assets/plugins/datatables/extensions/AutoFill/Readme.txt @@ -0,0 +1,38 @@ +# AutoFill + +AutoFill gives an Excel like option to a DataTable to click and drag over multiple cells, filling in information over the selected cells and incrementing numbers as needed. Key features include: + +* Click and drag cell content insertion +* Automatic incrementing of numeric information +* Enable and disable on any column +* Detailed callback functions for customisation +* Support for both DataTables and browser window scrolling + + +# Installation + +To use AutoFill, first download DataTables ( http://datatables.net/download ) and place the unzipped AutoFill package into a `extensions` directory in the DataTables package. This will allow the pages in the examples to operate correctly. To see the examples running, open the `examples` directory in your web-browser. + + +# Basic usage + +AutoFill is initialised using the `$.fn.dataTable.AutoFill` constructor. For example: + +```js +$(document).ready( function () { + var table = $('#example').dataTable(); + new $.fn.dataTable.AutoFill( table ); +} ); +``` + + +# Documentation / support + +* Documentation: http://datatables.net/extensions/autofill/ +* DataTables support forums: http://datatables.net/forums + + +# GitHub + +If you fancy getting involved with the development of AutoFill and help make it better, please refer to its GitHub repo: https://github.com/DataTables/AutoFill + diff --git a/public/assets/plugins/datatables/extensions/AutoFill/css/dataTables.autoFill.css b/public/assets/plugins/datatables/extensions/AutoFill/css/dataTables.autoFill.css new file mode 100644 index 00000000..cab59b3a --- /dev/null +++ b/public/assets/plugins/datatables/extensions/AutoFill/css/dataTables.autoFill.css @@ -0,0 +1,24 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * AutoFill styles + */ + +div.AutoFill_filler { + display: none; + position: absolute; + height: 14px; + width: 14px; + background: url(../images/filler.png) no-repeat center center; + z-index: 1002; +} + +div.AutoFill_border { + display: none; + position: absolute; + background-color: #0063dc; + z-index: 1001; + + box-shadow: 0px 0px 5px #76b4ff; + -moz-box-shadow: 0px 0px 5px #76b4ff; + -webkit-box-shadow: 0px 0px 5px #76b4ff; +} + diff --git a/public/assets/plugins/datatables/extensions/AutoFill/css/dataTables.autoFill.min.css b/public/assets/plugins/datatables/extensions/AutoFill/css/dataTables.autoFill.min.css new file mode 100644 index 00000000..b485f216 --- /dev/null +++ b/public/assets/plugins/datatables/extensions/AutoFill/css/dataTables.autoFill.min.css @@ -0,0 +1 @@ +div.AutoFill_filler{display:none;position:absolute;height:14px;width:14px;background:url(../images/filler.png) no-repeat center center;z-index:1002}div.AutoFill_border{display:none;position:absolute;background-color:#0063dc;z-index:1001;box-shadow:0px 0px 5px #76b4ff;-moz-box-shadow:0px 0px 5px #76b4ff;-webkit-box-shadow:0px 0px 5px #76b4ff} diff --git a/public/assets/plugins/datatables/extensions/AutoFill/examples/columns.html b/public/assets/plugins/datatables/extensions/AutoFill/examples/columns.html new file mode 100644 index 00000000..d891b139 --- /dev/null +++ b/public/assets/plugins/datatables/extensions/AutoFill/examples/columns.html @@ -0,0 +1,644 @@ + + + + + + + + AutoFill example - Column options + + + + + + + + + + + + + + +
        +
        +

        AutoFill example Column options

        + +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NamePositionOfficeAgeStart dateSalary
        NamePositionOfficeAgeStart dateSalary
        Tiger NixonSystem ArchitectEdinburgh612011/04/25$320,800
        Garrett WintersAccountantTokyo632011/07/25$170,750
        Ashton CoxJunior Technical AuthorSan Francisco662009/01/12$86,000
        Cedric KellySenior Javascript DeveloperEdinburgh222012/03/29$433,060
        Airi SatouAccountantTokyo332008/11/28$162,700
        Brielle WilliamsonIntegration SpecialistNew York612012/12/02$372,000
        Herrod ChandlerSales AssistantSan Francisco592012/08/06$137,500
        Rhona DavidsonIntegration SpecialistTokyo552010/10/14$327,900
        Colleen HurstJavascript DeveloperSan Francisco392009/09/15$205,500
        Sonya FrostSoftware EngineerEdinburgh232008/12/13$103,600
        Jena GainesOffice ManagerLondon302008/12/19$90,560
        Quinn FlynnSupport LeadEdinburgh222013/03/03$342,000
        Charde MarshallRegional DirectorSan Francisco362008/10/16$470,600
        Haley KennedySenior Marketing DesignerLondon432012/12/18$313,500
        Tatyana FitzpatrickRegional DirectorLondon192010/03/17$385,750
        Michael SilvaMarketing DesignerLondon662012/11/27$198,500
        Paul ByrdChief Financial Officer (CFO)New York642010/06/09$725,000
        Gloria LittleSystems AdministratorNew York592009/04/10$237,500
        Bradley GreerSoftware EngineerLondon412012/10/13$132,000
        Dai RiosPersonnel LeadEdinburgh352012/09/26$217,500
        Jenette CaldwellDevelopment LeadNew York302011/09/03$345,000
        Yuri BerryChief Marketing Officer (CMO)New York402009/06/25$675,000
        Caesar VancePre-Sales SupportNew York212011/12/12$106,450
        Doris WilderSales AssistantSidney232010/09/20$85,600
        Angelica RamosChief Executive Officer (CEO)London472009/10/09$1,200,000
        Gavin JoyceDeveloperEdinburgh422010/12/22$92,575
        Jennifer ChangRegional DirectorSingapore282010/11/14$357,650
        Brenden WagnerSoftware EngineerSan Francisco282011/06/07$206,850
        Fiona GreenChief Operating Officer (COO)San Francisco482010/03/11$850,000
        Shou ItouRegional MarketingTokyo202011/08/14$163,000
        Michelle HouseIntegration SpecialistSidney372011/06/02$95,400
        Suki BurksDeveloperLondon532009/10/22$114,500
        Prescott BartlettTechnical AuthorLondon272011/05/07$145,000
        Gavin CortezTeam LeaderSan Francisco222008/10/26$235,500
        Martena MccrayPost-Sales supportEdinburgh462011/03/09$324,050
        Unity ButlerMarketing DesignerSan Francisco472009/12/09$85,675
        Howard HatfieldOffice ManagerSan Francisco512008/12/16$164,500
        Hope FuentesSecretarySan Francisco412010/02/12$109,850
        Vivian HarrellFinancial ControllerSan Francisco622009/02/14$452,500
        Timothy MooneyOffice ManagerLondon372008/12/11$136,200
        Jackson BradshawDirectorNew York652008/09/26$645,750
        Olivia LiangSupport EngineerSingapore642011/02/03$234,500
        Bruno NashSoftware EngineerLondon382011/05/03$163,500
        Sakura YamamotoSupport EngineerTokyo372009/08/19$139,575
        Thor WaltonDeveloperNew York612013/08/11$98,540
        Finn CamachoSupport EngineerSan Francisco472009/07/07$87,500
        Serge BaldwinData CoordinatorSingapore642012/04/09$138,575
        Zenaida FrankSoftware EngineerNew York632010/01/04$125,250
        Zorita SerranoSoftware EngineerSan Francisco562012/06/01$115,000
        Jennifer AcostaJunior Javascript DeveloperEdinburgh432013/02/01$75,650
        Cara StevensSales AssistantNew York462011/12/06$145,600
        Hermione ButlerRegional DirectorLondon472011/03/21$356,250
        Lael GreerSystems AdministratorLondon212009/02/27$103,500
        Jonas AlexanderDeveloperSan Francisco302010/07/14$86,500
        Shad DeckerRegional DirectorEdinburgh512008/11/13$183,000
        Michael BruceJavascript DeveloperSingapore292011/06/27$183,000
        Donna SniderCustomer SupportNew York272011/01/25$112,000
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this + example:

        $(document).ready(function() { + var table = $('#example').dataTable(); + + new $.fn.dataTable.AutoFill( table, { + "columnDefs": [ + { enable: false, targets: [-1, -2] }, + { increment: false, targets: 3 } + ] + } ); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this + example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by + DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library + files (below), in order to correctly display the table. The additional CSS used is shown + below:

        +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the + table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data + will update automatically as any additional data is loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note + that this is just an example script using PHP. Server-side processing scripts can be written in any + language, using the protocol described in the + DataTables documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/AutoFill/examples/complete-callback.html b/public/assets/plugins/datatables/extensions/AutoFill/examples/complete-callback.html new file mode 100644 index 00000000..2076d4f2 --- /dev/null +++ b/public/assets/plugins/datatables/extensions/AutoFill/examples/complete-callback.html @@ -0,0 +1,652 @@ + + + + + + + + AutoFill example - Complete callback + + + + + + + + + + + + + + +
        +
        +

        AutoFill example Complete callback

        + +
        +

        AutoFill provides a number of customisable callback functions so you can tailor it's actions to + exactly what you need. This example shows the use of the complete callback function which + is executed at the end of an auto-fill drag, providing information about the cells that were + altered.

        + +

        For a complete description of the complete callback, please refer to the AutoFill documentation.

        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NamePositionOfficeAgeStart dateSalary
        NamePositionOfficeAgeStart dateSalary
        Tiger NixonSystem ArchitectEdinburgh612011/04/25$320,800
        Garrett WintersAccountantTokyo632011/07/25$170,750
        Ashton CoxJunior Technical AuthorSan Francisco662009/01/12$86,000
        Cedric KellySenior Javascript DeveloperEdinburgh222012/03/29$433,060
        Airi SatouAccountantTokyo332008/11/28$162,700
        Brielle WilliamsonIntegration SpecialistNew York612012/12/02$372,000
        Herrod ChandlerSales AssistantSan Francisco592012/08/06$137,500
        Rhona DavidsonIntegration SpecialistTokyo552010/10/14$327,900
        Colleen HurstJavascript DeveloperSan Francisco392009/09/15$205,500
        Sonya FrostSoftware EngineerEdinburgh232008/12/13$103,600
        Jena GainesOffice ManagerLondon302008/12/19$90,560
        Quinn FlynnSupport LeadEdinburgh222013/03/03$342,000
        Charde MarshallRegional DirectorSan Francisco362008/10/16$470,600
        Haley KennedySenior Marketing DesignerLondon432012/12/18$313,500
        Tatyana FitzpatrickRegional DirectorLondon192010/03/17$385,750
        Michael SilvaMarketing DesignerLondon662012/11/27$198,500
        Paul ByrdChief Financial Officer (CFO)New York642010/06/09$725,000
        Gloria LittleSystems AdministratorNew York592009/04/10$237,500
        Bradley GreerSoftware EngineerLondon412012/10/13$132,000
        Dai RiosPersonnel LeadEdinburgh352012/09/26$217,500
        Jenette CaldwellDevelopment LeadNew York302011/09/03$345,000
        Yuri BerryChief Marketing Officer (CMO)New York402009/06/25$675,000
        Caesar VancePre-Sales SupportNew York212011/12/12$106,450
        Doris WilderSales AssistantSidney232010/09/20$85,600
        Angelica RamosChief Executive Officer (CEO)London472009/10/09$1,200,000
        Gavin JoyceDeveloperEdinburgh422010/12/22$92,575
        Jennifer ChangRegional DirectorSingapore282010/11/14$357,650
        Brenden WagnerSoftware EngineerSan Francisco282011/06/07$206,850
        Fiona GreenChief Operating Officer (COO)San Francisco482010/03/11$850,000
        Shou ItouRegional MarketingTokyo202011/08/14$163,000
        Michelle HouseIntegration SpecialistSidney372011/06/02$95,400
        Suki BurksDeveloperLondon532009/10/22$114,500
        Prescott BartlettTechnical AuthorLondon272011/05/07$145,000
        Gavin CortezTeam LeaderSan Francisco222008/10/26$235,500
        Martena MccrayPost-Sales supportEdinburgh462011/03/09$324,050
        Unity ButlerMarketing DesignerSan Francisco472009/12/09$85,675
        Howard HatfieldOffice ManagerSan Francisco512008/12/16$164,500
        Hope FuentesSecretarySan Francisco412010/02/12$109,850
        Vivian HarrellFinancial ControllerSan Francisco622009/02/14$452,500
        Timothy MooneyOffice ManagerLondon372008/12/11$136,200
        Jackson BradshawDirectorNew York652008/09/26$645,750
        Olivia LiangSupport EngineerSingapore642011/02/03$234,500
        Bruno NashSoftware EngineerLondon382011/05/03$163,500
        Sakura YamamotoSupport EngineerTokyo372009/08/19$139,575
        Thor WaltonDeveloperNew York612013/08/11$98,540
        Finn CamachoSupport EngineerSan Francisco472009/07/07$87,500
        Serge BaldwinData CoordinatorSingapore642012/04/09$138,575
        Zenaida FrankSoftware EngineerNew York632010/01/04$125,250
        Zorita SerranoSoftware EngineerSan Francisco562012/06/01$115,000
        Jennifer AcostaJunior Javascript DeveloperEdinburgh432013/02/01$75,650
        Cara StevensSales AssistantNew York462011/12/06$145,600
        Hermione ButlerRegional DirectorLondon472011/03/21$356,250
        Lael GreerSystems AdministratorLondon212009/02/27$103,500
        Jonas AlexanderDeveloperSan Francisco302010/07/14$86,500
        Shad DeckerRegional DirectorEdinburgh512008/11/13$183,000
        Michael BruceJavascript DeveloperSingapore292011/06/27$183,000
        Donna SniderCustomer SupportNew York272011/01/25$112,000
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this + example:

        $(document).ready(function() { + var table = $('#example').dataTable(); + + new $.fn.dataTable.AutoFill( table, { + complete: function ( altered ) { + var last = altered[ altered.length-1 ]; + alert( + altered.length+' cells were altered in this auto-fill. The '+ + 'value of the last cell altered was: '+last.oldValue+' and is '+ + 'now '+last.newValue + ); + } + } ); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this + example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by + DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library + files (below), in order to correctly display the table. The additional CSS used is shown + below:

        +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the + table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data + will update automatically as any additional data is loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note + that this is just an example script using PHP. Server-side processing scripts can be written in any + language, using the protocol described in the + DataTables documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/AutoFill/examples/fill-both.html b/public/assets/plugins/datatables/extensions/AutoFill/examples/fill-both.html new file mode 100644 index 00000000..f65076e1 --- /dev/null +++ b/public/assets/plugins/datatables/extensions/AutoFill/examples/fill-both.html @@ -0,0 +1,641 @@ + + + + + + + + AutoFill example - Horizontal and vertical fill + + + + + + + + + + + + + + +
        +
        +

        AutoFill example Horizontal and vertical fill

        + +
        +

        By default AutoFill will allow the fill to operate only on a single column at a time (i.e. + vertically). However, it has the ability to provide the fill either horizontally, over both axis or + limited to just one axis depending on the direction of the drag. This option is provided by the + mode sanitisation option.

        + +

        In this case it is set to both (i.e. both horizontal and vertical axis) to provide the + filler along a row, rather than a column.

        + +

        For the full range of options and syntax for mode please refer to the AutoFill documentation.

        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NamePositionOfficeAgeStart dateSalary
        NamePositionOfficeAgeStart dateSalary
        Tiger NixonSystem ArchitectEdinburgh612011/04/25$320,800
        Garrett WintersAccountantTokyo632011/07/25$170,750
        Ashton CoxJunior Technical AuthorSan Francisco662009/01/12$86,000
        Cedric KellySenior Javascript DeveloperEdinburgh222012/03/29$433,060
        Airi SatouAccountantTokyo332008/11/28$162,700
        Brielle WilliamsonIntegration SpecialistNew York612012/12/02$372,000
        Herrod ChandlerSales AssistantSan Francisco592012/08/06$137,500
        Rhona DavidsonIntegration SpecialistTokyo552010/10/14$327,900
        Colleen HurstJavascript DeveloperSan Francisco392009/09/15$205,500
        Sonya FrostSoftware EngineerEdinburgh232008/12/13$103,600
        Jena GainesOffice ManagerLondon302008/12/19$90,560
        Quinn FlynnSupport LeadEdinburgh222013/03/03$342,000
        Charde MarshallRegional DirectorSan Francisco362008/10/16$470,600
        Haley KennedySenior Marketing DesignerLondon432012/12/18$313,500
        Tatyana FitzpatrickRegional DirectorLondon192010/03/17$385,750
        Michael SilvaMarketing DesignerLondon662012/11/27$198,500
        Paul ByrdChief Financial Officer (CFO)New York642010/06/09$725,000
        Gloria LittleSystems AdministratorNew York592009/04/10$237,500
        Bradley GreerSoftware EngineerLondon412012/10/13$132,000
        Dai RiosPersonnel LeadEdinburgh352012/09/26$217,500
        Jenette CaldwellDevelopment LeadNew York302011/09/03$345,000
        Yuri BerryChief Marketing Officer (CMO)New York402009/06/25$675,000
        Caesar VancePre-Sales SupportNew York212011/12/12$106,450
        Doris WilderSales AssistantSidney232010/09/20$85,600
        Angelica RamosChief Executive Officer (CEO)London472009/10/09$1,200,000
        Gavin JoyceDeveloperEdinburgh422010/12/22$92,575
        Jennifer ChangRegional DirectorSingapore282010/11/14$357,650
        Brenden WagnerSoftware EngineerSan Francisco282011/06/07$206,850
        Fiona GreenChief Operating Officer (COO)San Francisco482010/03/11$850,000
        Shou ItouRegional MarketingTokyo202011/08/14$163,000
        Michelle HouseIntegration SpecialistSidney372011/06/02$95,400
        Suki BurksDeveloperLondon532009/10/22$114,500
        Prescott BartlettTechnical AuthorLondon272011/05/07$145,000
        Gavin CortezTeam LeaderSan Francisco222008/10/26$235,500
        Martena MccrayPost-Sales supportEdinburgh462011/03/09$324,050
        Unity ButlerMarketing DesignerSan Francisco472009/12/09$85,675
        Howard HatfieldOffice ManagerSan Francisco512008/12/16$164,500
        Hope FuentesSecretarySan Francisco412010/02/12$109,850
        Vivian HarrellFinancial ControllerSan Francisco622009/02/14$452,500
        Timothy MooneyOffice ManagerLondon372008/12/11$136,200
        Jackson BradshawDirectorNew York652008/09/26$645,750
        Olivia LiangSupport EngineerSingapore642011/02/03$234,500
        Bruno NashSoftware EngineerLondon382011/05/03$163,500
        Sakura YamamotoSupport EngineerTokyo372009/08/19$139,575
        Thor WaltonDeveloperNew York612013/08/11$98,540
        Finn CamachoSupport EngineerSan Francisco472009/07/07$87,500
        Serge BaldwinData CoordinatorSingapore642012/04/09$138,575
        Zenaida FrankSoftware EngineerNew York632010/01/04$125,250
        Zorita SerranoSoftware EngineerSan Francisco562012/06/01$115,000
        Jennifer AcostaJunior Javascript DeveloperEdinburgh432013/02/01$75,650
        Cara StevensSales AssistantNew York462011/12/06$145,600
        Hermione ButlerRegional DirectorLondon472011/03/21$356,250
        Lael GreerSystems AdministratorLondon212009/02/27$103,500
        Jonas AlexanderDeveloperSan Francisco302010/07/14$86,500
        Shad DeckerRegional DirectorEdinburgh512008/11/13$183,000
        Michael BruceJavascript DeveloperSingapore292011/06/27$183,000
        Donna SniderCustomer SupportNew York272011/01/25$112,000
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this + example:

        $(document).ready(function() { + var table = $('#example').DataTable(); + + new $.fn.dataTable.AutoFill( table, { + mode: 'both' + } ); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this + example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by + DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library + files (below), in order to correctly display the table. The additional CSS used is shown + below:

        +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the + table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data + will update automatically as any additional data is loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note + that this is just an example script using PHP. Server-side processing scripts can be written in any + language, using the protocol described in the + DataTables documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/AutoFill/examples/fill-horizontal.html b/public/assets/plugins/datatables/extensions/AutoFill/examples/fill-horizontal.html new file mode 100644 index 00000000..13cadac9 --- /dev/null +++ b/public/assets/plugins/datatables/extensions/AutoFill/examples/fill-horizontal.html @@ -0,0 +1,641 @@ + + + + + + + + AutoFill example - Horizontal fill + + + + + + + + + + + + + + +
        +
        +

        AutoFill example Horizontal fill

        + +
        +

        By default AutoFill will allow the fill to operate only on a single column at a time (i.e. + vertically). However, it has the ability to provide the fill either horizontally, over both axis or + limited to just one axis depending on the direction of the drag. This option is provided by the + mode sanitisation option.

        + +

        In this case it is set to x (i.e. horizontal axis) to provide the filler along a row, + rather than a column.

        + +

        For the full range of options and syntax for mode please refer to the AutoFill documentation.

        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NamePositionOfficeAgeStart dateSalary
        NamePositionOfficeAgeStart dateSalary
        Tiger NixonSystem ArchitectEdinburgh612011/04/25$320,800
        Garrett WintersAccountantTokyo632011/07/25$170,750
        Ashton CoxJunior Technical AuthorSan Francisco662009/01/12$86,000
        Cedric KellySenior Javascript DeveloperEdinburgh222012/03/29$433,060
        Airi SatouAccountantTokyo332008/11/28$162,700
        Brielle WilliamsonIntegration SpecialistNew York612012/12/02$372,000
        Herrod ChandlerSales AssistantSan Francisco592012/08/06$137,500
        Rhona DavidsonIntegration SpecialistTokyo552010/10/14$327,900
        Colleen HurstJavascript DeveloperSan Francisco392009/09/15$205,500
        Sonya FrostSoftware EngineerEdinburgh232008/12/13$103,600
        Jena GainesOffice ManagerLondon302008/12/19$90,560
        Quinn FlynnSupport LeadEdinburgh222013/03/03$342,000
        Charde MarshallRegional DirectorSan Francisco362008/10/16$470,600
        Haley KennedySenior Marketing DesignerLondon432012/12/18$313,500
        Tatyana FitzpatrickRegional DirectorLondon192010/03/17$385,750
        Michael SilvaMarketing DesignerLondon662012/11/27$198,500
        Paul ByrdChief Financial Officer (CFO)New York642010/06/09$725,000
        Gloria LittleSystems AdministratorNew York592009/04/10$237,500
        Bradley GreerSoftware EngineerLondon412012/10/13$132,000
        Dai RiosPersonnel LeadEdinburgh352012/09/26$217,500
        Jenette CaldwellDevelopment LeadNew York302011/09/03$345,000
        Yuri BerryChief Marketing Officer (CMO)New York402009/06/25$675,000
        Caesar VancePre-Sales SupportNew York212011/12/12$106,450
        Doris WilderSales AssistantSidney232010/09/20$85,600
        Angelica RamosChief Executive Officer (CEO)London472009/10/09$1,200,000
        Gavin JoyceDeveloperEdinburgh422010/12/22$92,575
        Jennifer ChangRegional DirectorSingapore282010/11/14$357,650
        Brenden WagnerSoftware EngineerSan Francisco282011/06/07$206,850
        Fiona GreenChief Operating Officer (COO)San Francisco482010/03/11$850,000
        Shou ItouRegional MarketingTokyo202011/08/14$163,000
        Michelle HouseIntegration SpecialistSidney372011/06/02$95,400
        Suki BurksDeveloperLondon532009/10/22$114,500
        Prescott BartlettTechnical AuthorLondon272011/05/07$145,000
        Gavin CortezTeam LeaderSan Francisco222008/10/26$235,500
        Martena MccrayPost-Sales supportEdinburgh462011/03/09$324,050
        Unity ButlerMarketing DesignerSan Francisco472009/12/09$85,675
        Howard HatfieldOffice ManagerSan Francisco512008/12/16$164,500
        Hope FuentesSecretarySan Francisco412010/02/12$109,850
        Vivian HarrellFinancial ControllerSan Francisco622009/02/14$452,500
        Timothy MooneyOffice ManagerLondon372008/12/11$136,200
        Jackson BradshawDirectorNew York652008/09/26$645,750
        Olivia LiangSupport EngineerSingapore642011/02/03$234,500
        Bruno NashSoftware EngineerLondon382011/05/03$163,500
        Sakura YamamotoSupport EngineerTokyo372009/08/19$139,575
        Thor WaltonDeveloperNew York612013/08/11$98,540
        Finn CamachoSupport EngineerSan Francisco472009/07/07$87,500
        Serge BaldwinData CoordinatorSingapore642012/04/09$138,575
        Zenaida FrankSoftware EngineerNew York632010/01/04$125,250
        Zorita SerranoSoftware EngineerSan Francisco562012/06/01$115,000
        Jennifer AcostaJunior Javascript DeveloperEdinburgh432013/02/01$75,650
        Cara StevensSales AssistantNew York462011/12/06$145,600
        Hermione ButlerRegional DirectorLondon472011/03/21$356,250
        Lael GreerSystems AdministratorLondon212009/02/27$103,500
        Jonas AlexanderDeveloperSan Francisco302010/07/14$86,500
        Shad DeckerRegional DirectorEdinburgh512008/11/13$183,000
        Michael BruceJavascript DeveloperSingapore292011/06/27$183,000
        Donna SniderCustomer SupportNew York272011/01/25$112,000
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this + example:

        $(document).ready(function() { + var table = $('#example').DataTable(); + + new $.fn.dataTable.AutoFill( table, { + mode: 'x' + } ); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this + example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by + DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library + files (below), in order to correctly display the table. The additional CSS used is shown + below:

        +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the + table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data + will update automatically as any additional data is loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note + that this is just an example script using PHP. Server-side processing scripts can be written in any + language, using the protocol described in the + DataTables documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/AutoFill/examples/index.html b/public/assets/plugins/datatables/extensions/AutoFill/examples/index.html new file mode 100644 index 00000000..9cade86c --- /dev/null +++ b/public/assets/plugins/datatables/extensions/AutoFill/examples/index.html @@ -0,0 +1,66 @@ + + + + + + + + + + + + + AutoFill examples - AutoFill examples + + + +
        +
        +

        AutoFill example AutoFill examples

        + +
        +

        AutoFill gives an Excel like option to a DataTable to click and drag over multiple cells, filling in + information over the selected cells and incrementing numbers as needed.

        + +

        Thanks to Phoniax AS for their sponsorship of this plug-in for + DataTables.

        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/AutoFill/examples/scrolling.html b/public/assets/plugins/datatables/extensions/AutoFill/examples/scrolling.html new file mode 100644 index 00000000..66871ec7 --- /dev/null +++ b/public/assets/plugins/datatables/extensions/AutoFill/examples/scrolling.html @@ -0,0 +1,638 @@ + + + + + + + + AutoFill example - Scrolling DataTable + + + + + + + + + + + + + + +
        +
        +

        AutoFill example Scrolling DataTable

        + +
        +

        When dragging an AutoFill handle, the table (if DataTables scrolling is enabled) or the window will + be automatically scrolled, as you approach the edge of the scrolling component. The example below shows + the effect with DataTables scrolling (and also window if needed).

        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NamePositionOfficeAgeStart dateSalary
        NamePositionOfficeAgeStart dateSalary
        Tiger NixonSystem ArchitectEdinburgh612011/04/25$320,800
        Garrett WintersAccountantTokyo632011/07/25$170,750
        Ashton CoxJunior Technical AuthorSan Francisco662009/01/12$86,000
        Cedric KellySenior Javascript DeveloperEdinburgh222012/03/29$433,060
        Airi SatouAccountantTokyo332008/11/28$162,700
        Brielle WilliamsonIntegration SpecialistNew York612012/12/02$372,000
        Herrod ChandlerSales AssistantSan Francisco592012/08/06$137,500
        Rhona DavidsonIntegration SpecialistTokyo552010/10/14$327,900
        Colleen HurstJavascript DeveloperSan Francisco392009/09/15$205,500
        Sonya FrostSoftware EngineerEdinburgh232008/12/13$103,600
        Jena GainesOffice ManagerLondon302008/12/19$90,560
        Quinn FlynnSupport LeadEdinburgh222013/03/03$342,000
        Charde MarshallRegional DirectorSan Francisco362008/10/16$470,600
        Haley KennedySenior Marketing DesignerLondon432012/12/18$313,500
        Tatyana FitzpatrickRegional DirectorLondon192010/03/17$385,750
        Michael SilvaMarketing DesignerLondon662012/11/27$198,500
        Paul ByrdChief Financial Officer (CFO)New York642010/06/09$725,000
        Gloria LittleSystems AdministratorNew York592009/04/10$237,500
        Bradley GreerSoftware EngineerLondon412012/10/13$132,000
        Dai RiosPersonnel LeadEdinburgh352012/09/26$217,500
        Jenette CaldwellDevelopment LeadNew York302011/09/03$345,000
        Yuri BerryChief Marketing Officer (CMO)New York402009/06/25$675,000
        Caesar VancePre-Sales SupportNew York212011/12/12$106,450
        Doris WilderSales AssistantSidney232010/09/20$85,600
        Angelica RamosChief Executive Officer (CEO)London472009/10/09$1,200,000
        Gavin JoyceDeveloperEdinburgh422010/12/22$92,575
        Jennifer ChangRegional DirectorSingapore282010/11/14$357,650
        Brenden WagnerSoftware EngineerSan Francisco282011/06/07$206,850
        Fiona GreenChief Operating Officer (COO)San Francisco482010/03/11$850,000
        Shou ItouRegional MarketingTokyo202011/08/14$163,000
        Michelle HouseIntegration SpecialistSidney372011/06/02$95,400
        Suki BurksDeveloperLondon532009/10/22$114,500
        Prescott BartlettTechnical AuthorLondon272011/05/07$145,000
        Gavin CortezTeam LeaderSan Francisco222008/10/26$235,500
        Martena MccrayPost-Sales supportEdinburgh462011/03/09$324,050
        Unity ButlerMarketing DesignerSan Francisco472009/12/09$85,675
        Howard HatfieldOffice ManagerSan Francisco512008/12/16$164,500
        Hope FuentesSecretarySan Francisco412010/02/12$109,850
        Vivian HarrellFinancial ControllerSan Francisco622009/02/14$452,500
        Timothy MooneyOffice ManagerLondon372008/12/11$136,200
        Jackson BradshawDirectorNew York652008/09/26$645,750
        Olivia LiangSupport EngineerSingapore642011/02/03$234,500
        Bruno NashSoftware EngineerLondon382011/05/03$163,500
        Sakura YamamotoSupport EngineerTokyo372009/08/19$139,575
        Thor WaltonDeveloperNew York612013/08/11$98,540
        Finn CamachoSupport EngineerSan Francisco472009/07/07$87,500
        Serge BaldwinData CoordinatorSingapore642012/04/09$138,575
        Zenaida FrankSoftware EngineerNew York632010/01/04$125,250
        Zorita SerranoSoftware EngineerSan Francisco562012/06/01$115,000
        Jennifer AcostaJunior Javascript DeveloperEdinburgh432013/02/01$75,650
        Cara StevensSales AssistantNew York462011/12/06$145,600
        Hermione ButlerRegional DirectorLondon472011/03/21$356,250
        Lael GreerSystems AdministratorLondon212009/02/27$103,500
        Jonas AlexanderDeveloperSan Francisco302010/07/14$86,500
        Shad DeckerRegional DirectorEdinburgh512008/11/13$183,000
        Michael BruceJavascript DeveloperSingapore292011/06/27$183,000
        Donna SniderCustomer SupportNew York272011/01/25$112,000
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this + example:

        $(document).ready(function() { + var table = $('#example').dataTable( { + scrollY: 200, + scrollCollapse: false, + paginate: false + } ); + + new $.fn.dataTable.AutoFill( table ); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this + example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by + DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library + files (below), in order to correctly display the table. The additional CSS used is shown + below:

        +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the + table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data + will update automatically as any additional data is loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note + that this is just an example script using PHP. Server-side processing scripts can be written in any + language, using the protocol described in the + DataTables documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/AutoFill/examples/simple.html b/public/assets/plugins/datatables/extensions/AutoFill/examples/simple.html new file mode 100644 index 00000000..ea3db498 --- /dev/null +++ b/public/assets/plugins/datatables/extensions/AutoFill/examples/simple.html @@ -0,0 +1,631 @@ + + + + + + + + AutoFill example - Basic initialisation + + + + + + + + + + + + + + +
        +
        +

        AutoFill example Basic initialisation

        + +
        +

        AutoFill gives an Excel like option to a DataTable to click and drag over multiple cells, filling in + information over the selected cells and incrementing numbers as needed.

        + +

        AutoFill is initialised using the $.fn.dataTable.AutoFill function as shown in the + example below. It requires one parameter, the DataTable instance that AutoFill is to operate on, and + optionally a second configuration parameter, which is shown in the other AutoFill examples.

        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NamePositionOfficeAgeStart dateSalary
        NamePositionOfficeAgeStart dateSalary
        Tiger NixonSystem ArchitectEdinburgh612011/04/25$320,800
        Garrett WintersAccountantTokyo632011/07/25$170,750
        Ashton CoxJunior Technical AuthorSan Francisco662009/01/12$86,000
        Cedric KellySenior Javascript DeveloperEdinburgh222012/03/29$433,060
        Airi SatouAccountantTokyo332008/11/28$162,700
        Brielle WilliamsonIntegration SpecialistNew York612012/12/02$372,000
        Herrod ChandlerSales AssistantSan Francisco592012/08/06$137,500
        Rhona DavidsonIntegration SpecialistTokyo552010/10/14$327,900
        Colleen HurstJavascript DeveloperSan Francisco392009/09/15$205,500
        Sonya FrostSoftware EngineerEdinburgh232008/12/13$103,600
        Jena GainesOffice ManagerLondon302008/12/19$90,560
        Quinn FlynnSupport LeadEdinburgh222013/03/03$342,000
        Charde MarshallRegional DirectorSan Francisco362008/10/16$470,600
        Haley KennedySenior Marketing DesignerLondon432012/12/18$313,500
        Tatyana FitzpatrickRegional DirectorLondon192010/03/17$385,750
        Michael SilvaMarketing DesignerLondon662012/11/27$198,500
        Paul ByrdChief Financial Officer (CFO)New York642010/06/09$725,000
        Gloria LittleSystems AdministratorNew York592009/04/10$237,500
        Bradley GreerSoftware EngineerLondon412012/10/13$132,000
        Dai RiosPersonnel LeadEdinburgh352012/09/26$217,500
        Jenette CaldwellDevelopment LeadNew York302011/09/03$345,000
        Yuri BerryChief Marketing Officer (CMO)New York402009/06/25$675,000
        Caesar VancePre-Sales SupportNew York212011/12/12$106,450
        Doris WilderSales AssistantSidney232010/09/20$85,600
        Angelica RamosChief Executive Officer (CEO)London472009/10/09$1,200,000
        Gavin JoyceDeveloperEdinburgh422010/12/22$92,575
        Jennifer ChangRegional DirectorSingapore282010/11/14$357,650
        Brenden WagnerSoftware EngineerSan Francisco282011/06/07$206,850
        Fiona GreenChief Operating Officer (COO)San Francisco482010/03/11$850,000
        Shou ItouRegional MarketingTokyo202011/08/14$163,000
        Michelle HouseIntegration SpecialistSidney372011/06/02$95,400
        Suki BurksDeveloperLondon532009/10/22$114,500
        Prescott BartlettTechnical AuthorLondon272011/05/07$145,000
        Gavin CortezTeam LeaderSan Francisco222008/10/26$235,500
        Martena MccrayPost-Sales supportEdinburgh462011/03/09$324,050
        Unity ButlerMarketing DesignerSan Francisco472009/12/09$85,675
        Howard HatfieldOffice ManagerSan Francisco512008/12/16$164,500
        Hope FuentesSecretarySan Francisco412010/02/12$109,850
        Vivian HarrellFinancial ControllerSan Francisco622009/02/14$452,500
        Timothy MooneyOffice ManagerLondon372008/12/11$136,200
        Jackson BradshawDirectorNew York652008/09/26$645,750
        Olivia LiangSupport EngineerSingapore642011/02/03$234,500
        Bruno NashSoftware EngineerLondon382011/05/03$163,500
        Sakura YamamotoSupport EngineerTokyo372009/08/19$139,575
        Thor WaltonDeveloperNew York612013/08/11$98,540
        Finn CamachoSupport EngineerSan Francisco472009/07/07$87,500
        Serge BaldwinData CoordinatorSingapore642012/04/09$138,575
        Zenaida FrankSoftware EngineerNew York632010/01/04$125,250
        Zorita SerranoSoftware EngineerSan Francisco562012/06/01$115,000
        Jennifer AcostaJunior Javascript DeveloperEdinburgh432013/02/01$75,650
        Cara StevensSales AssistantNew York462011/12/06$145,600
        Hermione ButlerRegional DirectorLondon472011/03/21$356,250
        Lael GreerSystems AdministratorLondon212009/02/27$103,500
        Jonas AlexanderDeveloperSan Francisco302010/07/14$86,500
        Shad DeckerRegional DirectorEdinburgh512008/11/13$183,000
        Michael BruceJavascript DeveloperSingapore292011/06/27$183,000
        Donna SniderCustomer SupportNew York272011/01/25$112,000
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this + example:

        $(document).ready(function() { + var table = $('#example').DataTable(); + new $.fn.dataTable.AutoFill( table ); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this + example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by + DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library + files (below), in order to correctly display the table. The additional CSS used is shown + below:

        +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the + table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data + will update automatically as any additional data is loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note + that this is just an example script using PHP. Server-side processing scripts can be written in any + language, using the protocol described in the + DataTables documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/AutoFill/examples/step-callback.html b/public/assets/plugins/datatables/extensions/AutoFill/examples/step-callback.html new file mode 100644 index 00000000..c1255aaa --- /dev/null +++ b/public/assets/plugins/datatables/extensions/AutoFill/examples/step-callback.html @@ -0,0 +1,660 @@ + + + + + + + + AutoFill example - Step callback + + + + + + + + + + + + + + +
        +
        +

        AutoFill example Step callback

        + +
        +

        By default, AutoFill will increment cells that contain numbers by a single digit for each cell that + is iterated over (try the Age column below for example). This behaviour can be disabled + completely using the increment column option, but it can also be modified to suit your + requirements through use of the step column callback function.

        + +

        The step callback is executed for each cell in the auto-fill set and gives complete + control over how data is incremented. The example below shows the step function being used on the + Salary column to increment by 100, rather than 1 for each cell.

        + +

        For a complete description of the step callback, please refer to the AutoFill documentation.

        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NamePositionOfficeAgeStart dateSalary
        NamePositionOfficeAgeStart dateSalary
        Tiger NixonSystem ArchitectEdinburgh612011/04/25$320,800
        Garrett WintersAccountantTokyo632011/07/25$170,750
        Ashton CoxJunior Technical AuthorSan Francisco662009/01/12$86,000
        Cedric KellySenior Javascript DeveloperEdinburgh222012/03/29$433,060
        Airi SatouAccountantTokyo332008/11/28$162,700
        Brielle WilliamsonIntegration SpecialistNew York612012/12/02$372,000
        Herrod ChandlerSales AssistantSan Francisco592012/08/06$137,500
        Rhona DavidsonIntegration SpecialistTokyo552010/10/14$327,900
        Colleen HurstJavascript DeveloperSan Francisco392009/09/15$205,500
        Sonya FrostSoftware EngineerEdinburgh232008/12/13$103,600
        Jena GainesOffice ManagerLondon302008/12/19$90,560
        Quinn FlynnSupport LeadEdinburgh222013/03/03$342,000
        Charde MarshallRegional DirectorSan Francisco362008/10/16$470,600
        Haley KennedySenior Marketing DesignerLondon432012/12/18$313,500
        Tatyana FitzpatrickRegional DirectorLondon192010/03/17$385,750
        Michael SilvaMarketing DesignerLondon662012/11/27$198,500
        Paul ByrdChief Financial Officer (CFO)New York642010/06/09$725,000
        Gloria LittleSystems AdministratorNew York592009/04/10$237,500
        Bradley GreerSoftware EngineerLondon412012/10/13$132,000
        Dai RiosPersonnel LeadEdinburgh352012/09/26$217,500
        Jenette CaldwellDevelopment LeadNew York302011/09/03$345,000
        Yuri BerryChief Marketing Officer (CMO)New York402009/06/25$675,000
        Caesar VancePre-Sales SupportNew York212011/12/12$106,450
        Doris WilderSales AssistantSidney232010/09/20$85,600
        Angelica RamosChief Executive Officer (CEO)London472009/10/09$1,200,000
        Gavin JoyceDeveloperEdinburgh422010/12/22$92,575
        Jennifer ChangRegional DirectorSingapore282010/11/14$357,650
        Brenden WagnerSoftware EngineerSan Francisco282011/06/07$206,850
        Fiona GreenChief Operating Officer (COO)San Francisco482010/03/11$850,000
        Shou ItouRegional MarketingTokyo202011/08/14$163,000
        Michelle HouseIntegration SpecialistSidney372011/06/02$95,400
        Suki BurksDeveloperLondon532009/10/22$114,500
        Prescott BartlettTechnical AuthorLondon272011/05/07$145,000
        Gavin CortezTeam LeaderSan Francisco222008/10/26$235,500
        Martena MccrayPost-Sales supportEdinburgh462011/03/09$324,050
        Unity ButlerMarketing DesignerSan Francisco472009/12/09$85,675
        Howard HatfieldOffice ManagerSan Francisco512008/12/16$164,500
        Hope FuentesSecretarySan Francisco412010/02/12$109,850
        Vivian HarrellFinancial ControllerSan Francisco622009/02/14$452,500
        Timothy MooneyOffice ManagerLondon372008/12/11$136,200
        Jackson BradshawDirectorNew York652008/09/26$645,750
        Olivia LiangSupport EngineerSingapore642011/02/03$234,500
        Bruno NashSoftware EngineerLondon382011/05/03$163,500
        Sakura YamamotoSupport EngineerTokyo372009/08/19$139,575
        Thor WaltonDeveloperNew York612013/08/11$98,540
        Finn CamachoSupport EngineerSan Francisco472009/07/07$87,500
        Serge BaldwinData CoordinatorSingapore642012/04/09$138,575
        Zenaida FrankSoftware EngineerNew York632010/01/04$125,250
        Zorita SerranoSoftware EngineerSan Francisco562012/06/01$115,000
        Jennifer AcostaJunior Javascript DeveloperEdinburgh432013/02/01$75,650
        Cara StevensSales AssistantNew York462011/12/06$145,600
        Hermione ButlerRegional DirectorLondon472011/03/21$356,250
        Lael GreerSystems AdministratorLondon212009/02/27$103,500
        Jonas AlexanderDeveloperSan Francisco302010/07/14$86,500
        Shad DeckerRegional DirectorEdinburgh512008/11/13$183,000
        Michael BruceJavascript DeveloperSingapore292011/06/27$183,000
        Donna SniderCustomer SupportNew York272011/01/25$112,000
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this + example:

        $(document).ready(function() { + var table = $('#example').dataTable(); + + new $.fn.dataTable.AutoFill( table, { + columnDefs: [ { + targets: -1, + step: function ( cell, read, last, i, x, y ) { + var val = parseInt( (last || read).replace(/[$,]/g, ''), 10 ); + val += (x<0 || y<0 ? -100 : 100); // - if going back up, + if going down + + // Format for the currency column + return '$'+val.toString().replace( /\B(?=(\d{3})+(?!\d))/g, ',' ); + } + } ] + } ); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this + example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by + DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library + files (below), in order to correctly display the table. The additional CSS used is shown + below:

        +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the + table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data + will update automatically as any additional data is loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note + that this is just an example script using PHP. Server-side processing scripts can be written in any + language, using the protocol described in the + DataTables documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/AutoFill/images/filler.png b/public/assets/plugins/datatables/extensions/AutoFill/images/filler.png new file mode 100644 index 00000000..f2af65d8 Binary files /dev/null and b/public/assets/plugins/datatables/extensions/AutoFill/images/filler.png differ diff --git a/public/assets/plugins/datatables/extensions/AutoFill/js/dataTables.autoFill.js b/public/assets/plugins/datatables/extensions/AutoFill/js/dataTables.autoFill.js new file mode 100644 index 00000000..6bbfa35b --- /dev/null +++ b/public/assets/plugins/datatables/extensions/AutoFill/js/dataTables.autoFill.js @@ -0,0 +1,855 @@ +/*! AutoFill 1.2.1 + * ©2008-2014 SpryMedia Ltd - datatables.net/license + */ + +/** + * @summary AutoFill + * @description Add Excel like click and drag auto-fill options to DataTables + * @version 1.2.1 + * @file dataTables.autoFill.js + * @author SpryMedia Ltd (www.sprymedia.co.uk) + * @contact www.sprymedia.co.uk/contact + * @copyright Copyright 2010-2014 SpryMedia Ltd. + * + * This source file is free software, available under the following license: + * MIT license - http://datatables.net/license/mit + * + * This source file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. + * + * For details please refer to: http://www.datatables.net + */ + +(function( window, document, undefined ) { + +var factory = function( $, DataTable ) { +"use strict"; + +/** + * AutoFill provides Excel like auto-fill features for a DataTable + * + * @class AutoFill + * @constructor + * @param {object} oTD DataTables settings object + * @param {object} oConfig Configuration object for AutoFill + */ +var AutoFill = function( oDT, oConfig ) +{ + /* Sanity check that we are a new instance */ + if ( ! (this instanceof AutoFill) ) { + throw( "Warning: AutoFill must be initialised with the keyword 'new'" ); + } + + if ( ! $.fn.dataTableExt.fnVersionCheck('1.7.0') ) { + throw( "Warning: AutoFill requires DataTables 1.7 or greater"); + } + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Public class variables + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + this.c = {}; + + /** + * @namespace Settings object which contains customisable information for AutoFill instance + */ + this.s = { + /** + * @namespace Cached information about the little dragging icon (the filler) + */ + "filler": { + "height": 0, + "width": 0 + }, + + /** + * @namespace Cached information about the border display + */ + "border": { + "width": 2 + }, + + /** + * @namespace Store for live information for the current drag + */ + "drag": { + "startX": -1, + "startY": -1, + "startTd": null, + "endTd": null, + "dragging": false + }, + + /** + * @namespace Data cache for information that we need for scrolling the screen when we near + * the edges + */ + "screen": { + "interval": null, + "y": 0, + "height": 0, + "scrollTop": 0 + }, + + /** + * @namespace Data cache for the position of the DataTables scrolling element (when scrolling + * is enabled) + */ + "scroller": { + "top": 0, + "bottom": 0 + }, + + /** + * @namespace Information stored for each column. An array of objects + */ + "columns": [] + }; + + + /** + * @namespace Common and useful DOM elements for the class instance + */ + this.dom = { + "table": null, + "filler": null, + "borderTop": null, + "borderRight": null, + "borderBottom": null, + "borderLeft": null, + "currentTarget": null + }; + + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Public class methods + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + /** + * Retreieve the settings object from an instance + * @method fnSettings + * @returns {object} AutoFill settings object + */ + this.fnSettings = function () { + return this.s; + }; + + + /* Constructor logic */ + this._fnInit( oDT, oConfig ); + return this; +}; + + + +AutoFill.prototype = { + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Private methods (they are of course public in JS, but recommended as private) + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + /** + * Initialisation + * @method _fnInit + * @param {object} dt DataTables settings object + * @param {object} config Configuration object for AutoFill + * @returns void + */ + "_fnInit": function ( dt, config ) + { + var + that = this, + i, iLen; + + // Use DataTables API to get the settings allowing selectors, instances + // etc to be used, or for backwards compatibility get from the old + // fnSettings method + this.s.dt = DataTable.Api ? + new DataTable.Api( dt ).settings()[0] : + dt.fnSettings(); + this.s.init = config || {}; + this.dom.table = this.s.dt.nTable; + + $.extend( true, this.c, AutoFill.defaults, config ); + + /* Add and configure the columns */ + this._initColumns(); + + /* Auto Fill click and drag icon */ + var filler = $('
        ', { + 'class': 'AutoFill_filler' + } ) + .appendTo( 'body' ); + this.dom.filler = filler[0]; + + // Get the height / width of the click element + this.s.filler.height = filler.height(); + this.s.filler.width = filler.width(); + filler[0].style.display = "none"; + + /* Border display - one div for each side. We can't just use a single + * one with a border, as we want the events to effectively pass through + * the transparent bit of the box + */ + var border; + var appender = document.body; + if ( that.s.dt.oScroll.sY !== "" ) { + that.s.dt.nTable.parentNode.style.position = "relative"; + appender = that.s.dt.nTable.parentNode; + } + + border = $('
        ', { + "class": "AutoFill_border" + } ); + this.dom.borderTop = border.clone().appendTo( appender )[0]; + this.dom.borderRight = border.clone().appendTo( appender )[0]; + this.dom.borderBottom = border.clone().appendTo( appender )[0]; + this.dom.borderLeft = border.clone().appendTo( appender )[0]; + + /* Events */ + filler.on( 'mousedown.DTAF', function (e) { + this.onselectstart = function() { return false; }; + that._fnFillerDragStart.call( that, e ); + return false; + } ); + + $('tbody', this.dom.table).on( + 'mouseover.DTAF mouseout.DTAF', + '>tr>td, >tr>th', + function (e) { + that._fnFillerDisplay.call( that, e ); + } + ); + + $(this.dom.table).on( 'destroy.dt.DTAF', function () { + filler.off( 'mousedown.DTAF' ).remove(); + $('tbody', this.dom.table).off( 'mouseover.DTAF mouseout.DTAF' ); + } ); + }, + + + _initColumns: function ( ) + { + var that = this; + var i, ien; + var dt = this.s.dt; + var config = this.s.init; + + for ( i=0, ien=dt.aoColumns.length ; i offsetEnd.left) { + x1 = offsetEnd.left - border; + x2 = offsetStart.left + $(nStart).outerWidth(); + width = offsetStart.left + $(nStart).outerWidth() - offsetEnd.left + (2*border); + } + + if ( this.s.dt.oScroll.sY !== "" ) + { + /* The border elements are inside the DT scroller - so position relative to that */ + var + offsetScroll = $(this.s.dt.nTable.parentNode).offset(), + scrollTop = $(this.s.dt.nTable.parentNode).scrollTop(), + scrollLeft = $(this.s.dt.nTable.parentNode).scrollLeft(); + + x1 -= offsetScroll.left - scrollLeft; + x2 -= offsetScroll.left - scrollLeft; + y1 -= offsetScroll.top - scrollTop; + y2 -= offsetScroll.top - scrollTop; + } + + /* Top */ + oStyle = this.dom.borderTop.style; + oStyle.top = y1+"px"; + oStyle.left = x1+"px"; + oStyle.height = this.s.border.width+"px"; + oStyle.width = width+"px"; + + /* Bottom */ + oStyle = this.dom.borderBottom.style; + oStyle.top = y2+"px"; + oStyle.left = x1+"px"; + oStyle.height = this.s.border.width+"px"; + oStyle.width = width+"px"; + + /* Left */ + oStyle = this.dom.borderLeft.style; + oStyle.top = y1+"px"; + oStyle.left = x1+"px"; + oStyle.height = height+"px"; + oStyle.width = this.s.border.width+"px"; + + /* Right */ + oStyle = this.dom.borderRight.style; + oStyle.top = y1+"px"; + oStyle.left = x2+"px"; + oStyle.height = height+"px"; + oStyle.width = this.s.border.width+"px"; + }, + + + /** + * Mouse down event handler for starting a drag + * @method _fnFillerDragStart + * @param {Object} e Event object + * @returns void + */ + "_fnFillerDragStart": function (e) + { + var that = this; + var startingTd = this.dom.currentTarget; + + this.s.drag.dragging = true; + + that.dom.borderTop.style.display = "block"; + that.dom.borderRight.style.display = "block"; + that.dom.borderBottom.style.display = "block"; + that.dom.borderLeft.style.display = "block"; + + var coords = this._fnTargetCoords( startingTd ); + this.s.drag.startX = coords.x; + this.s.drag.startY = coords.y; + + this.s.drag.startTd = startingTd; + this.s.drag.endTd = startingTd; + + this._fnUpdateBorder( startingTd, startingTd ); + + $(document).bind('mousemove.AutoFill', function (e) { + that._fnFillerDragMove.call( that, e ); + } ); + + $(document).bind('mouseup.AutoFill', function (e) { + that._fnFillerFinish.call( that, e ); + } ); + + /* Scrolling information cache */ + this.s.screen.y = e.pageY; + this.s.screen.height = $(window).height(); + this.s.screen.scrollTop = $(document).scrollTop(); + + if ( this.s.dt.oScroll.sY !== "" ) + { + this.s.scroller.top = $(this.s.dt.nTable.parentNode).offset().top; + this.s.scroller.bottom = this.s.scroller.top + $(this.s.dt.nTable.parentNode).height(); + } + + /* Scrolling handler - we set an interval (which is cancelled on mouse up) which will fire + * regularly and see if we need to do any scrolling + */ + this.s.screen.interval = setInterval( function () { + var iScrollTop = $(document).scrollTop(); + var iScrollDelta = iScrollTop - that.s.screen.scrollTop; + that.s.screen.y += iScrollDelta; + + if ( that.s.screen.height - that.s.screen.y + iScrollTop < 50 ) + { + $('html, body').animate( { + "scrollTop": iScrollTop + 50 + }, 240, 'linear' ); + } + else if ( that.s.screen.y - iScrollTop < 50 ) + { + $('html, body').animate( { + "scrollTop": iScrollTop - 50 + }, 240, 'linear' ); + } + + if ( that.s.dt.oScroll.sY !== "" ) + { + if ( that.s.screen.y > that.s.scroller.bottom - 50 ) + { + $(that.s.dt.nTable.parentNode).animate( { + "scrollTop": $(that.s.dt.nTable.parentNode).scrollTop() + 50 + }, 240, 'linear' ); + } + else if ( that.s.screen.y < that.s.scroller.top + 50 ) + { + $(that.s.dt.nTable.parentNode).animate( { + "scrollTop": $(that.s.dt.nTable.parentNode).scrollTop() - 50 + }, 240, 'linear' ); + } + } + }, 250 ); + }, + + + /** + * Mouse move event handler for during a move. See if we want to update the display based on the + * new cursor position + * @method _fnFillerDragMove + * @param {Object} e Event object + * @returns void + */ + "_fnFillerDragMove": function (e) + { + if ( e.target && e.target.nodeName.toUpperCase() == "TD" && + e.target != this.s.drag.endTd ) + { + var coords = this._fnTargetCoords( e.target ); + + if ( this.c.mode == "y" && coords.x != this.s.drag.startX ) + { + e.target = $('tbody>tr:eq('+coords.y+')>td:eq('+this.s.drag.startX+')', this.dom.table)[0]; + } + if ( this.c.mode == "x" && coords.y != this.s.drag.startY ) + { + e.target = $('tbody>tr:eq('+this.s.drag.startY+')>td:eq('+coords.x+')', this.dom.table)[0]; + } + + if ( this.c.mode == "either") + { + if(coords.x != this.s.drag.startX ) + { + e.target = $('tbody>tr:eq('+this.s.drag.startY+')>td:eq('+coords.x+')', this.dom.table)[0]; + } + else if ( coords.y != this.s.drag.startY ) { + e.target = $('tbody>tr:eq('+coords.y+')>td:eq('+this.s.drag.startX+')', this.dom.table)[0]; + } + } + + // update coords + if ( this.c.mode !== "both" ) { + coords = this._fnTargetCoords( e.target ); + } + + var drag = this.s.drag; + drag.endTd = e.target; + + if ( coords.y >= this.s.drag.startY ) { + this._fnUpdateBorder( drag.startTd, drag.endTd ); + } + else { + this._fnUpdateBorder( drag.endTd, drag.startTd ); + } + this._fnFillerPosition( e.target ); + } + + /* Update the screen information so we can perform scrolling */ + this.s.screen.y = e.pageY; + this.s.screen.scrollTop = $(document).scrollTop(); + + if ( this.s.dt.oScroll.sY !== "" ) + { + this.s.scroller.scrollTop = $(this.s.dt.nTable.parentNode).scrollTop(); + this.s.scroller.top = $(this.s.dt.nTable.parentNode).offset().top; + this.s.scroller.bottom = this.s.scroller.top + $(this.s.dt.nTable.parentNode).height(); + } + }, + + + /** + * Mouse release handler - end the drag and take action to update the cells with the needed values + * @method _fnFillerFinish + * @param {Object} e Event object + * @returns void + */ + "_fnFillerFinish": function (e) + { + var that = this, i, iLen, j; + + $(document).unbind('mousemove.AutoFill mouseup.AutoFill'); + + this.dom.borderTop.style.display = "none"; + this.dom.borderRight.style.display = "none"; + this.dom.borderBottom.style.display = "none"; + this.dom.borderLeft.style.display = "none"; + + this.s.drag.dragging = false; + + clearInterval( this.s.screen.interval ); + + var cells = []; + var table = this.dom.table; + var coordsStart = this._fnTargetCoords( this.s.drag.startTd ); + var coordsEnd = this._fnTargetCoords( this.s.drag.endTd ); + var columnIndex = function ( visIdx ) { + return that.s.dt.oApi._fnVisibleToColumnIndex( that.s.dt, visIdx ); + }; + + // xxx - urgh - there must be a way of reducing this... + if ( coordsStart.y <= coordsEnd.y ) { + for ( i=coordsStart.y ; i<=coordsEnd.y ; i++ ) { + if ( coordsStart.x <= coordsEnd.x ) { + for ( j=coordsStart.x ; j<=coordsEnd.x ; j++ ) { + cells.push( { + node: $('tbody>tr:eq('+i+')>td:eq('+j+')', table)[0], + x: j - coordsStart.x, + y: i - coordsStart.y, + colIdx: columnIndex( j ) + } ); + } + } + else { + for ( j=coordsStart.x ; j>=coordsEnd.x ; j-- ) { + cells.push( { + node: $('tbody>tr:eq('+i+')>td:eq('+j+')', table)[0], + x: j - coordsStart.x, + y: i - coordsStart.y, + colIdx: columnIndex( j ) + } ); + } + } + } + } + else { + for ( i=coordsStart.y ; i>=coordsEnd.y ; i-- ) { + if ( coordsStart.x <= coordsEnd.x ) { + for ( j=coordsStart.x ; j<=coordsEnd.x ; j++ ) { + cells.push( { + node: $('tbody>tr:eq('+i+')>td:eq('+j+')', table)[0], + x: j - coordsStart.x, + y: i - coordsStart.y, + colIdx: columnIndex( j ) + } ); + } + } + else { + for ( j=coordsStart.x ; j>=coordsEnd.x ; j-- ) { + cells.push( { + node: $('tbody>tr:eq('+i+')>td:eq('+j+')', table)[0], + x: coordsStart.x - j, + y: coordsStart.y - i, + colIdx: columnIndex( j ) + } ); + } + } + } + } + + // An auto-fill requires 2 or more cells + if ( cells.length <= 1 ) { + return; + } + + var edited = []; + var previous; + + for ( i=0, iLen=cells.length ; i",{"class":"AutoFill_filler"}).appendTo("body");this.dom.filler=e[0];this.s.filler.height=e.height();this.s.filler.width=e.width();e[0].style.display= +"none";var g,f=j.body;""!==a.s.dt.oScroll.sY&&(a.s.dt.nTable.parentNode.style.position="relative",f=a.s.dt.nTable.parentNode);g=c("
        ",{"class":"AutoFill_border"});this.dom.borderTop=g.clone().appendTo(f)[0];this.dom.borderRight=g.clone().appendTo(f)[0];this.dom.borderBottom=g.clone().appendTo(f)[0];this.dom.borderLeft=g.clone().appendTo(f)[0];e.on("mousedown.DTAF",function(b){this.onselectstart=function(){return false};a._fnFillerDragStart.call(a,b);return false});c("tbody",this.dom.table).on("mouseover.DTAF mouseout.DTAF", +">tr>td, >tr>th",function(b){a._fnFillerDisplay.call(a,b)});c(this.dom.table).on("destroy.dt.DTAF",function(){e.off("mousedown.DTAF").remove();c("tbody",this.dom.table).off("mouseover.DTAF mouseout.DTAF")})},_initColumns:function(){var d=this,b,a,e=this.s.dt,g=this.s.init;b=0;for(a=e.aoColumns.length;bg.left&&(f=g.left-a,i=e.left+c(d).outerWidth(),j=e.left+c(d).outerWidth()-g.left+2*a);""!==this.s.dt.oScroll.sY&&(a=c(this.s.dt.nTable.parentNode).offset(),e=c(this.s.dt.nTable.parentNode).scrollTop(), +g=c(this.s.dt.nTable.parentNode).scrollLeft(),f-=a.left-g,i-=a.left-g,n-=a.top-e,h-=a.top-e);a=this.dom.borderTop.style;a.top=n+"px";a.left=f+"px";a.height=this.s.border.width+"px";a.width=j+"px";a=this.dom.borderBottom.style;a.top=h+"px";a.left=f+"px";a.height=this.s.border.width+"px";a.width=j+"px";a=this.dom.borderLeft.style;a.top=n+"px";a.left=f+"px";a.height=k+"px";a.width=this.s.border.width+"px";a=this.dom.borderRight.style;a.top=n+"px";a.left=i+"px";a.height=k+"px";a.width=this.s.border.width+ +"px"},_fnFillerDragStart:function(d){var b=this,a=this.dom.currentTarget;this.s.drag.dragging=!0;b.dom.borderTop.style.display="block";b.dom.borderRight.style.display="block";b.dom.borderBottom.style.display="block";b.dom.borderLeft.style.display="block";var e=this._fnTargetCoords(a);this.s.drag.startX=e.x;this.s.drag.startY=e.y;this.s.drag.startTd=a;this.s.drag.endTd=a;this._fnUpdateBorder(a,a);c(j).bind("mousemove.AutoFill",function(a){b._fnFillerDragMove.call(b,a)});c(j).bind("mouseup.AutoFill", +function(a){b._fnFillerFinish.call(b,a)});this.s.screen.y=d.pageY;this.s.screen.height=c(o).height();this.s.screen.scrollTop=c(j).scrollTop();""!==this.s.dt.oScroll.sY&&(this.s.scroller.top=c(this.s.dt.nTable.parentNode).offset().top,this.s.scroller.bottom=this.s.scroller.top+c(this.s.dt.nTable.parentNode).height());this.s.screen.interval=setInterval(function(){var a=c(j).scrollTop();b.s.screen.y=b.s.screen.y+(a-b.s.screen.scrollTop);b.s.screen.height-b.s.screen.y+a<50?c("html, body").animate({scrollTop:a+ +50},240,"linear"):b.s.screen.y-a<50&&c("html, body").animate({scrollTop:a-50},240,"linear");b.s.dt.oScroll.sY!==""&&(b.s.screen.y>b.s.scroller.bottom-50?c(b.s.dt.nTable.parentNode).animate({scrollTop:c(b.s.dt.nTable.parentNode).scrollTop()+50},240,"linear"):b.s.screen.ytr:eq("+b.y+")>td:eq("+this.s.drag.startX+")",this.dom.table)[0]);"x"==this.c.mode&&b.y!=this.s.drag.startY&&(d.target=c("tbody>tr:eq("+this.s.drag.startY+")>td:eq("+b.x+")",this.dom.table)[0]);"either"==this.c.mode&&(b.x!=this.s.drag.startX?d.target=c("tbody>tr:eq("+this.s.drag.startY+")>td:eq("+b.x+")",this.dom.table)[0]:b.y!=this.s.drag.startY&&(d.target=c("tbody>tr:eq("+b.y+")>td:eq("+this.s.drag.startX+ +")",this.dom.table)[0]));"both"!==this.c.mode&&(b=this._fnTargetCoords(d.target));var a=this.s.drag;a.endTd=d.target;b.y>=this.s.drag.startY?this._fnUpdateBorder(a.startTd,a.endTd):this._fnUpdateBorder(a.endTd,a.startTd);this._fnFillerPosition(d.target)}this.s.screen.y=d.pageY;this.s.screen.scrollTop=c(j).scrollTop();""!==this.s.dt.oScroll.sY&&(this.s.scroller.scrollTop=c(this.s.dt.nTable.parentNode).scrollTop(),this.s.scroller.top=c(this.s.dt.nTable.parentNode).offset().top,this.s.scroller.bottom= +this.s.scroller.top+c(this.s.dt.nTable.parentNode).height())},_fnFillerFinish:function(){var d=this,b,a;c(j).unbind("mousemove.AutoFill mouseup.AutoFill");this.dom.borderTop.style.display="none";this.dom.borderRight.style.display="none";this.dom.borderBottom.style.display="none";this.dom.borderLeft.style.display="none";this.s.drag.dragging=!1;clearInterval(this.s.screen.interval);var e=[],g=this.dom.table,f=this._fnTargetCoords(this.s.drag.startTd),i=this._fnTargetCoords(this.s.drag.endTd),h=function(a){return d.s.dt.oApi._fnVisibleToColumnIndex(d.s.dt, +a)};if(f.y<=i.y)for(b=f.y;b<=i.y;b++)if(f.x<=i.x)for(a=f.x;a<=i.x;a++)e.push({node:c("tbody>tr:eq("+b+")>td:eq("+a+")",g)[0],x:a-f.x,y:b-f.y,colIdx:h(a)});else for(a=f.x;a>=i.x;a--)e.push({node:c("tbody>tr:eq("+b+")>td:eq("+a+")",g)[0],x:a-f.x,y:b-f.y,colIdx:h(a)});else for(b=f.y;b>=i.y;b--)if(f.x<=i.x)for(a=f.x;a<=i.x;a++)e.push({node:c("tbody>tr:eq("+b+")>td:eq("+a+")",g)[0],x:a-f.x,y:b-f.y,colIdx:h(a)});else for(a=f.x;a>=i.x;a--)e.push({node:c("tbody>tr:eq("+b+")>td:eq("+a+")",g)[0],x:f.x-a,y:f.y- +b,colIdx:h(a)});if(!(1>=e.length)){var g=[],m;b=0;for(a=e.length;bg||0>f?-1:1)):a===m?b:a}}};return h};"function"===typeof define&&define.amd? +define(["jquery","datatables"],l):"object"===typeof exports?l(require("jquery"),require("datatables")):jQuery&&!jQuery.fn.dataTable.AutoFill&&l(jQuery,jQuery.fn.dataTable)})(window,document); diff --git a/public/assets/plugins/datatables/extensions/ColReorder/License.txt b/public/assets/plugins/datatables/extensions/ColReorder/License.txt new file mode 100644 index 00000000..9ade2f1b --- /dev/null +++ b/public/assets/plugins/datatables/extensions/ColReorder/License.txt @@ -0,0 +1,20 @@ +Copyright (c) 2010-2015 SpryMedia Limited +http://datatables.net + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/public/assets/plugins/datatables/extensions/ColReorder/Readme.md b/public/assets/plugins/datatables/extensions/ColReorder/Readme.md new file mode 100644 index 00000000..217dd60e --- /dev/null +++ b/public/assets/plugins/datatables/extensions/ColReorder/Readme.md @@ -0,0 +1,39 @@ +# ColReorder + +ColReorder adds the ability for the end user to click and drag column headers to reorder a table as they see fit, to DataTables. Key features include: + +* Very easy integration with DataTables +* Tight integration with all other DataTables plug-ins +* The ability to exclude the first (or more) column from being movable +* Predefine a column order +* Save staving integration with DataTables + + +# Installation + +To use ColReorder, first download DataTables ( http://datatables.net/download ) and place the unzipped ColReorder package into a `extensions` directory in the DataTables package. This will allow the pages in the examples to operate correctly. To see the examples running, open the `examples` directory in your web-browser. + + +# Basic usage + +ColReorder is initialised using the `$.fn.dataTable.ColReorder` constructor. For example: + +```js +$(document).ready( function () { + $('#example').DataTable(); + + new $.fn.dataTable.ColReorder( table ); +} ); +``` + + +# Documentation / support + +* Documentation: http://datatables.net/extensions/colreorder/ +* DataTables support forums: http://datatables.net/forums + + +# GitHub + +If you fancy getting involved with the development of ColReorder and help make it better, please refer to its GitHub repo: https://github.com/DataTables/ColReorder + diff --git a/public/assets/plugins/datatables/extensions/ColReorder/css/dataTables.colReorder.css b/public/assets/plugins/datatables/extensions/ColReorder/css/dataTables.colReorder.css new file mode 100644 index 00000000..bdd6aa0b --- /dev/null +++ b/public/assets/plugins/datatables/extensions/ColReorder/css/dataTables.colReorder.css @@ -0,0 +1,14 @@ +/* + * Namespace DTCR - "DataTables ColReorder" plug-in + */ + +table.DTCR_clonedTable { + background-color: rgba(255, 255, 255, 0.7); + z-index: 202; +} + +div.DTCR_pointer { + width: 1px; + background-color: #0259C4; + z-index: 201; +} \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/ColReorder/css/dataTables.colReorder.min.css b/public/assets/plugins/datatables/extensions/ColReorder/css/dataTables.colReorder.min.css new file mode 100644 index 00000000..77b230e0 --- /dev/null +++ b/public/assets/plugins/datatables/extensions/ColReorder/css/dataTables.colReorder.min.css @@ -0,0 +1 @@ +table.DTCR_clonedTable{background-color:rgba(255,255,255,0.7);z-index:202}div.DTCR_pointer{width:1px;background-color:#0259C4;z-index:201} diff --git a/public/assets/plugins/datatables/extensions/ColReorder/examples/alt_insert.html b/public/assets/plugins/datatables/extensions/ColReorder/examples/alt_insert.html new file mode 100644 index 00000000..16bedcfe --- /dev/null +++ b/public/assets/plugins/datatables/extensions/ColReorder/examples/alt_insert.html @@ -0,0 +1,637 @@ + + + + + + + + ColReorder example - Alternative insert styling + + + + + + + + + + + + + + +
        +
        +

        ColReorder example Alternative insert styling

        + +
        +

        Using CSS it is easy to modify the insert bar to suit your web-site. This example shows how an arrow can be used to show the insert point rather than the + straight bar used in the other examples by simply adding an extra CSS rule to include the image.

        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NamePositionOfficeAgeStart dateSalary
        NamePositionOfficeAgeStart dateSalary
        Tiger NixonSystem ArchitectEdinburgh612011/04/25$320,800
        Garrett WintersAccountantTokyo632011/07/25$170,750
        Ashton CoxJunior Technical AuthorSan Francisco662009/01/12$86,000
        Cedric KellySenior Javascript DeveloperEdinburgh222012/03/29$433,060
        Airi SatouAccountantTokyo332008/11/28$162,700
        Brielle WilliamsonIntegration SpecialistNew York612012/12/02$372,000
        Herrod ChandlerSales AssistantSan Francisco592012/08/06$137,500
        Rhona DavidsonIntegration SpecialistTokyo552010/10/14$327,900
        Colleen HurstJavascript DeveloperSan Francisco392009/09/15$205,500
        Sonya FrostSoftware EngineerEdinburgh232008/12/13$103,600
        Jena GainesOffice ManagerLondon302008/12/19$90,560
        Quinn FlynnSupport LeadEdinburgh222013/03/03$342,000
        Charde MarshallRegional DirectorSan Francisco362008/10/16$470,600
        Haley KennedySenior Marketing DesignerLondon432012/12/18$313,500
        Tatyana FitzpatrickRegional DirectorLondon192010/03/17$385,750
        Michael SilvaMarketing DesignerLondon662012/11/27$198,500
        Paul ByrdChief Financial Officer (CFO)New York642010/06/09$725,000
        Gloria LittleSystems AdministratorNew York592009/04/10$237,500
        Bradley GreerSoftware EngineerLondon412012/10/13$132,000
        Dai RiosPersonnel LeadEdinburgh352012/09/26$217,500
        Jenette CaldwellDevelopment LeadNew York302011/09/03$345,000
        Yuri BerryChief Marketing Officer (CMO)New York402009/06/25$675,000
        Caesar VancePre-Sales SupportNew York212011/12/12$106,450
        Doris WilderSales AssistantSidney232010/09/20$85,600
        Angelica RamosChief Executive Officer (CEO)London472009/10/09$1,200,000
        Gavin JoyceDeveloperEdinburgh422010/12/22$92,575
        Jennifer ChangRegional DirectorSingapore282010/11/14$357,650
        Brenden WagnerSoftware EngineerSan Francisco282011/06/07$206,850
        Fiona GreenChief Operating Officer (COO)San Francisco482010/03/11$850,000
        Shou ItouRegional MarketingTokyo202011/08/14$163,000
        Michelle HouseIntegration SpecialistSidney372011/06/02$95,400
        Suki BurksDeveloperLondon532009/10/22$114,500
        Prescott BartlettTechnical AuthorLondon272011/05/07$145,000
        Gavin CortezTeam LeaderSan Francisco222008/10/26$235,500
        Martena MccrayPost-Sales supportEdinburgh462011/03/09$324,050
        Unity ButlerMarketing DesignerSan Francisco472009/12/09$85,675
        Howard HatfieldOffice ManagerSan Francisco512008/12/16$164,500
        Hope FuentesSecretarySan Francisco412010/02/12$109,850
        Vivian HarrellFinancial ControllerSan Francisco622009/02/14$452,500
        Timothy MooneyOffice ManagerLondon372008/12/11$136,200
        Jackson BradshawDirectorNew York652008/09/26$645,750
        Olivia LiangSupport EngineerSingapore642011/02/03$234,500
        Bruno NashSoftware EngineerLondon382011/05/03$163,500
        Sakura YamamotoSupport EngineerTokyo372009/08/19$139,575
        Thor WaltonDeveloperNew York612013/08/11$98,540
        Finn CamachoSupport EngineerSan Francisco472009/07/07$87,500
        Serge BaldwinData CoordinatorSingapore642012/04/09$138,575
        Zenaida FrankSoftware EngineerNew York632010/01/04$125,250
        Zorita SerranoSoftware EngineerSan Francisco562012/06/01$115,000
        Jennifer AcostaJunior Javascript DeveloperEdinburgh432013/02/01$75,650
        Cara StevensSales AssistantNew York462011/12/06$145,600
        Hermione ButlerRegional DirectorLondon472011/03/21$356,250
        Lael GreerSystems AdministratorLondon212009/02/27$103,500
        Jonas AlexanderDeveloperSan Francisco302010/07/14$86,500
        Shad DeckerRegional DirectorEdinburgh512008/11/13$183,000
        Michael BruceJavascript DeveloperSingapore292011/06/27$183,000
        Donna SniderCustomer SupportNew York272011/01/25$112,000
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this example:

        $(document).ready(function() { + $('#example').DataTable( { + dom: 'Rlfrtip' + } ); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The + additional CSS used is shown below:

        div.DTCR_pointer { + margin-top: -15px; + margin-left: -9px; + width: 18px; + background: url('../images/insert.png') no-repeat top left; +} +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is + loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side + processing scripts can be written in any language, using the protocol described in the DataTables + documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/ColReorder/examples/col_filter.html b/public/assets/plugins/datatables/extensions/ColReorder/examples/col_filter.html new file mode 100644 index 00000000..355ff2b5 --- /dev/null +++ b/public/assets/plugins/datatables/extensions/ColReorder/examples/col_filter.html @@ -0,0 +1,656 @@ + + + + + + + + ColReorder example - Individual column filtering + + + + + + + + + + + + + + +
        +
        +

        ColReorder example Individual column filtering

        + +
        +

        This example of how to use ColReorder shows how it can with with DataTables' ability to do individual column filtering. The basic example is exactly the same as + the DataTables column filtering example, but with ColReorder also added to the table (through the R option for domDT).

        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NamePositionOfficeAgeStart dateSalary
        NamePositionOfficeAgeStart dateSalary
        Tiger NixonSystem ArchitectEdinburgh612011/04/25$320,800
        Garrett WintersAccountantTokyo632011/07/25$170,750
        Ashton CoxJunior Technical AuthorSan Francisco662009/01/12$86,000
        Cedric KellySenior Javascript DeveloperEdinburgh222012/03/29$433,060
        Airi SatouAccountantTokyo332008/11/28$162,700
        Brielle WilliamsonIntegration SpecialistNew York612012/12/02$372,000
        Herrod ChandlerSales AssistantSan Francisco592012/08/06$137,500
        Rhona DavidsonIntegration SpecialistTokyo552010/10/14$327,900
        Colleen HurstJavascript DeveloperSan Francisco392009/09/15$205,500
        Sonya FrostSoftware EngineerEdinburgh232008/12/13$103,600
        Jena GainesOffice ManagerLondon302008/12/19$90,560
        Quinn FlynnSupport LeadEdinburgh222013/03/03$342,000
        Charde MarshallRegional DirectorSan Francisco362008/10/16$470,600
        Haley KennedySenior Marketing DesignerLondon432012/12/18$313,500
        Tatyana FitzpatrickRegional DirectorLondon192010/03/17$385,750
        Michael SilvaMarketing DesignerLondon662012/11/27$198,500
        Paul ByrdChief Financial Officer (CFO)New York642010/06/09$725,000
        Gloria LittleSystems AdministratorNew York592009/04/10$237,500
        Bradley GreerSoftware EngineerLondon412012/10/13$132,000
        Dai RiosPersonnel LeadEdinburgh352012/09/26$217,500
        Jenette CaldwellDevelopment LeadNew York302011/09/03$345,000
        Yuri BerryChief Marketing Officer (CMO)New York402009/06/25$675,000
        Caesar VancePre-Sales SupportNew York212011/12/12$106,450
        Doris WilderSales AssistantSidney232010/09/20$85,600
        Angelica RamosChief Executive Officer (CEO)London472009/10/09$1,200,000
        Gavin JoyceDeveloperEdinburgh422010/12/22$92,575
        Jennifer ChangRegional DirectorSingapore282010/11/14$357,650
        Brenden WagnerSoftware EngineerSan Francisco282011/06/07$206,850
        Fiona GreenChief Operating Officer (COO)San Francisco482010/03/11$850,000
        Shou ItouRegional MarketingTokyo202011/08/14$163,000
        Michelle HouseIntegration SpecialistSidney372011/06/02$95,400
        Suki BurksDeveloperLondon532009/10/22$114,500
        Prescott BartlettTechnical AuthorLondon272011/05/07$145,000
        Gavin CortezTeam LeaderSan Francisco222008/10/26$235,500
        Martena MccrayPost-Sales supportEdinburgh462011/03/09$324,050
        Unity ButlerMarketing DesignerSan Francisco472009/12/09$85,675
        Howard HatfieldOffice ManagerSan Francisco512008/12/16$164,500
        Hope FuentesSecretarySan Francisco412010/02/12$109,850
        Vivian HarrellFinancial ControllerSan Francisco622009/02/14$452,500
        Timothy MooneyOffice ManagerLondon372008/12/11$136,200
        Jackson BradshawDirectorNew York652008/09/26$645,750
        Olivia LiangSupport EngineerSingapore642011/02/03$234,500
        Bruno NashSoftware EngineerLondon382011/05/03$163,500
        Sakura YamamotoSupport EngineerTokyo372009/08/19$139,575
        Thor WaltonDeveloperNew York612013/08/11$98,540
        Finn CamachoSupport EngineerSan Francisco472009/07/07$87,500
        Serge BaldwinData CoordinatorSingapore642012/04/09$138,575
        Zenaida FrankSoftware EngineerNew York632010/01/04$125,250
        Zorita SerranoSoftware EngineerSan Francisco562012/06/01$115,000
        Jennifer AcostaJunior Javascript DeveloperEdinburgh432013/02/01$75,650
        Cara StevensSales AssistantNew York462011/12/06$145,600
        Hermione ButlerRegional DirectorLondon472011/03/21$356,250
        Lael GreerSystems AdministratorLondon212009/02/27$103,500
        Jonas AlexanderDeveloperSan Francisco302010/07/14$86,500
        Shad DeckerRegional DirectorEdinburgh512008/11/13$183,000
        Michael BruceJavascript DeveloperSingapore292011/06/27$183,000
        Donna SniderCustomer SupportNew York272011/01/25$112,000
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this example:

        $(document).ready(function() { + // Setup - add a text input to each footer cell + $('#example tfoot th').each( function () { + var title = $('#example thead th').eq( $(this).index() ).text(); + $(this).html( '<input type="text" placeholder="Search '+title+'" />' ); + } ); + + // DataTable + var table = $('#example').DataTable( { + dom: 'Rlfrtip' + } ); + + // Apply the filter + $("#example tfoot input").on( 'keyup change', function () { + table + .column( $(this).parent().index()+':visible' ) + .search( this.value ) + .draw(); + } ); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The + additional CSS used is shown below:

        +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is + loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side + processing scripts can be written in any language, using the protocol described in the DataTables + documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/ColReorder/examples/colvis.html b/public/assets/plugins/datatables/extensions/ColReorder/examples/colvis.html new file mode 100644 index 00000000..54c79c2a --- /dev/null +++ b/public/assets/plugins/datatables/extensions/ColReorder/examples/colvis.html @@ -0,0 +1,635 @@ + + + + + + + + ColReorder example - ColVis integration + + + + + + + + + + + + + + + + +
        +
        +

        ColReorder example ColVis integration

        + +
        +

        ColReorder interfaces with the ColVis extension for DataTables by updating the order of the list of columns + whenever a reorder is done. This is shown in the example below, where one column has been initially hidden to add extra emphasis to ColVis.

        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NamePositionOfficeAgeStart dateSalary
        NamePositionOfficeAgeStart dateSalary
        Tiger NixonSystem ArchitectEdinburgh612011/04/25$320,800
        Garrett WintersAccountantTokyo632011/07/25$170,750
        Ashton CoxJunior Technical AuthorSan Francisco662009/01/12$86,000
        Cedric KellySenior Javascript DeveloperEdinburgh222012/03/29$433,060
        Airi SatouAccountantTokyo332008/11/28$162,700
        Brielle WilliamsonIntegration SpecialistNew York612012/12/02$372,000
        Herrod ChandlerSales AssistantSan Francisco592012/08/06$137,500
        Rhona DavidsonIntegration SpecialistTokyo552010/10/14$327,900
        Colleen HurstJavascript DeveloperSan Francisco392009/09/15$205,500
        Sonya FrostSoftware EngineerEdinburgh232008/12/13$103,600
        Jena GainesOffice ManagerLondon302008/12/19$90,560
        Quinn FlynnSupport LeadEdinburgh222013/03/03$342,000
        Charde MarshallRegional DirectorSan Francisco362008/10/16$470,600
        Haley KennedySenior Marketing DesignerLondon432012/12/18$313,500
        Tatyana FitzpatrickRegional DirectorLondon192010/03/17$385,750
        Michael SilvaMarketing DesignerLondon662012/11/27$198,500
        Paul ByrdChief Financial Officer (CFO)New York642010/06/09$725,000
        Gloria LittleSystems AdministratorNew York592009/04/10$237,500
        Bradley GreerSoftware EngineerLondon412012/10/13$132,000
        Dai RiosPersonnel LeadEdinburgh352012/09/26$217,500
        Jenette CaldwellDevelopment LeadNew York302011/09/03$345,000
        Yuri BerryChief Marketing Officer (CMO)New York402009/06/25$675,000
        Caesar VancePre-Sales SupportNew York212011/12/12$106,450
        Doris WilderSales AssistantSidney232010/09/20$85,600
        Angelica RamosChief Executive Officer (CEO)London472009/10/09$1,200,000
        Gavin JoyceDeveloperEdinburgh422010/12/22$92,575
        Jennifer ChangRegional DirectorSingapore282010/11/14$357,650
        Brenden WagnerSoftware EngineerSan Francisco282011/06/07$206,850
        Fiona GreenChief Operating Officer (COO)San Francisco482010/03/11$850,000
        Shou ItouRegional MarketingTokyo202011/08/14$163,000
        Michelle HouseIntegration SpecialistSidney372011/06/02$95,400
        Suki BurksDeveloperLondon532009/10/22$114,500
        Prescott BartlettTechnical AuthorLondon272011/05/07$145,000
        Gavin CortezTeam LeaderSan Francisco222008/10/26$235,500
        Martena MccrayPost-Sales supportEdinburgh462011/03/09$324,050
        Unity ButlerMarketing DesignerSan Francisco472009/12/09$85,675
        Howard HatfieldOffice ManagerSan Francisco512008/12/16$164,500
        Hope FuentesSecretarySan Francisco412010/02/12$109,850
        Vivian HarrellFinancial ControllerSan Francisco622009/02/14$452,500
        Timothy MooneyOffice ManagerLondon372008/12/11$136,200
        Jackson BradshawDirectorNew York652008/09/26$645,750
        Olivia LiangSupport EngineerSingapore642011/02/03$234,500
        Bruno NashSoftware EngineerLondon382011/05/03$163,500
        Sakura YamamotoSupport EngineerTokyo372009/08/19$139,575
        Thor WaltonDeveloperNew York612013/08/11$98,540
        Finn CamachoSupport EngineerSan Francisco472009/07/07$87,500
        Serge BaldwinData CoordinatorSingapore642012/04/09$138,575
        Zenaida FrankSoftware EngineerNew York632010/01/04$125,250
        Zorita SerranoSoftware EngineerSan Francisco562012/06/01$115,000
        Jennifer AcostaJunior Javascript DeveloperEdinburgh432013/02/01$75,650
        Cara StevensSales AssistantNew York462011/12/06$145,600
        Hermione ButlerRegional DirectorLondon472011/03/21$356,250
        Lael GreerSystems AdministratorLondon212009/02/27$103,500
        Jonas AlexanderDeveloperSan Francisco302010/07/14$86,500
        Shad DeckerRegional DirectorEdinburgh512008/11/13$183,000
        Michael BruceJavascript DeveloperSingapore292011/06/27$183,000
        Donna SniderCustomer SupportNew York272011/01/25$112,000
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this example:

        $(document).ready(function() { + var table = $('#example').DataTable( { + dom: 'RC<"clear">lfrtip', + columnDefs: [ + { visible: false, targets: 1 } + ] + } ); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The + additional CSS used is shown below:

        +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is + loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side + processing scripts can be written in any language, using the protocol described in the DataTables + documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/ColReorder/examples/fixedcolumns.html b/public/assets/plugins/datatables/extensions/ColReorder/examples/fixedcolumns.html new file mode 100644 index 00000000..0599ba48 --- /dev/null +++ b/public/assets/plugins/datatables/extensions/ColReorder/examples/fixedcolumns.html @@ -0,0 +1,831 @@ + + + + + + + + ColReorder example - FixedColumns integration + + + + + + + + + + + + + + + + +
        +
        +

        ColReorder example FixedColumns integration

        + +
        +

        While ColReorder works with the built-in scrolling options in DataTables (scrollYDT and scrollXDT) and also the FixedColumns + extension.

        + +

        ColReorder provides the fixedColumnsLeft and fixedColumnsRight options which allows you disallow reordering of the fixed columns + (which is required).

        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        First nameLast namePositionOfficeAgeStart dateSalaryExtn.E-mail
        TigerNixonSystem ArchitectEdinburgh612011/04/25$320,8005421t.nixon@datatables.net
        GarrettWintersAccountantTokyo632011/07/25$170,7508422g.winters@datatables.net
        AshtonCoxJunior Technical AuthorSan Francisco662009/01/12$86,0001562a.cox@datatables.net
        CedricKellySenior Javascript DeveloperEdinburgh222012/03/29$433,0606224c.kelly@datatables.net
        AiriSatouAccountantTokyo332008/11/28$162,7005407a.satou@datatables.net
        BrielleWilliamsonIntegration SpecialistNew York612012/12/02$372,0004804b.williamson@datatables.net
        HerrodChandlerSales AssistantSan Francisco592012/08/06$137,5009608h.chandler@datatables.net
        RhonaDavidsonIntegration SpecialistTokyo552010/10/14$327,9006200r.davidson@datatables.net
        ColleenHurstJavascript DeveloperSan Francisco392009/09/15$205,5002360c.hurst@datatables.net
        SonyaFrostSoftware EngineerEdinburgh232008/12/13$103,6001667s.frost@datatables.net
        JenaGainesOffice ManagerLondon302008/12/19$90,5603814j.gaines@datatables.net
        QuinnFlynnSupport LeadEdinburgh222013/03/03$342,0009497q.flynn@datatables.net
        ChardeMarshallRegional DirectorSan Francisco362008/10/16$470,6006741c.marshall@datatables.net
        HaleyKennedySenior Marketing DesignerLondon432012/12/18$313,5003597h.kennedy@datatables.net
        TatyanaFitzpatrickRegional DirectorLondon192010/03/17$385,7501965t.fitzpatrick@datatables.net
        MichaelSilvaMarketing DesignerLondon662012/11/27$198,5001581m.silva@datatables.net
        PaulByrdChief Financial Officer (CFO)New York642010/06/09$725,0003059p.byrd@datatables.net
        GloriaLittleSystems AdministratorNew York592009/04/10$237,5001721g.little@datatables.net
        BradleyGreerSoftware EngineerLondon412012/10/13$132,0002558b.greer@datatables.net
        DaiRiosPersonnel LeadEdinburgh352012/09/26$217,5002290d.rios@datatables.net
        JenetteCaldwellDevelopment LeadNew York302011/09/03$345,0001937j.caldwell@datatables.net
        YuriBerryChief Marketing Officer (CMO)New York402009/06/25$675,0006154y.berry@datatables.net
        CaesarVancePre-Sales SupportNew York212011/12/12$106,4508330c.vance@datatables.net
        DorisWilderSales AssistantSidney232010/09/20$85,6003023d.wilder@datatables.net
        AngelicaRamosChief Executive Officer (CEO)London472009/10/09$1,200,0005797a.ramos@datatables.net
        GavinJoyceDeveloperEdinburgh422010/12/22$92,5758822g.joyce@datatables.net
        JenniferChangRegional DirectorSingapore282010/11/14$357,6509239j.chang@datatables.net
        BrendenWagnerSoftware EngineerSan Francisco282011/06/07$206,8501314b.wagner@datatables.net
        FionaGreenChief Operating Officer (COO)San Francisco482010/03/11$850,0002947f.green@datatables.net
        ShouItouRegional MarketingTokyo202011/08/14$163,0008899s.itou@datatables.net
        MichelleHouseIntegration SpecialistSidney372011/06/02$95,4002769m.house@datatables.net
        SukiBurksDeveloperLondon532009/10/22$114,5006832s.burks@datatables.net
        PrescottBartlettTechnical AuthorLondon272011/05/07$145,0003606p.bartlett@datatables.net
        GavinCortezTeam LeaderSan Francisco222008/10/26$235,5002860g.cortez@datatables.net
        MartenaMccrayPost-Sales supportEdinburgh462011/03/09$324,0508240m.mccray@datatables.net
        UnityButlerMarketing DesignerSan Francisco472009/12/09$85,6755384u.butler@datatables.net
        HowardHatfieldOffice ManagerSan Francisco512008/12/16$164,5007031h.hatfield@datatables.net
        HopeFuentesSecretarySan Francisco412010/02/12$109,8506318h.fuentes@datatables.net
        VivianHarrellFinancial ControllerSan Francisco622009/02/14$452,5009422v.harrell@datatables.net
        TimothyMooneyOffice ManagerLondon372008/12/11$136,2007580t.mooney@datatables.net
        JacksonBradshawDirectorNew York652008/09/26$645,7501042j.bradshaw@datatables.net
        OliviaLiangSupport EngineerSingapore642011/02/03$234,5002120o.liang@datatables.net
        BrunoNashSoftware EngineerLondon382011/05/03$163,5006222b.nash@datatables.net
        SakuraYamamotoSupport EngineerTokyo372009/08/19$139,5759383s.yamamoto@datatables.net
        ThorWaltonDeveloperNew York612013/08/11$98,5408327t.walton@datatables.net
        FinnCamachoSupport EngineerSan Francisco472009/07/07$87,5002927f.camacho@datatables.net
        SergeBaldwinData CoordinatorSingapore642012/04/09$138,5758352s.baldwin@datatables.net
        ZenaidaFrankSoftware EngineerNew York632010/01/04$125,2507439z.frank@datatables.net
        ZoritaSerranoSoftware EngineerSan Francisco562012/06/01$115,0004389z.serrano@datatables.net
        JenniferAcostaJunior Javascript DeveloperEdinburgh432013/02/01$75,6503431j.acosta@datatables.net
        CaraStevensSales AssistantNew York462011/12/06$145,6003990c.stevens@datatables.net
        HermioneButlerRegional DirectorLondon472011/03/21$356,2501016h.butler@datatables.net
        LaelGreerSystems AdministratorLondon212009/02/27$103,5006733l.greer@datatables.net
        JonasAlexanderDeveloperSan Francisco302010/07/14$86,5008196j.alexander@datatables.net
        ShadDeckerRegional DirectorEdinburgh512008/11/13$183,0006373s.decker@datatables.net
        MichaelBruceJavascript DeveloperSingapore292011/06/27$183,0005384m.bruce@datatables.net
        DonnaSniderCustomer SupportNew York272011/01/25$112,0004226d.snider@datatables.net
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this example:

        $(document).ready(function() { + window.table = $('#example').DataTable( { + dom: 'Rlfrtip', + scrollX: true, + scrollCollapse: true, + columnDefs: [ + { orderable: false, targets: 0 }, + { orderable: false, targets: -1 } + ], + ordering: [[ 1, 'asc' ]], + colReorder: { + fixedColumnsLeft: 1, + fixedColumnsRight: 1 + } + } ); + + window.fc = new $.fn.dataTable.FixedColumns( table, { + leftColumns: 1, + rightColumns: 1 + } ); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The + additional CSS used is shown below:

        +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is + loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side + processing scripts can be written in any language, using the protocol described in the DataTables + documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/ColReorder/examples/fixedheader.html b/public/assets/plugins/datatables/extensions/ColReorder/examples/fixedheader.html new file mode 100644 index 00000000..40f05468 --- /dev/null +++ b/public/assets/plugins/datatables/extensions/ColReorder/examples/fixedheader.html @@ -0,0 +1,635 @@ + + + + + + + + ColReorder example - FixedHeader integration + + + + + + + + + + + + + + + + +
        +
        +

        ColReorder example FixedHeader integration

        + +
        +

        FixedHeader is a particularly useful plug-in for DataTables, allowing a table header to float at the top of a scrolling window. ColReorder works well with + FixedHeader, allowing you to reorder columns even using the floating header, as shown in the example below.

        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NamePositionOfficeAgeStart dateSalary
        NamePositionOfficeAgeStart dateSalary
        Tiger NixonSystem ArchitectEdinburgh612011/04/25$320,800
        Garrett WintersAccountantTokyo632011/07/25$170,750
        Ashton CoxJunior Technical AuthorSan Francisco662009/01/12$86,000
        Cedric KellySenior Javascript DeveloperEdinburgh222012/03/29$433,060
        Airi SatouAccountantTokyo332008/11/28$162,700
        Brielle WilliamsonIntegration SpecialistNew York612012/12/02$372,000
        Herrod ChandlerSales AssistantSan Francisco592012/08/06$137,500
        Rhona DavidsonIntegration SpecialistTokyo552010/10/14$327,900
        Colleen HurstJavascript DeveloperSan Francisco392009/09/15$205,500
        Sonya FrostSoftware EngineerEdinburgh232008/12/13$103,600
        Jena GainesOffice ManagerLondon302008/12/19$90,560
        Quinn FlynnSupport LeadEdinburgh222013/03/03$342,000
        Charde MarshallRegional DirectorSan Francisco362008/10/16$470,600
        Haley KennedySenior Marketing DesignerLondon432012/12/18$313,500
        Tatyana FitzpatrickRegional DirectorLondon192010/03/17$385,750
        Michael SilvaMarketing DesignerLondon662012/11/27$198,500
        Paul ByrdChief Financial Officer (CFO)New York642010/06/09$725,000
        Gloria LittleSystems AdministratorNew York592009/04/10$237,500
        Bradley GreerSoftware EngineerLondon412012/10/13$132,000
        Dai RiosPersonnel LeadEdinburgh352012/09/26$217,500
        Jenette CaldwellDevelopment LeadNew York302011/09/03$345,000
        Yuri BerryChief Marketing Officer (CMO)New York402009/06/25$675,000
        Caesar VancePre-Sales SupportNew York212011/12/12$106,450
        Doris WilderSales AssistantSidney232010/09/20$85,600
        Angelica RamosChief Executive Officer (CEO)London472009/10/09$1,200,000
        Gavin JoyceDeveloperEdinburgh422010/12/22$92,575
        Jennifer ChangRegional DirectorSingapore282010/11/14$357,650
        Brenden WagnerSoftware EngineerSan Francisco282011/06/07$206,850
        Fiona GreenChief Operating Officer (COO)San Francisco482010/03/11$850,000
        Shou ItouRegional MarketingTokyo202011/08/14$163,000
        Michelle HouseIntegration SpecialistSidney372011/06/02$95,400
        Suki BurksDeveloperLondon532009/10/22$114,500
        Prescott BartlettTechnical AuthorLondon272011/05/07$145,000
        Gavin CortezTeam LeaderSan Francisco222008/10/26$235,500
        Martena MccrayPost-Sales supportEdinburgh462011/03/09$324,050
        Unity ButlerMarketing DesignerSan Francisco472009/12/09$85,675
        Howard HatfieldOffice ManagerSan Francisco512008/12/16$164,500
        Hope FuentesSecretarySan Francisco412010/02/12$109,850
        Vivian HarrellFinancial ControllerSan Francisco622009/02/14$452,500
        Timothy MooneyOffice ManagerLondon372008/12/11$136,200
        Jackson BradshawDirectorNew York652008/09/26$645,750
        Olivia LiangSupport EngineerSingapore642011/02/03$234,500
        Bruno NashSoftware EngineerLondon382011/05/03$163,500
        Sakura YamamotoSupport EngineerTokyo372009/08/19$139,575
        Thor WaltonDeveloperNew York612013/08/11$98,540
        Finn CamachoSupport EngineerSan Francisco472009/07/07$87,500
        Serge BaldwinData CoordinatorSingapore642012/04/09$138,575
        Zenaida FrankSoftware EngineerNew York632010/01/04$125,250
        Zorita SerranoSoftware EngineerSan Francisco562012/06/01$115,000
        Jennifer AcostaJunior Javascript DeveloperEdinburgh432013/02/01$75,650
        Cara StevensSales AssistantNew York462011/12/06$145,600
        Hermione ButlerRegional DirectorLondon472011/03/21$356,250
        Lael GreerSystems AdministratorLondon212009/02/27$103,500
        Jonas AlexanderDeveloperSan Francisco302010/07/14$86,500
        Shad DeckerRegional DirectorEdinburgh512008/11/13$183,000
        Michael BruceJavascript DeveloperSingapore292011/06/27$183,000
        Donna SniderCustomer SupportNew York272011/01/25$112,000
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this example:

        $(document).ready(function() { + var table = $('#example').dataTable( { + dom: 'Rlfrtip' + } ); + + new $.fn.dataTable.fixedHeader( table ); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The + additional CSS used is shown below:

        +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is + loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side + processing scripts can be written in any language, using the protocol described in the DataTables + documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/ColReorder/examples/index.html b/public/assets/plugins/datatables/extensions/ColReorder/examples/index.html new file mode 100644 index 00000000..65018ab6 --- /dev/null +++ b/public/assets/plugins/datatables/extensions/ColReorder/examples/index.html @@ -0,0 +1,74 @@ + + + + + + + + + + + + + ColReorder examples - ColReorder examples + + + +
        +
        +

        ColReorder example ColReorder examples

        + +
        +

        ColReorder adds the ability for the end user to click and drag column headers to reorder a table as they see fit, to DataTables. Key features include:

        + +
          +
        • Very easy integration with DataTables
        • +
        • Tight integration with all other DataTables plug-ins
        • +
        • The ability to exclude the first (or more) column from being movable
        • +
        • Predefine a column order
        • +
        • Save staving integration with DataTables
        • +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/ColReorder/examples/jqueryui.html b/public/assets/plugins/datatables/extensions/ColReorder/examples/jqueryui.html new file mode 100644 index 00000000..8eedf912 --- /dev/null +++ b/public/assets/plugins/datatables/extensions/ColReorder/examples/jqueryui.html @@ -0,0 +1,635 @@ + + + + + + + + ColReorder example - jQuery UI styling + + + + + + + + + + + + + + + + +
        +
        +

        ColReorder example jQuery UI styling

        + +
        +

        This example shows how the jQuery UI ThemeRoller option in DataTables can be used with ColReorder.

        + +

        The important thing to note here is that it is easier to use new $.fn.dataTable.ColReorder() to add ColReorder to the table rather than domDT as the jQuery UI integration + uses a complex expression for domDT.

        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NamePositionOfficeAgeStart dateSalary
        NamePositionOfficeAgeStart dateSalary
        Tiger NixonSystem ArchitectEdinburgh612011/04/25$320,800
        Garrett WintersAccountantTokyo632011/07/25$170,750
        Ashton CoxJunior Technical AuthorSan Francisco662009/01/12$86,000
        Cedric KellySenior Javascript DeveloperEdinburgh222012/03/29$433,060
        Airi SatouAccountantTokyo332008/11/28$162,700
        Brielle WilliamsonIntegration SpecialistNew York612012/12/02$372,000
        Herrod ChandlerSales AssistantSan Francisco592012/08/06$137,500
        Rhona DavidsonIntegration SpecialistTokyo552010/10/14$327,900
        Colleen HurstJavascript DeveloperSan Francisco392009/09/15$205,500
        Sonya FrostSoftware EngineerEdinburgh232008/12/13$103,600
        Jena GainesOffice ManagerLondon302008/12/19$90,560
        Quinn FlynnSupport LeadEdinburgh222013/03/03$342,000
        Charde MarshallRegional DirectorSan Francisco362008/10/16$470,600
        Haley KennedySenior Marketing DesignerLondon432012/12/18$313,500
        Tatyana FitzpatrickRegional DirectorLondon192010/03/17$385,750
        Michael SilvaMarketing DesignerLondon662012/11/27$198,500
        Paul ByrdChief Financial Officer (CFO)New York642010/06/09$725,000
        Gloria LittleSystems AdministratorNew York592009/04/10$237,500
        Bradley GreerSoftware EngineerLondon412012/10/13$132,000
        Dai RiosPersonnel LeadEdinburgh352012/09/26$217,500
        Jenette CaldwellDevelopment LeadNew York302011/09/03$345,000
        Yuri BerryChief Marketing Officer (CMO)New York402009/06/25$675,000
        Caesar VancePre-Sales SupportNew York212011/12/12$106,450
        Doris WilderSales AssistantSidney232010/09/20$85,600
        Angelica RamosChief Executive Officer (CEO)London472009/10/09$1,200,000
        Gavin JoyceDeveloperEdinburgh422010/12/22$92,575
        Jennifer ChangRegional DirectorSingapore282010/11/14$357,650
        Brenden WagnerSoftware EngineerSan Francisco282011/06/07$206,850
        Fiona GreenChief Operating Officer (COO)San Francisco482010/03/11$850,000
        Shou ItouRegional MarketingTokyo202011/08/14$163,000
        Michelle HouseIntegration SpecialistSidney372011/06/02$95,400
        Suki BurksDeveloperLondon532009/10/22$114,500
        Prescott BartlettTechnical AuthorLondon272011/05/07$145,000
        Gavin CortezTeam LeaderSan Francisco222008/10/26$235,500
        Martena MccrayPost-Sales supportEdinburgh462011/03/09$324,050
        Unity ButlerMarketing DesignerSan Francisco472009/12/09$85,675
        Howard HatfieldOffice ManagerSan Francisco512008/12/16$164,500
        Hope FuentesSecretarySan Francisco412010/02/12$109,850
        Vivian HarrellFinancial ControllerSan Francisco622009/02/14$452,500
        Timothy MooneyOffice ManagerLondon372008/12/11$136,200
        Jackson BradshawDirectorNew York652008/09/26$645,750
        Olivia LiangSupport EngineerSingapore642011/02/03$234,500
        Bruno NashSoftware EngineerLondon382011/05/03$163,500
        Sakura YamamotoSupport EngineerTokyo372009/08/19$139,575
        Thor WaltonDeveloperNew York612013/08/11$98,540
        Finn CamachoSupport EngineerSan Francisco472009/07/07$87,500
        Serge BaldwinData CoordinatorSingapore642012/04/09$138,575
        Zenaida FrankSoftware EngineerNew York632010/01/04$125,250
        Zorita SerranoSoftware EngineerSan Francisco562012/06/01$115,000
        Jennifer AcostaJunior Javascript DeveloperEdinburgh432013/02/01$75,650
        Cara StevensSales AssistantNew York462011/12/06$145,600
        Hermione ButlerRegional DirectorLondon472011/03/21$356,250
        Lael GreerSystems AdministratorLondon212009/02/27$103,500
        Jonas AlexanderDeveloperSan Francisco302010/07/14$86,500
        Shad DeckerRegional DirectorEdinburgh512008/11/13$183,000
        Michael BruceJavascript DeveloperSingapore292011/06/27$183,000
        Donna SniderCustomer SupportNew York272011/01/25$112,000
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this example:

        $(document).ready(function() { + var table = $('#example').dataTable(); + + new $.fn.dataTable.ColReorder( table ); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The + additional CSS used is shown below:

        +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is + loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side + processing scripts can be written in any language, using the protocol described in the DataTables + documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/ColReorder/examples/new_init.html b/public/assets/plugins/datatables/extensions/ColReorder/examples/new_init.html new file mode 100644 index 00000000..01ab2aac --- /dev/null +++ b/public/assets/plugins/datatables/extensions/ColReorder/examples/new_init.html @@ -0,0 +1,626 @@ + + + + + + + + ColReorder example - Initialisation using `new` + + + + + + + + + + + + + + +
        +
        +

        ColReorder example Initialisation using `new`

        + +
        +

        As well as providing the option to be initialised through the R option of domDT, ColReorder can also be added to a DataTable using direct initialisation - new + $.fn.dataTable.ColReorder(); as shown in this example.

        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NamePositionOfficeAgeStart dateSalary
        NamePositionOfficeAgeStart dateSalary
        Tiger NixonSystem ArchitectEdinburgh612011/04/25$320,800
        Garrett WintersAccountantTokyo632011/07/25$170,750
        Ashton CoxJunior Technical AuthorSan Francisco662009/01/12$86,000
        Cedric KellySenior Javascript DeveloperEdinburgh222012/03/29$433,060
        Airi SatouAccountantTokyo332008/11/28$162,700
        Brielle WilliamsonIntegration SpecialistNew York612012/12/02$372,000
        Herrod ChandlerSales AssistantSan Francisco592012/08/06$137,500
        Rhona DavidsonIntegration SpecialistTokyo552010/10/14$327,900
        Colleen HurstJavascript DeveloperSan Francisco392009/09/15$205,500
        Sonya FrostSoftware EngineerEdinburgh232008/12/13$103,600
        Jena GainesOffice ManagerLondon302008/12/19$90,560
        Quinn FlynnSupport LeadEdinburgh222013/03/03$342,000
        Charde MarshallRegional DirectorSan Francisco362008/10/16$470,600
        Haley KennedySenior Marketing DesignerLondon432012/12/18$313,500
        Tatyana FitzpatrickRegional DirectorLondon192010/03/17$385,750
        Michael SilvaMarketing DesignerLondon662012/11/27$198,500
        Paul ByrdChief Financial Officer (CFO)New York642010/06/09$725,000
        Gloria LittleSystems AdministratorNew York592009/04/10$237,500
        Bradley GreerSoftware EngineerLondon412012/10/13$132,000
        Dai RiosPersonnel LeadEdinburgh352012/09/26$217,500
        Jenette CaldwellDevelopment LeadNew York302011/09/03$345,000
        Yuri BerryChief Marketing Officer (CMO)New York402009/06/25$675,000
        Caesar VancePre-Sales SupportNew York212011/12/12$106,450
        Doris WilderSales AssistantSidney232010/09/20$85,600
        Angelica RamosChief Executive Officer (CEO)London472009/10/09$1,200,000
        Gavin JoyceDeveloperEdinburgh422010/12/22$92,575
        Jennifer ChangRegional DirectorSingapore282010/11/14$357,650
        Brenden WagnerSoftware EngineerSan Francisco282011/06/07$206,850
        Fiona GreenChief Operating Officer (COO)San Francisco482010/03/11$850,000
        Shou ItouRegional MarketingTokyo202011/08/14$163,000
        Michelle HouseIntegration SpecialistSidney372011/06/02$95,400
        Suki BurksDeveloperLondon532009/10/22$114,500
        Prescott BartlettTechnical AuthorLondon272011/05/07$145,000
        Gavin CortezTeam LeaderSan Francisco222008/10/26$235,500
        Martena MccrayPost-Sales supportEdinburgh462011/03/09$324,050
        Unity ButlerMarketing DesignerSan Francisco472009/12/09$85,675
        Howard HatfieldOffice ManagerSan Francisco512008/12/16$164,500
        Hope FuentesSecretarySan Francisco412010/02/12$109,850
        Vivian HarrellFinancial ControllerSan Francisco622009/02/14$452,500
        Timothy MooneyOffice ManagerLondon372008/12/11$136,200
        Jackson BradshawDirectorNew York652008/09/26$645,750
        Olivia LiangSupport EngineerSingapore642011/02/03$234,500
        Bruno NashSoftware EngineerLondon382011/05/03$163,500
        Sakura YamamotoSupport EngineerTokyo372009/08/19$139,575
        Thor WaltonDeveloperNew York612013/08/11$98,540
        Finn CamachoSupport EngineerSan Francisco472009/07/07$87,500
        Serge BaldwinData CoordinatorSingapore642012/04/09$138,575
        Zenaida FrankSoftware EngineerNew York632010/01/04$125,250
        Zorita SerranoSoftware EngineerSan Francisco562012/06/01$115,000
        Jennifer AcostaJunior Javascript DeveloperEdinburgh432013/02/01$75,650
        Cara StevensSales AssistantNew York462011/12/06$145,600
        Hermione ButlerRegional DirectorLondon472011/03/21$356,250
        Lael GreerSystems AdministratorLondon212009/02/27$103,500
        Jonas AlexanderDeveloperSan Francisco302010/07/14$86,500
        Shad DeckerRegional DirectorEdinburgh512008/11/13$183,000
        Michael BruceJavascript DeveloperSingapore292011/06/27$183,000
        Donna SniderCustomer SupportNew York272011/01/25$112,000
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this example:

        $(document).ready(function() { + var table = $('#example').DataTable(); + + new $.fn.dataTable.ColReorder( table ); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The + additional CSS used is shown below:

        +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is + loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side + processing scripts can be written in any language, using the protocol described in the DataTables + documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/ColReorder/examples/predefined.html b/public/assets/plugins/datatables/extensions/ColReorder/examples/predefined.html new file mode 100644 index 00000000..3cbb1663 --- /dev/null +++ b/public/assets/plugins/datatables/extensions/ColReorder/examples/predefined.html @@ -0,0 +1,636 @@ + + + + + + + + ColReorder example - Predefined column ordering + + + + + + + + + + + + + + +
        +
        +

        ColReorder example Predefined column ordering

        + +
        +

        ColReorder provides the ability to specify a column ordering which is not that of the HTML (which typically you will want) through the parameter + colReorder.order. This is an array of integers with the column ordering you want.

        + +

        For full information about the ColReorder options, please refer to the ColReorder options + documentation.

        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NamePositionOfficeAgeStart dateSalary
        NamePositionOfficeAgeStart dateSalary
        Tiger NixonSystem ArchitectEdinburgh612011/04/25$320,800
        Garrett WintersAccountantTokyo632011/07/25$170,750
        Ashton CoxJunior Technical AuthorSan Francisco662009/01/12$86,000
        Cedric KellySenior Javascript DeveloperEdinburgh222012/03/29$433,060
        Airi SatouAccountantTokyo332008/11/28$162,700
        Brielle WilliamsonIntegration SpecialistNew York612012/12/02$372,000
        Herrod ChandlerSales AssistantSan Francisco592012/08/06$137,500
        Rhona DavidsonIntegration SpecialistTokyo552010/10/14$327,900
        Colleen HurstJavascript DeveloperSan Francisco392009/09/15$205,500
        Sonya FrostSoftware EngineerEdinburgh232008/12/13$103,600
        Jena GainesOffice ManagerLondon302008/12/19$90,560
        Quinn FlynnSupport LeadEdinburgh222013/03/03$342,000
        Charde MarshallRegional DirectorSan Francisco362008/10/16$470,600
        Haley KennedySenior Marketing DesignerLondon432012/12/18$313,500
        Tatyana FitzpatrickRegional DirectorLondon192010/03/17$385,750
        Michael SilvaMarketing DesignerLondon662012/11/27$198,500
        Paul ByrdChief Financial Officer (CFO)New York642010/06/09$725,000
        Gloria LittleSystems AdministratorNew York592009/04/10$237,500
        Bradley GreerSoftware EngineerLondon412012/10/13$132,000
        Dai RiosPersonnel LeadEdinburgh352012/09/26$217,500
        Jenette CaldwellDevelopment LeadNew York302011/09/03$345,000
        Yuri BerryChief Marketing Officer (CMO)New York402009/06/25$675,000
        Caesar VancePre-Sales SupportNew York212011/12/12$106,450
        Doris WilderSales AssistantSidney232010/09/20$85,600
        Angelica RamosChief Executive Officer (CEO)London472009/10/09$1,200,000
        Gavin JoyceDeveloperEdinburgh422010/12/22$92,575
        Jennifer ChangRegional DirectorSingapore282010/11/14$357,650
        Brenden WagnerSoftware EngineerSan Francisco282011/06/07$206,850
        Fiona GreenChief Operating Officer (COO)San Francisco482010/03/11$850,000
        Shou ItouRegional MarketingTokyo202011/08/14$163,000
        Michelle HouseIntegration SpecialistSidney372011/06/02$95,400
        Suki BurksDeveloperLondon532009/10/22$114,500
        Prescott BartlettTechnical AuthorLondon272011/05/07$145,000
        Gavin CortezTeam LeaderSan Francisco222008/10/26$235,500
        Martena MccrayPost-Sales supportEdinburgh462011/03/09$324,050
        Unity ButlerMarketing DesignerSan Francisco472009/12/09$85,675
        Howard HatfieldOffice ManagerSan Francisco512008/12/16$164,500
        Hope FuentesSecretarySan Francisco412010/02/12$109,850
        Vivian HarrellFinancial ControllerSan Francisco622009/02/14$452,500
        Timothy MooneyOffice ManagerLondon372008/12/11$136,200
        Jackson BradshawDirectorNew York652008/09/26$645,750
        Olivia LiangSupport EngineerSingapore642011/02/03$234,500
        Bruno NashSoftware EngineerLondon382011/05/03$163,500
        Sakura YamamotoSupport EngineerTokyo372009/08/19$139,575
        Thor WaltonDeveloperNew York612013/08/11$98,540
        Finn CamachoSupport EngineerSan Francisco472009/07/07$87,500
        Serge BaldwinData CoordinatorSingapore642012/04/09$138,575
        Zenaida FrankSoftware EngineerNew York632010/01/04$125,250
        Zorita SerranoSoftware EngineerSan Francisco562012/06/01$115,000
        Jennifer AcostaJunior Javascript DeveloperEdinburgh432013/02/01$75,650
        Cara StevensSales AssistantNew York462011/12/06$145,600
        Hermione ButlerRegional DirectorLondon472011/03/21$356,250
        Lael GreerSystems AdministratorLondon212009/02/27$103,500
        Jonas AlexanderDeveloperSan Francisco302010/07/14$86,500
        Shad DeckerRegional DirectorEdinburgh512008/11/13$183,000
        Michael BruceJavascript DeveloperSingapore292011/06/27$183,000
        Donna SniderCustomer SupportNew York272011/01/25$112,000
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this example:

        $(document).ready(function() { + $('#example').dataTable( { + dom: 'Rlfrtip', + colReorder: { + order: [ 4, 3, 2, 1, 0, 5 ] + } + } ); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The + additional CSS used is shown below:

        +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is + loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side + processing scripts can be written in any language, using the protocol described in the DataTables + documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/ColReorder/examples/realtime.html b/public/assets/plugins/datatables/extensions/ColReorder/examples/realtime.html new file mode 100644 index 00000000..c759409a --- /dev/null +++ b/public/assets/plugins/datatables/extensions/ColReorder/examples/realtime.html @@ -0,0 +1,637 @@ + + + + + + + + ColReorder example - Realtime updating + + + + + + + + + + + + + + +
        +
        +

        ColReorder example Realtime updating

        + +
        +

        While the ColReorder insertion point indicator can be styled, another option to show the end user what the column will look like when the table has been + reordered is to actually do the reordering while the mouse is still dragging the column header. This is shown in this example and is controlled by the + realtime parameter.

        + +

        For full information about the ColReorder options, please refer to the ColReorder options + documentation.

        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NamePositionOfficeAgeStart dateSalary
        NamePositionOfficeAgeStart dateSalary
        Tiger NixonSystem ArchitectEdinburgh612011/04/25$320,800
        Garrett WintersAccountantTokyo632011/07/25$170,750
        Ashton CoxJunior Technical AuthorSan Francisco662009/01/12$86,000
        Cedric KellySenior Javascript DeveloperEdinburgh222012/03/29$433,060
        Airi SatouAccountantTokyo332008/11/28$162,700
        Brielle WilliamsonIntegration SpecialistNew York612012/12/02$372,000
        Herrod ChandlerSales AssistantSan Francisco592012/08/06$137,500
        Rhona DavidsonIntegration SpecialistTokyo552010/10/14$327,900
        Colleen HurstJavascript DeveloperSan Francisco392009/09/15$205,500
        Sonya FrostSoftware EngineerEdinburgh232008/12/13$103,600
        Jena GainesOffice ManagerLondon302008/12/19$90,560
        Quinn FlynnSupport LeadEdinburgh222013/03/03$342,000
        Charde MarshallRegional DirectorSan Francisco362008/10/16$470,600
        Haley KennedySenior Marketing DesignerLondon432012/12/18$313,500
        Tatyana FitzpatrickRegional DirectorLondon192010/03/17$385,750
        Michael SilvaMarketing DesignerLondon662012/11/27$198,500
        Paul ByrdChief Financial Officer (CFO)New York642010/06/09$725,000
        Gloria LittleSystems AdministratorNew York592009/04/10$237,500
        Bradley GreerSoftware EngineerLondon412012/10/13$132,000
        Dai RiosPersonnel LeadEdinburgh352012/09/26$217,500
        Jenette CaldwellDevelopment LeadNew York302011/09/03$345,000
        Yuri BerryChief Marketing Officer (CMO)New York402009/06/25$675,000
        Caesar VancePre-Sales SupportNew York212011/12/12$106,450
        Doris WilderSales AssistantSidney232010/09/20$85,600
        Angelica RamosChief Executive Officer (CEO)London472009/10/09$1,200,000
        Gavin JoyceDeveloperEdinburgh422010/12/22$92,575
        Jennifer ChangRegional DirectorSingapore282010/11/14$357,650
        Brenden WagnerSoftware EngineerSan Francisco282011/06/07$206,850
        Fiona GreenChief Operating Officer (COO)San Francisco482010/03/11$850,000
        Shou ItouRegional MarketingTokyo202011/08/14$163,000
        Michelle HouseIntegration SpecialistSidney372011/06/02$95,400
        Suki BurksDeveloperLondon532009/10/22$114,500
        Prescott BartlettTechnical AuthorLondon272011/05/07$145,000
        Gavin CortezTeam LeaderSan Francisco222008/10/26$235,500
        Martena MccrayPost-Sales supportEdinburgh462011/03/09$324,050
        Unity ButlerMarketing DesignerSan Francisco472009/12/09$85,675
        Howard HatfieldOffice ManagerSan Francisco512008/12/16$164,500
        Hope FuentesSecretarySan Francisco412010/02/12$109,850
        Vivian HarrellFinancial ControllerSan Francisco622009/02/14$452,500
        Timothy MooneyOffice ManagerLondon372008/12/11$136,200
        Jackson BradshawDirectorNew York652008/09/26$645,750
        Olivia LiangSupport EngineerSingapore642011/02/03$234,500
        Bruno NashSoftware EngineerLondon382011/05/03$163,500
        Sakura YamamotoSupport EngineerTokyo372009/08/19$139,575
        Thor WaltonDeveloperNew York612013/08/11$98,540
        Finn CamachoSupport EngineerSan Francisco472009/07/07$87,500
        Serge BaldwinData CoordinatorSingapore642012/04/09$138,575
        Zenaida FrankSoftware EngineerNew York632010/01/04$125,250
        Zorita SerranoSoftware EngineerSan Francisco562012/06/01$115,000
        Jennifer AcostaJunior Javascript DeveloperEdinburgh432013/02/01$75,650
        Cara StevensSales AssistantNew York462011/12/06$145,600
        Hermione ButlerRegional DirectorLondon472011/03/21$356,250
        Lael GreerSystems AdministratorLondon212009/02/27$103,500
        Jonas AlexanderDeveloperSan Francisco302010/07/14$86,500
        Shad DeckerRegional DirectorEdinburgh512008/11/13$183,000
        Michael BruceJavascript DeveloperSingapore292011/06/27$183,000
        Donna SniderCustomer SupportNew York272011/01/25$112,000
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this example:

        $(document).ready(function() { + $('#example').dataTable( { + dom: 'Rlfrtip', + colReorder: { + realtime: true + } + } ); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The + additional CSS used is shown below:

        +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is + loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side + processing scripts can be written in any language, using the protocol described in the DataTables + documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/ColReorder/examples/reset.html b/public/assets/plugins/datatables/extensions/ColReorder/examples/reset.html new file mode 100644 index 00000000..b2e1fc08 --- /dev/null +++ b/public/assets/plugins/datatables/extensions/ColReorder/examples/reset.html @@ -0,0 +1,649 @@ + + + + + + + + ColReorder example - Reset ordering API + + + + + + + + + + + + + + +
        +
        +

        ColReorder example Reset ordering API

        + +
        +

        One useful control option to present the end user when using ColReorder is the ability to reset the column ordering to that which was found in the HTML. This + can be done by calling the reset API function. While ColReorder does not provide a visual element for this itself (in order to provide maximum + flexibility) it is easy to hook to an event handler, as shown in this example.

        + +

        For full information about the ColReorder API, please refer to the ColReorder API documentation.

        +

        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NamePositionOfficeAgeStart dateSalary
        NamePositionOfficeAgeStart dateSalary
        Tiger NixonSystem ArchitectEdinburgh612011/04/25$320,800
        Garrett WintersAccountantTokyo632011/07/25$170,750
        Ashton CoxJunior Technical AuthorSan Francisco662009/01/12$86,000
        Cedric KellySenior Javascript DeveloperEdinburgh222012/03/29$433,060
        Airi SatouAccountantTokyo332008/11/28$162,700
        Brielle WilliamsonIntegration SpecialistNew York612012/12/02$372,000
        Herrod ChandlerSales AssistantSan Francisco592012/08/06$137,500
        Rhona DavidsonIntegration SpecialistTokyo552010/10/14$327,900
        Colleen HurstJavascript DeveloperSan Francisco392009/09/15$205,500
        Sonya FrostSoftware EngineerEdinburgh232008/12/13$103,600
        Jena GainesOffice ManagerLondon302008/12/19$90,560
        Quinn FlynnSupport LeadEdinburgh222013/03/03$342,000
        Charde MarshallRegional DirectorSan Francisco362008/10/16$470,600
        Haley KennedySenior Marketing DesignerLondon432012/12/18$313,500
        Tatyana FitzpatrickRegional DirectorLondon192010/03/17$385,750
        Michael SilvaMarketing DesignerLondon662012/11/27$198,500
        Paul ByrdChief Financial Officer (CFO)New York642010/06/09$725,000
        Gloria LittleSystems AdministratorNew York592009/04/10$237,500
        Bradley GreerSoftware EngineerLondon412012/10/13$132,000
        Dai RiosPersonnel LeadEdinburgh352012/09/26$217,500
        Jenette CaldwellDevelopment LeadNew York302011/09/03$345,000
        Yuri BerryChief Marketing Officer (CMO)New York402009/06/25$675,000
        Caesar VancePre-Sales SupportNew York212011/12/12$106,450
        Doris WilderSales AssistantSidney232010/09/20$85,600
        Angelica RamosChief Executive Officer (CEO)London472009/10/09$1,200,000
        Gavin JoyceDeveloperEdinburgh422010/12/22$92,575
        Jennifer ChangRegional DirectorSingapore282010/11/14$357,650
        Brenden WagnerSoftware EngineerSan Francisco282011/06/07$206,850
        Fiona GreenChief Operating Officer (COO)San Francisco482010/03/11$850,000
        Shou ItouRegional MarketingTokyo202011/08/14$163,000
        Michelle HouseIntegration SpecialistSidney372011/06/02$95,400
        Suki BurksDeveloperLondon532009/10/22$114,500
        Prescott BartlettTechnical AuthorLondon272011/05/07$145,000
        Gavin CortezTeam LeaderSan Francisco222008/10/26$235,500
        Martena MccrayPost-Sales supportEdinburgh462011/03/09$324,050
        Unity ButlerMarketing DesignerSan Francisco472009/12/09$85,675
        Howard HatfieldOffice ManagerSan Francisco512008/12/16$164,500
        Hope FuentesSecretarySan Francisco412010/02/12$109,850
        Vivian HarrellFinancial ControllerSan Francisco622009/02/14$452,500
        Timothy MooneyOffice ManagerLondon372008/12/11$136,200
        Jackson BradshawDirectorNew York652008/09/26$645,750
        Olivia LiangSupport EngineerSingapore642011/02/03$234,500
        Bruno NashSoftware EngineerLondon382011/05/03$163,500
        Sakura YamamotoSupport EngineerTokyo372009/08/19$139,575
        Thor WaltonDeveloperNew York612013/08/11$98,540
        Finn CamachoSupport EngineerSan Francisco472009/07/07$87,500
        Serge BaldwinData CoordinatorSingapore642012/04/09$138,575
        Zenaida FrankSoftware EngineerNew York632010/01/04$125,250
        Zorita SerranoSoftware EngineerSan Francisco562012/06/01$115,000
        Jennifer AcostaJunior Javascript DeveloperEdinburgh432013/02/01$75,650
        Cara StevensSales AssistantNew York462011/12/06$145,600
        Hermione ButlerRegional DirectorLondon472011/03/21$356,250
        Lael GreerSystems AdministratorLondon212009/02/27$103,500
        Jonas AlexanderDeveloperSan Francisco302010/07/14$86,500
        Shad DeckerRegional DirectorEdinburgh512008/11/13$183,000
        Michael BruceJavascript DeveloperSingapore292011/06/27$183,000
        Donna SniderCustomer SupportNew York272011/01/25$112,000
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this example:

        $(document).ready(function() { + var table = $('#example').DataTable( { + dom: 'Rlfrtip', + colReorder: { + order: [ 4, 3, 2, 1, 0 ] + } + } ); + + $('#reset').click( function (e) { + e.preventDefault(); + + table.colReorder.reset(); + } ); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The + additional CSS used is shown below:

        +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is + loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side + processing scripts can be written in any language, using the protocol described in the DataTables + documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/ColReorder/examples/scrolling.html b/public/assets/plugins/datatables/extensions/ColReorder/examples/scrolling.html new file mode 100644 index 00000000..860e6655 --- /dev/null +++ b/public/assets/plugins/datatables/extensions/ColReorder/examples/scrolling.html @@ -0,0 +1,632 @@ + + + + + + + + ColReorder example - Scrolling table + + + + + + + + + + + + + + +
        +
        +

        ColReorder example Scrolling table

        + +
        +

        This is a simple example to show ColReorder working with DataTables scrolling (scrollYDT and scrollXDT).

        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NamePositionOfficeAgeStart dateSalary
        NamePositionOfficeAgeStart dateSalary
        Tiger NixonSystem ArchitectEdinburgh612011/04/25$320,800
        Garrett WintersAccountantTokyo632011/07/25$170,750
        Ashton CoxJunior Technical AuthorSan Francisco662009/01/12$86,000
        Cedric KellySenior Javascript DeveloperEdinburgh222012/03/29$433,060
        Airi SatouAccountantTokyo332008/11/28$162,700
        Brielle WilliamsonIntegration SpecialistNew York612012/12/02$372,000
        Herrod ChandlerSales AssistantSan Francisco592012/08/06$137,500
        Rhona DavidsonIntegration SpecialistTokyo552010/10/14$327,900
        Colleen HurstJavascript DeveloperSan Francisco392009/09/15$205,500
        Sonya FrostSoftware EngineerEdinburgh232008/12/13$103,600
        Jena GainesOffice ManagerLondon302008/12/19$90,560
        Quinn FlynnSupport LeadEdinburgh222013/03/03$342,000
        Charde MarshallRegional DirectorSan Francisco362008/10/16$470,600
        Haley KennedySenior Marketing DesignerLondon432012/12/18$313,500
        Tatyana FitzpatrickRegional DirectorLondon192010/03/17$385,750
        Michael SilvaMarketing DesignerLondon662012/11/27$198,500
        Paul ByrdChief Financial Officer (CFO)New York642010/06/09$725,000
        Gloria LittleSystems AdministratorNew York592009/04/10$237,500
        Bradley GreerSoftware EngineerLondon412012/10/13$132,000
        Dai RiosPersonnel LeadEdinburgh352012/09/26$217,500
        Jenette CaldwellDevelopment LeadNew York302011/09/03$345,000
        Yuri BerryChief Marketing Officer (CMO)New York402009/06/25$675,000
        Caesar VancePre-Sales SupportNew York212011/12/12$106,450
        Doris WilderSales AssistantSidney232010/09/20$85,600
        Angelica RamosChief Executive Officer (CEO)London472009/10/09$1,200,000
        Gavin JoyceDeveloperEdinburgh422010/12/22$92,575
        Jennifer ChangRegional DirectorSingapore282010/11/14$357,650
        Brenden WagnerSoftware EngineerSan Francisco282011/06/07$206,850
        Fiona GreenChief Operating Officer (COO)San Francisco482010/03/11$850,000
        Shou ItouRegional MarketingTokyo202011/08/14$163,000
        Michelle HouseIntegration SpecialistSidney372011/06/02$95,400
        Suki BurksDeveloperLondon532009/10/22$114,500
        Prescott BartlettTechnical AuthorLondon272011/05/07$145,000
        Gavin CortezTeam LeaderSan Francisco222008/10/26$235,500
        Martena MccrayPost-Sales supportEdinburgh462011/03/09$324,050
        Unity ButlerMarketing DesignerSan Francisco472009/12/09$85,675
        Howard HatfieldOffice ManagerSan Francisco512008/12/16$164,500
        Hope FuentesSecretarySan Francisco412010/02/12$109,850
        Vivian HarrellFinancial ControllerSan Francisco622009/02/14$452,500
        Timothy MooneyOffice ManagerLondon372008/12/11$136,200
        Jackson BradshawDirectorNew York652008/09/26$645,750
        Olivia LiangSupport EngineerSingapore642011/02/03$234,500
        Bruno NashSoftware EngineerLondon382011/05/03$163,500
        Sakura YamamotoSupport EngineerTokyo372009/08/19$139,575
        Thor WaltonDeveloperNew York612013/08/11$98,540
        Finn CamachoSupport EngineerSan Francisco472009/07/07$87,500
        Serge BaldwinData CoordinatorSingapore642012/04/09$138,575
        Zenaida FrankSoftware EngineerNew York632010/01/04$125,250
        Zorita SerranoSoftware EngineerSan Francisco562012/06/01$115,000
        Jennifer AcostaJunior Javascript DeveloperEdinburgh432013/02/01$75,650
        Cara StevensSales AssistantNew York462011/12/06$145,600
        Hermione ButlerRegional DirectorLondon472011/03/21$356,250
        Lael GreerSystems AdministratorLondon212009/02/27$103,500
        Jonas AlexanderDeveloperSan Francisco302010/07/14$86,500
        Shad DeckerRegional DirectorEdinburgh512008/11/13$183,000
        Michael BruceJavascript DeveloperSingapore292011/06/27$183,000
        Donna SniderCustomer SupportNew York272011/01/25$112,000
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this example:

        $(document).ready(function() { + $('#example').dataTable( { + dom: 'Rlfrtip', + scrollY: '200px', + paging: false + } ); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The + additional CSS used is shown below:

        +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is + loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side + processing scripts can be written in any language, using the protocol described in the DataTables + documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/ColReorder/examples/server_side.html b/public/assets/plugins/datatables/extensions/ColReorder/examples/server_side.html new file mode 100644 index 00000000..f682b7ab --- /dev/null +++ b/public/assets/plugins/datatables/extensions/ColReorder/examples/server_side.html @@ -0,0 +1,192 @@ + + + + + + + + ColReorder example - Server-side processing + + + + + + + + + + + + + + +
        +
        +

        ColReorder example Server-side processing

        + +
        +

        Server-side processing can be exceptionally useful in DataTables when dealing with massive data sets, and ColReorder works with this as would be expected.

        + +

        It is recommend that you use object based data with server-side processing and ColReorder, as this provides easily understandable mapping between the the + columns and the data relation on the server, otherwise you need to work out array indexes on each call!

        +
        + + + + + + + + + + + + + + + + + + + + + + + +
        NamePositionOfficeExtn.Start dateSalary
        NamePositionOfficeExtn.Start dateSalary
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this example:

        $(document).ready(function() { + $('#example').dataTable( { + dom: 'Rlfrtip', + processing: true, + serverSide: true, + ajax: "../../../examples/server_side/scripts/objects.php", + columns: [ + { data: "first_name" }, + { data: "last_name" }, + { data: "position" }, + { data: "office" }, + { data: "start_date" }, + { data: "salary" } + ] + } ); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The + additional CSS used is shown below:

        +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is + loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side + processing scripts can be written in any language, using the protocol described in the DataTables + documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/ColReorder/examples/simple.html b/public/assets/plugins/datatables/extensions/ColReorder/examples/simple.html new file mode 100644 index 00000000..92cffee7 --- /dev/null +++ b/public/assets/plugins/datatables/extensions/ColReorder/examples/simple.html @@ -0,0 +1,630 @@ + + + + + + + + ColReorder example - Basic initialisation + + + + + + + + + + + + + + +
        +
        +

        ColReorder example Basic initialisation

        + +
        +

        This example shows the basic use case of the ColReorder plug-in. With ColReorder enabled for a table, the user has the ability to click and drag any table + header cell, and drop it where they wish the column to be inserted. The insert point is shown visually, and the column reordering is done as soon as the mouse + button is released.

        + +

        ColReorder is added to a DataTable through the R character that it adds to DataTables feature plug-ins. This means that you simply add the + character R to the domDT parameter for your table to add ColReorder - as shown in the example below.

        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NamePositionOfficeAgeStart dateSalary
        NamePositionOfficeAgeStart dateSalary
        Tiger NixonSystem ArchitectEdinburgh612011/04/25$320,800
        Garrett WintersAccountantTokyo632011/07/25$170,750
        Ashton CoxJunior Technical AuthorSan Francisco662009/01/12$86,000
        Cedric KellySenior Javascript DeveloperEdinburgh222012/03/29$433,060
        Airi SatouAccountantTokyo332008/11/28$162,700
        Brielle WilliamsonIntegration SpecialistNew York612012/12/02$372,000
        Herrod ChandlerSales AssistantSan Francisco592012/08/06$137,500
        Rhona DavidsonIntegration SpecialistTokyo552010/10/14$327,900
        Colleen HurstJavascript DeveloperSan Francisco392009/09/15$205,500
        Sonya FrostSoftware EngineerEdinburgh232008/12/13$103,600
        Jena GainesOffice ManagerLondon302008/12/19$90,560
        Quinn FlynnSupport LeadEdinburgh222013/03/03$342,000
        Charde MarshallRegional DirectorSan Francisco362008/10/16$470,600
        Haley KennedySenior Marketing DesignerLondon432012/12/18$313,500
        Tatyana FitzpatrickRegional DirectorLondon192010/03/17$385,750
        Michael SilvaMarketing DesignerLondon662012/11/27$198,500
        Paul ByrdChief Financial Officer (CFO)New York642010/06/09$725,000
        Gloria LittleSystems AdministratorNew York592009/04/10$237,500
        Bradley GreerSoftware EngineerLondon412012/10/13$132,000
        Dai RiosPersonnel LeadEdinburgh352012/09/26$217,500
        Jenette CaldwellDevelopment LeadNew York302011/09/03$345,000
        Yuri BerryChief Marketing Officer (CMO)New York402009/06/25$675,000
        Caesar VancePre-Sales SupportNew York212011/12/12$106,450
        Doris WilderSales AssistantSidney232010/09/20$85,600
        Angelica RamosChief Executive Officer (CEO)London472009/10/09$1,200,000
        Gavin JoyceDeveloperEdinburgh422010/12/22$92,575
        Jennifer ChangRegional DirectorSingapore282010/11/14$357,650
        Brenden WagnerSoftware EngineerSan Francisco282011/06/07$206,850
        Fiona GreenChief Operating Officer (COO)San Francisco482010/03/11$850,000
        Shou ItouRegional MarketingTokyo202011/08/14$163,000
        Michelle HouseIntegration SpecialistSidney372011/06/02$95,400
        Suki BurksDeveloperLondon532009/10/22$114,500
        Prescott BartlettTechnical AuthorLondon272011/05/07$145,000
        Gavin CortezTeam LeaderSan Francisco222008/10/26$235,500
        Martena MccrayPost-Sales supportEdinburgh462011/03/09$324,050
        Unity ButlerMarketing DesignerSan Francisco472009/12/09$85,675
        Howard HatfieldOffice ManagerSan Francisco512008/12/16$164,500
        Hope FuentesSecretarySan Francisco412010/02/12$109,850
        Vivian HarrellFinancial ControllerSan Francisco622009/02/14$452,500
        Timothy MooneyOffice ManagerLondon372008/12/11$136,200
        Jackson BradshawDirectorNew York652008/09/26$645,750
        Olivia LiangSupport EngineerSingapore642011/02/03$234,500
        Bruno NashSoftware EngineerLondon382011/05/03$163,500
        Sakura YamamotoSupport EngineerTokyo372009/08/19$139,575
        Thor WaltonDeveloperNew York612013/08/11$98,540
        Finn CamachoSupport EngineerSan Francisco472009/07/07$87,500
        Serge BaldwinData CoordinatorSingapore642012/04/09$138,575
        Zenaida FrankSoftware EngineerNew York632010/01/04$125,250
        Zorita SerranoSoftware EngineerSan Francisco562012/06/01$115,000
        Jennifer AcostaJunior Javascript DeveloperEdinburgh432013/02/01$75,650
        Cara StevensSales AssistantNew York462011/12/06$145,600
        Hermione ButlerRegional DirectorLondon472011/03/21$356,250
        Lael GreerSystems AdministratorLondon212009/02/27$103,500
        Jonas AlexanderDeveloperSan Francisco302010/07/14$86,500
        Shad DeckerRegional DirectorEdinburgh512008/11/13$183,000
        Michael BruceJavascript DeveloperSingapore292011/06/27$183,000
        Donna SniderCustomer SupportNew York272011/01/25$112,000
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this example:

        $(document).ready(function() { + $('#example').DataTable( { + dom: 'Rlfrtip' + } ); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The + additional CSS used is shown below:

        +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is + loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side + processing scripts can be written in any language, using the protocol described in the DataTables + documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/ColReorder/examples/state_save.html b/public/assets/plugins/datatables/extensions/ColReorder/examples/state_save.html new file mode 100644 index 00000000..6e4e2e9e --- /dev/null +++ b/public/assets/plugins/datatables/extensions/ColReorder/examples/state_save.html @@ -0,0 +1,631 @@ + + + + + + + + ColReorder example - State saving + + + + + + + + + + + + + + +
        +
        +

        ColReorder example State saving

        + +
        +

        A useful interaction pattern to use in DataTables is state saving, so when the end user reloads or revisits a page its previous state is retained. ColReorder + works seamlessly with state saving in DataTables (stateSaveDT), remembering and restoring the column positions, as well as everything else such as sorting + and filtering.

        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NamePositionOfficeAgeStart dateSalary
        NamePositionOfficeAgeStart dateSalary
        Tiger NixonSystem ArchitectEdinburgh612011/04/25$320,800
        Garrett WintersAccountantTokyo632011/07/25$170,750
        Ashton CoxJunior Technical AuthorSan Francisco662009/01/12$86,000
        Cedric KellySenior Javascript DeveloperEdinburgh222012/03/29$433,060
        Airi SatouAccountantTokyo332008/11/28$162,700
        Brielle WilliamsonIntegration SpecialistNew York612012/12/02$372,000
        Herrod ChandlerSales AssistantSan Francisco592012/08/06$137,500
        Rhona DavidsonIntegration SpecialistTokyo552010/10/14$327,900
        Colleen HurstJavascript DeveloperSan Francisco392009/09/15$205,500
        Sonya FrostSoftware EngineerEdinburgh232008/12/13$103,600
        Jena GainesOffice ManagerLondon302008/12/19$90,560
        Quinn FlynnSupport LeadEdinburgh222013/03/03$342,000
        Charde MarshallRegional DirectorSan Francisco362008/10/16$470,600
        Haley KennedySenior Marketing DesignerLondon432012/12/18$313,500
        Tatyana FitzpatrickRegional DirectorLondon192010/03/17$385,750
        Michael SilvaMarketing DesignerLondon662012/11/27$198,500
        Paul ByrdChief Financial Officer (CFO)New York642010/06/09$725,000
        Gloria LittleSystems AdministratorNew York592009/04/10$237,500
        Bradley GreerSoftware EngineerLondon412012/10/13$132,000
        Dai RiosPersonnel LeadEdinburgh352012/09/26$217,500
        Jenette CaldwellDevelopment LeadNew York302011/09/03$345,000
        Yuri BerryChief Marketing Officer (CMO)New York402009/06/25$675,000
        Caesar VancePre-Sales SupportNew York212011/12/12$106,450
        Doris WilderSales AssistantSidney232010/09/20$85,600
        Angelica RamosChief Executive Officer (CEO)London472009/10/09$1,200,000
        Gavin JoyceDeveloperEdinburgh422010/12/22$92,575
        Jennifer ChangRegional DirectorSingapore282010/11/14$357,650
        Brenden WagnerSoftware EngineerSan Francisco282011/06/07$206,850
        Fiona GreenChief Operating Officer (COO)San Francisco482010/03/11$850,000
        Shou ItouRegional MarketingTokyo202011/08/14$163,000
        Michelle HouseIntegration SpecialistSidney372011/06/02$95,400
        Suki BurksDeveloperLondon532009/10/22$114,500
        Prescott BartlettTechnical AuthorLondon272011/05/07$145,000
        Gavin CortezTeam LeaderSan Francisco222008/10/26$235,500
        Martena MccrayPost-Sales supportEdinburgh462011/03/09$324,050
        Unity ButlerMarketing DesignerSan Francisco472009/12/09$85,675
        Howard HatfieldOffice ManagerSan Francisco512008/12/16$164,500
        Hope FuentesSecretarySan Francisco412010/02/12$109,850
        Vivian HarrellFinancial ControllerSan Francisco622009/02/14$452,500
        Timothy MooneyOffice ManagerLondon372008/12/11$136,200
        Jackson BradshawDirectorNew York652008/09/26$645,750
        Olivia LiangSupport EngineerSingapore642011/02/03$234,500
        Bruno NashSoftware EngineerLondon382011/05/03$163,500
        Sakura YamamotoSupport EngineerTokyo372009/08/19$139,575
        Thor WaltonDeveloperNew York612013/08/11$98,540
        Finn CamachoSupport EngineerSan Francisco472009/07/07$87,500
        Serge BaldwinData CoordinatorSingapore642012/04/09$138,575
        Zenaida FrankSoftware EngineerNew York632010/01/04$125,250
        Zorita SerranoSoftware EngineerSan Francisco562012/06/01$115,000
        Jennifer AcostaJunior Javascript DeveloperEdinburgh432013/02/01$75,650
        Cara StevensSales AssistantNew York462011/12/06$145,600
        Hermione ButlerRegional DirectorLondon472011/03/21$356,250
        Lael GreerSystems AdministratorLondon212009/02/27$103,500
        Jonas AlexanderDeveloperSan Francisco302010/07/14$86,500
        Shad DeckerRegional DirectorEdinburgh512008/11/13$183,000
        Michael BruceJavascript DeveloperSingapore292011/06/27$183,000
        Donna SniderCustomer SupportNew York272011/01/25$112,000
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this example:

        $(document).ready(function() { + $('#example').dataTable( { + dom: 'Rlfrtip', + stateSave: true + } ); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The + additional CSS used is shown below:

        +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is + loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side + processing scripts can be written in any language, using the protocol described in the DataTables + documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/ColReorder/images/insert.png b/public/assets/plugins/datatables/extensions/ColReorder/images/insert.png new file mode 100644 index 00000000..15d5522d Binary files /dev/null and b/public/assets/plugins/datatables/extensions/ColReorder/images/insert.png differ diff --git a/public/assets/plugins/datatables/extensions/ColReorder/js/dataTables.colReorder.js b/public/assets/plugins/datatables/extensions/ColReorder/js/dataTables.colReorder.js new file mode 100644 index 00000000..c3b2f1e2 --- /dev/null +++ b/public/assets/plugins/datatables/extensions/ColReorder/js/dataTables.colReorder.js @@ -0,0 +1,1372 @@ +/*! ColReorder 1.1.3 + * ©2010-2014 SpryMedia Ltd - datatables.net/license + */ + +/** + * @summary ColReorder + * @description Provide the ability to reorder columns in a DataTable + * @version 1.1.3 + * @file dataTables.colReorder.js + * @author SpryMedia Ltd (www.sprymedia.co.uk) + * @contact www.sprymedia.co.uk/contact + * @copyright Copyright 2010-2014 SpryMedia Ltd. + * + * This source file is free software, available under the following license: + * MIT license - http://datatables.net/license/mit + * + * This source file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. + * + * For details please refer to: http://www.datatables.net + */ + +(function(window, document, undefined) { + + +/** + * Switch the key value pairing of an index array to be value key (i.e. the old value is now the + * key). For example consider [ 2, 0, 1 ] this would be returned as [ 1, 2, 0 ]. + * @method fnInvertKeyValues + * @param array aIn Array to switch around + * @returns array + */ +function fnInvertKeyValues( aIn ) +{ + var aRet=[]; + for ( var i=0, iLen=aIn.length ; i= iCols ) + { + this.oApi._fnLog( oSettings, 1, "ColReorder 'from' index is out of bounds: "+iFrom ); + return; + } + + if ( iTo < 0 || iTo >= iCols ) + { + this.oApi._fnLog( oSettings, 1, "ColReorder 'to' index is out of bounds: "+iTo ); + return; + } + + /* + * Calculate the new column array index, so we have a mapping between the old and new + */ + var aiMapping = []; + for ( i=0, iLen=iCols ; i this.s.fixed-1 && i < iLen - this.s.fixedRight ) + { + this._fnMouseListener( i, this.s.dt.aoColumns[i].nTh ); + } + + /* Mark the original column order for later reference */ + this.s.dt.aoColumns[i]._ColReorder_iOrigCol = i; + } + + /* State saving */ + this.s.dt.oApi._fnCallbackReg( this.s.dt, 'aoStateSaveParams', function (oS, oData) { + that._fnStateSave.call( that, oData ); + }, "ColReorder_State" ); + + /* An initial column order has been specified */ + var aiOrder = null; + if ( this.s.init.aiOrder ) + { + aiOrder = this.s.init.aiOrder.slice(); + } + + /* State loading, overrides the column order given */ + if ( this.s.dt.oLoadedState && typeof this.s.dt.oLoadedState.ColReorder != 'undefined' && + this.s.dt.oLoadedState.ColReorder.length == this.s.dt.aoColumns.length ) + { + aiOrder = this.s.dt.oLoadedState.ColReorder; + } + + /* If we have an order to apply - do so */ + if ( aiOrder ) + { + /* We might be called during or after the DataTables initialisation. If before, then we need + * to wait until the draw is done, if after, then do what we need to do right away + */ + if ( !that.s.dt._bInitComplete ) + { + var bDone = false; + this.s.dt.aoDrawCallback.push( { + "fn": function () { + if ( !that.s.dt._bInitComplete && !bDone ) + { + bDone = true; + var resort = fnInvertKeyValues( aiOrder ); + that._fnOrderColumns.call( that, resort ); + } + }, + "sName": "ColReorder_Pre" + } ); + } + else + { + var resort = fnInvertKeyValues( aiOrder ); + that._fnOrderColumns.call( that, resort ); + } + } + else { + this._fnSetColumnIndexes(); + } + }, + + + /** + * Set the column order from an array + * @method _fnOrderColumns + * @param array a An array of integers which dictate the column order that should be applied + * @returns void + * @private + */ + "_fnOrderColumns": function ( a ) + { + if ( a.length != this.s.dt.aoColumns.length ) + { + this.s.dt.oInstance.oApi._fnLog( this.s.dt, 1, "ColReorder - array reorder does not "+ + "match known number of columns. Skipping." ); + return; + } + + for ( var i=0, iLen=a.length ; i
        ') + .addClass( 'DTCR_pointer' ) + .css( { + position: 'absolute', + top: scrolling ? + $('div.dataTables_scroll', this.s.dt.nTableWrapper).offset().top : + $(this.s.dt.nTable).offset().top, + height : scrolling ? + $('div.dataTables_scroll', this.s.dt.nTableWrapper).height() : + $(this.s.dt.nTable).height() + } ) + .appendTo( 'body' ); + }, + + /** + * Clean up ColReorder memory references and event handlers + * @method _fnDestroy + * @returns void + * @private + */ + "_fnDestroy": function () + { + var i, iLen; + + for ( i=0, iLen=this.s.dt.aoDrawCallback.length ; ib||b>=n)this.oApi._fnLog(a,1,"ColReorder 'from' index is out of bounds: "+b);else if(0>e||e>=n)this.oApi._fnLog(a,1,"ColReorder 'to' index is out of bounds: "+e);else{f=[];c=0;for(g=n;cthis.s.fixed-1&&eMath.pow(Math.pow(a.pageX-this.s.mouse.startX,2)+Math.pow(a.pageY-this.s.mouse.startY,2),0.5))return;this._fnCreateDragNode()}this.dom.drag.css({left:a.pageX-this.s.mouse.offsetX,top:a.pageY-this.s.mouse.offsetY});for(var b=!1,e=this.s.mouse.toIndex,d=1,c=this.s.aoTargets.length;d
        ").addClass("DTCR_pointer").css({position:"absolute",top:a?d("div.dataTables_scroll",this.s.dt.nTableWrapper).offset().top:d(this.s.dt.nTable).offset().top,height:a?d("div.dataTables_scroll",this.s.dt.nTableWrapper).height(): +d(this.s.dt.nTable).height()}).appendTo("body")},_fnDestroy:function(){var a,b;a=0;for(b=this.s.dt.aoDrawCallback.length;a
        ')[0], +g=c.childNodes[0],f=c.childNodes[1];this.dom.grid.dt.parentNode.insertBefore(c,this.dom.grid.dt);c.appendChild(this.dom.grid.dt);this.dom.grid.wrapper=c;0b.clientWidth&&(c.x=!0);a.offsetHeight>b.clientHeight&&(c.y=!0);return c},_fnDraw:function(a){this._fnGridLayout();this._fnCloneLeft(a);this._fnCloneRight(a);null!==this.s.fnDrawCallback&&this.s.fnDrawCallback.call(this,this.dom.clone.left,this.dom.clone.right);d(this).trigger("draw.dtfc",{leftClone:this.dom.clone.left,rightClone:this.dom.clone.right})},_fnCloneRight:function(a){if(!(0>= +this.s.iRightColumns)){var b,c=[];for(b=this.s.iTableColumns-this.s.iRightColumns;b=this.s.iLeftColumns)){var b,c=[];for(b=0;bthead",a.header);k.empty();e=0;for(h=n.length;ethead",a.header)[0]);e=0;for(h=n.length;etbody>tr",f.dom.body).css("height","auto");null!==a.body&&(a.body.parentNode.removeChild(a.body),a.body=null);a.body=d(this.dom.body).clone(!0)[0];a.body.className+=" DTFC_Cloned";a.body.style.paddingBottom=l.oScroll.iBarWidth+"px";a.body.style.marginBottom=2*l.oScroll.iBarWidth+"px";null!==a.body.getAttribute("id")&&a.body.removeAttribute("id");d(">thead>tr",a.body).empty();d(">tfoot", +a.body).remove();var p=d("tbody",a.body)[0];d(p).empty();if(0thead>tr",a.body)[0];for(o=0;otbody>tr",f.dom.body).each(function(a){var b=this.cloneNode(false);b.removeAttribute("id");a=f.s.dt.aoData[f.s.dt.oFeatures.bServerSide===false?f.s.dt.aiDisplay[f.s.dt._iDisplayStart+ +a]:a].anCells||d(this).children("td, th");for(o=0;o0){m=d(a[j]).clone(true,true)[0];b.appendChild(m)}}p.appendChild(b)})}else d(">tbody>tr",f.dom.body).each(function(){m=this.cloneNode(true);m.className=m.className+" DTFC_NoData";d("td",m).html("");p.appendChild(m)});a.body.style.width="100%";a.body.style.margin="0";a.body.style.padding="0";l.oScroller!==t&&(h=l.oScroller.dom.force,b.forcer?b.forcer.style.height=h.style.height:(b.forcer=h.cloneNode(!0),b.liner.appendChild(b.forcer))); +b.liner.appendChild(a.body);this._fnEqualiseHeights("tbody",f.dom.body,a.body);if(null!==l.nTFoot){if(g){null!==a.footer&&a.footer.parentNode.removeChild(a.footer);a.footer=d(this.dom.footer).clone(!0,!0)[0];a.footer.className+=" DTFC_Cloned";a.footer.style.width="100%";b.foot.appendChild(a.footer);n=this._fnCopyLayout(l.aoFooter,c);b=d(">tfoot",a.footer);b.empty();e=0;for(h=n.length;etfoot",a.footer)[0]);e=0;for(h=n.length;ethead",a.header)[0]);d(b).each(function(a){j=c[a];this.style.width=f.s.aiInnerWidths[j]+"px"});null!==f.s.dt.nTFoot&&(b=l.oApi._fnGetUniqueThs(l,d(">tfoot",a.footer)[0]),d(b).each(function(a){j=c[a];this.style.width=f.s.aiInnerWidths[j]+"px"}))},_fnGetTrNodes:function(a){for(var b= +[],c=0,d=a.childNodes.length;c"+a+">tr:eq(0)",b).children(":first");a.outerHeight();a.height();for(var e=this._fnGetTrNodes(e),b=this._fnGetTrNodes(c),h=[],c=0,a=b.length;cg?f:g,"semiauto"==this.s.sHeightMatch&& +(e[c]._DTTC_iHeight=g),h.push(g);c=0;for(a=b.length;c + + + + + + + FixedHeader example - Header and footer fixed + + + + + + + + + + + + + + +
        +
        +

        FixedHeader example Header and footer fixed

        + +
        +

        FixedHeader provides the ability to fix in place the header, footer, left and right columns of the + table. These are controlled by the options:

        + +
          +
        • top - default true
        • +
        • bottom - default false
        • +
        • left - default false
        • +
        • right - default false
        • +
        + +

        This example shows the header and footer of the table fixed by enabling the bottom + option.

        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NamePositionOfficeAgeStart dateSalary
        NamePositionOfficeAgeStart dateSalary
        Tiger NixonSystem ArchitectEdinburgh612011/04/25$320,800
        Garrett WintersAccountantTokyo632011/07/25$170,750
        Ashton CoxJunior Technical AuthorSan Francisco662009/01/12$86,000
        Cedric KellySenior Javascript DeveloperEdinburgh222012/03/29$433,060
        Airi SatouAccountantTokyo332008/11/28$162,700
        Brielle WilliamsonIntegration SpecialistNew York612012/12/02$372,000
        Herrod ChandlerSales AssistantSan Francisco592012/08/06$137,500
        Rhona DavidsonIntegration SpecialistTokyo552010/10/14$327,900
        Colleen HurstJavascript DeveloperSan Francisco392009/09/15$205,500
        Sonya FrostSoftware EngineerEdinburgh232008/12/13$103,600
        Jena GainesOffice ManagerLondon302008/12/19$90,560
        Quinn FlynnSupport LeadEdinburgh222013/03/03$342,000
        Charde MarshallRegional DirectorSan Francisco362008/10/16$470,600
        Haley KennedySenior Marketing DesignerLondon432012/12/18$313,500
        Tatyana FitzpatrickRegional DirectorLondon192010/03/17$385,750
        Michael SilvaMarketing DesignerLondon662012/11/27$198,500
        Paul ByrdChief Financial Officer (CFO)New York642010/06/09$725,000
        Gloria LittleSystems AdministratorNew York592009/04/10$237,500
        Bradley GreerSoftware EngineerLondon412012/10/13$132,000
        Dai RiosPersonnel LeadEdinburgh352012/09/26$217,500
        Jenette CaldwellDevelopment LeadNew York302011/09/03$345,000
        Yuri BerryChief Marketing Officer (CMO)New York402009/06/25$675,000
        Caesar VancePre-Sales SupportNew York212011/12/12$106,450
        Doris WilderSales AssistantSidney232010/09/20$85,600
        Angelica RamosChief Executive Officer (CEO)London472009/10/09$1,200,000
        Gavin JoyceDeveloperEdinburgh422010/12/22$92,575
        Jennifer ChangRegional DirectorSingapore282010/11/14$357,650
        Brenden WagnerSoftware EngineerSan Francisco282011/06/07$206,850
        Fiona GreenChief Operating Officer (COO)San Francisco482010/03/11$850,000
        Shou ItouRegional MarketingTokyo202011/08/14$163,000
        Michelle HouseIntegration SpecialistSidney372011/06/02$95,400
        Suki BurksDeveloperLondon532009/10/22$114,500
        Prescott BartlettTechnical AuthorLondon272011/05/07$145,000
        Gavin CortezTeam LeaderSan Francisco222008/10/26$235,500
        Martena MccrayPost-Sales supportEdinburgh462011/03/09$324,050
        Unity ButlerMarketing DesignerSan Francisco472009/12/09$85,675
        Howard HatfieldOffice ManagerSan Francisco512008/12/16$164,500
        Hope FuentesSecretarySan Francisco412010/02/12$109,850
        Vivian HarrellFinancial ControllerSan Francisco622009/02/14$452,500
        Timothy MooneyOffice ManagerLondon372008/12/11$136,200
        Jackson BradshawDirectorNew York652008/09/26$645,750
        Olivia LiangSupport EngineerSingapore642011/02/03$234,500
        Bruno NashSoftware EngineerLondon382011/05/03$163,500
        Sakura YamamotoSupport EngineerTokyo372009/08/19$139,575
        Thor WaltonDeveloperNew York612013/08/11$98,540
        Finn CamachoSupport EngineerSan Francisco472009/07/07$87,500
        Serge BaldwinData CoordinatorSingapore642012/04/09$138,575
        Zenaida FrankSoftware EngineerNew York632010/01/04$125,250
        Zorita SerranoSoftware EngineerSan Francisco562012/06/01$115,000
        Jennifer AcostaJunior Javascript DeveloperEdinburgh432013/02/01$75,650
        Cara StevensSales AssistantNew York462011/12/06$145,600
        Hermione ButlerRegional DirectorLondon472011/03/21$356,250
        Lael GreerSystems AdministratorLondon212009/02/27$103,500
        Jonas AlexanderDeveloperSan Francisco302010/07/14$86,500
        Shad DeckerRegional DirectorEdinburgh512008/11/13$183,000
        Michael BruceJavascript DeveloperSingapore292011/06/27$183,000
        Donna SniderCustomer SupportNew York272011/01/25$112,000
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this + example:

        $(document).ready(function() { + var table = $('#example').DataTable(); + + new $.fn.dataTable.FixedHeader( table, { + bottom: true + } ); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this + example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by + DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library + files (below), in order to correctly display the table. The additional CSS used is shown + below:

        +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the + table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data + will update automatically as any additional data is loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note + that this is just an example script using PHP. Server-side processing scripts can be written in any + language, using the protocol described in the + DataTables documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/FixedHeader/examples/index.html b/public/assets/plugins/datatables/extensions/FixedHeader/examples/index.html new file mode 100644 index 00000000..2198d78c --- /dev/null +++ b/public/assets/plugins/datatables/extensions/FixedHeader/examples/index.html @@ -0,0 +1,69 @@ + + + + + + + + + + + + + FixedHeader examples - FixedHeader examples + + + +
        +
        +

        FixedHeader example FixedHeader examples

        + +
        +

        At times it can be useful to ensure that column titles will remain always visible on a table, even + when a user scrolls down a table. The FixedHeader plug-in for DataTables will float the thead element above the table at all times to help address this issue. + The column titles also remain click-able to perform sorting. Key features include:

        + +
          +
        • Fix the header to the top of the window
        • +
        • Ability to fix the footer and left / right columns as well
        • +
        • z-Index ordering options
        • +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/FixedHeader/examples/simple.html b/public/assets/plugins/datatables/extensions/FixedHeader/examples/simple.html new file mode 100644 index 00000000..1ad6efa7 --- /dev/null +++ b/public/assets/plugins/datatables/extensions/FixedHeader/examples/simple.html @@ -0,0 +1,637 @@ + + + + + + + + FixedHeader example - Basic initialisation + + + + + + + + + + + + + + +
        +
        +

        FixedHeader example Basic initialisation

        + +
        +

        When displaying large amounts of data in a table, it can often be useful for the end user to have + the column titles (the thead element as a whole in fact) + always visible. This is particularly true if using DataTables with pagination disabled, or the display + length is set to a high value.

        + +

        The FixedHeader extension for DataTables will ensure that your column titles will scroll with the + page, showing at the top of the table at all times. Try the demo shown below - you might want to try + resizing the window for full effect! Note also that the column titles remain clickable to perform + sorting on the table.

        + +

        FixedHeader is initialised using the constructor new $.fn.dataTable.FixedHeader(); - + shown below.

        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NamePositionOfficeAgeStart dateSalary
        NamePositionOfficeAgeStart dateSalary
        Tiger NixonSystem ArchitectEdinburgh612011/04/25$320,800
        Garrett WintersAccountantTokyo632011/07/25$170,750
        Ashton CoxJunior Technical AuthorSan Francisco662009/01/12$86,000
        Cedric KellySenior Javascript DeveloperEdinburgh222012/03/29$433,060
        Airi SatouAccountantTokyo332008/11/28$162,700
        Brielle WilliamsonIntegration SpecialistNew York612012/12/02$372,000
        Herrod ChandlerSales AssistantSan Francisco592012/08/06$137,500
        Rhona DavidsonIntegration SpecialistTokyo552010/10/14$327,900
        Colleen HurstJavascript DeveloperSan Francisco392009/09/15$205,500
        Sonya FrostSoftware EngineerEdinburgh232008/12/13$103,600
        Jena GainesOffice ManagerLondon302008/12/19$90,560
        Quinn FlynnSupport LeadEdinburgh222013/03/03$342,000
        Charde MarshallRegional DirectorSan Francisco362008/10/16$470,600
        Haley KennedySenior Marketing DesignerLondon432012/12/18$313,500
        Tatyana FitzpatrickRegional DirectorLondon192010/03/17$385,750
        Michael SilvaMarketing DesignerLondon662012/11/27$198,500
        Paul ByrdChief Financial Officer (CFO)New York642010/06/09$725,000
        Gloria LittleSystems AdministratorNew York592009/04/10$237,500
        Bradley GreerSoftware EngineerLondon412012/10/13$132,000
        Dai RiosPersonnel LeadEdinburgh352012/09/26$217,500
        Jenette CaldwellDevelopment LeadNew York302011/09/03$345,000
        Yuri BerryChief Marketing Officer (CMO)New York402009/06/25$675,000
        Caesar VancePre-Sales SupportNew York212011/12/12$106,450
        Doris WilderSales AssistantSidney232010/09/20$85,600
        Angelica RamosChief Executive Officer (CEO)London472009/10/09$1,200,000
        Gavin JoyceDeveloperEdinburgh422010/12/22$92,575
        Jennifer ChangRegional DirectorSingapore282010/11/14$357,650
        Brenden WagnerSoftware EngineerSan Francisco282011/06/07$206,850
        Fiona GreenChief Operating Officer (COO)San Francisco482010/03/11$850,000
        Shou ItouRegional MarketingTokyo202011/08/14$163,000
        Michelle HouseIntegration SpecialistSidney372011/06/02$95,400
        Suki BurksDeveloperLondon532009/10/22$114,500
        Prescott BartlettTechnical AuthorLondon272011/05/07$145,000
        Gavin CortezTeam LeaderSan Francisco222008/10/26$235,500
        Martena MccrayPost-Sales supportEdinburgh462011/03/09$324,050
        Unity ButlerMarketing DesignerSan Francisco472009/12/09$85,675
        Howard HatfieldOffice ManagerSan Francisco512008/12/16$164,500
        Hope FuentesSecretarySan Francisco412010/02/12$109,850
        Vivian HarrellFinancial ControllerSan Francisco622009/02/14$452,500
        Timothy MooneyOffice ManagerLondon372008/12/11$136,200
        Jackson BradshawDirectorNew York652008/09/26$645,750
        Olivia LiangSupport EngineerSingapore642011/02/03$234,500
        Bruno NashSoftware EngineerLondon382011/05/03$163,500
        Sakura YamamotoSupport EngineerTokyo372009/08/19$139,575
        Thor WaltonDeveloperNew York612013/08/11$98,540
        Finn CamachoSupport EngineerSan Francisco472009/07/07$87,500
        Serge BaldwinData CoordinatorSingapore642012/04/09$138,575
        Zenaida FrankSoftware EngineerNew York632010/01/04$125,250
        Zorita SerranoSoftware EngineerSan Francisco562012/06/01$115,000
        Jennifer AcostaJunior Javascript DeveloperEdinburgh432013/02/01$75,650
        Cara StevensSales AssistantNew York462011/12/06$145,600
        Hermione ButlerRegional DirectorLondon472011/03/21$356,250
        Lael GreerSystems AdministratorLondon212009/02/27$103,500
        Jonas AlexanderDeveloperSan Francisco302010/07/14$86,500
        Shad DeckerRegional DirectorEdinburgh512008/11/13$183,000
        Michael BruceJavascript DeveloperSingapore292011/06/27$183,000
        Donna SniderCustomer SupportNew York272011/01/25$112,000
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this + example:

        $(document).ready(function() { + var table = $('#example').DataTable(); + + new $.fn.dataTable.FixedHeader( table ); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this + example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by + DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library + files (below), in order to correctly display the table. The additional CSS used is shown + below:

        +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the + table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data + will update automatically as any additional data is loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note + that this is just an example script using PHP. Server-side processing scripts can be written in any + language, using the protocol described in the + DataTables documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/FixedHeader/examples/top_left_right.html b/public/assets/plugins/datatables/extensions/FixedHeader/examples/top_left_right.html new file mode 100644 index 00000000..f15faeb5 --- /dev/null +++ b/public/assets/plugins/datatables/extensions/FixedHeader/examples/top_left_right.html @@ -0,0 +1,236 @@ + + + + + + + + FixedHeader example - Header, left and right all fixed + + + + + + + + + + + + + + +
        +
        +

        FixedHeader example Header, left and right all fixed

        + +
        +

        FixedHeader provides the ability to fix in place the header, footer, left and right columns of the + table. These are controlled by the options:

        + +
          +
        • top - default true
        • +
        • bottom - default false
        • +
        • left - default false
        • +
        • right - default false
        • +
        + +

        This example shows top, left and right enabled with index columns on the left and right.

        + +

        Note that in such a situation as this, the FixedColumns extension might be more useful, + particularly if you want to use the scrolling options built into DataTables.

        +
        + +
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this + example:

        $(document).ready(function() { + var table = $('#example').DataTable( { + "order": [ 1, 'asc' ], + "ajax": "../../../examples/ajax/data/objects.txt", + "columns": [ + { title: '', data: null, defaultContent: "" }, + { title: 'Name', data: "name" }, + { title: 'Position', data: "position" }, + { title: 'Office', data: "office" }, + { title: 'Extn.', data: "extn" }, + { title: 'Start date', data: "start_date" }, + { title: 'Salary', data: "salary" }, + { title: '', data: null, defaultContent: "" } + ], + initComplete: function () { + new $.fn.dataTable.FixedHeader( table, { + left: true, + right: true + } ); + } + } ); + + table.on( 'order.dt search.dt', function () { + table.column(0, {search:'applied', order:'applied'}).nodes().each( function (cell, i) { + cell.innerHTML = i+1; + } ); + + table.column(-1, {search:'applied', order:'applied'}).nodes().each( function (cell, i) { + cell.innerHTML = i+1; + } ); + } ).draw(); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this + example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by + DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library + files (below), in order to correctly display the table. The additional CSS used is shown + below:

        div.dataTables_wrapper { + width: 150%; + } + + div.FixedHeader_Cloned.fixedLeft tbody td { + border-right: 1px solid black; + } + + div.FixedHeader_Cloned.fixedRight tbody td { + border-left: 1px solid black; + } +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the + table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data + will update automatically as any additional data is loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note + that this is just an example script using PHP. Server-side processing scripts can be written in any + language, using the protocol described in the + DataTables documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/FixedHeader/examples/two_tables.html b/public/assets/plugins/datatables/extensions/FixedHeader/examples/two_tables.html new file mode 100644 index 00000000..1fbb3dfc --- /dev/null +++ b/public/assets/plugins/datatables/extensions/FixedHeader/examples/two_tables.html @@ -0,0 +1,354 @@ + + + + + + + + FixedHeader example - Multiple tables + + + + + + + + + + + + + + +
        +
        +

        FixedHeader example Multiple tables

        + +
        +

        The following example shows two DataTables enhanced tables both with FixedHeader enabled on them. + This is done simply by initialising FixedHeader on each table. This example also shows the footer being + fixed in place for the two tables.

        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NamePositionOfficeAgeSalary
        NamePositionOfficeAgeSalary
        Tiger NixonSystem ArchitectEdinburgh61$320,800
        Cedric KellySenior Javascript DeveloperEdinburgh22$433,060
        Sonya FrostSoftware EngineerEdinburgh23$103,600
        Quinn FlynnSupport LeadEdinburgh22$342,000
        Dai RiosPersonnel LeadEdinburgh35$217,500
        Gavin JoyceDeveloperEdinburgh42$92,575
        Martena MccrayPost-Sales supportEdinburgh46$324,050
        Jennifer AcostaJunior Javascript DeveloperEdinburgh43$75,650
        Shad DeckerRegional DirectorEdinburgh51$183,000
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NamePositionOfficeAgeSalary
        NamePositionOfficeAgeSalary
        Jena GainesOffice ManagerLondon30$90,560
        Haley KennedySenior Marketing DesignerLondon43$313,500
        Tatyana FitzpatrickRegional DirectorLondon19$385,750
        Michael SilvaMarketing DesignerLondon66$198,500
        Bradley GreerSoftware EngineerLondon41$132,000
        Angelica RamosChief Executive Officer (CEO)London47$1,200,000
        Suki BurksDeveloperLondon53$114,500
        Prescott BartlettTechnical AuthorLondon27$145,000
        Timothy MooneyOffice ManagerLondon37$136,200
        Bruno NashSoftware EngineerLondon38$163,500
        Hermione ButlerRegional DirectorLondon47$356,250
        Lael GreerSystems AdministratorLondon21$103,500
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this + example:

        $(document).ready(function() { + var t1 = $('table.display').eq(0).DataTable(); + new $.fn.dataTable.FixedHeader( t1, { + bottom: true + } ); + + var t2 = $('table.display').eq(1).DataTable(); + new $.fn.dataTable.FixedHeader( t2, { + bottom: true + } ); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this + example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by + DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library + files (below), in order to correctly display the table. The additional CSS used is shown + below:

        +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the + table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data + will update automatically as any additional data is loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note + that this is just an example script using PHP. Server-side processing scripts can be written in any + language, using the protocol described in the + DataTables documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/FixedHeader/examples/zIndexes.html b/public/assets/plugins/datatables/extensions/FixedHeader/examples/zIndexes.html new file mode 100644 index 00000000..a3292c4c --- /dev/null +++ b/public/assets/plugins/datatables/extensions/FixedHeader/examples/zIndexes.html @@ -0,0 +1,653 @@ + + + + + + + + FixedHeader example - z-index order control + + + + + + + + + + + + + + +
        +
        +

        FixedHeader example z-index order control

        + +
        +

        When you have two or more columns fixed on a table, there might be occasions when you which to have + one column floating on top of another. This example shows how you can do that with the initialisation + parameters zTop, zBottom, zLeft and zRight. In this + example the left column is set to float on top of the header. The difference is subtle, but can be + effective.

        + +

        The default zIndexes are:

        + +
          +
        • zTop: 104
        • +
        • zBottom: 103
        • +
        • zLeft: 102
        • +
        • zRight: 101
        • +
        + +

        This example shows the left column being floated on top of the header.

        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NamePositionOfficeAgeStart dateSalary
        NamePositionOfficeAgeStart dateSalary
        Tiger NixonSystem ArchitectEdinburgh612011/04/25$320,800
        Garrett WintersAccountantTokyo632011/07/25$170,750
        Ashton CoxJunior Technical AuthorSan Francisco662009/01/12$86,000
        Cedric KellySenior Javascript DeveloperEdinburgh222012/03/29$433,060
        Airi SatouAccountantTokyo332008/11/28$162,700
        Brielle WilliamsonIntegration SpecialistNew York612012/12/02$372,000
        Herrod ChandlerSales AssistantSan Francisco592012/08/06$137,500
        Rhona DavidsonIntegration SpecialistTokyo552010/10/14$327,900
        Colleen HurstJavascript DeveloperSan Francisco392009/09/15$205,500
        Sonya FrostSoftware EngineerEdinburgh232008/12/13$103,600
        Jena GainesOffice ManagerLondon302008/12/19$90,560
        Quinn FlynnSupport LeadEdinburgh222013/03/03$342,000
        Charde MarshallRegional DirectorSan Francisco362008/10/16$470,600
        Haley KennedySenior Marketing DesignerLondon432012/12/18$313,500
        Tatyana FitzpatrickRegional DirectorLondon192010/03/17$385,750
        Michael SilvaMarketing DesignerLondon662012/11/27$198,500
        Paul ByrdChief Financial Officer (CFO)New York642010/06/09$725,000
        Gloria LittleSystems AdministratorNew York592009/04/10$237,500
        Bradley GreerSoftware EngineerLondon412012/10/13$132,000
        Dai RiosPersonnel LeadEdinburgh352012/09/26$217,500
        Jenette CaldwellDevelopment LeadNew York302011/09/03$345,000
        Yuri BerryChief Marketing Officer (CMO)New York402009/06/25$675,000
        Caesar VancePre-Sales SupportNew York212011/12/12$106,450
        Doris WilderSales AssistantSidney232010/09/20$85,600
        Angelica RamosChief Executive Officer (CEO)London472009/10/09$1,200,000
        Gavin JoyceDeveloperEdinburgh422010/12/22$92,575
        Jennifer ChangRegional DirectorSingapore282010/11/14$357,650
        Brenden WagnerSoftware EngineerSan Francisco282011/06/07$206,850
        Fiona GreenChief Operating Officer (COO)San Francisco482010/03/11$850,000
        Shou ItouRegional MarketingTokyo202011/08/14$163,000
        Michelle HouseIntegration SpecialistSidney372011/06/02$95,400
        Suki BurksDeveloperLondon532009/10/22$114,500
        Prescott BartlettTechnical AuthorLondon272011/05/07$145,000
        Gavin CortezTeam LeaderSan Francisco222008/10/26$235,500
        Martena MccrayPost-Sales supportEdinburgh462011/03/09$324,050
        Unity ButlerMarketing DesignerSan Francisco472009/12/09$85,675
        Howard HatfieldOffice ManagerSan Francisco512008/12/16$164,500
        Hope FuentesSecretarySan Francisco412010/02/12$109,850
        Vivian HarrellFinancial ControllerSan Francisco622009/02/14$452,500
        Timothy MooneyOffice ManagerLondon372008/12/11$136,200
        Jackson BradshawDirectorNew York652008/09/26$645,750
        Olivia LiangSupport EngineerSingapore642011/02/03$234,500
        Bruno NashSoftware EngineerLondon382011/05/03$163,500
        Sakura YamamotoSupport EngineerTokyo372009/08/19$139,575
        Thor WaltonDeveloperNew York612013/08/11$98,540
        Finn CamachoSupport EngineerSan Francisco472009/07/07$87,500
        Serge BaldwinData CoordinatorSingapore642012/04/09$138,575
        Zenaida FrankSoftware EngineerNew York632010/01/04$125,250
        Zorita SerranoSoftware EngineerSan Francisco562012/06/01$115,000
        Jennifer AcostaJunior Javascript DeveloperEdinburgh432013/02/01$75,650
        Cara StevensSales AssistantNew York462011/12/06$145,600
        Hermione ButlerRegional DirectorLondon472011/03/21$356,250
        Lael GreerSystems AdministratorLondon212009/02/27$103,500
        Jonas AlexanderDeveloperSan Francisco302010/07/14$86,500
        Shad DeckerRegional DirectorEdinburgh512008/11/13$183,000
        Michael BruceJavascript DeveloperSingapore292011/06/27$183,000
        Donna SniderCustomer SupportNew York272011/01/25$112,000
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this + example:

        $(document).ready(function() { + var table = $('#example').DataTable(); + + new $.fn.dataTable.FixedHeader( table, { + left: true, + zLeft: 105 + } ); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this + example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by + DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library + files (below), in order to correctly display the table. The additional CSS used is shown + below:

        div.dataTables_wrapper { + width: 1500px; + } +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the + table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data + will update automatically as any additional data is loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note + that this is just an example script using PHP. Server-side processing scripts can be written in any + language, using the protocol described in the + DataTables documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/FixedHeader/js/dataTables.fixedHeader.js b/public/assets/plugins/datatables/extensions/FixedHeader/js/dataTables.fixedHeader.js new file mode 100644 index 00000000..90df8786 --- /dev/null +++ b/public/assets/plugins/datatables/extensions/FixedHeader/js/dataTables.fixedHeader.js @@ -0,0 +1,1028 @@ +/*! FixedHeader 2.1.2 + * ©2010-2014 SpryMedia Ltd - datatables.net/license + */ + +/** + * @summary FixedHeader + * @description Fix a table's header or footer, so it is always visible while + * Scrolling + * @version 2.1.2 + * @file dataTables.fixedHeader.js + * @author SpryMedia Ltd (www.sprymedia.co.uk) + * @contact www.sprymedia.co.uk/contact + * @copyright Copyright 2009-2014 SpryMedia Ltd. + * + * This source file is free software, available under the following license: + * MIT license - http://datatables.net/license/mit + * + * This source file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. + * + * For details please refer to: http://www.datatables.net + */ + +/* Global scope for FixedColumns for backwards compatibility - will be removed + * in future. Not documented in 1.1.x. + */ + +/* Global scope for FixedColumns */ +var FixedHeader; + +(function(window, document, undefined) { + + +var factory = function( $, DataTable ) { +"use strict"; + +/* + * Function: FixedHeader + * Purpose: Provide 'fixed' header, footer and columns for a DataTable + * Returns: object:FixedHeader - must be called with 'new' + * Inputs: mixed:mTable - target table + * @param {object} dt DataTables instance or HTML table node. With DataTables + * 1.10 this can also be a jQuery collection (with just a single table in its + * result set), a jQuery selector, DataTables API instance or settings + * object. + * @param {object} [oInit] initialisation settings, with the following + * properties (each optional) + * * bool:top - fix the header (default true) + * * bool:bottom - fix the footer (default false) + * * int:left - fix the left column(s) (default 0) + * * int:right - fix the right column(s) (default 0) + * * int:zTop - fixed header zIndex + * * int:zBottom - fixed footer zIndex + * * int:zLeft - fixed left zIndex + * * int:zRight - fixed right zIndex + */ +FixedHeader = function ( mTable, oInit ) { + /* Sanity check - you just know it will happen */ + if ( ! this instanceof FixedHeader ) + { + alert( "FixedHeader warning: FixedHeader must be initialised with the 'new' keyword." ); + return; + } + + var that = this; + var oSettings = { + "aoCache": [], + "oSides": { + "top": true, + "bottom": false, + "left": 0, + "right": 0 + }, + "oZIndexes": { + "top": 104, + "bottom": 103, + "left": 102, + "right": 101 + }, + "oCloneOnDraw": { + "top": false, + "bottom": false, + "left": true, + "right": true + }, + "oMes": { + "iTableWidth": 0, + "iTableHeight": 0, + "iTableLeft": 0, + "iTableRight": 0, /* note this is left+width, not actually "right" */ + "iTableTop": 0, + "iTableBottom": 0 /* note this is top+height, not actually "bottom" */ + }, + "oOffset": { + "top": 0 + }, + "nTable": null, + "bFooter": false, + "bInitComplete": false + }; + + /* + * Function: fnGetSettings + * Purpose: Get the settings for this object + * Returns: object: - settings object + * Inputs: - + */ + this.fnGetSettings = function () { + return oSettings; + }; + + /* + * Function: fnUpdate + * Purpose: Update the positioning and copies of the fixed elements + * Returns: - + * Inputs: - + */ + this.fnUpdate = function () { + this._fnUpdateClones(); + this._fnUpdatePositions(); + }; + + /* + * Function: fnPosition + * Purpose: Update the positioning of the fixed elements + * Returns: - + * Inputs: - + */ + this.fnPosition = function () { + this._fnUpdatePositions(); + }; + + + var dt = $.fn.dataTable.Api ? + new $.fn.dataTable.Api( mTable ).settings()[0] : + mTable.fnSettings(); + + dt._oPluginFixedHeader = this; + + /* Let's do it */ + this.fnInit( dt, oInit ); + +}; + + +/* + * Variable: FixedHeader + * Purpose: Prototype for FixedHeader + * Scope: global + */ +FixedHeader.prototype = { + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Initialisation + */ + + /* + * Function: fnInit + * Purpose: The "constructor" + * Returns: - + * Inputs: {as FixedHeader function} + */ + fnInit: function ( oDtSettings, oInit ) + { + var s = this.fnGetSettings(); + var that = this; + + /* Record the user definable settings */ + this.fnInitSettings( s, oInit ); + + if ( oDtSettings.oScroll.sX !== "" || oDtSettings.oScroll.sY !== "" ) + { + alert( "FixedHeader 2 is not supported with DataTables' scrolling mode at this time" ); + return; + } + + s.nTable = oDtSettings.nTable; + oDtSettings.aoDrawCallback.unshift( { + "fn": function () { + FixedHeader.fnMeasure(); + that._fnUpdateClones.call(that); + that._fnUpdatePositions.call(that); + }, + "sName": "FixedHeader" + } ); + + s.bFooter = ($('>tfoot', s.nTable).length > 0) ? true : false; + + /* Add the 'sides' that are fixed */ + if ( s.oSides.top ) + { + s.aoCache.push( that._fnCloneTable( "fixedHeader", "FixedHeader_Header", that._fnCloneThead ) ); + } + if ( s.oSides.bottom ) + { + s.aoCache.push( that._fnCloneTable( "fixedFooter", "FixedHeader_Footer", that._fnCloneTfoot ) ); + } + if ( s.oSides.left ) + { + s.aoCache.push( that._fnCloneTable( "fixedLeft", "FixedHeader_Left", that._fnCloneTLeft, s.oSides.left ) ); + } + if ( s.oSides.right ) + { + s.aoCache.push( that._fnCloneTable( "fixedRight", "FixedHeader_Right", that._fnCloneTRight, s.oSides.right ) ); + } + + /* Event listeners for window movement */ + FixedHeader.afnScroll.push( function () { + that._fnUpdatePositions.call(that); + } ); + + $(window).resize( function () { + FixedHeader.fnMeasure(); + that._fnUpdateClones.call(that); + that._fnUpdatePositions.call(that); + } ); + + $(s.nTable) + .on('column-reorder.dt', function () { + FixedHeader.fnMeasure(); + that._fnUpdateClones( true ); + that._fnUpdatePositions(); + } ) + .on('column-visibility.dt', function () { + FixedHeader.fnMeasure(); + that._fnUpdateClones( true ); + that._fnUpdatePositions(); + } ); + + /* Get things right to start with */ + FixedHeader.fnMeasure(); + that._fnUpdateClones(); + that._fnUpdatePositions(); + + s.bInitComplete = true; + }, + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Support functions + */ + + /* + * Function: fnInitSettings + * Purpose: Take the user's settings and copy them to our local store + * Returns: - + * Inputs: object:s - the local settings object + * object:oInit - the user's settings object + */ + fnInitSettings: function ( s, oInit ) + { + if ( oInit !== undefined ) + { + if ( oInit.top !== undefined ) { + s.oSides.top = oInit.top; + } + if ( oInit.bottom !== undefined ) { + s.oSides.bottom = oInit.bottom; + } + if ( typeof oInit.left == 'boolean' ) { + s.oSides.left = oInit.left ? 1 : 0; + } + else if ( oInit.left !== undefined ) { + s.oSides.left = oInit.left; + } + if ( typeof oInit.right == 'boolean' ) { + s.oSides.right = oInit.right ? 1 : 0; + } + else if ( oInit.right !== undefined ) { + s.oSides.right = oInit.right; + } + + if ( oInit.zTop !== undefined ) { + s.oZIndexes.top = oInit.zTop; + } + if ( oInit.zBottom !== undefined ) { + s.oZIndexes.bottom = oInit.zBottom; + } + if ( oInit.zLeft !== undefined ) { + s.oZIndexes.left = oInit.zLeft; + } + if ( oInit.zRight !== undefined ) { + s.oZIndexes.right = oInit.zRight; + } + + if ( oInit.offsetTop !== undefined ) { + s.oOffset.top = oInit.offsetTop; + } + if ( oInit.alwaysCloneTop !== undefined ) { + s.oCloneOnDraw.top = oInit.alwaysCloneTop; + } + if ( oInit.alwaysCloneBottom !== undefined ) { + s.oCloneOnDraw.bottom = oInit.alwaysCloneBottom; + } + if ( oInit.alwaysCloneLeft !== undefined ) { + s.oCloneOnDraw.left = oInit.alwaysCloneLeft; + } + if ( oInit.alwaysCloneRight !== undefined ) { + s.oCloneOnDraw.right = oInit.alwaysCloneRight; + } + } + }, + + /* + * Function: _fnCloneTable + * Purpose: Clone the table node and do basic initialisation + * Returns: - + * Inputs: - + */ + _fnCloneTable: function ( sType, sClass, fnClone, iCells ) + { + var s = this.fnGetSettings(); + var nCTable; + + /* We know that the table _MUST_ has a DIV wrapped around it, because this is simply how + * DataTables works. Therefore, we can set this to be relatively position (if it is not + * alreadu absolute, and use this as the base point for the cloned header + */ + if ( $(s.nTable.parentNode).css('position') != "absolute" ) + { + s.nTable.parentNode.style.position = "relative"; + } + + /* Just a shallow clone will do - we only want the table node */ + nCTable = s.nTable.cloneNode( false ); + nCTable.removeAttribute( 'id' ); + + var nDiv = document.createElement( 'div' ); + nDiv.style.position = "absolute"; + nDiv.style.top = "0px"; + nDiv.style.left = "0px"; + nDiv.className += " FixedHeader_Cloned "+sType+" "+sClass; + + /* Set the zIndexes */ + if ( sType == "fixedHeader" ) + { + nDiv.style.zIndex = s.oZIndexes.top; + } + if ( sType == "fixedFooter" ) + { + nDiv.style.zIndex = s.oZIndexes.bottom; + } + if ( sType == "fixedLeft" ) + { + nDiv.style.zIndex = s.oZIndexes.left; + } + else if ( sType == "fixedRight" ) + { + nDiv.style.zIndex = s.oZIndexes.right; + } + + /* remove margins since we are going to position it absolutely */ + nCTable.style.margin = "0"; + + /* Insert the newly cloned table into the DOM, on top of the "real" header */ + nDiv.appendChild( nCTable ); + document.body.appendChild( nDiv ); + + return { + "nNode": nCTable, + "nWrapper": nDiv, + "sType": sType, + "sPosition": "", + "sTop": "", + "sLeft": "", + "fnClone": fnClone, + "iCells": iCells + }; + }, + + /* + * Function: _fnMeasure + * Purpose: Get the current positioning of the table in the DOM + * Returns: - + * Inputs: - + */ + _fnMeasure: function () + { + var + s = this.fnGetSettings(), + m = s.oMes, + jqTable = $(s.nTable), + oOffset = jqTable.offset(), + iParentScrollTop = this._fnSumScroll( s.nTable.parentNode, 'scrollTop' ), + iParentScrollLeft = this._fnSumScroll( s.nTable.parentNode, 'scrollLeft' ); + + m.iTableWidth = jqTable.outerWidth(); + m.iTableHeight = jqTable.outerHeight(); + m.iTableLeft = oOffset.left + s.nTable.parentNode.scrollLeft; + m.iTableTop = oOffset.top + iParentScrollTop; + m.iTableRight = m.iTableLeft + m.iTableWidth; + m.iTableRight = FixedHeader.oDoc.iWidth - m.iTableLeft - m.iTableWidth; + m.iTableBottom = FixedHeader.oDoc.iHeight - m.iTableTop - m.iTableHeight; + }, + + /* + * Function: _fnSumScroll + * Purpose: Sum node parameters all the way to the top + * Returns: int: sum + * Inputs: node:n - node to consider + * string:side - scrollTop or scrollLeft + */ + _fnSumScroll: function ( n, side ) + { + var i = n[side]; + while ( n = n.parentNode ) + { + if ( n.nodeName == 'HTML' || n.nodeName == 'BODY' ) + { + break; + } + i = n[side]; + } + return i; + }, + + /* + * Function: _fnUpdatePositions + * Purpose: Loop over the fixed elements for this table and update their positions + * Returns: - + * Inputs: - + */ + _fnUpdatePositions: function () + { + var s = this.fnGetSettings(); + this._fnMeasure(); + + for ( var i=0, iLen=s.aoCache.length ; i oWin.iScrollTop + s.oOffset.top ) + { + /* Above the table */ + this._fnUpdateCache( oCache, 'sPosition', "absolute", 'position', nTable.style ); + this._fnUpdateCache( oCache, 'sTop', oMes.iTableTop+"px", 'top', nTable.style ); + this._fnUpdateCache( oCache, 'sLeft', oMes.iTableLeft+"px", 'left', nTable.style ); + } + else if ( oWin.iScrollTop + s.oOffset.top > oMes.iTableTop+iTbodyHeight ) + { + /* At the bottom of the table */ + this._fnUpdateCache( oCache, 'sPosition', "absolute", 'position', nTable.style ); + this._fnUpdateCache( oCache, 'sTop', (oMes.iTableTop+iTbodyHeight)+"px", 'top', nTable.style ); + this._fnUpdateCache( oCache, 'sLeft', oMes.iTableLeft+"px", 'left', nTable.style ); + } + else + { + /* In the middle of the table */ + this._fnUpdateCache( oCache, 'sPosition', 'fixed', 'position', nTable.style ); + this._fnUpdateCache( oCache, 'sTop', s.oOffset.top+"px", 'top', nTable.style ); + this._fnUpdateCache( oCache, 'sLeft', (oMes.iTableLeft-oWin.iScrollLeft)+"px", 'left', nTable.style ); + } + }, + + /* + * Function: _fnUpdateCache + * Purpose: Check the cache and update cache and value if needed + * Returns: - + * Inputs: object:oCache - local cache object + * string:sCache - cache property + * string:sSet - value to set + * string:sProperty - object property to set + * object:oObj - object to update + */ + _fnUpdateCache: function ( oCache, sCache, sSet, sProperty, oObj ) + { + if ( oCache[sCache] != sSet ) + { + oObj[sProperty] = sSet; + oCache[sCache] = sSet; + } + }, + + + + /** + * Copy the classes of all child nodes from one element to another. This implies + * that the two have identical structure - no error checking is performed to that + * fact. + * @param {element} source Node to copy classes from + * @param {element} dest Node to copy classes too + */ + _fnClassUpdate: function ( source, dest ) + { + var that = this; + + if ( source.nodeName.toUpperCase() === "TR" || source.nodeName.toUpperCase() === "TH" || + source.nodeName.toUpperCase() === "TD" || source.nodeName.toUpperCase() === "SPAN" ) + { + dest.className = source.className; + } + + $(source).children().each( function (i) { + that._fnClassUpdate( $(source).children()[i], $(dest).children()[i] ); + } ); + }, + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Cloning functions + */ + + /* + * Function: _fnCloneThead + * Purpose: Clone the thead element + * Returns: - + * Inputs: object:oCache - the cached values for this fixed element + */ + _fnCloneThead: function ( oCache ) + { + var s = this.fnGetSettings(); + var nTable = oCache.nNode; + + if ( s.bInitComplete && !s.oCloneOnDraw.top ) + { + this._fnClassUpdate( $('thead', s.nTable)[0], $('thead', nTable)[0] ); + return; + } + + /* Set the wrapper width to match that of the cloned table */ + var iDtWidth = $(s.nTable).outerWidth(); + oCache.nWrapper.style.width = iDtWidth+"px"; + nTable.style.width = iDtWidth+"px"; + + /* Remove any children the cloned table has */ + while ( nTable.childNodes.length > 0 ) + { + $('thead th', nTable).unbind( 'click' ); + nTable.removeChild( nTable.childNodes[0] ); + } + + /* Clone the DataTables header */ + var nThead = $('thead', s.nTable).clone(true)[0]; + nTable.appendChild( nThead ); + + /* Copy the widths across - apparently a clone isn't good enough for this */ + var a = []; + var b = []; + + $("thead>tr th", s.nTable).each( function (i) { + a.push( $(this).width() ); + } ); + + $("thead>tr td", s.nTable).each( function (i) { + b.push( $(this).width() ); + } ); + + $("thead>tr th", s.nTable).each( function (i) { + $("thead>tr th:eq("+i+")", nTable).width( a[i] ); + $(this).width( a[i] ); + } ); + + $("thead>tr td", s.nTable).each( function (i) { + $("thead>tr td:eq("+i+")", nTable).width( b[i] ); + $(this).width( b[i] ); + } ); + + // Stop DataTables 1.9 from putting a focus ring on the headers when + // clicked to sort + $('th.sorting, th.sorting_desc, th.sorting_asc', nTable).bind( 'click', function () { + this.blur(); + } ); + }, + + /* + * Function: _fnCloneTfoot + * Purpose: Clone the tfoot element + * Returns: - + * Inputs: object:oCache - the cached values for this fixed element + */ + _fnCloneTfoot: function ( oCache ) + { + var s = this.fnGetSettings(); + var nTable = oCache.nNode; + + /* Set the wrapper width to match that of the cloned table */ + oCache.nWrapper.style.width = $(s.nTable).outerWidth()+"px"; + + /* Remove any children the cloned table has */ + while ( nTable.childNodes.length > 0 ) + { + nTable.removeChild( nTable.childNodes[0] ); + } + + /* Clone the DataTables footer */ + var nTfoot = $('tfoot', s.nTable).clone(true)[0]; + nTable.appendChild( nTfoot ); + + /* Copy the widths across - apparently a clone isn't good enough for this */ + $("tfoot:eq(0)>tr th", s.nTable).each( function (i) { + $("tfoot:eq(0)>tr th:eq("+i+")", nTable).width( $(this).width() ); + } ); + + $("tfoot:eq(0)>tr td", s.nTable).each( function (i) { + $("tfoot:eq(0)>tr td:eq("+i+")", nTable).width( $(this).width() ); + } ); + }, + + /* + * Function: _fnCloneTLeft + * Purpose: Clone the left column(s) + * Returns: - + * Inputs: object:oCache - the cached values for this fixed element + */ + _fnCloneTLeft: function ( oCache ) + { + var s = this.fnGetSettings(); + var nTable = oCache.nNode; + var nBody = $('tbody', s.nTable)[0]; + + /* Remove any children the cloned table has */ + while ( nTable.childNodes.length > 0 ) + { + nTable.removeChild( nTable.childNodes[0] ); + } + + /* Is this the most efficient way to do this - it looks horrible... */ + nTable.appendChild( $("thead", s.nTable).clone(true)[0] ); + nTable.appendChild( $("tbody", s.nTable).clone(true)[0] ); + if ( s.bFooter ) + { + nTable.appendChild( $("tfoot", s.nTable).clone(true)[0] ); + } + + /* Remove unneeded cells */ + var sSelector = 'gt(' + (oCache.iCells - 1) + ')'; + $('thead tr', nTable).each( function (k) { + $('th:' + sSelector, this).remove(); + } ); + + $('tfoot tr', nTable).each( function (k) { + $('th:' + sSelector, this).remove(); + } ); + + $('tbody tr', nTable).each( function (k) { + $('td:' + sSelector, this).remove(); + } ); + + this.fnEqualiseHeights( 'thead', nBody.parentNode, nTable ); + this.fnEqualiseHeights( 'tbody', nBody.parentNode, nTable ); + this.fnEqualiseHeights( 'tfoot', nBody.parentNode, nTable ); + + var iWidth = 0; + for (var i = 0; i < oCache.iCells; i++) { + iWidth += $('thead tr th:eq(' + i + ')', s.nTable).outerWidth(); + } + nTable.style.width = iWidth+"px"; + oCache.nWrapper.style.width = iWidth+"px"; + }, + + /* + * Function: _fnCloneTRight + * Purpose: Clone the right most column(s) + * Returns: - + * Inputs: object:oCache - the cached values for this fixed element + */ + _fnCloneTRight: function ( oCache ) + { + var s = this.fnGetSettings(); + var nBody = $('tbody', s.nTable)[0]; + var nTable = oCache.nNode; + var iCols = $('tbody tr:eq(0) td', s.nTable).length; + + /* Remove any children the cloned table has */ + while ( nTable.childNodes.length > 0 ) + { + nTable.removeChild( nTable.childNodes[0] ); + } + + /* Is this the most efficient way to do this - it looks horrible... */ + nTable.appendChild( $("thead", s.nTable).clone(true)[0] ); + nTable.appendChild( $("tbody", s.nTable).clone(true)[0] ); + if ( s.bFooter ) + { + nTable.appendChild( $("tfoot", s.nTable).clone(true)[0] ); + } + $('thead tr th:lt('+(iCols-oCache.iCells)+')', nTable).remove(); + $('tfoot tr th:lt('+(iCols-oCache.iCells)+')', nTable).remove(); + + /* Remove unneeded cells */ + $('tbody tr', nTable).each( function (k) { + $('td:lt('+(iCols-oCache.iCells)+')', this).remove(); + } ); + + this.fnEqualiseHeights( 'thead', nBody.parentNode, nTable ); + this.fnEqualiseHeights( 'tbody', nBody.parentNode, nTable ); + this.fnEqualiseHeights( 'tfoot', nBody.parentNode, nTable ); + + var iWidth = 0; + for (var i = 0; i < oCache.iCells; i++) { + iWidth += $('thead tr th:eq('+(iCols-1-i)+')', s.nTable).outerWidth(); + } + nTable.style.width = iWidth+"px"; + oCache.nWrapper.style.width = iWidth+"px"; + }, + + + /** + * Equalise the heights of the rows in a given table node in a cross browser way. Note that this + * is more or less lifted as is from FixedColumns + * @method fnEqualiseHeights + * @returns void + * @param {string} parent Node type - thead, tbody or tfoot + * @param {element} original Original node to take the heights from + * @param {element} clone Copy the heights to + * @private + */ + "fnEqualiseHeights": function ( parent, original, clone ) + { + var that = this; + var originals = $(parent +' tr', original); + var height; + + $(parent+' tr', clone).each( function (k) { + height = originals.eq( k ).css('height'); + + // This is nasty :-(. IE has a sub-pixel error even when setting + // the height below (the Firefox fix) which causes the fixed column + // to go out of alignment. Need to add a pixel before the assignment + // Can this be feature detected? Not sure how... + if ( navigator.appName == 'Microsoft Internet Explorer' ) { + height = parseInt( height, 10 ) + 1; + } + + $(this).css( 'height', height ); + + // For Firefox to work, we need to also set the height of the + // original row, to the value that we read from it! Otherwise there + // is a sub-pixel rounding error + originals.eq( k ).css( 'height', height ); + } ); + } +}; + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Static properties and methods + * We use these for speed! This information is common to all instances of FixedHeader, so no + * point if having them calculated and stored for each different instance. + */ + +/* + * Variable: oWin + * Purpose: Store information about the window positioning + * Scope: FixedHeader + */ +FixedHeader.oWin = { + "iScrollTop": 0, + "iScrollRight": 0, + "iScrollBottom": 0, + "iScrollLeft": 0, + "iHeight": 0, + "iWidth": 0 +}; + +/* + * Variable: oDoc + * Purpose: Store information about the document size + * Scope: FixedHeader + */ +FixedHeader.oDoc = { + "iHeight": 0, + "iWidth": 0 +}; + +/* + * Variable: afnScroll + * Purpose: Array of functions that are to be used for the scrolling components + * Scope: FixedHeader + */ +FixedHeader.afnScroll = []; + +/* + * Function: fnMeasure + * Purpose: Update the measurements for the window and document + * Returns: - + * Inputs: - + */ +FixedHeader.fnMeasure = function () +{ + var + jqWin = $(window), + jqDoc = $(document), + oWin = FixedHeader.oWin, + oDoc = FixedHeader.oDoc; + + oDoc.iHeight = jqDoc.height(); + oDoc.iWidth = jqDoc.width(); + + oWin.iHeight = jqWin.height(); + oWin.iWidth = jqWin.width(); + oWin.iScrollTop = jqWin.scrollTop(); + oWin.iScrollLeft = jqWin.scrollLeft(); + oWin.iScrollRight = oDoc.iWidth - oWin.iScrollLeft - oWin.iWidth; + oWin.iScrollBottom = oDoc.iHeight - oWin.iScrollTop - oWin.iHeight; +}; + + +FixedHeader.version = "2.1.2"; + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Global processing + */ + +/* + * Just one 'scroll' event handler in FixedHeader, which calls the required components. This is + * done as an optimisation, to reduce calculation and proagation time + */ +$(window).scroll( function () { + FixedHeader.fnMeasure(); + + for ( var i=0, iLen=FixedHeader.afnScroll.length ; itfoot",c.nTable).length?!0:!1,c.oSides.top&&c.aoCache.push(d._fnCloneTable("fixedHeader","FixedHeader_Header",d._fnCloneThead)),c.oSides.bottom&&c.aoCache.push(d._fnCloneTable("fixedFooter","FixedHeader_Footer",d._fnCloneTfoot)),c.oSides.left&&c.aoCache.push(d._fnCloneTable("fixedLeft","FixedHeader_Left",d._fnCloneTLeft,c.oSides.left)), +c.oSides.right&&c.aoCache.push(d._fnCloneTable("fixedRight","FixedHeader_Right",d._fnCloneTRight,c.oSides.right)),FixedHeader.afnScroll.push(function(){d._fnUpdatePositions.call(d)}),e(j).resize(function(){FixedHeader.fnMeasure();d._fnUpdateClones.call(d);d._fnUpdatePositions.call(d)}),e(c.nTable).on("column-reorder.dt",function(){FixedHeader.fnMeasure();d._fnUpdateClones(!0);d._fnUpdatePositions()}).on("column-visibility.dt",function(){FixedHeader.fnMeasure();d._fnUpdateClones(!0);d._fnUpdatePositions()}), +FixedHeader.fnMeasure(),d._fnUpdateClones(),d._fnUpdatePositions(),c.bInitComplete=!0)},fnInitSettings:function(a,b){if(b!==h&&(b.top!==h&&(a.oSides.top=b.top),b.bottom!==h&&(a.oSides.bottom=b.bottom),"boolean"==typeof b.left?a.oSides.left=b.left?1:0:b.left!==h&&(a.oSides.left=b.left),"boolean"==typeof b.right?a.oSides.right=b.right?1:0:b.right!==h&&(a.oSides.right=b.right),b.zTop!==h&&(a.oZIndexes.top=b.zTop),b.zBottom!==h&&(a.oZIndexes.bottom=b.zBottom),b.zLeft!==h&&(a.oZIndexes.left=b.zLeft),b.zRight!== +h&&(a.oZIndexes.right=b.zRight),b.offsetTop!==h&&(a.oOffset.top=b.offsetTop),b.alwaysCloneTop!==h&&(a.oCloneOnDraw.top=b.alwaysCloneTop),b.alwaysCloneBottom!==h&&(a.oCloneOnDraw.bottom=b.alwaysCloneBottom),b.alwaysCloneLeft!==h&&(a.oCloneOnDraw.left=b.alwaysCloneLeft),b.alwaysCloneRight!==h))a.oCloneOnDraw.right=b.alwaysCloneRight},_fnCloneTable:function(a,b,c,d){var f=this.fnGetSettings(),g;"absolute"!=e(f.nTable.parentNode).css("position")&&(f.nTable.parentNode.style.position="relative");g=f.nTable.cloneNode(!1); +g.removeAttribute("id");var i=k.createElement("div");i.style.position="absolute";i.style.top="0px";i.style.left="0px";i.className+=" FixedHeader_Cloned "+a+" "+b;"fixedHeader"==a&&(i.style.zIndex=f.oZIndexes.top);"fixedFooter"==a&&(i.style.zIndex=f.oZIndexes.bottom);"fixedLeft"==a?i.style.zIndex=f.oZIndexes.left:"fixedRight"==a&&(i.style.zIndex=f.oZIndexes.right);g.style.margin="0";i.appendChild(g);k.body.appendChild(i);return{nNode:g,nWrapper:i,sType:a,sPosition:"",sTop:"",sLeft:"",fnClone:c,iCells:d}}, +_fnMeasure:function(){var a=this.fnGetSettings(),b=a.oMes,c=e(a.nTable),d=c.offset(),f=this._fnSumScroll(a.nTable.parentNode,"scrollTop");this._fnSumScroll(a.nTable.parentNode,"scrollLeft");b.iTableWidth=c.outerWidth();b.iTableHeight=c.outerHeight();b.iTableLeft=d.left+a.nTable.parentNode.scrollLeft;b.iTableTop=d.top+f;b.iTableRight=b.iTableLeft+b.iTableWidth;b.iTableRight=FixedHeader.oDoc.iWidth-b.iTableLeft-b.iTableWidth;b.iTableBottom=FixedHeader.oDoc.iHeight-b.iTableTop-b.iTableHeight},_fnSumScroll:function(a, +b){for(var c=a[b];(a=a.parentNode)&&!("HTML"==a.nodeName||"BODY"==a.nodeName);)c=a[b];return c},_fnUpdatePositions:function(){var a=this.fnGetSettings();this._fnMeasure();for(var b=0,c=a.aoCache.length;bd.iScrollTop+b.oOffset.top?(this._fnUpdateCache(a,"sPosition","absolute","position",e.style),this._fnUpdateCache(a,"sTop",c.iTableTop+"px","top",e.style),this._fnUpdateCache(a,"sLeft",c.iTableLeft+"px","left",e.style)):d.iScrollTop+b.oOffset.top>c.iTableTop+ +g?(this._fnUpdateCache(a,"sPosition","absolute","position",e.style),this._fnUpdateCache(a,"sTop",c.iTableTop+g+"px","top",e.style),this._fnUpdateCache(a,"sLeft",c.iTableLeft+"px","left",e.style)):(this._fnUpdateCache(a,"sPosition","fixed","position",e.style),this._fnUpdateCache(a,"sTop",b.oOffset.top+"px","top",e.style),this._fnUpdateCache(a,"sLeft",c.iTableLeft-d.iScrollLeft+"px","left",e.style))},_fnUpdateCache:function(a,b,c,d,e){a[b]!=c&&(e[d]=c,a[b]=c)},_fnClassUpdate:function(a,b){var c=this; +if("TR"===a.nodeName.toUpperCase()||"TH"===a.nodeName.toUpperCase()||"TD"===a.nodeName.toUpperCase()||"SPAN"===a.nodeName.toUpperCase())b.className=a.className;e(a).children().each(function(d){c._fnClassUpdate(e(a).children()[d],e(b).children()[d])})},_fnCloneThead:function(a){var b=this.fnGetSettings(),c=a.nNode;if(b.bInitComplete&&!b.oCloneOnDraw.top)this._fnClassUpdate(e("thead",b.nTable)[0],e("thead",c)[0]);else{var d=e(b.nTable).outerWidth();a.nWrapper.style.width=d+"px";for(c.style.width=d+ +"px";0tr th",b.nTable).each(function(){f.push(e(this).width())});e("thead>tr td",b.nTable).each(function(){g.push(e(this).width())});e("thead>tr th",b.nTable).each(function(a){e("thead>tr th:eq("+a+")",c).width(f[a]);e(this).width(f[a])});e("thead>tr td",b.nTable).each(function(a){e("thead>tr td:eq("+a+")",c).width(g[a]);e(this).width(g[a])}); +e("th.sorting, th.sorting_desc, th.sorting_asc",c).bind("click",function(){this.blur()})}},_fnCloneTfoot:function(a){var b=this.fnGetSettings(),c=a.nNode;for(a.nWrapper.style.width=e(b.nTable).outerWidth()+"px";0tr th",b.nTable).each(function(a){e("tfoot:eq(0)>tr th:eq("+a+")",c).width(e(this).width())});e("tfoot:eq(0)>tr td",b.nTable).each(function(a){e("tfoot:eq(0)>tr td:eq("+ +a+")",c).width(e(this).width())})},_fnCloneTLeft:function(a){for(var b=this.fnGetSettings(),c=a.nNode,d=e("tbody",b.nTable)[0];0 + + + + + + + KeyTable example - Events + + + + + + + + + + + + + + +
        +
        +

        KeyTable example Events

        + +
        +

        KeyTable provides the ability to listen for events such as focus, blur, + esc (the escape key) and 'return' (the return key) can be assigned event handling + functions through KeyTable's the API. This gives you the ability to take an action on a cell.

        + +

        The example shown below has a few cells (selected at random, but near the top) with blur and focus + events assigned to them. You can also see the navigation around the table using arrow keys.

        +
        + +
        + Event information:
        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NamePositionOfficeAgeStart dateSalary
        NamePositionOfficeAgeStart dateSalary
        Tiger NixonSystem ArchitectEdinburgh612011/04/25$320,800
        Garrett WintersAccountantTokyo632011/07/25$170,750
        Ashton CoxJunior Technical AuthorSan Francisco662009/01/12$86,000
        Cedric KellySenior Javascript DeveloperEdinburgh222012/03/29$433,060
        Airi SatouAccountantTokyo332008/11/28$162,700
        Brielle WilliamsonIntegration SpecialistNew York612012/12/02$372,000
        Herrod ChandlerSales AssistantSan Francisco592012/08/06$137,500
        Rhona DavidsonIntegration SpecialistTokyo552010/10/14$327,900
        Colleen HurstJavascript DeveloperSan Francisco392009/09/15$205,500
        Sonya FrostSoftware EngineerEdinburgh232008/12/13$103,600
        Jena GainesOffice ManagerLondon302008/12/19$90,560
        Quinn FlynnSupport LeadEdinburgh222013/03/03$342,000
        Charde MarshallRegional DirectorSan Francisco362008/10/16$470,600
        Haley KennedySenior Marketing DesignerLondon432012/12/18$313,500
        Tatyana FitzpatrickRegional DirectorLondon192010/03/17$385,750
        Michael SilvaMarketing DesignerLondon662012/11/27$198,500
        Paul ByrdChief Financial Officer (CFO)New York642010/06/09$725,000
        Gloria LittleSystems AdministratorNew York592009/04/10$237,500
        Bradley GreerSoftware EngineerLondon412012/10/13$132,000
        Dai RiosPersonnel LeadEdinburgh352012/09/26$217,500
        Jenette CaldwellDevelopment LeadNew York302011/09/03$345,000
        Yuri BerryChief Marketing Officer (CMO)New York402009/06/25$675,000
        Caesar VancePre-Sales SupportNew York212011/12/12$106,450
        Doris WilderSales AssistantSidney232010/09/20$85,600
        Angelica RamosChief Executive Officer (CEO)London472009/10/09$1,200,000
        Gavin JoyceDeveloperEdinburgh422010/12/22$92,575
        Jennifer ChangRegional DirectorSingapore282010/11/14$357,650
        Brenden WagnerSoftware EngineerSan Francisco282011/06/07$206,850
        Fiona GreenChief Operating Officer (COO)San Francisco482010/03/11$850,000
        Shou ItouRegional MarketingTokyo202011/08/14$163,000
        Michelle HouseIntegration SpecialistSidney372011/06/02$95,400
        Suki BurksDeveloperLondon532009/10/22$114,500
        Prescott BartlettTechnical AuthorLondon272011/05/07$145,000
        Gavin CortezTeam LeaderSan Francisco222008/10/26$235,500
        Martena MccrayPost-Sales supportEdinburgh462011/03/09$324,050
        Unity ButlerMarketing DesignerSan Francisco472009/12/09$85,675
        Howard HatfieldOffice ManagerSan Francisco512008/12/16$164,500
        Hope FuentesSecretarySan Francisco412010/02/12$109,850
        Vivian HarrellFinancial ControllerSan Francisco622009/02/14$452,500
        Timothy MooneyOffice ManagerLondon372008/12/11$136,200
        Jackson BradshawDirectorNew York652008/09/26$645,750
        Olivia LiangSupport EngineerSingapore642011/02/03$234,500
        Bruno NashSoftware EngineerLondon382011/05/03$163,500
        Sakura YamamotoSupport EngineerTokyo372009/08/19$139,575
        Thor WaltonDeveloperNew York612013/08/11$98,540
        Finn CamachoSupport EngineerSan Francisco472009/07/07$87,500
        Serge BaldwinData CoordinatorSingapore642012/04/09$138,575
        Zenaida FrankSoftware EngineerNew York632010/01/04$125,250
        Zorita SerranoSoftware EngineerSan Francisco562012/06/01$115,000
        Jennifer AcostaJunior Javascript DeveloperEdinburgh432013/02/01$75,650
        Cara StevensSales AssistantNew York462011/12/06$145,600
        Hermione ButlerRegional DirectorLondon472011/03/21$356,250
        Lael GreerSystems AdministratorLondon212009/02/27$103,500
        Jonas AlexanderDeveloperSan Francisco302010/07/14$86,500
        Shad DeckerRegional DirectorEdinburgh512008/11/13$183,000
        Michael BruceJavascript DeveloperSingapore292011/06/27$183,000
        Donna SniderCustomer SupportNew York272011/01/25$112,000
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this + example:

        function eventMsg ( msg ) { + var n = document.getElementById('info'); + n.innerHTML += msg+"<br>"; + n.scrollTop = n.scrollHeight; +} + +$(document).ready(function() { + var table = $('#example').DataTable(); + var keys = new $.fn.dataTable.KeyTable( table ); + + /* Focus handler for all cells in last column */ + keys.event.focus( 4, null, function( node, x, y ) { + eventMsg( "Cell "+x+","+y+" focused ('live' event - column)" ); + } ); + + /* Focus handler for all cells in 8th row */ + keys.event.focus( null, 7, function( node, x, y ) { + eventMsg( "Cell "+x+","+y+" focused ('live' event - row)" ); + } ); + + /* Focus using coords. */ + keys.event.focus( 1, 0, function( node ) { + keys.event.remove.focus( node ); + eventMsg( "Cell 1,0 focus - this event has now been removed" ); + } ); + + keys.event.focus( 1, 3, function() { + eventMsg( "Cell 1,3 focus" ); + } ); + + /* focus with a node */ + keys.event.focus( $('#example tbody tr:eq(2) td:eq(0)')[0], function() { + eventMsg( "Cell 0,2 focus" ); + } ); + + /* Blur using a node */ + keys.event.blur( $('#example tbody tr:eq(1) td:eq(2)')[0], function() { + eventMsg( "Cell 1,2 blur" ); + } ); + + /* Blur using coords */ + keys.event.blur( 2, 4, function() { + eventMsg( "Cell 2,4 blur" ); + } ); + + /* Action */ + keys.event.action( 2, 2, function( node ) { + eventMsg( "Cell 2,2 action" ); + if ( node.style.fontWeight == "" || node.style.fontWeight == "normal" ) { + node.style.fontWeight = "bold"; + } + else { + node.style.fontWeight = "normal"; + } + } ); + + keys.event.action( 2, 5, function( node ) { + eventMsg( "Cell 2,5 action" ); + if ( node.style.fontStyle == "" ) { + node.style.fontStyle = "italic"; + } + else { + node.style.fontStyle = ""; + } + } ); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this + example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by + DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library + files (below), in order to correctly display the table. The additional CSS used is shown + below:

        +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the + table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data + will update automatically as any additional data is loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note + that this is just an example script using PHP. Server-side processing scripts can be written in any + language, using the protocol described in the + DataTables documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/KeyTable/examples/html.html b/public/assets/plugins/datatables/extensions/KeyTable/examples/html.html new file mode 100644 index 00000000..a0a0e108 --- /dev/null +++ b/public/assets/plugins/datatables/extensions/KeyTable/examples/html.html @@ -0,0 +1,627 @@ + + + + + + + + KeyTable example - Plain HTML table + + + + + + + + + + + + + + +
        +
        +

        KeyTable example Plain HTML table

        + +
        +

        As well as being usable with DataTables, KeyTable can also be used with a plain HTML table. Please + note that this ability is deprecated and will be removed in KeyTable 1.3.

        + +

        This example shows KeyTable being initialised without any parameter, which instructs it to search + for any table with the class KeyTable which will be used.

        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NamePositionOfficeAgeStart dateSalary
        NamePositionOfficeAgeStart dateSalary
        Tiger NixonSystem ArchitectEdinburgh612011/04/25$320,800
        Garrett WintersAccountantTokyo632011/07/25$170,750
        Ashton CoxJunior Technical AuthorSan Francisco662009/01/12$86,000
        Cedric KellySenior Javascript DeveloperEdinburgh222012/03/29$433,060
        Airi SatouAccountantTokyo332008/11/28$162,700
        Brielle WilliamsonIntegration SpecialistNew York612012/12/02$372,000
        Herrod ChandlerSales AssistantSan Francisco592012/08/06$137,500
        Rhona DavidsonIntegration SpecialistTokyo552010/10/14$327,900
        Colleen HurstJavascript DeveloperSan Francisco392009/09/15$205,500
        Sonya FrostSoftware EngineerEdinburgh232008/12/13$103,600
        Jena GainesOffice ManagerLondon302008/12/19$90,560
        Quinn FlynnSupport LeadEdinburgh222013/03/03$342,000
        Charde MarshallRegional DirectorSan Francisco362008/10/16$470,600
        Haley KennedySenior Marketing DesignerLondon432012/12/18$313,500
        Tatyana FitzpatrickRegional DirectorLondon192010/03/17$385,750
        Michael SilvaMarketing DesignerLondon662012/11/27$198,500
        Paul ByrdChief Financial Officer (CFO)New York642010/06/09$725,000
        Gloria LittleSystems AdministratorNew York592009/04/10$237,500
        Bradley GreerSoftware EngineerLondon412012/10/13$132,000
        Dai RiosPersonnel LeadEdinburgh352012/09/26$217,500
        Jenette CaldwellDevelopment LeadNew York302011/09/03$345,000
        Yuri BerryChief Marketing Officer (CMO)New York402009/06/25$675,000
        Caesar VancePre-Sales SupportNew York212011/12/12$106,450
        Doris WilderSales AssistantSidney232010/09/20$85,600
        Angelica RamosChief Executive Officer (CEO)London472009/10/09$1,200,000
        Gavin JoyceDeveloperEdinburgh422010/12/22$92,575
        Jennifer ChangRegional DirectorSingapore282010/11/14$357,650
        Brenden WagnerSoftware EngineerSan Francisco282011/06/07$206,850
        Fiona GreenChief Operating Officer (COO)San Francisco482010/03/11$850,000
        Shou ItouRegional MarketingTokyo202011/08/14$163,000
        Michelle HouseIntegration SpecialistSidney372011/06/02$95,400
        Suki BurksDeveloperLondon532009/10/22$114,500
        Prescott BartlettTechnical AuthorLondon272011/05/07$145,000
        Gavin CortezTeam LeaderSan Francisco222008/10/26$235,500
        Martena MccrayPost-Sales supportEdinburgh462011/03/09$324,050
        Unity ButlerMarketing DesignerSan Francisco472009/12/09$85,675
        Howard HatfieldOffice ManagerSan Francisco512008/12/16$164,500
        Hope FuentesSecretarySan Francisco412010/02/12$109,850
        Vivian HarrellFinancial ControllerSan Francisco622009/02/14$452,500
        Timothy MooneyOffice ManagerLondon372008/12/11$136,200
        Jackson BradshawDirectorNew York652008/09/26$645,750
        Olivia LiangSupport EngineerSingapore642011/02/03$234,500
        Bruno NashSoftware EngineerLondon382011/05/03$163,500
        Sakura YamamotoSupport EngineerTokyo372009/08/19$139,575
        Thor WaltonDeveloperNew York612013/08/11$98,540
        Finn CamachoSupport EngineerSan Francisco472009/07/07$87,500
        Serge BaldwinData CoordinatorSingapore642012/04/09$138,575
        Zenaida FrankSoftware EngineerNew York632010/01/04$125,250
        Zorita SerranoSoftware EngineerSan Francisco562012/06/01$115,000
        Jennifer AcostaJunior Javascript DeveloperEdinburgh432013/02/01$75,650
        Cara StevensSales AssistantNew York462011/12/06$145,600
        Hermione ButlerRegional DirectorLondon472011/03/21$356,250
        Lael GreerSystems AdministratorLondon212009/02/27$103,500
        Jonas AlexanderDeveloperSan Francisco302010/07/14$86,500
        Shad DeckerRegional DirectorEdinburgh512008/11/13$183,000
        Michael BruceJavascript DeveloperSingapore292011/06/27$183,000
        Donna SniderCustomer SupportNew York272011/01/25$112,000
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this + example:

        $(document).ready(function() { + $('#example').addClass('KeyTable'); + new $.fn.dataTable.KeyTable(); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this + example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by + DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library + files (below), in order to correctly display the table. The additional CSS used is shown + below:

        +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the + table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data + will update automatically as any additional data is loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note + that this is just an example script using PHP. Server-side processing scripts can be written in any + language, using the protocol described in the + DataTables documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/KeyTable/examples/index.html b/public/assets/plugins/datatables/extensions/KeyTable/examples/index.html new file mode 100644 index 00000000..71ab0a8f --- /dev/null +++ b/public/assets/plugins/datatables/extensions/KeyTable/examples/index.html @@ -0,0 +1,69 @@ + + + + + + + + + + + + + KeyTable examples - KeyTable examples + + + +
        +
        +

        KeyTable example KeyTable examples

        + +
        +

        KeyTable provides enhanced accessibility and navigation options for DataTables enhanced tables, by + allowing Excel like cell navigation on any table. Events (focus, blur, action etc) can be assigned to + individual cells, columns, rows or all cells to allow advanced interaction options.. Key features + include:

        + +
          +
        • Easy to use spreadsheet like interaction
        • +
        • Fully integrated with DataTables
        • +
        • Wide range of supported events
        • +
        • Works without DataTables if you just want a plain table
        • +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/KeyTable/examples/scrolling.html b/public/assets/plugins/datatables/extensions/KeyTable/examples/scrolling.html new file mode 100644 index 00000000..6df15805 --- /dev/null +++ b/public/assets/plugins/datatables/extensions/KeyTable/examples/scrolling.html @@ -0,0 +1,637 @@ + + + + + + + + KeyTable example - Scrolling table + + + + + + + + + + + + + + +
        +
        +

        KeyTable example Scrolling table

        + +
        +

        KeyTable supports DataTables' scrolling options (scrollXDT and scrollYDT) without required any additional + configuration. As the navigation keys are used to alter the focus of the KeyTable, the DataTables + scrolling position is altered to show the focused cell.

        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NamePositionOfficeAgeStart dateSalary
        NamePositionOfficeAgeStart dateSalary
        Tiger NixonSystem ArchitectEdinburgh612011/04/25$320,800
        Garrett WintersAccountantTokyo632011/07/25$170,750
        Ashton CoxJunior Technical AuthorSan Francisco662009/01/12$86,000
        Cedric KellySenior Javascript DeveloperEdinburgh222012/03/29$433,060
        Airi SatouAccountantTokyo332008/11/28$162,700
        Brielle WilliamsonIntegration SpecialistNew York612012/12/02$372,000
        Herrod ChandlerSales AssistantSan Francisco592012/08/06$137,500
        Rhona DavidsonIntegration SpecialistTokyo552010/10/14$327,900
        Colleen HurstJavascript DeveloperSan Francisco392009/09/15$205,500
        Sonya FrostSoftware EngineerEdinburgh232008/12/13$103,600
        Jena GainesOffice ManagerLondon302008/12/19$90,560
        Quinn FlynnSupport LeadEdinburgh222013/03/03$342,000
        Charde MarshallRegional DirectorSan Francisco362008/10/16$470,600
        Haley KennedySenior Marketing DesignerLondon432012/12/18$313,500
        Tatyana FitzpatrickRegional DirectorLondon192010/03/17$385,750
        Michael SilvaMarketing DesignerLondon662012/11/27$198,500
        Paul ByrdChief Financial Officer (CFO)New York642010/06/09$725,000
        Gloria LittleSystems AdministratorNew York592009/04/10$237,500
        Bradley GreerSoftware EngineerLondon412012/10/13$132,000
        Dai RiosPersonnel LeadEdinburgh352012/09/26$217,500
        Jenette CaldwellDevelopment LeadNew York302011/09/03$345,000
        Yuri BerryChief Marketing Officer (CMO)New York402009/06/25$675,000
        Caesar VancePre-Sales SupportNew York212011/12/12$106,450
        Doris WilderSales AssistantSidney232010/09/20$85,600
        Angelica RamosChief Executive Officer (CEO)London472009/10/09$1,200,000
        Gavin JoyceDeveloperEdinburgh422010/12/22$92,575
        Jennifer ChangRegional DirectorSingapore282010/11/14$357,650
        Brenden WagnerSoftware EngineerSan Francisco282011/06/07$206,850
        Fiona GreenChief Operating Officer (COO)San Francisco482010/03/11$850,000
        Shou ItouRegional MarketingTokyo202011/08/14$163,000
        Michelle HouseIntegration SpecialistSidney372011/06/02$95,400
        Suki BurksDeveloperLondon532009/10/22$114,500
        Prescott BartlettTechnical AuthorLondon272011/05/07$145,000
        Gavin CortezTeam LeaderSan Francisco222008/10/26$235,500
        Martena MccrayPost-Sales supportEdinburgh462011/03/09$324,050
        Unity ButlerMarketing DesignerSan Francisco472009/12/09$85,675
        Howard HatfieldOffice ManagerSan Francisco512008/12/16$164,500
        Hope FuentesSecretarySan Francisco412010/02/12$109,850
        Vivian HarrellFinancial ControllerSan Francisco622009/02/14$452,500
        Timothy MooneyOffice ManagerLondon372008/12/11$136,200
        Jackson BradshawDirectorNew York652008/09/26$645,750
        Olivia LiangSupport EngineerSingapore642011/02/03$234,500
        Bruno NashSoftware EngineerLondon382011/05/03$163,500
        Sakura YamamotoSupport EngineerTokyo372009/08/19$139,575
        Thor WaltonDeveloperNew York612013/08/11$98,540
        Finn CamachoSupport EngineerSan Francisco472009/07/07$87,500
        Serge BaldwinData CoordinatorSingapore642012/04/09$138,575
        Zenaida FrankSoftware EngineerNew York632010/01/04$125,250
        Zorita SerranoSoftware EngineerSan Francisco562012/06/01$115,000
        Jennifer AcostaJunior Javascript DeveloperEdinburgh432013/02/01$75,650
        Cara StevensSales AssistantNew York462011/12/06$145,600
        Hermione ButlerRegional DirectorLondon472011/03/21$356,250
        Lael GreerSystems AdministratorLondon212009/02/27$103,500
        Jonas AlexanderDeveloperSan Francisco302010/07/14$86,500
        Shad DeckerRegional DirectorEdinburgh512008/11/13$183,000
        Michael BruceJavascript DeveloperSingapore292011/06/27$183,000
        Donna SniderCustomer SupportNew York272011/01/25$112,000
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this + example:

        $(document).ready(function() { + var table = $('#example').DataTable( { + scrollY: 300, + paging: false + } ); + + new $.fn.dataTable.KeyTable( table ); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this + example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by + DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library + files (below), in order to correctly display the table. The additional CSS used is shown + below:

        +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the + table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data + will update automatically as any additional data is loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note + that this is just an example script using PHP. Server-side processing scripts can be written in any + language, using the protocol described in the + DataTables documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/KeyTable/examples/simple.html b/public/assets/plugins/datatables/extensions/KeyTable/examples/simple.html new file mode 100644 index 00000000..e18ed1c6 --- /dev/null +++ b/public/assets/plugins/datatables/extensions/KeyTable/examples/simple.html @@ -0,0 +1,631 @@ + + + + + + + + KeyTable example - Basic initialisation + + + + + + + + + + + + + + +
        +
        +

        KeyTable example Basic initialisation

        + +
        +

        KeyTable allows you to use keyboard navigation on a DataTables enhanced table, like an Excel + spreadsheet. The focused cell is shown through the CSS class ('focus') which in the case below is + simply a blue border. Use your keyboard's arrow keys and click the cells in the table to navigate.

        + +

        This example simply shows key table being initialised on a DataTable, but events can be listened for through the KeyTable API which provide interaction + options.

        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NamePositionOfficeAgeStart dateSalary
        NamePositionOfficeAgeStart dateSalary
        Tiger NixonSystem ArchitectEdinburgh612011/04/25$320,800
        Garrett WintersAccountantTokyo632011/07/25$170,750
        Ashton CoxJunior Technical AuthorSan Francisco662009/01/12$86,000
        Cedric KellySenior Javascript DeveloperEdinburgh222012/03/29$433,060
        Airi SatouAccountantTokyo332008/11/28$162,700
        Brielle WilliamsonIntegration SpecialistNew York612012/12/02$372,000
        Herrod ChandlerSales AssistantSan Francisco592012/08/06$137,500
        Rhona DavidsonIntegration SpecialistTokyo552010/10/14$327,900
        Colleen HurstJavascript DeveloperSan Francisco392009/09/15$205,500
        Sonya FrostSoftware EngineerEdinburgh232008/12/13$103,600
        Jena GainesOffice ManagerLondon302008/12/19$90,560
        Quinn FlynnSupport LeadEdinburgh222013/03/03$342,000
        Charde MarshallRegional DirectorSan Francisco362008/10/16$470,600
        Haley KennedySenior Marketing DesignerLondon432012/12/18$313,500
        Tatyana FitzpatrickRegional DirectorLondon192010/03/17$385,750
        Michael SilvaMarketing DesignerLondon662012/11/27$198,500
        Paul ByrdChief Financial Officer (CFO)New York642010/06/09$725,000
        Gloria LittleSystems AdministratorNew York592009/04/10$237,500
        Bradley GreerSoftware EngineerLondon412012/10/13$132,000
        Dai RiosPersonnel LeadEdinburgh352012/09/26$217,500
        Jenette CaldwellDevelopment LeadNew York302011/09/03$345,000
        Yuri BerryChief Marketing Officer (CMO)New York402009/06/25$675,000
        Caesar VancePre-Sales SupportNew York212011/12/12$106,450
        Doris WilderSales AssistantSidney232010/09/20$85,600
        Angelica RamosChief Executive Officer (CEO)London472009/10/09$1,200,000
        Gavin JoyceDeveloperEdinburgh422010/12/22$92,575
        Jennifer ChangRegional DirectorSingapore282010/11/14$357,650
        Brenden WagnerSoftware EngineerSan Francisco282011/06/07$206,850
        Fiona GreenChief Operating Officer (COO)San Francisco482010/03/11$850,000
        Shou ItouRegional MarketingTokyo202011/08/14$163,000
        Michelle HouseIntegration SpecialistSidney372011/06/02$95,400
        Suki BurksDeveloperLondon532009/10/22$114,500
        Prescott BartlettTechnical AuthorLondon272011/05/07$145,000
        Gavin CortezTeam LeaderSan Francisco222008/10/26$235,500
        Martena MccrayPost-Sales supportEdinburgh462011/03/09$324,050
        Unity ButlerMarketing DesignerSan Francisco472009/12/09$85,675
        Howard HatfieldOffice ManagerSan Francisco512008/12/16$164,500
        Hope FuentesSecretarySan Francisco412010/02/12$109,850
        Vivian HarrellFinancial ControllerSan Francisco622009/02/14$452,500
        Timothy MooneyOffice ManagerLondon372008/12/11$136,200
        Jackson BradshawDirectorNew York652008/09/26$645,750
        Olivia LiangSupport EngineerSingapore642011/02/03$234,500
        Bruno NashSoftware EngineerLondon382011/05/03$163,500
        Sakura YamamotoSupport EngineerTokyo372009/08/19$139,575
        Thor WaltonDeveloperNew York612013/08/11$98,540
        Finn CamachoSupport EngineerSan Francisco472009/07/07$87,500
        Serge BaldwinData CoordinatorSingapore642012/04/09$138,575
        Zenaida FrankSoftware EngineerNew York632010/01/04$125,250
        Zorita SerranoSoftware EngineerSan Francisco562012/06/01$115,000
        Jennifer AcostaJunior Javascript DeveloperEdinburgh432013/02/01$75,650
        Cara StevensSales AssistantNew York462011/12/06$145,600
        Hermione ButlerRegional DirectorLondon472011/03/21$356,250
        Lael GreerSystems AdministratorLondon212009/02/27$103,500
        Jonas AlexanderDeveloperSan Francisco302010/07/14$86,500
        Shad DeckerRegional DirectorEdinburgh512008/11/13$183,000
        Michael BruceJavascript DeveloperSingapore292011/06/27$183,000
        Donna SniderCustomer SupportNew York272011/01/25$112,000
        + +
          +
        • Javascript
        • +
        • HTML
        • +
        • CSS
        • +
        • Ajax
        • +
        • Server-side script
        • +
        + +
        +
        +

        The Javascript shown below is used to initialise the table shown in this + example:

        $(document).ready(function() { + var table = $('#example').DataTable(); + + new $.fn.dataTable.KeyTable( table ); +} ); + +

        In addition to the above code, the following Javascript library files are loaded for use in this + example:

        + + +
        + +
        +

        The HTML shown below is the raw HTML table element, before it has been enhanced by + DataTables:

        +
        + +
        +
        +

        This example uses a little bit of additional CSS beyond what is loaded from the library + files (below), in order to correctly display the table. The additional CSS used is shown + below:

        +
        + +

        The following CSS library files are loaded for use in this example to provide the styling of the + table:

        + + +
        + +
        +

        This table loads data by Ajax. The latest data that has been loaded is shown below. This data + will update automatically as any additional data is loaded.

        +
        + +
        +

        The script used to perform the server-side processing for this table is shown below. Please note + that this is just an example script using PHP. Server-side processing scripts can be written in any + language, using the protocol described in the + DataTables documentation.

        +
        +
        +
        +
        + +
        + +
        + + \ No newline at end of file diff --git a/public/assets/plugins/datatables/extensions/KeyTable/js/dataTables.keyTable.js b/public/assets/plugins/datatables/extensions/KeyTable/js/dataTables.keyTable.js new file mode 100644 index 00000000..f303f766 --- /dev/null +++ b/public/assets/plugins/datatables/extensions/KeyTable/js/dataTables.keyTable.js @@ -0,0 +1,1175 @@ +/*! KeyTable 1.2.1 + * ©2010-2014 SpryMedia Ltd - datatables.net/license + */ + +/** + * @summary KeyTable + * @description Spreadsheet like keyboard navigation for DataTables + * @version 1.2.1 + * @file dataTables.keyTable.js + * @author SpryMedia Ltd (www.sprymedia.co.uk) + * @contact www.sprymedia.co.uk/contact + * @copyright Copyright 2009-2014 SpryMedia Ltd. + * + * This source file is free software, available under the following license: + * MIT license - http://datatables.net/license/mit + * + * This source file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. + * + * For details please refer to: http://www.datatables.net + */ + +// Global scope for KeyTable for backwards compatibility. Will be removed in 1.3 +var KeyTable; + + +(function(window, document, undefined) { + + +var factory = function( $, DataTable ) { +"use strict"; + +KeyTable = function ( oInit ) +{ + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * API parameters + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + /* + * Variable: block + * Purpose: Flag whether or not KeyTable events should be processed + * Scope: KeyTable - public + */ + this.block = false; + + /* + * Variable: event + * Purpose: Container for all event application methods + * Scope: KeyTable - public + * Notes: This object contains all the public methods for adding and removing events - these + * are dynamically added later on + */ + this.event = { + "remove": {} + }; + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * API methods + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + /* + * Function: fnGetCurrentPosition + * Purpose: Get the currently focused cell's position + * Returns: array int: [ x, y ] + * Inputs: void + */ + this.fnGetCurrentPosition = function () + { + return [ _iOldX, _iOldY ]; + }; + + + /* + * Function: fnGetCurrentData + * Purpose: Get the currently focused cell's data (innerHTML) + * Returns: string: - data requested + * Inputs: void + */ + this.fnGetCurrentData = function () + { + return _nOldFocus.innerHTML; + }; + + + /* + * Function: fnGetCurrentTD + * Purpose: Get the currently focused cell + * Returns: node: - focused element + * Inputs: void + */ + this.fnGetCurrentTD = function () + { + return _nOldFocus; + }; + + + /* + * Function: fnSetPosition + * Purpose: Set the position of the focused cell + * Returns: - + * Inputs: int:x - x coordinate + * int:y - y coordinate + * Notes: Thanks to Rohan Daxini for the basis of this function + */ + this.fnSetPosition = function( x, y ) + { + if ( typeof x == 'object' && x.nodeName ) + { + _fnSetFocus( x ); + } + else + { + _fnSetFocus( _fnCellFromCoords(x, y) ); + } + }; + + + /* + * Function: fnBlur + * Purpose: Blur the current focus + * Returns: - + * Inputs: - + */ + this.fnBlur = function() + { + _fnBlur(); + }; + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Private parameters + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + /* + * Variable: _nBody + * Purpose: Body node of the table - cached for renference + * Scope: KeyTable - private + */ + var _nBody = null; + + /* + * Variable: + * Purpose: + * Scope: KeyTable - private + */ + var _nOldFocus = null; + + /* + * Variable: _iOldX and _iOldY + * Purpose: X and Y coords of the old elemet that was focused on + * Scope: KeyTable - private + */ + var _iOldX = null; + var _iOldY = null; + + /* + * Variable: _that + * Purpose: Scope saving for 'this' after a jQuery event + * Scope: KeyTable - private + */ + var _that = null; + + /* + * Variable: sFocusClass + * Purpose: Class that should be used for focusing on a cell + * Scope: KeyTable - private + */ + var _sFocusClass = "focus"; + + /* + * Variable: _bKeyCapture + * Purpose: Flag for should KeyTable capture key events or not + * Scope: KeyTable - private + */ + var _bKeyCapture = false; + + /* + * Variable: _oaoEvents + * Purpose: Event cache object, one array for each supported event for speed of searching + * Scope: KeyTable - private + */ + var _oaoEvents = { + "action": [], + "esc": [], + "focus": [], + "blur": [] + }; + + /* + * Variable: _oDatatable + * Purpose: DataTables settings object for if we are actually using a + * DataTables table + * Scope: KeyTable - private + */ + var _oDatatable = null; + + var _bForm; + var _nInput; + var _bInputFocused = false; + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Private methods + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Key table events + */ + + /* + * Function: _fnEventAddTemplate + * Purpose: Create a function (with closure for sKey) event addition API + * Returns: function: - template function + * Inputs: string:sKey - type of event to detect + */ + function _fnEventAddTemplate( sKey ) + { + /* + * Function: - + * Purpose: API function for adding event to cache + * Returns: - + * Inputs: 1. node:x - target node to add event for + * 2. function:y - callback function to apply + * or + * 1. int:x - x coord. of target cell (can be null for live events) + * 2. int:y - y coord. of target cell (can be null for live events) + * 3. function:z - callback function to apply + * Notes: This function is (interally) overloaded (in as much as javascript allows for + * that) - the target cell can be given by either node or coords. + */ + return function ( x, y, z ) { + if ( (x===null || typeof x == "number") && + (y===null || typeof y == "number") && + typeof z == "function" ) + { + _fnEventAdd( sKey, x, y, z ); + } + else if ( typeof x == "object" && typeof y == "function" ) + { + var aCoords = _fnCoordsFromCell( x ); + _fnEventAdd( sKey, aCoords[0], aCoords[1], y ); + } + else + { + alert( "Unhandable event type was added: x" +x+ " y:" +y+ " z:" +z ); + } + }; + } + + + /* + * Function: _fnEventRemoveTemplate + * Purpose: Create a function (with closure for sKey) event removal API + * Returns: function: - template function + * Inputs: string:sKey - type of event to detect + */ + function _fnEventRemoveTemplate( sKey ) + { + /* + * Function: - + * Purpose: API function for removing event from cache + * Returns: int: - number of events removed + * Inputs: 1. node:x - target node to remove event from + * 2. function:y - callback function to apply + * or + * 1. int:x - x coord. of target cell (can be null for live events) + * 2. int:y - y coord. of target cell (can be null for live events) + * 3. function:z - callback function to remove - optional + * Notes: This function is (interally) overloaded (in as much as javascript allows for + * that) - the target cell can be given by either node or coords and the function + * to remove is optional + */ + return function ( x, y, z ) { + if ( (x===null || typeof arguments[0] == "number") && + (y===null || typeof arguments[1] == "number" ) ) + { + if ( typeof arguments[2] == "function" ) + { + _fnEventRemove( sKey, x, y, z ); + } + else + { + _fnEventRemove( sKey, x, y ); + } + } + else if ( typeof arguments[0] == "object" ) + { + var aCoords = _fnCoordsFromCell( x ); + if ( typeof arguments[1] == "function" ) + { + _fnEventRemove( sKey, aCoords[0], aCoords[1], y ); + } + else + { + _fnEventRemove( sKey, aCoords[0], aCoords[1] ); + } + } + else + { + alert( "Unhandable event type was removed: x" +x+ " y:" +y+ " z:" +z ); + } + }; + } + + /* Use the template functions to add the event API functions */ + for ( var sKey in _oaoEvents ) + { + if ( sKey ) + { + this.event[sKey] = _fnEventAddTemplate( sKey ); + this.event.remove[sKey] = _fnEventRemoveTemplate( sKey ); + } + } + + + /* + * Function: _fnEventAdd + * Purpose: Add an event to the internal cache + * Returns: - + * Inputs: string:sType - type of event to add, given by the available elements in _oaoEvents + * int:x - x-coords to add event to - can be null for "blanket" event + * int:y - y-coords to add event to - can be null for "blanket" event + * function:fn - callback function for when triggered + */ + function _fnEventAdd( sType, x, y, fn ) + { + _oaoEvents[sType].push( { + "x": x, + "y": y, + "fn": fn + } ); + } + + + /* + * Function: _fnEventRemove + * Purpose: Remove an event from the event cache + * Returns: int: - number of matching events removed + * Inputs: string:sType - type of event to look for + * node:nTarget - target table cell + * function:fn - optional - remove this function. If not given all handlers of this + * type will be removed + */ + function _fnEventRemove( sType, x, y, fn ) + { + var iCorrector = 0; + + for ( var i=0, iLen=_oaoEvents[sType].length ; i= oSettings.fnDisplayEnd() ) + { + if ( oSettings._iDisplayLength >= 0 ) + { + /* Make sure we are not over running the display array */ + if ( oSettings._iDisplayStart + oSettings._iDisplayLength < oSettings.fnRecordsDisplay() ) + { + oSettings._iDisplayStart += oSettings._iDisplayLength; + } + } + else + { + oSettings._iDisplayStart = 0; + } + _oDatatable.oApi._fnCalculateEnd( oSettings ); + } + + /* Page backwards */ + while ( iRow < oSettings._iDisplayStart ) + { + oSettings._iDisplayStart = oSettings._iDisplayLength>=0 ? + oSettings._iDisplayStart - oSettings._iDisplayLength : + 0; + + if ( oSettings._iDisplayStart < 0 ) + { + oSettings._iDisplayStart = 0; + } + _oDatatable.oApi._fnCalculateEnd( oSettings ); + } + + /* Re-draw the table */ + _oDatatable.oApi._fnDraw( oSettings ); + + /* Restore the key capture */ + _bKeyCapture = bKeyCaptureCache; + } + + /* Cache the information that we are interested in */ + var aNewPos = _fnCoordsFromCell( nTarget ); + _nOldFocus = nTarget; + _iOldX = aNewPos[0]; + _iOldY = aNewPos[1]; + + var iViewportHeight, iViewportWidth, iScrollTop, iScrollLeft, iHeight, iWidth, aiPos; + if ( bAutoScroll ) + { + /* Scroll the viewport such that the new cell is fully visible in the rendered window */ + iViewportHeight = $(window).height(); + iViewportWidth = $(window).width(); + iScrollTop = $(document).scrollTop(); + iScrollLeft = $(document).scrollLeft(); + iHeight = nTarget.offsetHeight; + iWidth = nTarget.offsetWidth; + aiPos = _fnGetPos( nTarget ); + + /* Take account of scrolling in DataTables 1.7 - remove scrolling since that would add to + * the positioning calculation + */ + if ( _oDatatable && typeof oSettings.oScroll != 'undefined' && + (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "") ) + { + aiPos[1] -= $(oSettings.nTable.parentNode).scrollTop(); + aiPos[0] -= $(oSettings.nTable.parentNode).scrollLeft(); + } + + /* Correct viewport positioning for vertical scrolling */ + if ( aiPos[1]+iHeight > iScrollTop+iViewportHeight ) + { + /* Displayed element if off the bottom of the viewport */ + _fnSetScrollTop( aiPos[1]+iHeight - iViewportHeight ); + } + else if ( aiPos[1] < iScrollTop ) + { + /* Displayed element if off the top of the viewport */ + _fnSetScrollTop( aiPos[1] ); + } + + /* Correct viewport positioning for horizontal scrolling */ + if ( aiPos[0]+iWidth > iScrollLeft+iViewportWidth ) + { + /* Displayed element is off the bottom of the viewport */ + _fnSetScrollLeft( aiPos[0]+iWidth - iViewportWidth ); + } + else if ( aiPos[0] < iScrollLeft ) + { + /* Displayed element if off the Left of the viewport */ + _fnSetScrollLeft( aiPos[0] ); + } + } + + /* Take account of scrolling in DataTables 1.7 */ + if ( _oDatatable && typeof oSettings.oScroll != 'undefined' && + (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "") ) + { + var dtScrollBody = oSettings.nTable.parentNode; + iViewportHeight = dtScrollBody.clientHeight; + iViewportWidth = dtScrollBody.clientWidth; + iScrollTop = dtScrollBody.scrollTop; + iScrollLeft = dtScrollBody.scrollLeft; + iHeight = nTarget.offsetHeight; + iWidth = nTarget.offsetWidth; + + /* Correct for vertical scrolling */ + if ( nTarget.offsetTop + iHeight > iViewportHeight+iScrollTop ) + { + dtScrollBody.scrollTop = (nTarget.offsetTop + iHeight) - iViewportHeight; + } + else if ( nTarget.offsetTop < iScrollTop ) + { + dtScrollBody.scrollTop = nTarget.offsetTop; + } + + /* Correct for horizontal scrolling */ + if ( nTarget.offsetLeft + iWidth > iViewportWidth+iScrollLeft ) + { + dtScrollBody.scrollLeft = (nTarget.offsetLeft + iWidth) - iViewportWidth; + } + else if ( nTarget.offsetLeft < iScrollLeft ) + { + dtScrollBody.scrollLeft = nTarget.offsetLeft; + } + } + + /* Focused - so we want to capture the keys */ + _fnCaptureKeys(); + + /* Fire of the focus event if there is one */ + _fnEventFire( "focus", _iOldX, _iOldY ); + } + + + /* + * Function: _fnBlur + * Purpose: Blur focus from the whole table + * Returns: - + * Inputs: - + */ + function _fnBlur() + { + _fnRemoveFocus( _nOldFocus ); + _iOldX = null; + _iOldY = null; + _nOldFocus = null; + _fnReleaseKeys(); + } + + + /* + * Function: _fnRemoveFocus + * Purpose: Remove focus from a cell and fire any blur events which are attached + * Returns: - + * Inputs: node:nTarget - cell of interest + */ + function _fnRemoveFocus( nTarget ) + { + $(nTarget).removeClass( _sFocusClass ); + $(nTarget).parent().removeClass( _sFocusClass ); + _fnEventFire( "blur", _iOldX, _iOldY ); + } + + + /* + * Function: _fnClick + * Purpose: Focus on the element that has been clicked on by the user + * Returns: - + * Inputs: event:e - click event + */ + function _fnClick ( e ) + { + var nTarget = this; + while ( nTarget.nodeName != "TD" ) + { + nTarget = nTarget.parentNode; + } + + _fnSetFocus( nTarget ); + _fnCaptureKeys(); + } + + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Key events + */ + + /* + * Function: _fnKey + * Purpose: Deal with a key events, be it moving the focus or return etc. + * Returns: bool: - allow browser default action + * Inputs: event:e - key event + */ + function _fnKey ( e ) + { + /* If user or system has blocked KeyTable from doing anything, just ignore this event */ + if ( _that.block || !_bKeyCapture ) + { + return true; + } + + /* If a modifier key is pressed (exapct shift), ignore the event */ + if ( e.metaKey || e.altKey || e.ctrlKey ) + { + return true; + } + var + x, y, + iTableWidth = _nBody.getElementsByTagName('tr')[0].getElementsByTagName('td').length, + iTableHeight; + + /* Get table height and width - done here so as to be dynamic (if table is updated) */ + if ( _oDatatable ) + { + /* + * Locate the current node in the DataTable overriding the old positions - the reason for + * is is that there might have been some DataTables interaction between the last focus and + * now + */ + iTableHeight = _oDatatable.aiDisplay.length; + + var aDtPos = _fnFindDtCell( _nOldFocus ); + if ( aDtPos === null ) + { + /* If the table has been updated such that the focused cell can't be seen - do nothing */ + return; + } + _iOldX = aDtPos[ 0 ]; + _iOldY = aDtPos[ 1 ]; + } + else + { + iTableHeight = _nBody.getElementsByTagName('tr').length; + } + + /* Capture shift+tab to match the left arrow key */ + var iKey = (e.keyCode == 9 && e.shiftKey) ? -1 : e.keyCode; + + switch( iKey ) + { + case 13: /* return */ + e.preventDefault(); + e.stopPropagation(); + _fnEventFire( "action", _iOldX, _iOldY ); + return true; + + case 27: /* esc */ + if ( !_fnEventFire( "esc", _iOldX, _iOldY ) ) + { + /* Only lose focus if there isn't an escape handler on the cell */ + _fnBlur(); + return; + } + x = _iOldX; + y = _iOldY; + break; + + case -1: + case 37: /* left arrow */ + if ( _iOldX > 0 ) { + x = _iOldX - 1; + y = _iOldY; + } else if ( _iOldY > 0 ) { + x = iTableWidth-1; + y = _iOldY - 1; + } else { + /* at start of table */ + if ( iKey == -1 && _bForm ) + { + /* If we are in a form, return focus to the 'input' element such that tabbing will + * follow correctly in the browser + */ + _bInputFocused = true; + _nInput.focus(); + + /* This timeout is a little nasty - but IE appears to have some asyhnc behaviour for + * focus + */ + setTimeout( function(){ _bInputFocused = false; }, 0 ); + _bKeyCapture = false; + _fnBlur(); + return true; + } + else + { + return false; + } + } + break; + + case 38: /* up arrow */ + if ( _iOldY > 0 ) { + x = _iOldX; + y = _iOldY - 1; + } else { + return false; + } + break; + + case 36: /* home */ + x = _iOldX; + y = 0; + break; + + case 33: /* page up */ + x = _iOldX; + y = _iOldY - 10; + if (y < 0) { + y = 0; + } + break; + + case 9: /* tab */ + case 39: /* right arrow */ + if ( _iOldX < iTableWidth-1 ) { + x = _iOldX + 1; + y = _iOldY; + } else if ( _iOldY < iTableHeight-1 ) { + x = 0; + y = _iOldY + 1; + } else { + /* at end of table */ + if ( iKey == 9 && _bForm ) + { + /* If we are in a form, return focus to the 'input' element such that tabbing will + * follow correctly in the browser + */ + _bInputFocused = true; + _nInput.focus(); + + /* This timeout is a little nasty - but IE appears to have some asyhnc behaviour for + * focus + */ + setTimeout( function(){ _bInputFocused = false; }, 0 ); + _bKeyCapture = false; + _fnBlur(); + return true; + } + else + { + return false; + } + } + break; + + case 40: /* down arrow */ + if ( _iOldY < iTableHeight-1 ) { + x = _iOldX; + y = _iOldY + 1; + } else { + return false; + } + break; + + case 35: /* end */ + x = _iOldX; + y = iTableHeight-1; + break; + + case 34: /* page down */ + x = _iOldX; + y = _iOldY+10; + if (y > iTableHeight-1) { + y = iTableHeight-1; + } + break; + + default: /* Nothing we are interested in */ + return true; + } + + _fnSetFocus( _fnCellFromCoords(x, y) ); + return false; + } + + + /* + * Function: _fnCaptureKeys + * Purpose: Start capturing key events for this table + * Returns: - + * Inputs: - + */ + function _fnCaptureKeys( ) + { + if ( !_bKeyCapture ) + { + _bKeyCapture = true; + } + } + + + /* + * Function: _fnReleaseKeys + * Purpose: Stop capturing key events for this table + * Returns: - + * Inputs: - + */ + function _fnReleaseKeys( ) + { + _bKeyCapture = false; + } + + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Support functions + */ + + /* + * Function: _fnCellFromCoords + * Purpose: Calulate the target TD cell from x and y coordinates + * Returns: node: - TD target + * Inputs: int:x - x coordinate + * int:y - y coordinate + */ + function _fnCellFromCoords( x, y ) + { + if ( _oDatatable ) + { + if ( typeof _oDatatable.aoData[ _oDatatable.aiDisplay[ y ] ] != 'undefined' ) + { + return _oDatatable.aoData[ _oDatatable.aiDisplay[ y ] ].nTr.getElementsByTagName('td')[x]; + } + else + { + return null; + } + } + else + { + return $('tr:eq('+y+')>td:eq('+x+')', _nBody )[0]; + } + } + + + /* + * Function: _fnCoordsFromCell + * Purpose: Calculate the x and y position in a table from a TD cell + * Returns: array[2] int: [x, y] + * Inputs: node:n - TD cell of interest + * Notes: Not actually interested in this for DataTables since it might go out of date + */ + function _fnCoordsFromCell( n ) + { + if ( _oDatatable ) + { + return [ + $('td', n.parentNode).index(n), + $('tr', n.parentNode.parentNode).index(n.parentNode) + _oDatatable._iDisplayStart + ]; + } + else + { + return [ + $('td', n.parentNode).index(n), + $('tr', n.parentNode.parentNode).index(n.parentNode) + ]; + } + } + + + /* + * Function: _fnSetScrollTop + * Purpose: Set the vertical scrolling position + * Returns: - + * Inputs: int:iPos - scrolltop + * Notes: This is so nasty, but without browser detection you can't tell which you should set + * So on browsers that support both, the scroll top will be set twice. I can live with + * that :-) + */ + function _fnSetScrollTop( iPos ) + { + document.documentElement.scrollTop = iPos; + document.body.scrollTop = iPos; + } + + + /* + * Function: _fnSetScrollLeft + * Purpose: Set the horizontal scrolling position + * Returns: - + * Inputs: int:iPos - scrollleft + */ + function _fnSetScrollLeft( iPos ) + { + document.documentElement.scrollLeft = iPos; + document.body.scrollLeft = iPos; + } + + + /* + * Function: _fnGetPos + * Purpose: Get the position of an object on the rendered page + * Returns: array[2] int: [left, right] + * Inputs: node:obj - element of interest + */ + function _fnGetPos ( obj ) + { + var iLeft = 0; + var iTop = 0; + + if (obj.offsetParent) + { + iLeft = obj.offsetLeft; + iTop = obj.offsetTop; + obj = obj.offsetParent; + while (obj) + { + iLeft += obj.offsetLeft; + iTop += obj.offsetTop; + obj = obj.offsetParent; + } + } + return [iLeft,iTop]; + } + + + /* + * Function: _fnFindDtCell + * Purpose: Get the coords. of a cell from the DataTables internal information + * Returns: array[2] int: [x, y] coords. or null if not found + * Inputs: node:nTarget - the node of interest + */ + function _fnFindDtCell( nTarget ) + { + for ( var i=0, iLen=_oDatatable.aiDisplay.length ; i
  • '+ + '

    Copied '+lines+' row'+plural+' to the clipboard.

    ', + 1500 + ); + } + } ), + + "pdf": $.extend( {}, TableTools.buttonBase, { + "sAction": "flash_pdf", + "sNewLine": "\n", + "sFileName": "*.pdf", + "sButtonClass": "DTTT_button_pdf", + "sButtonText": "PDF", + "sPdfOrientation": "portrait", + "sPdfSize": "A4", + "sPdfMessage": "", + "fnClick": function( nButton, oConfig, flash ) { + this.fnSetText( flash, + "title:"+ this.fnGetTitle(oConfig) +"\n"+ + "message:"+ oConfig.sPdfMessage +"\n"+ + "colWidth:"+ this.fnCalcColRatios(oConfig) +"\n"+ + "orientation:"+ oConfig.sPdfOrientation +"\n"+ + "size:"+ oConfig.sPdfSize +"\n"+ + "--/TableToolsOpts--\n" + + this.fnGetTableData(oConfig) + ); + } + } ), + + "print": $.extend( {}, TableTools.buttonBase, { + "sInfo": "
    Print view

    Please use your browser's print function to "+ + "print this table. Press escape when finished.

    ", + "sMessage": null, + "bShowAll": true, + "sToolTip": "View print view", + "sButtonClass": "DTTT_button_print", + "sButtonText": "Print", + "fnClick": function ( nButton, oConfig ) { + this.fnPrint( true, oConfig ); + } + } ), + + "text": $.extend( {}, TableTools.buttonBase ), + + "select": $.extend( {}, TableTools.buttonBase, { + "sButtonText": "Select button", + "fnSelect": function( nButton, oConfig ) { + if ( this.fnGetSelected().length !== 0 ) { + $(nButton).removeClass( this.classes.buttons.disabled ); + } else { + $(nButton).addClass( this.classes.buttons.disabled ); + } + }, + "fnInit": function( nButton, oConfig ) { + $(nButton).addClass( this.classes.buttons.disabled ); + } + } ), + + "select_single": $.extend( {}, TableTools.buttonBase, { + "sButtonText": "Select button", + "fnSelect": function( nButton, oConfig ) { + var iSelected = this.fnGetSelected().length; + if ( iSelected == 1 ) { + $(nButton).removeClass( this.classes.buttons.disabled ); + } else { + $(nButton).addClass( this.classes.buttons.disabled ); + } + }, + "fnInit": function( nButton, oConfig ) { + $(nButton).addClass( this.classes.buttons.disabled ); + } + } ), + + "select_all": $.extend( {}, TableTools.buttonBase, { + "sButtonText": "Select all", + "fnClick": function( nButton, oConfig ) { + this.fnSelectAll(); + }, + "fnSelect": function( nButton, oConfig ) { + if ( this.fnGetSelected().length == this.s.dt.fnRecordsDisplay() ) { + $(nButton).addClass( this.classes.buttons.disabled ); + } else { + $(nButton).removeClass( this.classes.buttons.disabled ); + } + } + } ), + + "select_none": $.extend( {}, TableTools.buttonBase, { + "sButtonText": "Deselect all", + "fnClick": function( nButton, oConfig ) { + this.fnSelectNone(); + }, + "fnSelect": function( nButton, oConfig ) { + if ( this.fnGetSelected().length !== 0 ) { + $(nButton).removeClass( this.classes.buttons.disabled ); + } else { + $(nButton).addClass( this.classes.buttons.disabled ); + } + }, + "fnInit": function( nButton, oConfig ) { + $(nButton).addClass( this.classes.buttons.disabled ); + } + } ), + + "ajax": $.extend( {}, TableTools.buttonBase, { + "sAjaxUrl": "/xhr.php", + "sButtonText": "Ajax button", + "fnClick": function( nButton, oConfig ) { + var sData = this.fnGetTableData(oConfig); + $.ajax( { + "url": oConfig.sAjaxUrl, + "data": [ + { "name": "tableData", "value": sData } + ], + "success": oConfig.fnAjaxComplete, + "dataType": "json", + "type": "POST", + "cache": false, + "error": function () { + alert( "Error detected when sending table data to server" ); + } + } ); + }, + "fnAjaxComplete": function( json ) { + alert( 'Ajax complete' ); + } + } ), + + "div": $.extend( {}, TableTools.buttonBase, { + "sAction": "div", + "sTag": "div", + "sButtonClass": "DTTT_nonbutton", + "sButtonText": "Text button" + } ), + + "collection": $.extend( {}, TableTools.buttonBase, { + "sAction": "collection", + "sButtonClass": "DTTT_button_collection", + "sButtonText": "Collection", + "fnClick": function( nButton, oConfig ) { + this._fnCollectionShow(nButton, oConfig); + } + } ) +}; +/* + * on* callback parameters: + * 1. node - button element + * 2. object - configuration object for this button + * 3. object - ZeroClipboard reference (flash button only) + * 4. string - Returned string from Flash (flash button only - and only on 'complete') + */ + +// Alias to match the other plug-ins styling +TableTools.buttons = TableTools.BUTTONS; + + +/** + * @namespace Classes used by TableTools - allows the styles to be override easily. + * Note that when TableTools initialises it will take a copy of the classes object + * and will use its internal copy for the remainder of its run time. + */ +TableTools.classes = { + "container": "DTTT_container", + "buttons": { + "normal": "DTTT_button", + "disabled": "DTTT_disabled" + }, + "collection": { + "container": "DTTT_collection", + "background": "DTTT_collection_background", + "buttons": { + "normal": "DTTT_button", + "disabled": "DTTT_disabled" + } + }, + "select": { + "table": "DTTT_selectable", + "row": "DTTT_selected selected" + }, + "print": { + "body": "DTTT_Print", + "info": "DTTT_print_info", + "message": "DTTT_PrintMessage" + } +}; + + +/** + * @namespace ThemeRoller classes - built in for compatibility with DataTables' + * bJQueryUI option. + */ +TableTools.classes_themeroller = { + "container": "DTTT_container ui-buttonset ui-buttonset-multi", + "buttons": { + "normal": "DTTT_button ui-button ui-state-default" + }, + "collection": { + "container": "DTTT_collection ui-buttonset ui-buttonset-multi" + } +}; + + +/** + * @namespace TableTools default settings for initialisation + */ +TableTools.DEFAULTS = { + "sSwfPath": "../swf/copy_csv_xls_pdf.swf", + "sRowSelect": "none", + "sRowSelector": "tr", + "sSelectedClass": null, + "fnPreRowSelect": null, + "fnRowSelected": null, + "fnRowDeselected": null, + "aButtons": [ "copy", "csv", "xls", "pdf", "print" ], + "oTags": { + "container": "div", + "button": "a", // We really want to use buttons here, but Firefox and IE ignore the + // click on the Flash element in the button (but not mouse[in|out]). + "liner": "span", + "collection": { + "container": "div", + "button": "a", + "liner": "span" + } + } +}; + +// Alias to match the other plug-ins +TableTools.defaults = TableTools.DEFAULTS; + + +/** + * Name of this class + * @constant CLASS + * @type String + * @default TableTools + */ +TableTools.prototype.CLASS = "TableTools"; + + +/** + * TableTools version + * @constant VERSION + * @type String + * @default See code + */ +TableTools.version = "2.2.4"; + + + +// DataTables 1.10 API +// +// This will be extended in a big way in in TableTools 3 to provide API methods +// such as rows().select() and rows.selected() etc, but for the moment the +// tabletools() method simply returns the instance. + +if ( $.fn.dataTable.Api ) { + $.fn.dataTable.Api.register( 'tabletools()', function () { + var tt = null; + + if ( this.context.length > 0 ) { + tt = TableTools.fnGetInstance( this.context[0].nTable ); + } + + return tt; + } ); +} + + + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Initialisation + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Register a new feature with DataTables + */ +if ( typeof $.fn.dataTable == "function" && + typeof $.fn.dataTableExt.fnVersionCheck == "function" && + $.fn.dataTableExt.fnVersionCheck('1.9.0') ) +{ + $.fn.dataTableExt.aoFeatures.push( { + "fnInit": function( oDTSettings ) { + var init = oDTSettings.oInit; + var opts = init ? + init.tableTools || init.oTableTools || {} : + {}; + + return new TableTools( oDTSettings.oInstance, opts ).dom.container; + }, + "cFeature": "T", + "sFeature": "TableTools" + } ); +} +else +{ + alert( "Warning: TableTools requires DataTables 1.9.0 or newer - www.datatables.net/download"); +} + +$.fn.DataTable.TableTools = TableTools; + +})(jQuery, window, document); + +/* + * Register a new feature with DataTables + */ +if ( typeof $.fn.dataTable == "function" && + typeof $.fn.dataTableExt.fnVersionCheck == "function" && + $.fn.dataTableExt.fnVersionCheck('1.9.0') ) +{ + $.fn.dataTableExt.aoFeatures.push( { + "fnInit": function( oDTSettings ) { + var oOpts = typeof oDTSettings.oInit.oTableTools != 'undefined' ? + oDTSettings.oInit.oTableTools : {}; + + var oTT = new TableTools( oDTSettings.oInstance, oOpts ); + TableTools._aInstances.push( oTT ); + + return oTT.dom.container; + }, + "cFeature": "T", + "sFeature": "TableTools" + } ); +} +else +{ + alert( "Warning: TableTools 2 requires DataTables 1.9.0 or newer - www.datatables.net/download"); +} + + +$.fn.dataTable.TableTools = TableTools; +$.fn.DataTable.TableTools = TableTools; + + +return TableTools; +}; // /factory + + +// Define as an AMD module if possible +if ( typeof define === 'function' && define.amd ) { + define( ['jquery', 'datatables'], factory ); +} +else if ( typeof exports === 'object' ) { + // Node/CommonJS + factory( require('jquery'), require('datatables') ); +} +else if ( jQuery && !jQuery.fn.dataTable.TableTools ) { + // Otherwise simply initialise as normal, stopping multiple evaluation + factory( jQuery, jQuery.fn.dataTable ); +} + + +})(window, document); + diff --git a/public/assets/plugins/datatables/extensions/TableTools/js/dataTables.tableTools.min.js b/public/assets/plugins/datatables/extensions/TableTools/js/dataTables.tableTools.min.js new file mode 100644 index 00000000..e8c87056 --- /dev/null +++ b/public/assets/plugins/datatables/extensions/TableTools/js/dataTables.tableTools.min.js @@ -0,0 +1,70 @@ +/*! + TableTools 2.2.4 + 2009-2015 SpryMedia Ltd - datatables.net/license + + ZeroClipboard 1.0.4 + Author: Joseph Huckaby - MIT licensed +*/ +var TableTools; +(function(n,k,q){var p=function(m,p){var g={version:"1.0.4-TableTools2",clients:{},moviePath:"",nextId:1,$:function(a){"string"==typeof a&&(a=k.getElementById(a));a.addClass||(a.hide=function(){this.style.display="none"},a.show=function(){this.style.display=""},a.addClass=function(a){this.removeClass(a);this.className+=" "+a},a.removeClass=function(a){this.className=this.className.replace(RegExp("\\s*"+a+"\\s*")," ").replace(/^\s+/,"").replace(/\s+$/,"")},a.hasClass=function(a){return!!this.className.match(RegExp("\\s*"+a+ +"\\s*"))});return a},setMoviePath:function(a){this.moviePath=a},dispatch:function(a,b,c){(a=this.clients[a])&&a.receiveEvent(b,c)},register:function(a,b){this.clients[a]=b},getDOMObjectPosition:function(a){var b={left:0,top:0,width:a.width?a.width:a.offsetWidth,height:a.height?a.height:a.offsetHeight};""!==a.style.width&&(b.width=a.style.width.replace("px",""));""!==a.style.height&&(b.height=a.style.height.replace("px",""));for(;a;)b.left+=a.offsetLeft,b.top+=a.offsetTop,a=a.offsetParent;return b}, +Client:function(a){this.handlers={};this.id=g.nextId++;this.movieId="ZeroClipboard_TableToolsMovie_"+this.id;g.register(this.id,this);a&&this.glue(a)}};g.Client.prototype={id:0,ready:!1,movie:null,clipText:"",fileName:"",action:"copy",handCursorEnabled:!0,cssEffects:!0,handlers:null,sized:!1,glue:function(a,b){this.domElement=g.$(a);var c=99;this.domElement.style.zIndex&&(c=parseInt(this.domElement.style.zIndex,10)+1);var d=g.getDOMObjectPosition(this.domElement);this.div=k.createElement("div");var f= +this.div.style;f.position="absolute";f.left="0px";f.top="0px";f.width=d.width+"px";f.height=d.height+"px";f.zIndex=c;"undefined"!=typeof b&&""!==b&&(this.div.title=b);0!==d.width&&0!==d.height&&(this.sized=!0);this.domElement&&(this.domElement.appendChild(this.div),this.div.innerHTML=this.getHTML(d.width,d.height).replace(/&/g,"&"))},positionElement:function(){var a=g.getDOMObjectPosition(this.domElement),b=this.div.style;b.position="absolute";b.width=a.width+"px";b.height=a.height+"px";0!==a.width&& +0!==a.height&&(this.sized=!0,b=this.div.childNodes[0],b.width=a.width,b.height=a.height)},getHTML:function(a,b){var c="",d="id="+this.id+"&width="+a+"&height="+b;if(navigator.userAgent.match(/MSIE/))var f=location.href.match(/^https/i)?"https://":"http://",c=c+('');else c+='';return c},hide:function(){this.div&&(this.div.style.left="-2000px")},show:function(){this.reposition()},destroy:function(){if(this.domElement&&this.div){this.hide();this.div.innerHTML="";var a=k.getElementsByTagName("body")[0];try{a.removeChild(this.div)}catch(b){}this.div=this.domElement=null}},reposition:function(a){a&&((this.domElement=g.$(a))||this.hide());if(this.domElement&&this.div){var a=g.getDOMObjectPosition(this.domElement),b=this.div.style;b.left=""+a.left+ +"px";b.top=""+a.top+"px"}},clearText:function(){this.clipText="";this.ready&&this.movie.clearText()},appendText:function(a){this.clipText+=a;this.ready&&this.movie.appendText(a)},setText:function(a){this.clipText=a;this.ready&&this.movie.setText(a)},setCharSet:function(a){this.charSet=a;this.ready&&this.movie.setCharSet(a)},setBomInc:function(a){this.incBom=a;this.ready&&this.movie.setBomInc(a)},setFileName:function(a){this.fileName=a;this.ready&&this.movie.setFileName(a)},setAction:function(a){this.action= +a;this.ready&&this.movie.setAction(a)},addEventListener:function(a,b){a=a.toString().toLowerCase().replace(/^on/,"");this.handlers[a]||(this.handlers[a]=[]);this.handlers[a].push(b)},setHandCursor:function(a){this.handCursorEnabled=a;this.ready&&this.movie.setHandCursor(a)},setCSSEffects:function(a){this.cssEffects=!!a},receiveEvent:function(a,b){var c,a=a.toString().toLowerCase().replace(/^on/,"");switch(a){case "load":this.movie=k.getElementById(this.movieId);if(!this.movie){c=this;setTimeout(function(){c.receiveEvent("load", +null)},1);return}if(!this.ready&&navigator.userAgent.match(/Firefox/)&&navigator.userAgent.match(/Windows/)){c=this;setTimeout(function(){c.receiveEvent("load",null)},100);this.ready=!0;return}this.ready=!0;this.movie.clearText();this.movie.appendText(this.clipText);this.movie.setFileName(this.fileName);this.movie.setAction(this.action);this.movie.setCharSet(this.charSet);this.movie.setBomInc(this.incBom);this.movie.setHandCursor(this.handCursorEnabled);break;case "mouseover":this.domElement&&this.cssEffects&& +this.recoverActive&&this.domElement.addClass("active");break;case "mouseout":this.domElement&&this.cssEffects&&(this.recoverActive=!1,this.domElement.hasClass("active")&&(this.domElement.removeClass("active"),this.recoverActive=!0));break;case "mousedown":this.domElement&&this.cssEffects&&this.domElement.addClass("active");break;case "mouseup":this.domElement&&this.cssEffects&&(this.domElement.removeClass("active"),this.recoverActive=!1)}if(this.handlers[a])for(var d=0,f=this.handlers[a].length;d< +f;d++){var e=this.handlers[a][d];if("function"==typeof e)e(this,b);else if("object"==typeof e&&2==e.length)e[0][e[1]](this,b);else if("string"==typeof e)n[e](this,b)}}};n.ZeroClipboard_TableTools=g;var e=jQuery;TableTools=function(a,b){!this instanceof TableTools&&alert("Warning: TableTools must be initialised with the keyword 'new'");this.s={that:this,dt:e.fn.dataTable.Api?(new e.fn.dataTable.Api(a)).settings()[0]:a.fnSettings(),print:{saveStart:-1,saveLength:-1,saveScroll:-1,funcEnd:function(){}}, +buttonCounter:0,select:{type:"",selected:[],preRowSelect:null,postSelected:null,postDeselected:null,all:!1,selectedClass:""},custom:{},swfPath:"",buttonSet:[],master:!1,tags:{}};this.dom={container:null,table:null,print:{hidden:[],message:null},collection:{collection:null,background:null}};this.classes=e.extend(!0,{},TableTools.classes);this.s.dt.bJUI&&e.extend(!0,this.classes,TableTools.classes_themeroller);this.fnSettings=function(){return this.s};"undefined"==typeof b&&(b={});TableTools._aInstances.push(this); +this._fnConstruct(b);return this};TableTools.prototype={fnGetSelected:function(a){var b=[],c=this.s.dt.aoData,d=this.s.dt.aiDisplay,f;if(a){a=0;for(f=d.length;a"¡".toString().length?b.replace(/[^a-zA-Z0-9_\u00A1-\uFFFF\.,\-_ !\(\)]/g,""):b.replace(/[^a-zA-Z0-9_\.,\-_ !\(\)]/g,"")},fnCalcColRatios:function(a){var b=this.s.dt.aoColumns,a=this._fnColumnTargets(a.mColumns),c=[],d=0,f=0,e,i;e=0;for(i=a.length;e").addClass(this.classes.print.info).html(a).appendTo("body");setTimeout(function(){c.fadeOut("normal",function(){c.remove()})},b)},fnContainer:function(){return this.dom.container},_fnConstruct:function(a){var b=this;this._fnCustomiseSettings(a);this.dom.container=k.createElement(this.s.tags.container);this.dom.container.className=this.classes.container; +"none"!=this.s.select.type&&this._fnRowSelectConfig();this._fnButtonDefinations(this.s.buttonSet,this.dom.container);this.s.dt.aoDestroyCallback.push({sName:"TableTools",fn:function(){e(b.s.dt.nTBody).off("click.DTTT_Select",b.s.custom.sRowSelector).off("mousedown.DTTT_Select","tr").off("mouseup.DTTT_Select","tr");e(b.dom.container).empty();var a=e.inArray(b,TableTools._aInstances);-1!==a&&TableTools._aInstances.splice(a,1)}})},_fnCustomiseSettings:function(a){"undefined"==typeof this.s.dt._TableToolsInit&& +(this.s.master=!0,this.s.dt._TableToolsInit=!0);this.dom.table=this.s.dt.nTable;this.s.custom=e.extend({},TableTools.DEFAULTS,a);this.s.swfPath=this.s.custom.sSwfPath;"undefined"!=typeof g&&(g.moviePath=this.s.swfPath);this.s.select.type=this.s.custom.sRowSelect;this.s.select.preRowSelect=this.s.custom.fnPreRowSelect;this.s.select.postSelected=this.s.custom.fnRowSelected;this.s.select.postDeselected=this.s.custom.fnRowDeselected;this.s.custom.sSelectedClass&&(this.classes.select.row=this.s.custom.sSelectedClass); +this.s.tags=this.s.custom.oTags;this.s.buttonSet=this.s.custom.aButtons},_fnButtonDefinations:function(a,b){for(var c,d=0,f=a.length;dh?i:h)+"px";l.style.width=(o>g?o:g)+"px";l.className=this.classes.collection.background;e(l).css("opacity",0);k.body.appendChild(l);k.body.appendChild(f);i=e(f).outerWidth();o=e(f).outerHeight();j+i>g&&(f.style.left=g-i+"px");d+o>h&&(f.style.top=d-o-e(a).outerHeight()+"px");this.dom.collection.collection=f;this.dom.collection.background=l;setTimeout(function(){e(f).animate({opacity:1},500);e(l).animate({opacity:0.25}, +500)},10);this.fnResizeButtons();e(l).click(function(){c._fnCollectionHide.call(c,null,null)})},_fnCollectionHide:function(a,b){!(null!==b&&"collection"==b.sExtends)&&null!==this.dom.collection.collection&&(e(this.dom.collection.collection).animate({opacity:0},500,function(){this.style.display="none"}),e(this.dom.collection.background).animate({opacity:0},500,function(){this.parentNode.removeChild(this)}),this.dom.collection.collection=null,this.dom.collection.background=null)},_fnRowSelectConfig:function(){if(this.s.master){var a= +this,b=this.s.dt;e(b.nTable).addClass(this.classes.select.table);"os"===this.s.select.type&&(e(b.nTBody).on("mousedown.DTTT_Select","tr",function(a){if(a.shiftKey)e(b.nTBody).css("-moz-user-select","none").one("selectstart.DTTT_Select","tr",function(){return!1})}),e(b.nTBody).on("mouseup.DTTT_Select","tr",function(){e(b.nTBody).css("-moz-user-select","")}));e(b.nTBody).on("click.DTTT_Select",this.s.custom.sRowSelector,function(c){var d=this.nodeName.toLowerCase()==="tr"?this:e(this).parents("tr")[0], +f=a.s.select,j=a.s.dt.oInstance.fnGetPosition(d);if(d.parentNode==b.nTBody&&b.oInstance.fnGetData(d)!==null){if(f.type=="os")if(c.ctrlKey||c.metaKey)a.fnIsSelected(d)?a._fnRowDeselect(d,c):a._fnRowSelect(d,c);else if(c.shiftKey){var i=a.s.dt.aiDisplay.slice(),h=e.inArray(f.lastRow,i),o=e.inArray(j,i);if(a.fnGetSelected().length===0||h===-1)i.splice(e.inArray(j,i)+1,i.length);else{if(h>o)var g=o,o=h,h=g;i.splice(o+1,i.length);i.splice(0,h)}if(a.fnIsSelected(d)){i.splice(e.inArray(j,i),1);a._fnRowDeselect(i, +c)}else a._fnRowSelect(i,c)}else if(a.fnIsSelected(d)&&a.fnGetSelected().length===1)a._fnRowDeselect(d,c);else{a.fnSelectNone();a._fnRowSelect(d,c)}else if(a.fnIsSelected(d))a._fnRowDeselect(d,c);else if(f.type=="single"){a.fnSelectNone();a._fnRowSelect(d,c)}else f.type=="multi"&&a._fnRowSelect(d,c);f.lastRow=j}});b.oApi._fnCallbackReg(b,"aoRowCreatedCallback",function(c,d,f){b.aoData[f]._DTTT_selected&&e(c).addClass(a.classes.select.row)},"TableTools-SelectAll")}},_fnRowSelect:function(a,b){var c= +this._fnSelectData(a),d=[],f,j;f=0;for(j=c.length;f/g,"").replace(/^\s+|\s+$/g,""),h=this._fnHtmlDecode(h),j.push(this._fnBoundData(h,a.sFieldBoundary,l)));i.push(j.join(a.sFieldSeperator))}d=!0;var m;f=this.fnGetSelectedIndexes();m=(d="none"!==this.s.select.type&&d&&0!==f.length)?f:p.Api?(new p.Api(g)).rows(a.oSelectorOpts).indexes().flatten().toArray():g.oInstance.$("tr",a.oSelectorOpts).map(function(a,b){return g.oInstance.fnGetPosition(b)}).get(); +d=0;for(f=m.length;d]+)).*?>/gi,"$1$2$3"),h=h.replace(/<.*?>/g,"")):h+="",h=h.replace(/^\s+/,"").replace(/\s+$/,""),h=this._fnHtmlDecode(h),j.push(this._fnBoundData(h,a.sFieldBoundary,l)));i.push(j.join(a.sFieldSeperator));a.bOpenRows&& +(b=e.grep(g.aoOpenRows,function(a){return a.nParent===k}),1===b.length&&(h=this._fnBoundData(e("td",b[0].nTr).html(),a.sFieldBoundary,l),i.push(h)))}if(a.bFooter&&null!==g.nTFoot){j=[];b=0;for(c=g.aoColumns.length;b/g,""),h=this._fnHtmlDecode(h),j.push(this._fnBoundData(h,a.sFieldBoundary,l)));i.push(j.join(a.sFieldSeperator))}return i.join(this._fnNewline(a))},_fnBoundData:function(a,b,c){return""=== +b?a:b+a.replace(c,b+b)+b},_fnChunkData:function(a,b){for(var c=[],d=a.length,f=0;f").addClass(this.classes.print.message).html(a.sMessage).prependTo("body");this.s.print.saveScroll=e(n).scrollTop();n.scrollTo(0,0);e(k).bind("keydown.DTTT",function(a){if(a.keyCode==27){a.preventDefault();b._fnPrintEnd.call(b,a)}})},_fnPrintEnd:function(){var a=this.s.dt,b=this.s.print;this._fnPrintShowNodes();if(""!==a.oScroll.sX||""!==a.oScroll.sY)e(this.s.dt.nTable).unbind("draw.DTTT_Print"), +this._fnPrintScrollEnd();n.scrollTo(0,b.saveScroll);e("div."+this.classes.print.message).remove();e(k.body).removeClass("DTTT_Print");a._iDisplayStart=b.saveStart;a._iDisplayLength=b.saveLength;a.oApi._fnCalculateEnd&&a.oApi._fnCalculateEnd(a);a.oApi._fnDraw(a);e(k).unbind("keydown.DTTT")},_fnPrintScrollStart:function(){var a=this.s.dt;a.nScrollHead.getElementsByTagName("div")[0].getElementsByTagName("table");var b=a.nTable.parentNode,c;c=a.nTable.getElementsByTagName("thead");0Table copied

    Copied "+a+" row"+(1==a?"":"s")+" to the clipboard.

    ",1500)}}),pdf:e.extend({},TableTools.buttonBase,{sAction:"flash_pdf",sNewLine:"\n",sFileName:"*.pdf",sButtonClass:"DTTT_button_pdf",sButtonText:"PDF",sPdfOrientation:"portrait",sPdfSize:"A4",sPdfMessage:"",fnClick:function(a,b,c){this.fnSetText(c,"title:"+this.fnGetTitle(b)+"\nmessage:"+b.sPdfMessage+"\ncolWidth:"+this.fnCalcColRatios(b)+ +"\norientation:"+b.sPdfOrientation+"\nsize:"+b.sPdfSize+"\n--/TableToolsOpts--\n"+this.fnGetTableData(b))}}),print:e.extend({},TableTools.buttonBase,{sInfo:"
    Print view

    Please use your browser's print function to print this table. Press escape when finished.

    ",sMessage:null,bShowAll:!0,sToolTip:"View print view",sButtonClass:"DTTT_button_print",sButtonText:"Print",fnClick:function(a,b){this.fnPrint(!0,b)}}),text:e.extend({},TableTools.buttonBase),select:e.extend({},TableTools.buttonBase, +{sButtonText:"Select button",fnSelect:function(a){0!==this.fnGetSelected().length?e(a).removeClass(this.classes.buttons.disabled):e(a).addClass(this.classes.buttons.disabled)},fnInit:function(a){e(a).addClass(this.classes.buttons.disabled)}}),select_single:e.extend({},TableTools.buttonBase,{sButtonText:"Select button",fnSelect:function(a){1==this.fnGetSelected().length?e(a).removeClass(this.classes.buttons.disabled):e(a).addClass(this.classes.buttons.disabled)},fnInit:function(a){e(a).addClass(this.classes.buttons.disabled)}}), +select_all:e.extend({},TableTools.buttonBase,{sButtonText:"Select all",fnClick:function(){this.fnSelectAll()},fnSelect:function(a){this.fnGetSelected().length==this.s.dt.fnRecordsDisplay()?e(a).addClass(this.classes.buttons.disabled):e(a).removeClass(this.classes.buttons.disabled)}}),select_none:e.extend({},TableTools.buttonBase,{sButtonText:"Deselect all",fnClick:function(){this.fnSelectNone()},fnSelect:function(a){0!==this.fnGetSelected().length?e(a).removeClass(this.classes.buttons.disabled):e(a).addClass(this.classes.buttons.disabled)}, +fnInit:function(a){e(a).addClass(this.classes.buttons.disabled)}}),ajax:e.extend({},TableTools.buttonBase,{sAjaxUrl:"/xhr.php",sButtonText:"Ajax button",fnClick:function(a,b){var c=this.fnGetTableData(b);e.ajax({url:b.sAjaxUrl,data:[{name:"tableData",value:c}],success:b.fnAjaxComplete,dataType:"json",type:"POST",cache:!1,error:function(){alert("Error detected when sending table data to server")}})},fnAjaxComplete:function(){alert("Ajax complete")}}),div:e.extend({},TableTools.buttonBase,{sAction:"div", +sTag:"div",sButtonClass:"DTTT_nonbutton",sButtonText:"Text button"}),collection:e.extend({},TableTools.buttonBase,{sAction:"collection",sButtonClass:"DTTT_button_collection",sButtonText:"Collection",fnClick:function(a,b){this._fnCollectionShow(a,b)}})};TableTools.buttons=TableTools.BUTTONS;TableTools.classes={container:"DTTT_container",buttons:{normal:"DTTT_button",disabled:"DTTT_disabled"},collection:{container:"DTTT_collection",background:"DTTT_collection_background",buttons:{normal:"DTTT_button", +disabled:"DTTT_disabled"}},select:{table:"DTTT_selectable",row:"DTTT_selected selected"},print:{body:"DTTT_Print",info:"DTTT_print_info",message:"DTTT_PrintMessage"}};TableTools.classes_themeroller={container:"DTTT_container ui-buttonset ui-buttonset-multi",buttons:{normal:"DTTT_button ui-button ui-state-default"},collection:{container:"DTTT_collection ui-buttonset ui-buttonset-multi"}};TableTools.DEFAULTS={sSwfPath:"../swf/copy_csv_xls_pdf.swf",sRowSelect:"none",sRowSelector:"tr",sSelectedClass:null, +fnPreRowSelect:null,fnRowSelected:null,fnRowDeselected:null,aButtons:["copy","csv","xls","pdf","print"],oTags:{container:"div",button:"a",liner:"span",collection:{container:"div",button:"a",liner:"span"}}};TableTools.defaults=TableTools.DEFAULTS;TableTools.prototype.CLASS="TableTools";TableTools.version="2.2.4";e.fn.dataTable.Api&&e.fn.dataTable.Api.register("tabletools()",function(){var a=null;0 .sorting_1, +table.dataTable.order-column tbody tr > .sorting_2, +table.dataTable.order-column tbody tr > .sorting_3, table.dataTable.display tbody tr > .sorting_1, +table.dataTable.display tbody tr > .sorting_2, +table.dataTable.display tbody tr > .sorting_3 { + background-color: #f9f9f9; +} +table.dataTable.order-column tbody tr.selected > .sorting_1, +table.dataTable.order-column tbody tr.selected > .sorting_2, +table.dataTable.order-column tbody tr.selected > .sorting_3, table.dataTable.display tbody tr.selected > .sorting_1, +table.dataTable.display tbody tr.selected > .sorting_2, +table.dataTable.display tbody tr.selected > .sorting_3 { + background-color: #acbad4; +} +table.dataTable.display tbody tr.odd > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd > .sorting_1 { + background-color: #f1f1f1; +} +table.dataTable.display tbody tr.odd > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd > .sorting_2 { + background-color: #f3f3f3; +} +table.dataTable.display tbody tr.odd > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd > .sorting_3 { + background-color: whitesmoke; +} +table.dataTable.display tbody tr.odd.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_1 { + background-color: #a6b3cd; +} +table.dataTable.display tbody tr.odd.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_2 { + background-color: #a7b5ce; +} +table.dataTable.display tbody tr.odd.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_3 { + background-color: #a9b6d0; +} +table.dataTable.display tbody tr.even > .sorting_1, table.dataTable.order-column.stripe tbody tr.even > .sorting_1 { + background-color: #f9f9f9; +} +table.dataTable.display tbody tr.even > .sorting_2, table.dataTable.order-column.stripe tbody tr.even > .sorting_2 { + background-color: #fbfbfb; +} +table.dataTable.display tbody tr.even > .sorting_3, table.dataTable.order-column.stripe tbody tr.even > .sorting_3 { + background-color: #fdfdfd; +} +table.dataTable.display tbody tr.even.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_1 { + background-color: #acbad4; +} +table.dataTable.display tbody tr.even.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_2 { + background-color: #adbbd6; +} +table.dataTable.display tbody tr.even.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_3 { + background-color: #afbdd8; +} +table.dataTable.display tbody tr:hover > .sorting_1, table.dataTable.order-column.hover tbody tr:hover > .sorting_1 { + background-color: #eaeaea; +} +table.dataTable.display tbody tr:hover > .sorting_2, table.dataTable.order-column.hover tbody tr:hover > .sorting_2 { + background-color: #ebebeb; +} +table.dataTable.display tbody tr:hover > .sorting_3, table.dataTable.order-column.hover tbody tr:hover > .sorting_3 { + background-color: #eeeeee; +} +table.dataTable.display tbody tr:hover.selected > .sorting_1, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_1 { + background-color: #a1aec7; +} +table.dataTable.display tbody tr:hover.selected > .sorting_2, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_2 { + background-color: #a2afc8; +} +table.dataTable.display tbody tr:hover.selected > .sorting_3, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_3 { + background-color: #a4b2cb; +} +table.dataTable.no-footer { + border-bottom: 1px solid #111; +} +table.dataTable.nowrap th, table.dataTable.nowrap td { + white-space: nowrap; +} +table.dataTable.compact thead th, +table.dataTable.compact thead td { + padding: 4px 17px 4px 4px; +} +table.dataTable.compact tfoot th, +table.dataTable.compact tfoot td { + padding: 4px; +} +table.dataTable.compact tbody th, +table.dataTable.compact tbody td { + padding: 4px; +} +table.dataTable th.dt-left, +table.dataTable td.dt-left { + text-align: left; +} +table.dataTable th.dt-center, +table.dataTable td.dt-center, +table.dataTable td.dataTables_empty { + text-align: center; +} +table.dataTable th.dt-right, +table.dataTable td.dt-right { + text-align: right; +} +table.dataTable th.dt-justify, +table.dataTable td.dt-justify { + text-align: justify; +} +table.dataTable th.dt-nowrap, +table.dataTable td.dt-nowrap { + white-space: nowrap; +} +table.dataTable thead th.dt-head-left, +table.dataTable thead td.dt-head-left, +table.dataTable tfoot th.dt-head-left, +table.dataTable tfoot td.dt-head-left { + text-align: left; +} +table.dataTable thead th.dt-head-center, +table.dataTable thead td.dt-head-center, +table.dataTable tfoot th.dt-head-center, +table.dataTable tfoot td.dt-head-center { + text-align: center; +} +table.dataTable thead th.dt-head-right, +table.dataTable thead td.dt-head-right, +table.dataTable tfoot th.dt-head-right, +table.dataTable tfoot td.dt-head-right { + text-align: right; +} +table.dataTable thead th.dt-head-justify, +table.dataTable thead td.dt-head-justify, +table.dataTable tfoot th.dt-head-justify, +table.dataTable tfoot td.dt-head-justify { + text-align: justify; +} +table.dataTable thead th.dt-head-nowrap, +table.dataTable thead td.dt-head-nowrap, +table.dataTable tfoot th.dt-head-nowrap, +table.dataTable tfoot td.dt-head-nowrap { + white-space: nowrap; +} +table.dataTable tbody th.dt-body-left, +table.dataTable tbody td.dt-body-left { + text-align: left; +} +table.dataTable tbody th.dt-body-center, +table.dataTable tbody td.dt-body-center { + text-align: center; +} +table.dataTable tbody th.dt-body-right, +table.dataTable tbody td.dt-body-right { + text-align: right; +} +table.dataTable tbody th.dt-body-justify, +table.dataTable tbody td.dt-body-justify { + text-align: justify; +} +table.dataTable tbody th.dt-body-nowrap, +table.dataTable tbody td.dt-body-nowrap { + white-space: nowrap; +} + +table.dataTable, +table.dataTable th, +table.dataTable td { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; +} + +/* + * Control feature layout + */ +.dataTables_wrapper { + position: relative; + clear: both; + *zoom: 1; + zoom: 1; +} +.dataTables_wrapper .dataTables_length { + float: left; +} +.dataTables_wrapper .dataTables_filter { + float: right; + text-align: right; +} +.dataTables_wrapper .dataTables_filter input { + margin-left: 0.5em; +} +.dataTables_wrapper .dataTables_info { + clear: both; + float: left; + padding-top: 0.755em; +} +.dataTables_wrapper .dataTables_paginate { + float: right; + text-align: right; + padding-top: 0.25em; +} +.dataTables_wrapper .dataTables_paginate .paginate_button { + box-sizing: border-box; + display: inline-block; + min-width: 1.5em; + padding: 0.5em 1em; + margin-left: 2px; + text-align: center; + text-decoration: none !important; + cursor: pointer; + *cursor: hand; + color: #333 !important; + border: 1px solid transparent; +} +.dataTables_wrapper .dataTables_paginate .paginate_button.current, .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover { + color: #333 !important; + border: 1px solid #cacaca; + background-color: white; + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, white), color-stop(100%, #dcdcdc)); + /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, white 0%, #dcdcdc 100%); + /* Chrome10+,Safari5.1+ */ + background: -moz-linear-gradient(top, white 0%, #dcdcdc 100%); + /* FF3.6+ */ + background: -ms-linear-gradient(top, white 0%, #dcdcdc 100%); + /* IE10+ */ + background: -o-linear-gradient(top, white 0%, #dcdcdc 100%); + /* Opera 11.10+ */ + background: linear-gradient(to bottom, white 0%, #dcdcdc 100%); + /* W3C */ +} +.dataTables_wrapper .dataTables_paginate .paginate_button.disabled, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active { + cursor: default; + color: #666 !important; + border: 1px solid transparent; + background: transparent; + box-shadow: none; +} +.dataTables_wrapper .dataTables_paginate .paginate_button:hover { + color: white !important; + border: 1px solid #111; + background-color: #585858; + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111)); + /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #585858 0%, #111 100%); + /* Chrome10+,Safari5.1+ */ + background: -moz-linear-gradient(top, #585858 0%, #111 100%); + /* FF3.6+ */ + background: -ms-linear-gradient(top, #585858 0%, #111 100%); + /* IE10+ */ + background: -o-linear-gradient(top, #585858 0%, #111 100%); + /* Opera 11.10+ */ + background: linear-gradient(to bottom, #585858 0%, #111 100%); + /* W3C */ +} +.dataTables_wrapper .dataTables_paginate .paginate_button:active { + outline: none; + background-color: #2b2b2b; + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c)); + /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%); + /* Chrome10+,Safari5.1+ */ + background: -moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%); + /* FF3.6+ */ + background: -ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%); + /* IE10+ */ + background: -o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%); + /* Opera 11.10+ */ + background: linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%); + /* W3C */ + box-shadow: inset 0 0 3px #111; +} +.dataTables_wrapper .dataTables_paginate .ellipsis { + padding: 0 1em; +} +.dataTables_wrapper .dataTables_processing { + position: absolute; + top: 50%; + left: 50%; + width: 100%; + height: 40px; + margin-left: -50%; + margin-top: -25px; + padding-top: 20px; + text-align: center; + font-size: 1.2em; + background-color: white; + background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(25%, rgba(255, 255, 255, 0.9)), color-stop(75%, rgba(255, 255, 255, 0.9)), color-stop(100%, rgba(255, 255, 255, 0))); + /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); + /* Chrome10+,Safari5.1+ */ + background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); + /* FF3.6+ */ + background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); + /* IE10+ */ + background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); + /* Opera 11.10+ */ + background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); + /* W3C */ +} +.dataTables_wrapper .dataTables_length, +.dataTables_wrapper .dataTables_filter, +.dataTables_wrapper .dataTables_info, +.dataTables_wrapper .dataTables_processing, +.dataTables_wrapper .dataTables_paginate { + color: #333; +} +.dataTables_wrapper .dataTables_scroll { + clear: both; +} +.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody { + *margin-top: -1px; + -webkit-overflow-scrolling: touch; +} +.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th > div.dataTables_sizing, +.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td > div.dataTables_sizing { + height: 0; + overflow: hidden; + margin: 0 !important; + padding: 0 !important; +} +.dataTables_wrapper.no-footer .dataTables_scrollBody { + border-bottom: 1px solid #111; +} +.dataTables_wrapper.no-footer div.dataTables_scrollHead table, +.dataTables_wrapper.no-footer div.dataTables_scrollBody table { + border-bottom: none; +} +.dataTables_wrapper:after { + visibility: hidden; + display: block; + content: ""; + clear: both; + height: 0; +} + +@media screen and (max-width: 767px) { + .dataTables_wrapper .dataTables_info, + .dataTables_wrapper .dataTables_paginate { + float: none; + text-align: center; + } + .dataTables_wrapper .dataTables_paginate { + margin-top: 0.5em; + } +} +@media screen and (max-width: 640px) { + .dataTables_wrapper .dataTables_length, + .dataTables_wrapper .dataTables_filter { + float: none; + text-align: center; + } + .dataTables_wrapper .dataTables_filter { + margin-top: 0.5em; + } +} diff --git a/public/assets/plugins/datatables/jquery.dataTables.js b/public/assets/plugins/datatables/jquery.dataTables.js new file mode 100644 index 00000000..2a9bdb36 --- /dev/null +++ b/public/assets/plugins/datatables/jquery.dataTables.js @@ -0,0 +1,14951 @@ +/*! DataTables 1.10.7 + * ©2008-2014 SpryMedia Ltd - datatables.net/license + */ + +/** + * @summary DataTables + * @description Paginate, search and order HTML tables + * @version 1.10.7 + * @file jquery.dataTables.js + * @author SpryMedia Ltd (www.sprymedia.co.uk) + * @contact www.sprymedia.co.uk/contact + * @copyright Copyright 2008-2014 SpryMedia Ltd. + * + * This source file is free software, available under the following license: + * MIT license - http://datatables.net/license + * + * This source file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. + * + * For details please refer to: http://www.datatables.net + */ + +/*jslint evil: true, undef: true, browser: true */ +/*globals $,require,jQuery,define,_selector_run,_selector_opts,_selector_first,_selector_row_indexes,_ext,_Api,_api_register,_api_registerPlural,_re_new_lines,_re_html,_re_formatted_numeric,_re_escape_regex,_empty,_intVal,_numToDecimal,_isNumber,_isHtml,_htmlNumeric,_pluck,_pluck_order,_range,_stripHtml,_unique,_fnBuildAjax,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnAjaxDataSrc,_fnAddColumn,_fnColumnOptions,_fnAdjustColumnSizing,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnVisbleColumns,_fnGetColumns,_fnColumnTypes,_fnApplyColumnDefs,_fnHungarianMap,_fnCamelToHungarian,_fnLanguageCompat,_fnBrowserDetect,_fnAddData,_fnAddTr,_fnNodeToDataIndex,_fnNodeToColumnIndex,_fnGetCellData,_fnSetCellData,_fnSplitObjNotation,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnGetDataMaster,_fnClearTable,_fnDeleteIndex,_fnInvalidate,_fnGetRowElements,_fnCreateTr,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAddOptionsHtml,_fnDetectHeader,_fnGetUniqueThs,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnFilterCreateSearch,_fnEscapeRegex,_fnFilterData,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnInfoMacros,_fnInitialise,_fnInitComplete,_fnLengthChange,_fnFeatureHtmlLength,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnFeatureHtmlTable,_fnScrollDraw,_fnApplyToChildren,_fnCalculateColumnWidths,_fnThrottle,_fnConvertToWidth,_fnScrollingWidthAdjust,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnScrollBarWidth,_fnSortFlatten,_fnSort,_fnSortAria,_fnSortListener,_fnSortAttachListener,_fnSortingClasses,_fnSortData,_fnSaveState,_fnLoadState,_fnSettingsFromNode,_fnLog,_fnMap,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnLengthOverflow,_fnRenderer,_fnDataSource,_fnRowAttributes*/ + +(/** @lends */function( window, document, undefined ) { + +(function( factory ) { + "use strict"; + + if ( typeof define === 'function' && define.amd ) { + // Define as an AMD module if possible + define( 'datatables', ['jquery'], factory ); + } + else if ( typeof exports === 'object' ) { + // Node/CommonJS + module.exports = factory( require( 'jquery' ) ); + } + else if ( jQuery && !jQuery.fn.dataTable ) { + // Define using browser globals otherwise + // Prevent multiple instantiations if the script is loaded twice + factory( jQuery ); + } +} +(/** @lends */function( $ ) { + "use strict"; + + /** + * DataTables is a plug-in for the jQuery Javascript library. It is a highly + * flexible tool, based upon the foundations of progressive enhancement, + * which will add advanced interaction controls to any HTML table. For a + * full list of features please refer to + * [DataTables.net](href="http://datatables.net). + * + * Note that the `DataTable` object is not a global variable but is aliased + * to `jQuery.fn.DataTable` and `jQuery.fn.dataTable` through which it may + * be accessed. + * + * @class + * @param {object} [init={}] Configuration object for DataTables. Options + * are defined by {@link DataTable.defaults} + * @requires jQuery 1.7+ + * + * @example + * // Basic initialisation + * $(document).ready( function { + * $('#example').dataTable(); + * } ); + * + * @example + * // Initialisation with configuration options - in this case, disable + * // pagination and sorting. + * $(document).ready( function { + * $('#example').dataTable( { + * "paginate": false, + * "sort": false + * } ); + * } ); + */ + var DataTable; + + + /* + * It is useful to have variables which are scoped locally so only the + * DataTables functions can access them and they don't leak into global space. + * At the same time these functions are often useful over multiple files in the + * core and API, so we list, or at least document, all variables which are used + * by DataTables as private variables here. This also ensures that there is no + * clashing of variable names and that they can easily referenced for reuse. + */ + + + // Defined else where + // _selector_run + // _selector_opts + // _selector_first + // _selector_row_indexes + + var _ext; // DataTable.ext + var _Api; // DataTable.Api + var _api_register; // DataTable.Api.register + var _api_registerPlural; // DataTable.Api.registerPlural + + var _re_dic = {}; + var _re_new_lines = /[\r\n]/g; + var _re_html = /<.*?>/g; + var _re_date_start = /^[\w\+\-]/; + var _re_date_end = /[\w\+\-]$/; + + // Escape regular expression special characters + var _re_escape_regex = new RegExp( '(\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-' ].join('|\\') + ')', 'g' ); + + // http://en.wikipedia.org/wiki/Foreign_exchange_market + // - \u20BD - Russian ruble. + // - \u20a9 - South Korean Won + // - \u20BA - Turkish Lira + // - \u20B9 - Indian Rupee + // - R - Brazil (R$) and South Africa + // - fr - Swiss Franc + // - kr - Swedish krona, Norwegian krone and Danish krone + // - \u2009 is thin space and \u202F is narrow no-break space, both used in many + // standards as thousands separators. + var _re_formatted_numeric = /[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfk]/gi; + + + var _empty = function ( d ) { + return !d || d === true || d === '-' ? true : false; + }; + + + var _intVal = function ( s ) { + var integer = parseInt( s, 10 ); + return !isNaN(integer) && isFinite(s) ? integer : null; + }; + + // Convert from a formatted number with characters other than `.` as the + // decimal place, to a Javascript number + var _numToDecimal = function ( num, decimalPoint ) { + // Cache created regular expressions for speed as this function is called often + if ( ! _re_dic[ decimalPoint ] ) { + _re_dic[ decimalPoint ] = new RegExp( _fnEscapeRegex( decimalPoint ), 'g' ); + } + return typeof num === 'string' && decimalPoint !== '.' ? + num.replace( /\./g, '' ).replace( _re_dic[ decimalPoint ], '.' ) : + num; + }; + + + var _isNumber = function ( d, decimalPoint, formatted ) { + var strType = typeof d === 'string'; + + // If empty return immediately so there must be a number if it is a + // formatted string (this stops the string "k", or "kr", etc being detected + // as a formatted number for currency + if ( _empty( d ) ) { + return true; + } + + if ( decimalPoint && strType ) { + d = _numToDecimal( d, decimalPoint ); + } + + if ( formatted && strType ) { + d = d.replace( _re_formatted_numeric, '' ); + } + + return !isNaN( parseFloat(d) ) && isFinite( d ); + }; + + + // A string without HTML in it can be considered to be HTML still + var _isHtml = function ( d ) { + return _empty( d ) || typeof d === 'string'; + }; + + + var _htmlNumeric = function ( d, decimalPoint, formatted ) { + if ( _empty( d ) ) { + return true; + } + + var html = _isHtml( d ); + return ! html ? + null : + _isNumber( _stripHtml( d ), decimalPoint, formatted ) ? + true : + null; + }; + + + var _pluck = function ( a, prop, prop2 ) { + var out = []; + var i=0, ien=a.length; + + // Could have the test in the loop for slightly smaller code, but speed + // is essential here + if ( prop2 !== undefined ) { + for ( ; i') + .css( { + position: 'absolute', + top: 0, + left: 0, + height: 1, + width: 1, + overflow: 'hidden' + } ) + .append( + $('
    ') + .css( { + position: 'absolute', + top: 1, + left: 1, + width: 100, + overflow: 'scroll' + } ) + .append( + $('
    ') + .css( { + width: '100%', + height: 10 + } ) + ) + ) + .appendTo( 'body' ); + + var test = n.find('.test'); + + // IE6/7 will oversize a width 100% element inside a scrolling element, to + // include the width of the scrollbar, while other browsers ensure the inner + // element is contained without forcing scrolling + browser.bScrollOversize = test[0].offsetWidth === 100; + + // In rtl text layout, some browsers (most, but not all) will place the + // scrollbar on the left, rather than the right. + browser.bScrollbarLeft = Math.round( test.offset().left ) !== 1; + + n.remove(); + } + + + /** + * Array.prototype reduce[Right] method, used for browsers which don't support + * JS 1.6. Done this way to reduce code size, since we iterate either way + * @param {object} settings dataTables settings object + * @memberof DataTable#oApi + */ + function _fnReduce ( that, fn, init, start, end, inc ) + { + var + i = start, + value, + isSet = false; + + if ( init !== undefined ) { + value = init; + isSet = true; + } + + while ( i !== end ) { + if ( ! that.hasOwnProperty(i) ) { + continue; + } + + value = isSet ? + fn( value, that[i], i, that ) : + that[i]; + + isSet = true; + i += inc; + } + + return value; + } + + /** + * Add a column to the list used for the table with default values + * @param {object} oSettings dataTables settings object + * @param {node} nTh The th element for this column + * @memberof DataTable#oApi + */ + function _fnAddColumn( oSettings, nTh ) + { + // Add column to aoColumns array + var oDefaults = DataTable.defaults.column; + var iCol = oSettings.aoColumns.length; + var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, { + "nTh": nTh ? nTh : document.createElement('th'), + "sTitle": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '', + "aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol], + "mData": oDefaults.mData ? oDefaults.mData : iCol, + idx: iCol + } ); + oSettings.aoColumns.push( oCol ); + + // Add search object for column specific search. Note that the `searchCols[ iCol ]` + // passed into extend can be undefined. This allows the user to give a default + // with only some of the parameters defined, and also not give a default + var searchCols = oSettings.aoPreSearchCols; + searchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch, searchCols[ iCol ] ); + + // Use the default column options function to initialise classes etc + _fnColumnOptions( oSettings, iCol, $(nTh).data() ); + } + + + /** + * Apply options for a column + * @param {object} oSettings dataTables settings object + * @param {int} iCol column index to consider + * @param {object} oOptions object with sType, bVisible and bSearchable etc + * @memberof DataTable#oApi + */ + function _fnColumnOptions( oSettings, iCol, oOptions ) + { + var oCol = oSettings.aoColumns[ iCol ]; + var oClasses = oSettings.oClasses; + var th = $(oCol.nTh); + + // Try to get width information from the DOM. We can't get it from CSS + // as we'd need to parse the CSS stylesheet. `width` option can override + if ( ! oCol.sWidthOrig ) { + // Width attribute + oCol.sWidthOrig = th.attr('width') || null; + + // Style attribute + var t = (th.attr('style') || '').match(/width:\s*(\d+[pxem%]+)/); + if ( t ) { + oCol.sWidthOrig = t[1]; + } + } + + /* User specified column options */ + if ( oOptions !== undefined && oOptions !== null ) + { + // Backwards compatibility + _fnCompatCols( oOptions ); + + // Map camel case parameters to their Hungarian counterparts + _fnCamelToHungarian( DataTable.defaults.column, oOptions ); + + /* Backwards compatibility for mDataProp */ + if ( oOptions.mDataProp !== undefined && !oOptions.mData ) + { + oOptions.mData = oOptions.mDataProp; + } + + if ( oOptions.sType ) + { + oCol._sManualType = oOptions.sType; + } + + // `class` is a reserved word in Javascript, so we need to provide + // the ability to use a valid name for the camel case input + if ( oOptions.className && ! oOptions.sClass ) + { + oOptions.sClass = oOptions.className; + } + + $.extend( oCol, oOptions ); + _fnMap( oCol, oOptions, "sWidth", "sWidthOrig" ); + + /* iDataSort to be applied (backwards compatibility), but aDataSort will take + * priority if defined + */ + if ( oOptions.iDataSort !== undefined ) + { + oCol.aDataSort = [ oOptions.iDataSort ]; + } + _fnMap( oCol, oOptions, "aDataSort" ); + } + + /* Cache the data get and set functions for speed */ + var mDataSrc = oCol.mData; + var mData = _fnGetObjectDataFn( mDataSrc ); + var mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null; + + var attrTest = function( src ) { + return typeof src === 'string' && src.indexOf('@') !== -1; + }; + oCol._bAttrSrc = $.isPlainObject( mDataSrc ) && ( + attrTest(mDataSrc.sort) || attrTest(mDataSrc.type) || attrTest(mDataSrc.filter) + ); + + oCol.fnGetData = function (rowData, type, meta) { + var innerData = mData( rowData, type, undefined, meta ); + + return mRender && type ? + mRender( innerData, type, rowData, meta ) : + innerData; + }; + oCol.fnSetData = function ( rowData, val, meta ) { + return _fnSetObjectDataFn( mDataSrc )( rowData, val, meta ); + }; + + // Indicate if DataTables should read DOM data as an object or array + // Used in _fnGetRowElements + if ( typeof mDataSrc !== 'number' ) { + oSettings._rowReadObject = true; + } + + /* Feature sorting overrides column specific when off */ + if ( !oSettings.oFeatures.bSort ) + { + oCol.bSortable = false; + th.addClass( oClasses.sSortableNone ); // Have to add class here as order event isn't called + } + + /* Check that the class assignment is correct for sorting */ + var bAsc = $.inArray('asc', oCol.asSorting) !== -1; + var bDesc = $.inArray('desc', oCol.asSorting) !== -1; + if ( !oCol.bSortable || (!bAsc && !bDesc) ) + { + oCol.sSortingClass = oClasses.sSortableNone; + oCol.sSortingClassJUI = ""; + } + else if ( bAsc && !bDesc ) + { + oCol.sSortingClass = oClasses.sSortableAsc; + oCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed; + } + else if ( !bAsc && bDesc ) + { + oCol.sSortingClass = oClasses.sSortableDesc; + oCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed; + } + else + { + oCol.sSortingClass = oClasses.sSortable; + oCol.sSortingClassJUI = oClasses.sSortJUI; + } + } + + + /** + * Adjust the table column widths for new data. Note: you would probably want to + * do a redraw after calling this function! + * @param {object} settings dataTables settings object + * @memberof DataTable#oApi + */ + function _fnAdjustColumnSizing ( settings ) + { + /* Not interested in doing column width calculation if auto-width is disabled */ + if ( settings.oFeatures.bAutoWidth !== false ) + { + var columns = settings.aoColumns; + + _fnCalculateColumnWidths( settings ); + for ( var i=0 , iLen=columns.length ; i