diff --git a/Makefile b/Makefile index 70cea4bd77..2fdb81e09b 100644 --- a/Makefile +++ b/Makefile @@ -557,6 +557,7 @@ TEST_INTEGRATIONS_71 := \ TEST_WEB_71 := \ test_metrics \ test_web_cakephp_28 \ + test_web_cakephp_310 \ test_web_codeigniter_22 \ test_web_codeigniter_31 \ test_web_laravel_42 \ @@ -610,6 +611,7 @@ TEST_INTEGRATIONS_72 := \ TEST_WEB_72 := \ test_metrics \ + test_web_cakephp_310 \ test_web_codeigniter_22 \ test_web_codeigniter_31 \ test_web_drupal_89 \ @@ -669,6 +671,7 @@ TEST_INTEGRATIONS_73 :=\ TEST_WEB_73 := \ test_metrics \ + test_web_cakephp_310 \ test_web_codeigniter_22 \ test_web_codeigniter_31 \ test_web_drupal_89 \ @@ -730,6 +733,8 @@ TEST_INTEGRATIONS_74 := \ TEST_WEB_74 := \ test_metrics \ + test_web_cakephp_310 \ + test_web_cakephp_45 \ test_web_codeigniter_22 \ test_web_codeigniter_31 \ test_web_drupal_89 \ @@ -792,6 +797,7 @@ TEST_INTEGRATIONS_80 := \ TEST_WEB_80 := \ test_metrics \ + test_web_cakephp_45 \ test_web_codeigniter_22 \ test_web_codeigniter_31 \ test_web_drupal_95 \ @@ -840,6 +846,8 @@ TEST_INTEGRATIONS_81 := \ TEST_WEB_81 := \ test_metrics \ + test_web_cakephp_45 \ + test_web_cakephp_50 \ test_web_codeigniter_22 \ test_web_codeigniter_31 \ test_web_drupal_95 \ @@ -891,6 +899,8 @@ TEST_INTEGRATIONS_82 := \ TEST_WEB_82 := \ test_metrics \ + test_web_cakephp_45 \ + test_web_cakephp_50 \ test_web_codeigniter_22 \ test_web_codeigniter_31 \ test_web_drupal_95 \ @@ -946,6 +956,8 @@ TEST_INTEGRATIONS_83 := \ TEST_WEB_83 := \ test_metrics \ + test_web_cakephp_45 \ + test_web_cakephp_50 \ test_web_codeigniter_22 \ test_web_codeigniter_31 \ test_web_drupal_95 \ @@ -1230,6 +1242,15 @@ test_integrations_swoole_5: global_test_run_dependencies test_web_cakephp_28: global_test_run_dependencies $(call run_composer_with_retry,tests/Frameworks/CakePHP/Version_2_8,) $(call run_tests_debug,--testsuite=cakephp-28-test) +test_web_cakephp_310: global_test_run_dependencies + $(call run_composer_with_retry,tests/Frameworks/CakePHP/Version_3_10,) + $(call run_tests_debug,--testsuite=cakephp-310-test) +test_web_cakephp_45: global_test_run_dependencies + $(call run_composer_with_retry,tests/Frameworks/CakePHP/Version_4_5,) + $(call run_tests_debug,--testsuite=cakephp-45-test) +test_web_cakephp_50: global_test_run_dependencies + $(call run_composer_with_retry,tests/Frameworks/CakePHP/Version_5_0,) + $(call run_tests_debug,--testsuite=cakephp-50-test) test_web_codeigniter_22: global_test_run_dependencies $(call run_tests_debug,--testsuite=codeigniter-22-test) test_web_codeigniter_31: global_test_run_dependencies diff --git a/composer.json b/composer.json index b11ab618a8..53502a53d7 100644 --- a/composer.json +++ b/composer.json @@ -36,7 +36,8 @@ "sort-packages": true, "allow-plugins": { "g1a/composer-test-scenarios": true, - "php-http/discovery": true + "php-http/discovery": true, + "cakephp/plugin-installer": true } }, "autoload": { diff --git a/ext/integrations/integrations.c b/ext/integrations/integrations.c index 83a80ac46c..61a865cfdb 100644 --- a/ext/integrations/integrations.c +++ b/ext/integrations/integrations.c @@ -227,6 +227,10 @@ void ddtrace_integrations_minit(void) { "DDTrace\\Integrations\\CakePHP\\CakePHPIntegration"); DD_SET_UP_DEFERRED_LOADING_BY_METHOD(DDTRACE_INTEGRATION_CAKEPHP, "Dispatcher", "__construct", "DDTrace\\Integrations\\CakePHP\\CakePHPIntegration"); + DD_SET_UP_DEFERRED_LOADING_BY_METHOD(DDTRACE_INTEGRATION_CAKEPHP, "App\\Application", "__construct", + "DDTrace\\Integrations\\CakePHP\\CakePHPIntegration"); + DD_SET_UP_DEFERRED_LOADING_BY_METHOD(DDTRACE_INTEGRATION_CAKEPHP, "Cake\\Http\\Server", "__construct", + "DDTrace\\Integrations\\CakePHP\\CakePHPIntegration"); DD_SET_UP_DEFERRED_LOADING_BY_FUNCTION(DDTRACE_INTEGRATION_EXEC, "exec", "DDTrace\\Integrations\\Exec\\ExecIntegration"); diff --git a/src/DDTrace/Integrations/CakePHP/CakePHPIntegration.php b/src/DDTrace/Integrations/CakePHP/CakePHPIntegration.php index 8dfe458571..7f24c1926c 100644 --- a/src/DDTrace/Integrations/CakePHP/CakePHPIntegration.php +++ b/src/DDTrace/Integrations/CakePHP/CakePHPIntegration.php @@ -2,13 +2,10 @@ namespace DDTrace\Integrations\CakePHP; -use CakeRequest; +use DDTrace\Integrations\CakePHP\V2\CakePHPIntegrationLoader as CakePHPIntegrationLoaderV2; +use DDTrace\Integrations\CakePHP\V3\CakePHPIntegrationLoader as CakePHPIntegrationLoaderV3; use DDTrace\Integrations\Integration; -use DDTrace\SpanData; use DDTrace\Tag; -use DDTrace\Type; -use DDTrace\Util\Normalizer; -use Router; class CakePHPIntegration extends Integration { @@ -16,6 +13,10 @@ class CakePHPIntegration extends Integration public $appName; public $rootSpan; + public $setRootSpanInfoFn; + public $handleExceptionFn; + public $setStatusCodeFn; + public $parseRouteFn; /** * @return string The integration name. @@ -25,122 +26,59 @@ public function getName() return self::NAME; } - // CakePHP v2.x - we don't need to check for v3 since it does not have \Dispatcher or \ShellDispatcher public function init(): int { $integration = $this; - // Since "Dispatcher" and "App" are common names, check for a CakePHP signature before loading - if (!defined('CAKE_CORE_INCLUDE_PATH')) { - return self::NOT_AVAILABLE; - } - - $integration->rootSpan = null; - - $setRootSpanInfoFn = function () use ($integration) { + $integration->setRootSpanInfoFn = function () use ($integration) { $rootSpan = \DDTrace\root_span(); if ($rootSpan === null) { return; } $integration->appName = \ddtrace_config_app_name(CakePHPIntegration::NAME); - $integration->rootSpan = $rootSpan; - $integration->addTraceAnalyticsIfEnabled($integration->rootSpan); - $integration->rootSpan->service = $integration->appName; + $integration->addTraceAnalyticsIfEnabled($rootSpan); + $rootSpan->service = $integration->appName; if ('cli' === PHP_SAPI) { - $integration->rootSpan->name = 'cakephp.console'; - $integration->rootSpan->resource = - !empty($_SERVER['argv'][1]) ? 'cake_console ' . $_SERVER['argv'][1] : 'cake_console'; + $rootSpan->name = 'cakephp.console'; + $rootSpan->resource = !empty($_SERVER['argv'][1]) + ? 'cake_console ' . $_SERVER['argv'][1] + : 'cake_console'; } else { - $integration->rootSpan->name = 'cakephp.request'; - $integration->rootSpan->meta[Tag::SPAN_KIND] = 'server'; + $rootSpan->name = 'cakephp.request'; + $rootSpan->meta[Tag::SPAN_KIND] = 'server'; } - $integration->rootSpan->meta[Tag::COMPONENT] = CakePHPIntegration::NAME; + $rootSpan->meta[Tag::COMPONENT] = CakePHPIntegration::NAME; }; - \DDTrace\hook_method('App', 'init', $setRootSpanInfoFn); - \DDTrace\hook_method('Dispatcher', '__construct', $setRootSpanInfoFn); - - \DDTrace\trace_method( - 'Controller', - 'invokeAction', - function (SpanData $span, array $args) use ($integration) { - $span->name = $span->resource = 'Controller.invokeAction'; - $span->type = Type::WEB_SERVLET; - $span->service = $integration->appName; - $span->meta[Tag::COMPONENT] = CakePHPIntegration::NAME; - - $request = $args[0]; - if (!$request instanceof CakeRequest) { - return; - } - - if (dd_trace_env_config("DD_HTTP_SERVER_ROUTE_BASED_NAMING")) { - $integration->rootSpan->resource = - $_SERVER['REQUEST_METHOD'] . ' ' . $this->name . 'Controller@' . $request->params['action']; - } - - if (!array_key_exists(Tag::HTTP_URL, $integration->rootSpan->meta)) { - $integration->rootSpan->meta[Tag::HTTP_URL] = Router::url($request->here, true) - . Normalizer::sanitizedQueryString(); - } - $integration->rootSpan->meta['cakephp.route.controller'] = $request->params['controller']; - $integration->rootSpan->meta['cakephp.route.action'] = $request->params['action']; - if (isset($request->params['plugin'])) { - $integration->rootSpan->meta['cakephp.plugin'] = $request->params['plugin']; - } + $integration->handleExceptionFn = function ($This, $scope, $args) use ($integration) { + $rootSpan = \DDTrace\root_span(); + if ($rootSpan !== null) { + $integration->setError($rootSpan, $args[0]); } - ); - - // This only traces the default exception renderer - // Remove this when error tracking is added - // Other possible places to trace - // - ErrorHandler::handleException() - // - Controller::appError() - // - Exception.handler - // - Exception.renderer - \DDTrace\trace_method('ExceptionRenderer', '__construct', [ - 'instrument_when_limited' => 1, - 'posthook' => function (SpanData $span, array $args) use ($integration) { - $integration->setError($integration->rootSpan, $args[0]); - $span->meta[Tag::COMPONENT] = CakePHPIntegration::NAME; - return false; - }, - ]); - - \DDTrace\trace_method('CakeResponse', 'statusCode', [ - 'instrument_when_limited' => 1, - 'posthook' => function (SpanData $span, $args, $return) use ($integration) { - $integration->rootSpan->meta[Tag::HTTP_STATUS_CODE] = $return; - $span->meta[Tag::COMPONENT] = CakePHPIntegration::NAME; - return false; - }, - ]); + }; - // Create a trace span for every template rendered - \DDTrace\trace_method('View', 'render', function (SpanData $span) use ($integration) { - $span->name = 'cakephp.view'; - $span->type = Type::WEB_SERVLET; - $file = $this->viewPath . '/' . $this->view . $this->ext; - $span->resource = $file; - $span->meta = ['cakephp.view' => $file]; - $span->service = $integration->appName; - $span->meta[Tag::COMPONENT] = CakePHPIntegration::NAME; - }); + $integration->setStatusCodeFn = function ($This, $scope, $args, $retval) use ($integration) { + $rootSpan = \DDTrace\root_span(); + if ($rootSpan) { + $rootSpan->meta[Tag::HTTP_STATUS_CODE] = $retval; + } + }; - \DDTrace\hook_method( - 'CakeRoute', - 'parse', - null, - function ($app, $appClass, $args, $retval) use ($integration) { - if (!$retval) { - return; - } + $integration->parseRouteFn = function ($app, $appClass, $args, $retval) use ($integration) { + if (!$retval) { + return; + } - $integration->rootSpan->meta[Tag::HTTP_ROUTE] = $app->template; + $rootSpan = \DDTrace\root_span(); + if ($rootSpan !== null) { + $rootSpan->meta[Tag::HTTP_ROUTE] = $app->template; } - ); + }; - return Integration::LOADED; + $loader = class_exists('Cake\Http\Server') // Only exists in V3+ + ? new CakePHPIntegrationLoaderV3() + : new CakePHPIntegrationLoaderV2(); + return $loader->load($integration); } } diff --git a/src/DDTrace/Integrations/CakePHP/V2/CakePHPIntegrationLoader.php b/src/DDTrace/Integrations/CakePHP/V2/CakePHPIntegrationLoader.php new file mode 100644 index 0000000000..13b5aa901d --- /dev/null +++ b/src/DDTrace/Integrations/CakePHP/V2/CakePHPIntegrationLoader.php @@ -0,0 +1,99 @@ +setRootSpanInfoFn); + \DDTrace\hook_method('Dispatcher', '__construct', $integration->setRootSpanInfoFn); + + \DDTrace\trace_method( + 'Controller', + 'invokeAction', + function (SpanData $span, array $args) use ($integration) { + $span->name = $span->resource = 'Controller.invokeAction'; + $span->type = Type::WEB_SERVLET; + $span->service = $integration->appName; + $span->meta[Tag::COMPONENT] = CakePHPIntegration::NAME; + + $request = $args[0]; + if (!$request instanceof CakeRequest) { + return; + } + + $rootSpan = \DDTrace\root_span(); + + if (dd_trace_env_config("DD_HTTP_SERVER_ROUTE_BASED_NAMING")) { + $rootSpan->resource = + $_SERVER['REQUEST_METHOD'] . ' ' . $this->name . 'Controller@' . $request->params['action']; + } + + if (!array_key_exists(Tag::HTTP_URL, $rootSpan->meta)) { + $rootSpan->meta[Tag::HTTP_URL] = Router::url($request->here, true) + . Normalizer::sanitizedQueryString(); + } + $rootSpan->meta['cakephp.route.controller'] = $request->params['controller']; + $rootSpan->meta['cakephp.route.action'] = $request->params['action']; + if (isset($request->params['plugin'])) { + $rootSpan->meta['cakephp.plugin'] = $request->params['plugin']; + } + } + ); + + // This only traces the default exception renderer + // Remove this when error tracking is added + // Other possible places to trace + // - ErrorHandler::handleException() + // - Controller::appError() + // - Exception.handler + // - Exception.renderer + \DDTrace\hook_method( + 'ExceptionRenderer', + '__construct', + $integration->handleExceptionFn + ); + + \DDTrace\hook_method( + 'CakeResponse', + 'statusCode', + null, + $integration->setStatusCodeFn + ); + + // Create a trace span for every template rendered + \DDTrace\trace_method('View', 'render', function (SpanData $span) use ($integration) { + $span->name = 'cakephp.view'; + $span->type = Type::WEB_SERVLET; + $file = $this->viewPath . '/' . $this->view . $this->ext; + $span->resource = $file; + $span->meta = ['cakephp.view' => $file]; + $span->service = $integration->appName; + $span->meta[Tag::COMPONENT] = CakePHPIntegration::NAME; + }); + + \DDTrace\hook_method( + 'CakeRoute', + 'parse', + null, + $integration->parseRouteFn + ); + + return Integration::LOADED; + } +} diff --git a/src/DDTrace/Integrations/CakePHP/V3/CakePHPIntegrationLoader.php b/src/DDTrace/Integrations/CakePHP/V3/CakePHPIntegrationLoader.php new file mode 100644 index 0000000000..6ab43c25ea --- /dev/null +++ b/src/DDTrace/Integrations/CakePHP/V3/CakePHPIntegrationLoader.php @@ -0,0 +1,124 @@ +setRootSpanInfoFn); + \DDTrace\hook_method('Cake\Http\Server', '__construct', $integration->setRootSpanInfoFn); + + \DDTrace\trace_method( + 'Cake\Controller\Controller', + 'invokeAction', + function (SpanData $span) use ($integration) { + $span->name = $span->resource = 'Controller.invokeAction'; + $span->type = Type::WEB_SERVLET; + $span->service = $integration->appName; + $span->meta[Tag::COMPONENT] = CakePHPIntegration::NAME; + + /** @var \Cake\Controller\Controller $this */ + $request = $this->request; + if (!$request instanceof ServerRequest) { + return; + } + + $rootSpan = \DDTrace\root_span(); + + if (dd_trace_env_config("DD_HTTP_SERVER_ROUTE_BASED_NAMING")) { + $rootSpan->resource = + $_SERVER['REQUEST_METHOD'] . ' ' . $this->name . 'Controller@' . $request->getParam('action'); + } + + if (!array_key_exists(Tag::HTTP_URL, $rootSpan->meta)) { + $rootSpan->meta[Tag::HTTP_URL] = Router::url($request->getAttribute('here'), true) + . Normalizer::sanitizedQueryString(); + } + $rootSpan->meta['cakephp.route.controller'] = $request->getParam('controller'); + $rootSpan->meta['cakephp.route.action'] = $request->getParam('action'); + $plugin = $request->getParam('plugin'); + if ($plugin) { + $rootSpan->meta['cakephp.plugin'] = $plugin; + } + } + ); + + \DDTrace\hook_method( + 'Cake\Error\Middleware\ErrorHandlerMiddleware', + 'handleException', + $integration->handleExceptionFn + ); + + \DDTrace\hook_method( + 'Cake\Http\Response', + 'getStatusCode', + null, + $integration->setStatusCodeFn + ); + + // Create a trace span for every template rendered + \DDTrace\install_hook( + 'Cake\View\View::render', + function (HookData $renderHook) { + $renderHook->span(); + + // The next Cake\View\View::_getViewFileName (v3) or Cake\View\View::_getTemplateFileName (v4+) call + // will happen from render and will return the filename of the given action template file with the + // extension (e.g., .ctp, .twig) + $methodName = version_compare(\Cake\Core\Configure::version(), '4.0.0', '>=') ? + 'Cake\View\View::_getTemplateFileName' : 'Cake\View\View::_getViewFileName'; + \DDTrace\install_hook( + $methodName, + null, + function (HookData $hook) use ($renderHook) { + $renderHook->data['viewFileName'] = $hook->returned; + \DDTrace\remove_hook($hook->id); + } + ); + }, function (HookData $renderHook) use ($integration) { + $span = $renderHook->span(); + $span->name = 'cakephp.view'; + $span->type = Type::WEB_SERVLET; + $span->service = $integration->appName; + $span->meta[Tag::COMPONENT] = CakePHPIntegration::NAME; + + $absoluteFilePath = $renderHook->data['viewFileName'] ?? ''; + $fileExtension = pathinfo($absoluteFilePath, PATHINFO_EXTENSION); + $fileExtension = $fileExtension ? '.' . $fileExtension : ''; + /** @var \Cake\View\View $this */ + $file = $this->getTemplatePath() . '/' . $this->getTemplate() . $fileExtension; + $span->resource = $file; + $span->meta['cakephp.view'] = $file; + + $plugin = $this->getPlugin(); + if ($plugin) { + $span->meta['cakephp.plugin'] = $plugin; + } + + $theme = $this->getTheme(); + if ($theme) { + $span->meta['cakephp.theme'] = $theme; + } + }); + + \DDTrace\hook_method( + 'Cake\Routing\Route\Route', + 'parseRequest', + null, + $integration->parseRouteFn + ); + + return Integration::LOADED; + } +} diff --git a/tests/Frameworks/CakePHP/Version_3_10/.editorconfig b/tests/Frameworks/CakePHP/Version_3_10/.editorconfig new file mode 100644 index 0000000000..209e731b3e --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/.editorconfig @@ -0,0 +1,23 @@ +; This file is for unifying the coding style for different editors and IDEs. +; More information at http://editorconfig.org + +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.bat] +end_of_line = crlf + +[*.yml] +indent_size = 2 + +[*.twig] +insert_final_newline = false + +[Makefile] +indent_style = tab diff --git a/tests/Frameworks/CakePHP/Version_3_10/.gitattributes b/tests/Frameworks/CakePHP/Version_3_10/.gitattributes new file mode 100644 index 0000000000..aafe2efbe2 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/.gitattributes @@ -0,0 +1,50 @@ +# Define the line ending behavior of the different file extensions +# Set default behavior, in case users don't have core.autocrlf set. +* text=auto +* text eol=lf + +# Explicitly declare text files we want to always be normalized and converted +# to native line endings on checkout. +*.php text +*.default text +*.ctp text +*.sql text +*.md text +*.po text +*.js text +*.css text +*.ini text +*.properties text +*.txt text +*.xml text +*.svg text +*.yml text +.htaccess text + +# Declare files that will always have CRLF line endings on checkout. +*.bat eol=crlf + +# Declare files that will always have LF line endings on checkout. +*.pem eol=lf + +# Denote all files that are truly binary and should not be modified. +*.png binary +*.jpg binary +*.gif binary +*.webp binary +*.ico binary +*.mo binary +*.pdf binary +*.phar binary +*.woff binary +*.woff2 binary +*.ttf binary +*.otf binary +*.eot binary +*.gz binary +*.bz2 binary +*.7z binary +*.zip binary +*.webm binary +*.mp4 binary +*.ogv binary diff --git a/tests/Frameworks/CakePHP/Version_3_10/.gitignore b/tests/Frameworks/CakePHP/Version_3_10/.gitignore new file mode 100644 index 0000000000..53786253f4 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/.gitignore @@ -0,0 +1,41 @@ +# CakePHP specific files # +########################## +/config/app_local.php +/config/.env +/logs/* +/tmp/* +/vendor/* + +# OS generated files # +###################### +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +Icon? +ehthumbs.db +Thumbs.db +.directory + +# Tool specific files # +####################### +# vim +*~ +*.swp +*.swo +# sublime text & textmate +*.sublime-* +*.stTheme.cache +*.tmlanguage.cache +*.tmPreferences.cache +# Eclipse +.settings/* +# JetBrains, aka PHPStorm, IntelliJ IDEA +.idea/* +# NetBeans +nbproject/* +# Visual Studio Code +.vscode +# Sass preprocessor +.sass-cache/ diff --git a/tests/Frameworks/CakePHP/Version_3_10/.htaccess b/tests/Frameworks/CakePHP/Version_3_10/.htaccess new file mode 100644 index 0000000000..54b08e82e1 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/.htaccess @@ -0,0 +1,12 @@ +# Uncomment the following to prevent the httpoxy vulnerability +# See: https://httpoxy.org/ +# +# RequestHeader unset Proxy +# + + + RewriteEngine on + RewriteRule ^(\.well-known/.*)$ $1 [L] + RewriteRule ^$ webroot/ [L] + RewriteRule (.*) webroot/$1 [L] + diff --git a/tests/Frameworks/CakePHP/Version_3_10/.travis.yml b/tests/Frameworks/CakePHP/Version_3_10/.travis.yml new file mode 100644 index 0000000000..e8da19226a --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/.travis.yml @@ -0,0 +1,33 @@ +language: php + +php: + - 5.6 + - 7.4 + +env: + global: + - DEFAULT=1 + +matrix: + include: + - php: 7.3 + env: CHECKS=1 DEFAULT=0 + +before_script: + - composer install --no-interaction + - if [[ $DEFAULT == 1 ]]; then composer run-script post-install-cmd --no-interaction; fi + + - if [[ $CHECKS == 1 ]]; then composer stan-setup; fi + +script: + - if [[ $DEFAULT == 1 ]]; then composer test; fi + + - if [[ $CHECKS == 1 ]]; then composer cs-check; fi + - if [[ $CHECKS == 1 ]]; then composer stan; fi + +cache: + directories: + - $HOME/.composer/cache + +notifications: + email: false diff --git a/tests/Frameworks/CakePHP/Version_3_10/README.md b/tests/Frameworks/CakePHP/Version_3_10/README.md new file mode 100644 index 0000000000..1c4be816e6 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/README.md @@ -0,0 +1,51 @@ +# CakePHP Application Skeleton + +[![Build Status](https://img.shields.io/travis/cakephp/app/master.svg?style=flat-square)](https://travis-ci.org/cakephp/app) +[![Total Downloads](https://img.shields.io/packagist/dt/cakephp/app.svg?style=flat-square)](https://packagist.org/packages/cakephp/app) + +A skeleton for creating applications with [CakePHP](https://cakephp.org) 3.x. + +The framework source code can be found here: [cakephp/cakephp](https://github.com/cakephp/cakephp). + +## Installation + +1. Download [Composer](https://getcomposer.org/doc/00-intro.md) or update `composer self-update`. +2. Run `php composer.phar create-project --prefer-dist cakephp/app [app_name]`. + +If Composer is installed globally, run + +```bash +composer create-project --prefer-dist "cakephp/app:^3.8" +``` + +In case you want to use a custom app dir name (e.g. `/myapp/`): + +```bash +composer create-project --prefer-dist "cakephp/app:^3.8" myapp +``` + +You can now either use your machine's webserver to view the default home page, or start +up the built-in webserver with: + +```bash +bin/cake server -p 8765 +``` + +Then visit `http://localhost:8765` to see the welcome page. + +## Update + +Since this skeleton is a starting point for your application and various files +would have been modified as per your needs, there isn't a way to provide +automated upgrades, so you have to do any updates manually. + +## Configuration + +Read and edit `config/app.php` and setup the `'Datasources'` and any other +configuration relevant for your application. + +## Layout + +The app skeleton uses a subset of [Foundation](http://foundation.zurb.com/) (v5) CSS +framework by default. You can, however, replace it with any other library or +custom styles. diff --git a/tests/Frameworks/CakePHP/Version_3_10/bin/cake b/tests/Frameworks/CakePHP/Version_3_10/bin/cake new file mode 100755 index 0000000000..4b696c883f --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/bin/cake @@ -0,0 +1,75 @@ +#!/usr/bin/env sh +################################################################################ +# +# Cake is a shell script for invoking CakePHP shell commands +# +# CakePHP(tm) : Rapid Development Framework (https://cakephp.org) +# Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) +# +# Licensed under The MIT License +# For full copyright and license information, please see the LICENSE.txt +# Redistributions of files must retain the above copyright notice. +# +# @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) +# @link https://cakephp.org CakePHP(tm) Project +# @since 1.2.0 +# @license https://opensource.org/licenses/mit-license.php MIT License +# +################################################################################ + +# Canonicalize by following every symlink of the given name recursively +canonicalize() { + NAME="$1" + if [ -f "$NAME" ] + then + DIR=$(dirname -- "$NAME") + NAME=$(cd -P "$DIR" > /dev/null && pwd -P)/$(basename -- "$NAME") + fi + while [ -h "$NAME" ]; do + DIR=$(dirname -- "$NAME") + SYM=$(readlink "$NAME") + NAME=$(cd "$DIR" > /dev/null && cd "$(dirname -- "$SYM")" > /dev/null && pwd)/$(basename -- "$SYM") + done + echo "$NAME" +} + +# Find a CLI version of PHP +findCliPhp() { + for TESTEXEC in php php-cli /usr/local/bin/php + do + SAPI=$(echo "" | $TESTEXEC 2>/dev/null) + if [ "$SAPI" = "cli" ] + then + echo $TESTEXEC + return + fi + done + echo "Failed to find a CLI version of PHP; falling back to system standard php executable" >&2 + echo "php"; +} + +# If current path is a symlink, resolve to real path +realname="$0" +if [ -L "$realname" ] +then + realname=$(readlink -f "$0") +fi + +CONSOLE=$(dirname -- "$(canonicalize "$realname")") +APP=$(dirname "$CONSOLE") + +# If your CLI PHP is somewhere that this doesn't find, you can define a PHP environment +# variable with the correct path in it. +if [ -z "$PHP" ] +then + PHP=$(findCliPhp) +fi + +if [ "$(basename "$realname")" != 'cake' ] +then + exec "$PHP" "$CONSOLE"/cake.php "$(basename "$realname")" "$@" +else + exec "$PHP" "$CONSOLE"/cake.php "$@" +fi + +exit diff --git a/tests/Frameworks/CakePHP/Version_3_10/bin/cake.bat b/tests/Frameworks/CakePHP/Version_3_10/bin/cake.bat new file mode 100644 index 0000000000..ad13782298 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/bin/cake.bat @@ -0,0 +1,27 @@ +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:: +:: Cake is a Windows batch script for invoking CakePHP shell commands +:: +:: CakePHP(tm) : Rapid Development Framework (https://cakephp.org) +:: Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) +:: +:: Licensed under The MIT License +:: Redistributions of files must retain the above copyright notice. +:: +:: @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) +:: @link https://cakephp.org CakePHP(tm) Project +:: @since 2.0.0 +:: @license https://opensource.org/licenses/mit-license.php MIT License +:: +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +@echo off + +SET app=%0 +SET lib=%~dp0 + +php "%lib%cake.php" %* + +echo. + +exit /B %ERRORLEVEL% diff --git a/tests/Frameworks/CakePHP/Version_3_10/bin/cake.php b/tests/Frameworks/CakePHP/Version_3_10/bin/cake.php new file mode 100644 index 0000000000..320ee36439 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/bin/cake.php @@ -0,0 +1,12 @@ +#!/usr/bin/php -q +run($argv)); diff --git a/tests/Frameworks/CakePHP/Version_3_10/composer.json b/tests/Frameworks/CakePHP/Version_3_10/composer.json new file mode 100644 index 0000000000..db51a52ba8 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/composer.json @@ -0,0 +1,58 @@ +{ + "name": "cakephp/app", + "description": "CakePHP skeleton app", + "homepage": "https://cakephp.org", + "type": "project", + "license": "MIT", + "require": { + "php": ">=5.6", + "cakephp/cakephp": "3.10.*", + "cakephp/migrations": "^2.0.0", + "cakephp/plugin-installer": "^1.3", + "mobiledetect/mobiledetectlib": "2.*" + }, + "require-dev": { + "cakephp/bake": "^1.9.0", + "cakephp/cakephp-codesniffer": "^3.0", + "cakephp/debug_kit": "^3.17.0", + "josegonzalez/dotenv": "3.*", + "phpunit/phpunit": "^5|^6", + "psy/psysh": "@stable" + }, + "suggest": { + "markstory/asset_compress": "An asset compression plugin which provides file concatenation and a flexible filter system for preprocessing and minification.", + "dereuromark/cakephp-ide-helper": "After baking your code, this keeps your annotations in sync with the code evolving from there on for maximum IDE and PHPStan/Psalm compatibility." + }, + "autoload": { + "psr-4": { + "App\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "App\\Test\\": "tests/", + "Cake\\Test\\": "vendor/cakephp/cakephp/tests/" + } + }, + "scripts": { + "post-install-cmd": "App\\Console\\Installer::postInstall", + "post-create-project-cmd": "App\\Console\\Installer::postInstall", + "post-autoload-dump": "Cake\\Composer\\Installer\\PluginInstaller::postAutoloadDump", + "check": [ + "@test", + "@cs-check" + ], + "cs-check": "phpcs --colors -p --extensions=php --standard=vendor/cakephp/cakephp-codesniffer/CakePHP src/ tests/ config/ webroot/", + "cs-fix": "phpcbf --colors -p --extensions=php --standard=vendor/cakephp/cakephp-codesniffer/CakePHP src/ tests/ config/ webroot/", + "stan": "phpstan analyse -l 5 src/", + "stan-setup": "cp composer.json composer.backup && composer require --dev phpstan/phpstan-shim:^0.11 && mv composer.backup composer.json", + "test": "phpunit --colors=always" + }, + "prefer-stable": true, + "config": { + "sort-packages": true, + "allow-plugins": { + "cakephp/plugin-installer": true + } + } +} diff --git a/tests/Frameworks/CakePHP/Version_3_10/config/.env.example b/tests/Frameworks/CakePHP/Version_3_10/config/.env.example new file mode 100644 index 0000000000..15060f7be7 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/config/.env.example @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# Used as a default to seed config/.env which +# enables you to use environment variables to configure +# the aspects of your application that vary by +# environment. +# +# Having this file in production is considered a **SECURITY RISK** and also decreases +# the boostrap performance of your application. +# +# To use this file, first copy it into `config/.env`. Also ensure the related +# code block for loading this file is uncommented in `config/boostrap.php` +# +# In development .env files are parsed by PHP +# and set into the environment. This provides a simpler +# development workflow over standard environment variables. +export APP_NAME="__APP_NAME__" +export DEBUG="true" +export APP_ENCODING="UTF-8" +export APP_DEFAULT_LOCALE="en_US" +export APP_DEFAULT_TIMEZONE="UTC" +export SECURITY_SALT="__SALT__" + +# Uncomment these to define cache configuration via environment variables. +#export CACHE_DURATION="+2 minutes" +#export CACHE_DEFAULT_URL="file://tmp/cache/?prefix=${APP_NAME}_default&duration=${CACHE_DURATION}" +#export CACHE_CAKECORE_URL="file://tmp/cache/persistent?prefix=${APP_NAME}_cake_core&serialize=true&duration=${CACHE_DURATION}" +#export CACHE_CAKEMODEL_URL="file://tmp/cache/models?prefix=${APP_NAME}_cake_model&serialize=true&duration=${CACHE_DURATION}" + +# Uncomment these to define email transport configuration via environment variables. +#export EMAIL_TRANSPORT_DEFAULT_URL="" + +# Uncomment these to define database configuration via environment variables. +#export DATABASE_URL="mysql://my_app:secret@localhost/${APP_NAME}?encoding=utf8&timezone=UTC&cacheMetadata=true"eIdentifiers=false&persistent=false" +#export DATABASE_TEST_URL="mysql://my_app:secret@localhost/test_${APP_NAME}?encoding=utf8&timezone=UTC&cacheMetadata=true"eIdentifiers=false&persistent=false" + +# Uncomment these to define logging configuration via environment variables. +#export LOG_DEBUG_URL="file://logs/?levels[]=notice&levels[]=info&levels[]=debug&file=debug" +#export LOG_ERROR_URL="file://logs/?levels[]=warning&levels[]=error&levels[]=critical&levels[]=alert&levels[]=emergency&file=error" diff --git a/tests/Frameworks/CakePHP/Version_3_10/config/app.php b/tests/Frameworks/CakePHP/Version_3_10/config/app.php new file mode 100644 index 0000000000..afc81fa799 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/config/app.php @@ -0,0 +1,404 @@ + filter_var(env('DEBUG', false), FILTER_VALIDATE_BOOLEAN), + + /* + * Configure basic information about the application. + * + * - namespace - The namespace to find app classes under. + * - defaultLocale - The default locale for translation, formatting currencies and numbers, date and time. + * - encoding - The encoding used for HTML + database connections. + * - base - The base directory the app resides in. If false this + * will be auto detected. + * - dir - Name of app directory. + * - webroot - The webroot directory. + * - wwwRoot - The file path to webroot. + * - baseUrl - To configure CakePHP to *not* use mod_rewrite and to + * use CakePHP pretty URLs, remove these .htaccess + * files: + * /.htaccess + * /webroot/.htaccess + * And uncomment the baseUrl key below. + * - fullBaseUrl - A base URL to use for absolute links. When set to false (default) + * CakePHP generates required value based on `HTTP_HOST` environment variable. + * However, you can define it manually to optimize performance or if you + * are concerned about people manipulating the `Host` header. + * - imageBaseUrl - Web path to the public images directory under webroot. + * - cssBaseUrl - Web path to the public css directory under webroot. + * - jsBaseUrl - Web path to the public js directory under webroot. + * - paths - Configure paths for non class based resources. Supports the + * `plugins`, `templates`, `locales` subkeys, which allow the definition of + * paths for plugins, view templates and locale files respectively. + */ + 'App' => [ + 'namespace' => 'App', + 'encoding' => env('APP_ENCODING', 'UTF-8'), + 'defaultLocale' => env('APP_DEFAULT_LOCALE', 'en_US'), + 'defaultTimezone' => env('APP_DEFAULT_TIMEZONE', 'UTC'), + 'base' => false, + 'dir' => 'src', + 'webroot' => 'webroot', + 'wwwRoot' => WWW_ROOT, + //'baseUrl' => env('SCRIPT_NAME'), + 'fullBaseUrl' => false, + 'imageBaseUrl' => 'img/', + 'cssBaseUrl' => 'css/', + 'jsBaseUrl' => 'js/', + 'paths' => [ + 'plugins' => [ROOT . DS . 'plugins' . DS], + 'templates' => [APP . 'Template' . DS], + 'locales' => [APP . 'Locale' . DS], + ], + ], + + /* + * Security and encryption configuration + * + * - salt - A random string used in security hashing methods. + * The salt value is also used as the encryption key. + * You should treat it as extremely sensitive data. + */ + 'Security' => [ + 'salt' => env('SECURITY_SALT'), + ], + + /* + * Apply timestamps with the last modified time to static assets (js, css, images). + * Will append a querystring parameter containing the time the file was modified. + * This is useful for busting browser caches. + * + * Set to true to apply timestamps when debug is true. Set to 'force' to always + * enable timestamping regardless of debug value. + */ + 'Asset' => [ + //'timestamp' => true, + // 'cacheTime' => '+1 year' + ], + + /* + * Configure the cache adapters. + */ + 'Cache' => [ + 'default' => [ + 'className' => FileEngine::class, + 'path' => CACHE, + 'url' => env('CACHE_DEFAULT_URL', null), + ], + + /* + * Configure the cache used for general framework caching. + * Translation cache files are stored with this configuration. + * Duration will be set to '+2 minutes' in bootstrap.php when debug = true + * If you set 'className' => 'Null' core cache will be disabled. + */ + '_cake_core_' => [ + 'className' => FileEngine::class, + 'prefix' => 'myapp_cake_core_', + 'path' => CACHE . 'persistent/', + 'serialize' => true, + 'duration' => '+1 years', + 'url' => env('CACHE_CAKECORE_URL', null), + ], + + /* + * Configure the cache for model and datasource caches. This cache + * configuration is used to store schema descriptions, and table listings + * in connections. + * Duration will be set to '+2 minutes' in bootstrap.php when debug = true + */ + '_cake_model_' => [ + 'className' => FileEngine::class, + 'prefix' => 'myapp_cake_model_', + 'path' => CACHE . 'models/', + 'serialize' => true, + 'duration' => '+1 years', + 'url' => env('CACHE_CAKEMODEL_URL', null), + ], + + /* + * Configure the cache for routes. The cached routes collection is built the + * first time the routes are processed through `config/routes.php`. + * Duration will be set to '+2 seconds' in bootstrap.php when debug = true + */ + '_cake_routes_' => [ + 'className' => FileEngine::class, + 'prefix' => 'myapp_cake_routes_', + 'path' => CACHE, + 'serialize' => true, + 'duration' => '+1 years', + 'url' => env('CACHE_CAKEROUTES_URL', null), + ], + ], + + /* + * Configure the Error and Exception handlers used by your application. + * + * By default errors are displayed using Debugger, when debug is true and logged + * by Cake\Log\Log when debug is false. + * + * In CLI environments exceptions will be printed to stderr with a backtrace. + * In web environments an HTML page will be displayed for the exception. + * With debug true, framework errors like Missing Controller will be displayed. + * When debug is false, framework errors will be coerced into generic HTTP errors. + * + * Options: + * + * - `errorLevel` - int - The level of errors you are interested in capturing. + * - `trace` - boolean - Whether or not backtraces should be included in + * logged errors/exceptions. + * - `log` - boolean - Whether or not you want exceptions logged. + * - `exceptionRenderer` - string - The class responsible for rendering + * uncaught exceptions. If you choose a custom class you should place + * the file for that class in src/Error. This class needs to implement a + * render method. + * - `skipLog` - array - List of exceptions to skip for logging. Exceptions that + * extend one of the listed exceptions will also be skipped for logging. + * E.g.: + * `'skipLog' => ['Cake\Http\Exception\NotFoundException', 'Cake\Http\Exception\UnauthorizedException']` + * - `extraFatalErrorMemory` - int - The number of megabytes to increase + * the memory limit by when a fatal error is encountered. This allows + * breathing room to complete logging or error handling. + */ + 'Error' => [ + 'errorLevel' => E_ALL, + 'exceptionRenderer' => ExceptionRenderer::class, + 'skipLog' => [], + 'log' => true, + 'trace' => true, + ], + + /* + * Email configuration. + * + * By defining transports separately from delivery profiles you can easily + * re-use transport configuration across multiple profiles. + * + * You can specify multiple configurations for production, development and + * testing. + * + * Each transport needs a `className`. Valid options are as follows: + * + * Mail - Send using PHP mail function + * Smtp - Send using SMTP + * Debug - Do not send the email, just return the result + * + * You can add custom transports (or override existing transports) by adding the + * appropriate file to src/Mailer/Transport. Transports should be named + * 'YourTransport.php', where 'Your' is the name of the transport. + */ + 'EmailTransport' => [ + 'default' => [ + 'className' => MailTransport::class, + /* + * The keys host, port, timeout, username, password, client and tls + * are used in SMTP transports + */ + 'host' => 'localhost', + 'port' => 25, + 'timeout' => 30, + /* + * It is recommended to set these options through your environment or app_local.php + */ + //'username' => null, + //'password' => null, + 'client' => null, + 'tls' => false, + 'url' => env('EMAIL_TRANSPORT_DEFAULT_URL', null), + ], + ], + + /* + * Email delivery profiles + * + * Delivery profiles allow you to predefine various properties about email + * messages from your application and give the settings a name. This saves + * duplication across your application and makes maintenance and development + * easier. Each profile accepts a number of keys. See `Cake\Mailer\Email` + * for more information. + */ + 'Email' => [ + 'default' => [ + 'transport' => 'default', + 'from' => 'you@localhost', + /* + * Will by default be set to config value of App.encoding, if that exists otherwise to UTF-8. + */ + //'charset' => 'utf-8', + //'headerCharset' => 'utf-8', + ], + ], + + /* + * Connection information used by the ORM to connect + * to your application's datastores. + * + * ### Notes + * - Drivers include Mysql Postgres Sqlite Sqlserver + * See vendor\cakephp\cakephp\src\Database\Driver for complete list + * - Do not use periods in database name - it may lead to error. + * See https://github.com/cakephp/cakephp/issues/6471 for details. + * - 'encoding' is recommended to be set to full UTF-8 4-Byte support. + * E.g set it to 'utf8mb4' in MariaDB and MySQL and 'utf8' for any + * other RDBMS. + */ + 'Datasources' => [ + 'default' => [ + 'className' => Connection::class, + 'driver' => Mysql::class, + 'persistent' => false, + 'host' => 'localhost', + /* + * CakePHP will use the default DB port based on the driver selected + * MySQL on MAMP uses port 8889, MAMP users will want to uncomment + * the following line and set the port accordingly + */ + //'port' => 'non_standard_port_number', + /* + * It is recommended to set these options through your environment or app_local.php + */ + //'username' => 'my_app', + //'password' => 'secret', + //'database' => 'my_app', + /* + * You do not need to set this flag to use full utf-8 encoding (internal default since CakePHP 3.6). + */ + //'encoding' => 'utf8mb4', + 'timezone' => 'UTC', + 'flags' => [], + 'cacheMetadata' => true, + 'log' => false, + + /* + * Set identifier quoting to true if you are using reserved words or + * special characters in your table or column names. Enabling this + * setting will result in queries built using the Query Builder having + * identifiers quoted when creating SQL. It should be noted that this + * decreases performance because each query needs to be traversed and + * manipulated before being executed. + */ + 'quoteIdentifiers' => false, + + /* + * During development, if using MySQL < 5.6, uncommenting the + * following line could boost the speed at which schema metadata is + * fetched from the database. It can also be set directly with the + * mysql configuration directive 'innodb_stats_on_metadata = 0' + * which is the recommended value in production environments + */ + //'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'], + + 'url' => env('DATABASE_URL', null), + ], + + /* + * The test connection is used during the test suite. + */ + 'test' => [ + 'className' => Connection::class, + 'driver' => Mysql::class, + 'persistent' => false, + 'host' => 'localhost', + //'port' => 'non_standard_port_number', + 'username' => 'my_app', + 'password' => 'secret', + 'database' => 'test_myapp', + //'encoding' => 'utf8mb4', + 'timezone' => 'UTC', + 'cacheMetadata' => true, + 'quoteIdentifiers' => false, + 'log' => false, + //'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'], + 'url' => env('DATABASE_TEST_URL', null), + ], + ], + + /* + * Configures logging options + */ + 'Log' => [ + 'debug' => [ + 'className' => FileLog::class, + 'path' => LOGS, + 'file' => 'debug', + 'url' => env('LOG_DEBUG_URL', null), + 'scopes' => false, + 'levels' => ['notice', 'info', 'debug'], + ], + 'error' => [ + 'className' => FileLog::class, + 'path' => LOGS, + 'file' => 'error', + 'url' => env('LOG_ERROR_URL', null), + 'scopes' => false, + 'levels' => ['warning', 'error', 'critical', 'alert', 'emergency'], + ], + // To enable this dedicated query log, you need set your datasource's log flag to true + 'queries' => [ + 'className' => FileLog::class, + 'path' => LOGS, + 'file' => 'queries', + 'url' => env('LOG_QUERIES_URL', null), + 'scopes' => ['queriesLog'], + ], + ], + + /* + * Session configuration. + * + * Contains an array of settings to use for session configuration. The + * `defaults` key is used to define a default preset to use for sessions, any + * settings declared here will override the settings of the default config. + * + * ## Options + * + * - `cookie` - The name of the cookie to use. Defaults to 'CAKEPHP'. Avoid using `.` in cookie names, + * as PHP will drop sessions from cookies with `.` in the name. + * - `cookiePath` - The url path for which session cookie is set. Maps to the + * `session.cookie_path` php.ini config. Defaults to base path of app. + * - `timeout` - The time in minutes the session should be valid for. + * Pass 0 to disable checking timeout. + * Please note that php.ini's session.gc_maxlifetime must be equal to or greater + * than the largest Session['timeout'] in all served websites for it to have the + * desired effect. + * - `defaults` - The default configuration set to use as a basis for your session. + * There are four built-in options: php, cake, cache, database. + * - `handler` - Can be used to enable a custom session handler. Expects an + * array with at least the `engine` key, being the name of the Session engine + * class to use for managing the session. CakePHP bundles the `CacheSession` + * and `DatabaseSession` engines. + * - `ini` - An associative array of additional ini values to set. + * + * The built-in `defaults` options are: + * + * - 'php' - Uses settings defined in your php.ini. + * - 'cake' - Saves session files in CakePHP's /tmp directory. + * - 'database' - Uses CakePHP's database sessions. + * - 'cache' - Use the Cache class to save sessions. + * + * To define a custom session handler, save it at src/Network/Session/.php. + * Make sure the class implements PHP's `SessionHandlerInterface` and set + * Session.handler to + * + * To use database sessions, load the SQL file located at config/schema/sessions.sql + */ + 'Session' => [ + 'defaults' => 'php', + ], +]; diff --git a/tests/Frameworks/CakePHP/Version_3_10/config/app_local.example.php b/tests/Frameworks/CakePHP/Version_3_10/config/app_local.example.php new file mode 100644 index 0000000000..8be54ed561 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/config/app_local.example.php @@ -0,0 +1,71 @@ + filter_var(env('DEBUG', true), FILTER_VALIDATE_BOOLEAN), + + /* + * Security and encryption configuration + * + * - salt - A random string used in security hashing methods. + * The salt value is also used as the encryption key. + * You should treat it as extremely sensitive data. + */ + 'Security' => [ + 'salt' => env('SECURITY_SALT', '__SALT__'), + ], + + /* + * Connection information used by the ORM to connect + * to your application's datastores. + * + * See app.php for more configuration options. + */ + 'Datasources' => [ + 'default' => [ + 'host' => 'localhost', + /* + * CakePHP will use the default DB port based on the driver selected + * MySQL on MAMP uses port 8889, MAMP users will want to uncomment + * the following line and set the port accordingly + */ + //'port' => 'non_standard_port_number', + 'username' => 'my_app', + 'password' => 'secret', + 'database' => 'my_app', + 'log' => true, + 'url' => env('DATABASE_URL', null), + ], + ], + + /* + * Email configuration. + * + * Host and credential configuration in case you are using SmtpTransport + * + * See app.php for more configuration options. + */ + 'EmailTransport' => [ + 'default' => [ + 'host' => 'localhost', + 'port' => 25, + 'username' => null, + 'password' => null, + 'client' => null, + 'url' => env('EMAIL_TRANSPORT_DEFAULT_URL', null), + ], + ], +]; diff --git a/tests/Frameworks/CakePHP/Version_3_10/config/bootstrap.php b/tests/Frameworks/CakePHP/Version_3_10/config/bootstrap.php new file mode 100644 index 0000000000..1a5a89aa24 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/config/bootstrap.php @@ -0,0 +1,203 @@ +parse() +// ->putenv() +// ->toEnv() +// ->toServer(); +// } + +/* + * Read configuration file and inject configuration into various + * CakePHP classes. + * + * By default there is only one configuration file. It is often a good + * idea to create multiple configuration files, and separate the configuration + * that changes from configuration that does not. This makes deployment simpler. + */ +try { + Configure::config('default', new PhpConfig()); + Configure::load('app', 'default', false); +} catch (\Exception $e) { + exit($e->getMessage() . "\n"); +} + +/* + * Load an environment local configuration file to provide overrides to your configuration. + * Notice: For security reasons app_local.php will not be included in your git repo. + */ +if (file_exists(CONFIG . 'app_local.php')) { + Configure::load('app_local', 'default'); +} + +/* + * When debug = true the metadata cache should only last + * for a short time. + */ +if (Configure::read('debug')) { + Configure::write('Cache._cake_model_.duration', '+2 minutes'); + Configure::write('Cache._cake_core_.duration', '+2 minutes'); + // disable router cache during development + Configure::write('Cache._cake_routes_.duration', '+2 seconds'); +} + +/* + * Set the default server timezone. Using UTC makes time calculations / conversions easier. + * Check http://php.net/manual/en/timezones.php for list of valid timezone strings. + */ +date_default_timezone_set(Configure::read('App.defaultTimezone')); + +/* + * Configure the mbstring extension to use the correct encoding. + */ +mb_internal_encoding(Configure::read('App.encoding')); + +/* + * Set the default locale. This controls how dates, number and currency is + * formatted and sets the default language to use for translations. + */ +ini_set('intl.default_locale', Configure::read('App.defaultLocale')); + +/* + * Register application error and exception handlers. + */ +$isCli = PHP_SAPI === 'cli'; +if ($isCli) { + (new ConsoleErrorHandler(Configure::read('Error')))->register(); +} else { + (new ErrorHandler(Configure::read('Error')))->register(); +} + +/* + * Include the CLI bootstrap overrides. + */ +if ($isCli) { + require __DIR__ . '/bootstrap_cli.php'; +} + +/* + * Set the full base URL. + * This URL is used as the base of all absolute links. + * + * If you define fullBaseUrl in your config file you can remove this. + */ +if (!Configure::read('App.fullBaseUrl')) { + $s = null; + if (env('HTTPS')) { + $s = 's'; + } + + $httpHost = env('HTTP_HOST'); + if (isset($httpHost)) { + Configure::write('App.fullBaseUrl', 'http' . $s . '://' . $httpHost); + } + unset($httpHost, $s); +} + +Cache::setConfig(Configure::consume('Cache')); +ConnectionManager::setConfig(Configure::consume('Datasources')); +TransportFactory::setConfig(Configure::consume('EmailTransport')); +Email::setConfig(Configure::consume('Email')); +Log::setConfig(Configure::consume('Log')); +Security::setSalt(Configure::consume('Security.salt')); + +/* + * The default crypto extension in 3.0 is OpenSSL. + * If you are migrating from 2.x uncomment this code to + * use a more compatible Mcrypt based implementation + */ +//Security::engine(new \Cake\Utility\Crypto\Mcrypt()); + +/* + * Setup detectors for mobile and tablet. + */ +ServerRequest::addDetector('mobile', function ($request) { + $detector = new \Detection\MobileDetect(); + + return $detector->isMobile(); +}); +ServerRequest::addDetector('tablet', function ($request) { + $detector = new \Detection\MobileDetect(); + + return $detector->isTablet(); +}); + +/* + * Enable immutable time objects in the ORM. + * + * You can enable default locale format parsing by adding calls + * to `useLocaleParser()`. This enables the automatic conversion of + * locale specific date formats. For details see + * @link https://book.cakephp.org/3/en/core-libraries/internationalization-and-localization.html#parsing-localized-datetime-data + */ +Type::build('time') + ->useImmutable(); +Type::build('date') + ->useImmutable(); +Type::build('datetime') + ->useImmutable(); +Type::build('timestamp') + ->useImmutable(); + +/* + * Custom Inflector rules, can be set to correctly pluralize or singularize + * table, model, controller names or whatever other string is passed to the + * inflection functions. + */ +//Inflector::rules('plural', ['/^(inflect)or$/i' => '\1ables']); +//Inflector::rules('irregular', ['red' => 'redlings']); +//Inflector::rules('uninflected', ['dontinflectme']); +//Inflector::rules('transliteration', ['/å/' => 'aa']); diff --git a/tests/Frameworks/CakePHP/Version_3_10/config/bootstrap_cli.php b/tests/Frameworks/CakePHP/Version_3_10/config/bootstrap_cli.php new file mode 100644 index 0000000000..bb9c850dc5 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/config/bootstrap_cli.php @@ -0,0 +1,28 @@ += 50.1 is needed to use CakePHP. Please update the `libicu` package of your system.' . PHP_EOL, E_USER_ERROR); +} + +/* + * You can remove this if you are confident you have mbstring installed. + */ +if (!extension_loaded('mbstring')) { + trigger_error('You must enable the mbstring extension to use CakePHP.' . PHP_EOL, E_USER_ERROR); +} diff --git a/tests/Frameworks/CakePHP/Version_3_10/config/routes.php b/tests/Frameworks/CakePHP/Version_3_10/config/routes.php new file mode 100644 index 0000000000..0a981341eb --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/config/routes.php @@ -0,0 +1,109 @@ +registerMiddleware('csrf', new CsrfProtectionMiddleware([ + 'httpOnly' => true, + ])); + + /* + * Apply a middleware to the current route scope. + * Requires middleware to be registered through `Application::routes()` with `registerMiddleware()` + */ + $routes->applyMiddleware('csrf'); + + /* + * Here, we are connecting '/' (base path) to a controller called 'Pages', + * its action called 'display', and we pass a param to select the view file + * to use (in this case, src/Template/Pages/home.ctp)... + */ + $routes->connect('/', ['controller' => 'Pages', 'action' => 'display', 'home']); + + /* + * ...and connect the rest of 'Pages' controller's URLs. + */ + $routes->connect('/pages/*', ['controller' => 'Pages', 'action' => 'display']); + + $routes->connect('/parameterized/:param', + ['controller' => 'Parameterized', 'action' => 'customAction'], + ['pass' => ['param']] + ); + + /* + * Connect catchall routes for all controllers. + * + * Using the argument `DashedRoute`, the `fallbacks` method is a shortcut for + * + * ``` + * $routes->connect('/:controller', ['action' => 'index'], ['routeClass' => 'DashedRoute']); + * $routes->connect('/:controller/:action/*', [], ['routeClass' => 'DashedRoute']); + * ``` + * + * Any route class can be used with this method, such as: + * - DashedRoute + * - InflectedRoute + * - Route + * - Or your own route class + * + * You can remove these routes once you've connected the + * routes you want in your application. + */ + $routes->fallbacks(DashedRoute::class); +}); + +/* + * If you need a different set of middleware or none at all, + * open new scope and define routes there. + * + * ``` + * Router::scope('/api', function (RouteBuilder $routes) { + * // No $routes->applyMiddleware() here. + * // Connect API actions here. + * }); + * ``` + */ diff --git a/tests/Frameworks/CakePHP/Version_3_10/config/schema/i18n.sql b/tests/Frameworks/CakePHP/Version_3_10/config/schema/i18n.sql new file mode 100644 index 0000000000..e59d1e6511 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/config/schema/i18n.sql @@ -0,0 +1,18 @@ +# Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) +# +# Licensed under The MIT License +# For full copyright and license information, please see the LICENSE.txt +# Redistributions of files must retain the above copyright notice. +# MIT License (https://opensource.org/licenses/mit-license.php) + +CREATE TABLE i18n ( + id int NOT NULL auto_increment, + locale varchar(6) NOT NULL, + model varchar(255) NOT NULL, + foreign_key int(10) NOT NULL, + field varchar(255) NOT NULL, + content text, + PRIMARY KEY (id), + UNIQUE INDEX I18N_LOCALE_FIELD(locale, model, foreign_key, field), + INDEX I18N_FIELD(model, foreign_key, field) +); diff --git a/tests/Frameworks/CakePHP/Version_3_10/config/schema/sessions.sql b/tests/Frameworks/CakePHP/Version_3_10/config/schema/sessions.sql new file mode 100644 index 0000000000..1aa0a0f54e --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/config/schema/sessions.sql @@ -0,0 +1,15 @@ +# Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) +# +# Licensed under The MIT License +# For full copyright and license information, please see the LICENSE.txt +# Redistributions of files must retain the above copyright notice. +# MIT License (https://opensource.org/licenses/mit-license.php) + +CREATE TABLE `sessions` ( + `id` char(40) CHARACTER SET ascii COLLATE ascii_bin NOT NULL, + `created` datetime DEFAULT CURRENT_TIMESTAMP, -- optional, requires MySQL 5.6.5+ + `modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- optional, requires MySQL 5.6.5+ + `data` blob DEFAULT NULL, -- for PostgreSQL use bytea instead of blob + `expires` int(10) unsigned DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/tests/Frameworks/CakePHP/Version_3_10/index.php b/tests/Frameworks/CakePHP/Version_3_10/index.php new file mode 100644 index 0000000000..4591769163 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/index.php @@ -0,0 +1,16 @@ + + + + + + + + + + + tests/TestCase/ + + + + + + + + + + + + + + + + + src/ + plugins/*/src/ + + src/Console/Installer.php + + + + diff --git a/tests/Frameworks/CakePHP/Version_3_10/plugins/empty b/tests/Frameworks/CakePHP/Version_3_10/plugins/empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Frameworks/CakePHP/Version_3_10/src/Application.php b/tests/Frameworks/CakePHP/Version_3_10/src/Application.php new file mode 100644 index 0000000000..3d0d28e588 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/src/Application.php @@ -0,0 +1,99 @@ +bootstrapCli(); + } + + /* + * Only try to load DebugKit in development mode + * Debug Kit should not be installed on a production system + */ + if (Configure::read('debug')) { + $this->addPlugin('DebugKit'); + } + + // Load more plugins here + } + + /** + * Setup the middleware queue your application will use. + * + * @param \Cake\Http\MiddlewareQueue $middlewareQueue The middleware queue to setup. + * @return \Cake\Http\MiddlewareQueue The updated middleware queue. + */ + public function middleware($middlewareQueue) + { + $middlewareQueue + // Catch any exceptions in the lower layers, + // and make an error page/response + ->add(new ErrorHandlerMiddleware(null, Configure::read('Error'))) + + // Handle plugin/theme assets like CakePHP normally does. + ->add(new AssetMiddleware([ + 'cacheTime' => Configure::read('Asset.cacheTime'), + ])) + + // Add routing middleware. + // If you have a large number of routes connected, turning on routes + // caching in production could improve performance. For that when + // creating the middleware instance specify the cache config name by + // using it's second constructor argument: + // `new RoutingMiddleware($this, '_cake_routes_')` + ->add(new RoutingMiddleware($this)); + + return $middlewareQueue; + } + + /** + * @return void + */ + protected function bootstrapCli() + { + try { + $this->addPlugin('Bake'); + } catch (MissingPluginException $e) { + // Do not halt if the plugin is missing + } + + $this->addPlugin('Migrations'); + + // Load more plugins here + } +} diff --git a/tests/Frameworks/CakePHP/Version_3_10/src/Console/Installer.php b/tests/Frameworks/CakePHP/Version_3_10/src/Console/Installer.php new file mode 100644 index 0000000000..26dc31e987 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/src/Console/Installer.php @@ -0,0 +1,246 @@ +getIO(); + + $rootDir = dirname(dirname(__DIR__)); + + static::createAppLocalConfig($rootDir, $io); + static::createWritableDirectories($rootDir, $io); + + // ask if the permissions should be changed + if ($io->isInteractive()) { + $validator = function ($arg) { + if (in_array($arg, ['Y', 'y', 'N', 'n'])) { + return $arg; + } + throw new Exception('This is not a valid answer. Please choose Y or n.'); + }; + $setFolderPermissions = $io->askAndValidate( + 'Set Folder Permissions ? (Default to Y) [Y,n]? ', + $validator, + 10, + 'Y' + ); + + if (in_array($setFolderPermissions, ['Y', 'y'])) { + static::setFolderPermissions($rootDir, $io); + } + } else { + static::setFolderPermissions($rootDir, $io); + } + + static::setSecuritySalt($rootDir, $io); + + $class = 'Cake\Codeception\Console\Installer'; + if (class_exists($class)) { + $class::customizeCodeceptionBinary($event); + } + } + + /** + * Create config/app_local.php file if it does not exist. + * + * @param string $dir The application's root directory. + * @param \Composer\IO\IOInterface $io IO interface to write to console. + * @return void + */ + public static function createAppLocalConfig($dir, $io) + { + $appLocalConfig = $dir . '/config/app_local.php'; + $appLocalConfigTemplate = $dir . '/config/app_local.example.php'; + if (!file_exists($appLocalConfig)) { + copy($appLocalConfigTemplate, $appLocalConfig); + $io->write('Created `config/app_local.php` file'); + } + } + + /** + * Create the `logs` and `tmp` directories. + * + * @param string $dir The application's root directory. + * @param \Composer\IO\IOInterface $io IO interface to write to console. + * @return void + */ + public static function createWritableDirectories($dir, $io) + { + foreach (static::WRITABLE_DIRS as $path) { + $path = $dir . '/' . $path; + if (!file_exists($path)) { + mkdir($path); + $io->write('Created `' . $path . '` directory'); + } + } + } + + /** + * Set globally writable permissions on the "tmp" and "logs" directory. + * + * This is not the most secure default, but it gets people up and running quickly. + * + * @param string $dir The application's root directory. + * @param \Composer\IO\IOInterface $io IO interface to write to console. + * @return void + */ + public static function setFolderPermissions($dir, $io) + { + // Change the permissions on a path and output the results. + $changePerms = function ($path) use ($io) { + $currentPerms = fileperms($path) & 0777; + $worldWritable = $currentPerms | 0007; + if ($worldWritable == $currentPerms) { + return; + } + + $res = chmod($path, $worldWritable); + if ($res) { + $io->write('Permissions set on ' . $path); + } else { + $io->write('Failed to set permissions on ' . $path); + } + }; + + $walker = function ($dir) use (&$walker, $changePerms) { + $files = array_diff(scandir($dir), ['.', '..']); + foreach ($files as $file) { + $path = $dir . '/' . $file; + + if (!is_dir($path)) { + continue; + } + + $changePerms($path); + $walker($path); + } + }; + + $walker($dir . '/tmp'); + $changePerms($dir . '/tmp'); + $changePerms($dir . '/logs'); + } + + /** + * Set the security.salt value in the application's config file. + * + * @param string $dir The application's root directory. + * @param \Composer\IO\IOInterface $io IO interface to write to console. + * @return void + */ + public static function setSecuritySalt($dir, $io) + { + $newKey = hash('sha256', Security::randomBytes(64)); + static::setSecuritySaltInFile($dir, $io, $newKey, 'app_local.php'); + } + + /** + * Set the security.salt value in a given file + * + * @param string $dir The application's root directory. + * @param \Composer\IO\IOInterface $io IO interface to write to console. + * @param string $newKey key to set in the file + * @param string $file A path to a file relative to the application's root + * @return void + */ + public static function setSecuritySaltInFile($dir, $io, $newKey, $file) + { + $config = $dir . '/config/' . $file; + $content = file_get_contents($config); + + $content = str_replace('__SALT__', $newKey, $content, $count); + + if ($count == 0) { + $io->write('No Security.salt placeholder to replace.'); + + return; + } + + $result = file_put_contents($config, $content); + if ($result) { + $io->write('Updated Security.salt value in config/' . $file); + + return; + } + $io->write('Unable to update Security.salt value.'); + } + + /** + * Set the APP_NAME value in a given file + * + * @param string $dir The application's root directory. + * @param \Composer\IO\IOInterface $io IO interface to write to console. + * @param string $appName app name to set in the file + * @param string $file A path to a file relative to the application's root + * @return void + */ + public static function setAppNameInFile($dir, $io, $appName, $file) + { + $config = $dir . '/config/' . $file; + $content = file_get_contents($config); + $content = str_replace('__APP_NAME__', $appName, $content, $count); + + if ($count == 0) { + $io->write('No __APP_NAME__ placeholder to replace.'); + + return; + } + + $result = file_put_contents($config, $content); + if ($result) { + $io->write('Updated __APP_NAME__ value in config/' . $file); + + return; + } + $io->write('Unable to update __APP_NAME__ value.'); + } +} diff --git a/tests/Frameworks/CakePHP/Version_3_10/src/Controller/AppController.php b/tests/Frameworks/CakePHP/Version_3_10/src/Controller/AppController.php new file mode 100644 index 0000000000..99d0858e97 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/src/Controller/AppController.php @@ -0,0 +1,55 @@ +loadComponent('Security');` + * + * @return void + */ + public function initialize() + { + parent::initialize(); + + $this->loadComponent('RequestHandler', [ + 'enableBeforeRedirect' => false, + ]); + $this->loadComponent('Flash'); + + /* + * Enable the following component for recommended CakePHP security settings. + * see https://book.cakephp.org/3/en/controllers/components/security.html + */ + //$this->loadComponent('Security'); + } +} diff --git a/tests/Frameworks/CakePHP/Version_3_10/src/Controller/Component/empty b/tests/Frameworks/CakePHP/Version_3_10/src/Controller/Component/empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Frameworks/CakePHP/Version_3_10/src/Controller/ErrorController.php b/tests/Frameworks/CakePHP/Version_3_10/src/Controller/ErrorController.php new file mode 100644 index 0000000000..caf67d7234 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/src/Controller/ErrorController.php @@ -0,0 +1,75 @@ +loadComponent('RequestHandler', [ + 'enableBeforeRedirect' => false, + ]); + } + + /** + * beforeFilter callback. + * + * @param \Cake\Event\Event $event Event. + * @return \Cake\Http\Response|null|void + */ + public function beforeFilter(Event $event) + { + } + + /** + * beforeRender callback. + * + * @param \Cake\Event\Event $event Event. + * @return \Cake\Http\Response|null|void + */ + public function beforeRender(Event $event) + { + parent::beforeRender($event); + + $this->viewBuilder()->setTemplatePath('Error'); + } + + /** + * afterFilter callback. + * + * @param \Cake\Event\Event $event Event. + * @return \Cake\Http\Response|null|void + */ + public function afterFilter(Event $event) + { + } + + public function index() + { + throw new \Exception('Foo error'); + } +} diff --git a/tests/Frameworks/CakePHP/Version_3_10/src/Controller/PagesController.php b/tests/Frameworks/CakePHP/Version_3_10/src/Controller/PagesController.php new file mode 100644 index 0000000000..ddc9a509c4 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/src/Controller/PagesController.php @@ -0,0 +1,68 @@ +redirect('/'); + } + if (in_array('..', $path, true) || in_array('.', $path, true)) { + throw new ForbiddenException(); + } + $page = $subpage = null; + + if (!empty($path[0])) { + $page = $path[0]; + } + if (!empty($path[1])) { + $subpage = $path[1]; + } + $this->set(compact('page', 'subpage')); + + try { + $this->render(implode('/', $path)); + } catch (MissingTemplateException $exception) { + if (Configure::read('debug')) { + throw $exception; + } + throw new NotFoundException(); + } + } +} diff --git a/tests/Frameworks/CakePHP/Version_3_10/src/Controller/ParameterizedController.php b/tests/Frameworks/CakePHP/Version_3_10/src/Controller/ParameterizedController.php new file mode 100644 index 0000000000..f41e3ec2f1 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/src/Controller/ParameterizedController.php @@ -0,0 +1,12 @@ +autoRender = false; + echo "Hello $param"; + } +} diff --git a/tests/Frameworks/CakePHP/Version_3_10/src/Controller/SimpleController.php b/tests/Frameworks/CakePHP/Version_3_10/src/Controller/SimpleController.php new file mode 100644 index 0000000000..fbdd428881 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/src/Controller/SimpleController.php @@ -0,0 +1,12 @@ +autoRender = false; + echo 'Hello.'; + } +} diff --git a/tests/Frameworks/CakePHP/Version_3_10/src/Controller/Simple_viewController.php b/tests/Frameworks/CakePHP/Version_3_10/src/Controller/Simple_viewController.php new file mode 100644 index 0000000000..87462eec32 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/src/Controller/Simple_viewController.php @@ -0,0 +1,10 @@ +err('Unable to load Psy\Shell.'); + $this->err(''); + $this->err('Make sure you have installed psysh as a dependency,'); + $this->err('and that Psy\Shell is registered in your autoloader.'); + $this->err(''); + $this->err('If you are using composer run'); + $this->err(''); + $this->err('$ php composer.phar require --dev psy/psysh'); + $this->err(''); + + return self::CODE_ERROR; + } + + $this->out("You can exit with `CTRL-C` or `exit`"); + $this->out(''); + + Log::drop('debug'); + Log::drop('error'); + $this->_io->setLoggers(false); + restore_error_handler(); + restore_exception_handler(); + + $psy = new PsyShell(); + $psy->run(); + } + + /** + * Display help for this console. + * + * @return \Cake\Console\ConsoleOptionParser + */ + public function getOptionParser() + { + $parser = new ConsoleOptionParser('console'); + $parser->setDescription( + 'This shell provides a REPL that you can use to interact with ' . + 'your application in a command line designed to run PHP code. ' . + 'You can use it to run adhoc queries with your models, or ' . + 'explore the features of CakePHP and your application.' . + "\n\n" . + 'You will need to have psysh installed for this Shell to work.' + ); + + return $parser; + } +} diff --git a/tests/Frameworks/CakePHP/Version_3_10/src/Template/Cell/empty b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Cell/empty new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Cell/empty @@ -0,0 +1 @@ + diff --git a/tests/Frameworks/CakePHP/Version_3_10/src/Template/Element/Flash/default.ctp b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Element/Flash/default.ctp new file mode 100644 index 0000000000..061c700920 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Element/Flash/default.ctp @@ -0,0 +1,15 @@ + +
diff --git a/tests/Frameworks/CakePHP/Version_3_10/src/Template/Element/Flash/error.ctp b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Element/Flash/error.ctp new file mode 100644 index 0000000000..2ebf2357c0 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Element/Flash/error.ctp @@ -0,0 +1,11 @@ + +
diff --git a/tests/Frameworks/CakePHP/Version_3_10/src/Template/Element/Flash/success.ctp b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Element/Flash/success.ctp new file mode 100644 index 0000000000..73eaac48d3 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Element/Flash/success.ctp @@ -0,0 +1,11 @@ + +
diff --git a/tests/Frameworks/CakePHP/Version_3_10/src/Template/Email/html/default.ctp b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Email/html/default.ctp new file mode 100644 index 0000000000..ac3daa7feb --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Email/html/default.ctp @@ -0,0 +1,20 @@ + ' . $line . "

\n"; +endforeach; diff --git a/tests/Frameworks/CakePHP/Version_3_10/src/Template/Email/text/default.ctp b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Email/text/default.ctp new file mode 100644 index 0000000000..862cd9f769 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Email/text/default.ctp @@ -0,0 +1,16 @@ +layout = 'error'; + +if (Configure::read('debug')) : + $this->layout = 'dev_error'; + + $this->assign('title', $message); + $this->assign('templateName', 'error400.ctp'); + + $this->start('file'); +?> +queryString)) : ?> +

+ SQL Query: + queryString) ?> +

+ +params)) : ?> + SQL Query Params: + params) ?> + +element('auto_table_warning') ?> +end(); +endif; +?> +

+

+ : + '{$url}'") ?> +

diff --git a/tests/Frameworks/CakePHP/Version_3_10/src/Template/Error/error500.ctp b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Error/error500.ctp new file mode 100644 index 0000000000..3328cc52cb --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Error/error500.ctp @@ -0,0 +1,43 @@ +layout = 'error'; + +if (Configure::read('debug')) : + $this->layout = 'dev_error'; + + $this->assign('title', $message); + $this->assign('templateName', 'error500.ctp'); + + $this->start('file'); +?> +queryString)) : ?> +

+ SQL Query: + queryString) ?> +

+ +params)) : ?> + SQL Query Params: + params) ?> + + + Error in: + getFile()), $error->getLine()) ?> + +element('auto_table_warning'); + + if (extension_loaded('xdebug')) : + xdebug_print_function_stack(); + endif; + + $this->end(); +endif; +?> +

+

+ : + +

diff --git a/tests/Frameworks/CakePHP/Version_3_10/src/Template/Layout/Email/html/default.ctp b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Layout/Email/html/default.ctp new file mode 100644 index 0000000000..3ff87ff835 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Layout/Email/html/default.ctp @@ -0,0 +1,24 @@ + + + + + <?= $this->fetch('title') ?> + + + fetch('content') ?> + + diff --git a/tests/Frameworks/CakePHP/Version_3_10/src/Template/Layout/Email/text/default.ctp b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Layout/Email/text/default.ctp new file mode 100644 index 0000000000..29b439ccc4 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Layout/Email/text/default.ctp @@ -0,0 +1,16 @@ +fetch('content'); diff --git a/tests/Frameworks/CakePHP/Version_3_10/src/Template/Layout/ajax.ctp b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Layout/ajax.ctp new file mode 100644 index 0000000000..cd51169db7 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Layout/ajax.ctp @@ -0,0 +1,17 @@ +fetch('content'); diff --git a/tests/Frameworks/CakePHP/Version_3_10/src/Template/Layout/default.ctp b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Layout/default.ctp new file mode 100644 index 0000000000..77b2828d9f --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Layout/default.ctp @@ -0,0 +1,58 @@ + + + + + Html->charset() ?> + + + <?= $cakeDescription ?>: + <?= $this->fetch('title') ?> + + Html->meta('icon') ?> + + Html->css('base.css') ?> + Html->css('style.css') ?> + + fetch('meta') ?> + fetch('css') ?> + fetch('script') ?> + + + + Flash->render() ?> +
+ fetch('content') ?> +
+
+
+ + diff --git a/tests/Frameworks/CakePHP/Version_3_10/src/Template/Layout/error.ctp b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Layout/error.ctp new file mode 100644 index 0000000000..654f0dbe07 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Layout/error.ctp @@ -0,0 +1,48 @@ + + + + + Html->charset() ?> + + <?= $this->fetch('title') ?> + + Html->meta('icon') ?> + + Html->css('base.css') ?> + Html->css('style.css') ?> + + fetch('meta') ?> + fetch('css') ?> + fetch('script') ?> + + +
+ +
+ Flash->render() ?> + + fetch('content') ?> +
+ +
+ + diff --git a/tests/Frameworks/CakePHP/Version_3_10/src/Template/Layout/rss/default.ctp b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Layout/rss/default.ctp new file mode 100644 index 0000000000..8269be2128 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Layout/rss/default.ctp @@ -0,0 +1,11 @@ +fetch('title'); +endif; + +echo $this->Rss->document( + $this->Rss->channel([], $channel, $this->fetch('content')) +); diff --git a/tests/Frameworks/CakePHP/Version_3_10/src/Template/Pages/home.ctp b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Pages/home.ctp new file mode 100644 index 0000000000..f9aff9e681 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Pages/home.ctp @@ -0,0 +1,276 @@ +layout = false; + +if (!Configure::read('debug')) : + throw new NotFoundException( + 'Please replace src/Template/Pages/home.ctp with your own version or re-enable debug mode.' + ); +endif; + +$cakeDescription = 'CakePHP: the rapid development PHP framework'; +?> + + + + Html->charset() ?> + + + <?= $cakeDescription ?> + + + Html->meta('icon') ?> + Html->css('base.css') ?> + Html->css('style.css') ?> + Html->css('home.css') ?> + + + + +
+
Html->image('cake.logo.svg') ?>
+
+

Welcome to CakePHP Red Velvet. Build fast. Grow solid.

+
+
+ +
+
+
+

Please be aware that this page will not be shown if you turn off debug mode unless you replace src/Template/Pages/home.ctp with your own version.

+
+
+ +
+ +
+
+ +
+
+

Environment

+
    + =')) : ?> +
  • Your version of PHP is 5.6.0 or higher (detected ).
  • + +
  • Your version of PHP is too low. You need PHP 5.6.0 or higher to use CakePHP (detected ).
  • + + + +
  • Your version of PHP has the mbstring extension loaded.
  • + +
  • Your version of PHP does NOT have the mbstring extension loaded.
  • + + + +
  • Your version of PHP has the openssl extension loaded.
  • + +
  • Your version of PHP has the mcrypt extension loaded.
  • + +
  • Your version of PHP does NOT have the openssl or mcrypt extension loaded.
  • + + + +
  • Your version of PHP has the intl extension loaded.
  • + +
  • Your version of PHP does NOT have the intl extension loaded.
  • + +
+
+
+

Filesystem

+
    + +
  • Your tmp directory is writable.
  • + +
  • Your tmp directory is NOT writable.
  • + + + +
  • Your logs directory is writable.
  • + +
  • Your logs directory is NOT writable.
  • + + + + +
  • The Engine is being used for core caching. To change the config edit config/app.php
  • + +
  • Your cache is NOT working. Please check the settings in config/app.php
  • + +
+
+
+
+ +
+
+

Database

+ connect(); + } catch (Exception $connectionError) { + $connected = false; + $errorMsg = $connectionError->getMessage(); + if (method_exists($connectionError, 'getAttributes')) : + $attributes = $connectionError->getAttributes(); + if (isset($errorMsg['message'])) : + $errorMsg .= '
' . $attributes['message']; + endif; + endif; + } + ?> +
    + +
  • CakePHP is able to connect to the database.
  • + +
  • CakePHP is NOT able to connect to the database.
  • + +
+
+
+

DebugKit

+
    + +
  • DebugKit is loaded.
  • + +
  • DebugKit is NOT loaded. You need to either install pdo_sqlite, or define the "debug_kit" connection name.
  • + +
+
+
+
+ +
+
+

Editing this Page

+
    +
  • To change the content of this page, edit: src/Template/Pages/home.ctp.
  • +
  • You can also add some CSS styles for your pages at: webroot/css/.
  • +
+
+
+

Getting Started

+ +
+
+ +
+
+

More about Cake

+

+ CakePHP is a rapid development framework for PHP which uses commonly known design patterns like Front Controller and MVC.
+ Our primary goal is to provide a structured framework that enables PHP users at all levels to rapidly develop robust web applications, without any loss to flexibility. +

+
+
+
+ +
+
+ P +

Help and Bug Reports

+ +
+
+ r +

Docs and Downloads

+ +
+
+ s +

Training and Certification

+ +
+
+ + + diff --git a/tests/Frameworks/CakePHP/Version_3_10/src/Template/Simple_view/index.ctp b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Simple_view/index.ctp new file mode 100644 index 0000000000..60ab36c4a4 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/src/Template/Simple_view/index.ctp @@ -0,0 +1,2 @@ +

Simple HTML view

+

Hello.

diff --git a/tests/Frameworks/CakePHP/Version_3_10/src/View/AjaxView.php b/tests/Frameworks/CakePHP/Version_3_10/src/View/AjaxView.php new file mode 100644 index 0000000000..3cb7869266 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/src/View/AjaxView.php @@ -0,0 +1,49 @@ +response = $this->response->withType('ajax'); + } +} diff --git a/tests/Frameworks/CakePHP/Version_3_10/src/View/AppView.php b/tests/Frameworks/CakePHP/Version_3_10/src/View/AppView.php new file mode 100644 index 0000000000..49ad38cdc6 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/src/View/AppView.php @@ -0,0 +1,40 @@ +loadHelper('Html');` + * + * @return void + */ + public function initialize() + { + } +} diff --git a/tests/Frameworks/CakePHP/Version_3_10/src/View/Cell/empty b/tests/Frameworks/CakePHP/Version_3_10/src/View/Cell/empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Frameworks/CakePHP/Version_3_10/src/View/Helper/empty b/tests/Frameworks/CakePHP/Version_3_10/src/View/Helper/empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Frameworks/CakePHP/Version_3_10/tests/Fixture/empty b/tests/Frameworks/CakePHP/Version_3_10/tests/Fixture/empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Frameworks/CakePHP/Version_3_10/tests/TestCase/ApplicationTest.php b/tests/Frameworks/CakePHP/Version_3_10/tests/TestCase/ApplicationTest.php new file mode 100644 index 0000000000..908b23539f --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/tests/TestCase/ApplicationTest.php @@ -0,0 +1,84 @@ +bootstrap(); + $plugins = $app->getPlugins(); + + $this->assertCount(3, $plugins); + $this->assertSame('Bake', $plugins->get('Bake')->getName()); + $this->assertSame('Migrations', $plugins->get('Migrations')->getName()); + $this->assertSame('DebugKit', $plugins->get('DebugKit')->getName()); + } + + /** + * testBootstrapPluginWitoutHalt + * + * @return void + */ + public function testBootstrapPluginWithoutHalt() + { + $this->expectException(InvalidArgumentException::class); + + $app = $this->getMockBuilder(Application::class) + ->setConstructorArgs([dirname(dirname(__DIR__)) . '/config']) + ->setMethods(['addPlugin']) + ->getMock(); + + $app->method('addPlugin') + ->will($this->throwException(new InvalidArgumentException('test exception.'))); + + $app->bootstrap(); + } + + /** + * testMiddleware + * + * @return void + */ + public function testMiddleware() + { + $app = new Application(dirname(dirname(__DIR__)) . '/config'); + $middleware = new MiddlewareQueue(); + + $middleware = $app->middleware($middleware); + + $this->assertInstanceOf(ErrorHandlerMiddleware::class, $middleware->get(0)); + $this->assertInstanceOf(AssetMiddleware::class, $middleware->get(1)); + $this->assertInstanceOf(RoutingMiddleware::class, $middleware->get(2)); + } +} diff --git a/tests/Frameworks/CakePHP/Version_3_10/tests/TestCase/Controller/Component/empty b/tests/Frameworks/CakePHP/Version_3_10/tests/TestCase/Controller/Component/empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Frameworks/CakePHP/Version_3_10/tests/TestCase/Controller/PagesControllerTest.php b/tests/Frameworks/CakePHP/Version_3_10/tests/TestCase/Controller/PagesControllerTest.php new file mode 100644 index 0000000000..1f611eca4d --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/tests/TestCase/Controller/PagesControllerTest.php @@ -0,0 +1,125 @@ +get('/'); + $this->assertResponseOk(); + $this->get('/'); + $this->assertResponseOk(); + } + + /** + * testDisplay method + * + * @return void + */ + public function testDisplay() + { + $this->get('/pages/home'); + $this->assertResponseOk(); + $this->assertResponseContains('CakePHP'); + $this->assertResponseContains(''); + } + + /** + * Test that missing template renders 404 page in production + * + * @return void + */ + public function testMissingTemplate() + { + Configure::write('debug', false); + $this->get('/pages/not_existing'); + + $this->assertResponseError(); + $this->assertResponseContains('Error'); + } + + /** + * Test that missing template in debug mode renders missing_template error page + * + * @return void + */ + public function testMissingTemplateInDebug() + { + Configure::write('debug', true); + $this->get('/pages/not_existing'); + + $this->assertResponseFailure(); + $this->assertResponseContains('Missing Template'); + $this->assertResponseContains('Stacktrace'); + $this->assertResponseContains('not_existing.ctp'); + } + + /** + * Test directory traversal protection + * + * @return void + */ + public function testDirectoryTraversalProtection() + { + $this->get('/pages/../Layout/ajax'); + $this->assertResponseCode(403); + $this->assertResponseContains('Forbidden'); + } + + /** + * Test that CSRF protection is applied to page rendering. + * + * @reutrn void + */ + public function testCsrfAppliedError() + { + $this->post('/pages/home', ['hello' => 'world']); + + $this->assertResponseCode(403); + $this->assertResponseContains('CSRF'); + } + + /** + * Test that CSRF protection is applied to page rendering. + * + * @reutrn void + */ + public function testCsrfAppliedOk() + { + $this->enableCsrfToken(); + $this->post('/pages/home', ['hello' => 'world']); + + $this->assertResponseCode(200); + $this->assertResponseContains('CakePHP'); + } +} diff --git a/tests/Frameworks/CakePHP/Version_3_10/tests/TestCase/Model/Behavior/empty b/tests/Frameworks/CakePHP/Version_3_10/tests/TestCase/Model/Behavior/empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Frameworks/CakePHP/Version_3_10/tests/TestCase/View/Helper/empty b/tests/Frameworks/CakePHP/Version_3_10/tests/TestCase/View/Helper/empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Frameworks/CakePHP/Version_3_10/tests/bootstrap.php b/tests/Frameworks/CakePHP/Version_3_10/tests/bootstrap.php new file mode 100644 index 0000000000..0ca191e4a0 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/tests/bootstrap.php @@ -0,0 +1,12 @@ + + RewriteEngine On + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^ index.php [L] + diff --git a/tests/Frameworks/CakePHP/Version_3_10/webroot/css/base.css b/tests/Frameworks/CakePHP/Version_3_10/webroot/css/base.css new file mode 100644 index 0000000000..458cd94893 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/webroot/css/base.css @@ -0,0 +1,455 @@ +/*! normalize.css v3.0.2 | MIT License | git.io/normalize */ + +/** + * 1. Set default font family to sans-serif. + * 2. Prevent iOS text size adjust after orientation change, without disabling + * user zoom. + */ + +html { + font-family: sans-serif; /* 1 */ + -ms-text-size-adjust: 100%; /* 2 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/** + * Remove default margin. + */ + +body { + margin: 0; +} + +/* HTML5 display definitions + ========================================================================== */ + +/** + * Correct `block` display not defined for any HTML5 element in IE 8/9. + * Correct `block` display not defined for `details` or `summary` in IE 10/11 + * and Firefox. + * Correct `block` display not defined for `main` in IE 11. + */ + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; +} + +/** + * 1. Correct `inline-block` display not defined in IE 8/9. + * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. + */ + +audio, +canvas, +progress, +video { + display: inline-block; /* 1 */ + vertical-align: baseline; /* 2 */ +} + +/** + * Prevent modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ + +audio:not([controls]) { + display: none; + height: 0; +} + +/** + * Address `[hidden]` styling not present in IE 8/9/10. + * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. + */ + +[hidden], +template { + display: none; +} + +/* Links + ========================================================================== */ + +/** + * Remove the gray background color from active links in IE 10. + */ + +a { + background-color: transparent; +} + +/** + * Improve readability when focused and also mouse hovered in all browsers. + */ + +a:active, +a:hover { + outline: 0; +} + +/* Text-level semantics + ========================================================================== */ + +/** + * Address styling not present in IE 8/9/10/11, Safari, and Chrome. + */ + +abbr[title] { + border-bottom: 1px dotted; +} + +/** + * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. + */ + +b, +strong { + font-weight: bold; +} + +/** + * Address styling not present in Safari and Chrome. + */ + +dfn { + font-style: italic; +} + +/** + * Address variable `h1` font-size and margin within `section` and `article` + * contexts in Firefox 4+, Safari, and Chrome. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/** + * Address styling not present in IE 8/9. + */ + +mark { + background: #ff0; + color: #000; +} + +/** + * Address inconsistent and variable font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` affecting `line-height` in all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +/* Embedded content + ========================================================================== */ + +/** + * Remove border when inside `a` element in IE 8/9/10. + */ + +img { + border: 0; +} + +/** + * Correct overflow not hidden in IE 9/10/11. + */ + +svg:not(:root) { + overflow: hidden; +} + +/* Grouping content + ========================================================================== */ + +/** + * Address margin not present in IE 8/9 and Safari. + */ + +figure { + margin: 1em 40px; +} + +/** + * Address differences between Firefox and other browsers. + */ + +hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; +} + +/** + * Contain overflow in all browsers. + */ + +pre { + overflow: auto; +} + +/** + * Address odd `em`-unit font size rendering in all browsers. + */ + +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} + +/* Forms + ========================================================================== */ + +/** + * Known limitation: by default, Chrome and Safari on OS X allow very limited + * styling of `select`, unless a `border` property is set. + */ + +/** + * 1. Correct color not being inherited. + * Known issue: affects color of disabled elements. + * 2. Correct font properties not being inherited. + * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. + */ + +button, +input, +optgroup, +select, +textarea { + color: inherit; /* 1 */ + font: inherit; /* 2 */ + margin: 0; /* 3 */ +} + +/** + * Address `overflow` set to `hidden` in IE 8/9/10/11. + */ + +button { + overflow: visible; +} + +/** + * Address inconsistent `text-transform` inheritance for `button` and `select`. + * All other form control elements do not inherit `text-transform` values. + * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. + * Correct `select` style inheritance in Firefox. + */ + +button, +select { + text-transform: none; +} + +/** + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Correct inability to style clickable `input` types in iOS. + * 3. Improve usability and consistency of cursor style between image-type + * `input` and others. + */ + +button, +html input[type="button"], /* 1 */ +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; /* 2 */ + cursor: pointer; /* 3 */ +} + +/** + * Re-set default cursor for disabled elements. + */ + +button[disabled], +html input[disabled] { + cursor: default; +} + +/** + * Remove inner padding and border in Firefox 4+. + */ + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/** + * Address Firefox 4+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ + +input { + line-height: normal; +} + +/** + * It's recommended that you don't attempt to style these elements. + * Firefox's implementation doesn't respect box-sizing, padding, or width. + * + * 1. Address box sizing set to `content-box` in IE 8/9/10. + * 2. Remove excess padding in IE 8/9/10. + */ + +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Fix the cursor style for Chrome's increment/decrement buttons. For certain + * `font-size` values of the `input`, it causes the cursor style of the + * decrement button to change from `default` to `text`. + */ + +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Address `appearance` set to `searchfield` in Safari and Chrome. + * 2. Address `box-sizing` set to `border-box` in Safari and Chrome + * (include `-moz` to future-proof). + */ + +input[type="search"] { + -webkit-appearance: textfield; /* 1 */ + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; /* 2 */ + box-sizing: content-box; +} + +/** + * Remove inner padding and search cancel button in Safari and Chrome on OS X. + * Safari (but not Chrome) clips the cancel button when the search input has + * padding (and `textfield` appearance). + */ + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * Define consistent border, margin, and padding. + */ + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +/** + * 1. Correct `color` not being inherited in IE 8/9/10/11. + * 2. Remove padding so people aren't caught out if they zero out fieldsets. + */ + +legend { + border: 0; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Remove default vertical scrollbar in IE 8/9/10/11. + */ + +textarea { + overflow: auto; +} + +/** + * Don't inherit the `font-weight` (applied by a rule above). + * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. + */ + +optgroup { + font-weight: bold; +} + +/* Tables + ========================================================================== */ + +/** + * Remove most spacing between table cells. + */ + +table { + border-collapse: collapse; + border-spacing: 0; +} + +td, +th { + padding: 0; +} + +/** + * Foundation for Sites by ZURB + * Version 5 + */ + +/* + * Copyright (c) 2013-2014 ZURB, inc. +* MIT License +* 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. +*/ + +meta.foundation-version{font-family:"{{ VERSION }}"}meta.foundation-mq-small{font-family:"/only screen/";width:0}meta.foundation-mq-small-only{font-family:"/only screen and (max-width: 40em)/";width:0}meta.foundation-mq-medium{font-family:"/only screen and (min-width:40.0625em)/";width:40.0625em}meta.foundation-mq-medium-only{font-family:"/only screen and (min-width:40.0625em) and (max-width:64em)/";width:40.0625em}meta.foundation-mq-large{font-family:"/only screen and (min-width:64.0625em)/";width:64.0625em}meta.foundation-mq-large-only{font-family:"/only screen and (min-width:64.0625em) and (max-width:90em)/";width:64.0625em}meta.foundation-mq-xlarge{font-family:"/only screen and (min-width:90.0625em)/";width:90.0625em}meta.foundation-mq-xlarge-only{font-family:"/only screen and (min-width:90.0625em) and (max-width:120em)/";width:90.0625em}meta.foundation-mq-xxlarge{font-family:"/only screen and (min-width:120.0625em)/";width:120.0625em}meta.foundation-data-attribute-namespace{font-family:false}html,body{height:100%}html{box-sizing:border-box}*,*:before,*:after{-webkit-box-sizing:inherit;-moz-box-sizing:inherit;box-sizing:inherit}html,body{font-size:100%}body{background:#fff;color:#222;cursor:auto;font-family:"Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;font-style:normal;font-weight:normal;line-height:1.5;margin:0;padding:0;position:relative}a:hover{cursor:pointer}img{max-width:100%;height:auto}img{-ms-interpolation-mode:bicubic}#map_canvas img,#map_canvas embed,#map_canvas object,.map_canvas img,.map_canvas embed,.map_canvas object,.mqa-display img,.mqa-display embed,.mqa-display object{max-width:none !important}.left{float:left !important}.right{float:right !important}.clearfix:before,.clearfix:after{content:" ";display:table}.clearfix:after{clear:both}.hide{display:none}.invisible{visibility:hidden}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}img{display:inline-block;vertical-align:middle}textarea{height:auto;min-height:50px}select{width:100%}.row{margin:0 auto;max-width:62.5rem;width:100%}.row:before,.row:after{content:" ";display:table}.row:after{clear:both}.row.collapse>.column,.row.collapse>.columns{padding-left:0;padding-right:0}.row.collapse .row{margin-left:0;margin-right:0}.row .row{margin:0 -0.9375rem;max-width:none;width:auto}.row .row:before,.row .row:after{content:" ";display:table}.row .row:after{clear:both}.row .row.collapse{margin:0;max-width:none;width:auto}.row .row.collapse:before,.row .row.collapse:after{content:" ";display:table}.row .row.collapse:after{clear:both}.column,.columns{padding-left:0.9375rem;padding-right:0.9375rem;width:100%;float:left}.column+.column:last-child,.columns+.column:last-child,.column+.columns:last-child,.columns+.columns:last-child{float:right}.column+.column.end,.columns+.column.end,.column+.columns.end,.columns+.columns.end{float:left}@media only screen{.small-push-0{position:relative;left:0;right:auto}.small-pull-0{position:relative;right:0;left:auto}.small-push-1{position:relative;left:8.33333%;right:auto}.small-pull-1{position:relative;right:8.33333%;left:auto}.small-push-2{position:relative;left:16.66667%;right:auto}.small-pull-2{position:relative;right:16.66667%;left:auto}.small-push-3{position:relative;left:25%;right:auto}.small-pull-3{position:relative;right:25%;left:auto}.small-push-4{position:relative;left:33.33333%;right:auto}.small-pull-4{position:relative;right:33.33333%;left:auto}.small-push-5{position:relative;left:41.66667%;right:auto}.small-pull-5{position:relative;right:41.66667%;left:auto}.small-push-6{position:relative;left:50%;right:auto}.small-pull-6{position:relative;right:50%;left:auto}.small-push-7{position:relative;left:58.33333%;right:auto}.small-pull-7{position:relative;right:58.33333%;left:auto}.small-push-8{position:relative;left:66.66667%;right:auto}.small-pull-8{position:relative;right:66.66667%;left:auto}.small-push-9{position:relative;left:75%;right:auto}.small-pull-9{position:relative;right:75%;left:auto}.small-push-10{position:relative;left:83.33333%;right:auto}.small-pull-10{position:relative;right:83.33333%;left:auto}.small-push-11{position:relative;left:91.66667%;right:auto}.small-pull-11{position:relative;right:91.66667%;left:auto}.column,.columns{position:relative;padding-left:0.9375rem;padding-right:0.9375rem;float:left}.small-1{width:8.33333%}.small-2{width:16.66667%}.small-3{width:25%}.small-4{width:33.33333%}.small-5{width:41.66667%}.small-6{width:50%}.small-7{width:58.33333%}.small-8{width:66.66667%}.small-9{width:75%}.small-10{width:83.33333%}.small-11{width:91.66667%}.small-12{width:100%}.small-offset-0{margin-left:0 !important}.small-offset-1{margin-left:8.33333% !important}.small-offset-2{margin-left:16.66667% !important}.small-offset-3{margin-left:25% !important}.small-offset-4{margin-left:33.33333% !important}.small-offset-5{margin-left:41.66667% !important}.small-offset-6{margin-left:50% !important}.small-offset-7{margin-left:58.33333% !important}.small-offset-8{margin-left:66.66667% !important}.small-offset-9{margin-left:75% !important}.small-offset-10{margin-left:83.33333% !important}.small-offset-11{margin-left:91.66667% !important}.small-reset-order{float:left;left:auto;margin-left:0;margin-right:0;right:auto}.column.small-centered,.columns.small-centered{margin-left:auto;margin-right:auto;float:none}.column.small-uncentered,.columns.small-uncentered{float:left;margin-left:0;margin-right:0}.column.small-centered:last-child,.columns.small-centered:last-child{float:none}.column.small-uncentered:last-child,.columns.small-uncentered:last-child{float:left}.column.small-uncentered.opposite,.columns.small-uncentered.opposite{float:right}.row.small-collapse>.column,.row.small-collapse>.columns{padding-left:0;padding-right:0}.row.small-collapse .row{margin-left:0;margin-right:0}.row.small-uncollapse>.column,.row.small-uncollapse>.columns{padding-left:0.9375rem;padding-right:0.9375rem;float:left}}@media only screen and (min-width: 40.0625em){.medium-push-0{position:relative;left:0;right:auto}.medium-pull-0{position:relative;right:0;left:auto}.medium-push-1{position:relative;left:8.33333%;right:auto}.medium-pull-1{position:relative;right:8.33333%;left:auto}.medium-push-2{position:relative;left:16.66667%;right:auto}.medium-pull-2{position:relative;right:16.66667%;left:auto}.medium-push-3{position:relative;left:25%;right:auto}.medium-pull-3{position:relative;right:25%;left:auto}.medium-push-4{position:relative;left:33.33333%;right:auto}.medium-pull-4{position:relative;right:33.33333%;left:auto}.medium-push-5{position:relative;left:41.66667%;right:auto}.medium-pull-5{position:relative;right:41.66667%;left:auto}.medium-push-6{position:relative;left:50%;right:auto}.medium-pull-6{position:relative;right:50%;left:auto}.medium-push-7{position:relative;left:58.33333%;right:auto}.medium-pull-7{position:relative;right:58.33333%;left:auto}.medium-push-8{position:relative;left:66.66667%;right:auto}.medium-pull-8{position:relative;right:66.66667%;left:auto}.medium-push-9{position:relative;left:75%;right:auto}.medium-pull-9{position:relative;right:75%;left:auto}.medium-push-10{position:relative;left:83.33333%;right:auto}.medium-pull-10{position:relative;right:83.33333%;left:auto}.medium-push-11{position:relative;left:91.66667%;right:auto}.medium-pull-11{position:relative;right:91.66667%;left:auto}.column,.columns{position:relative;padding-left:0.9375rem;padding-right:0.9375rem;float:left}.medium-1{width:8.33333%}.medium-2{width:16.66667%}.medium-3{width:25%}.medium-4{width:33.33333%}.medium-5{width:41.66667%}.medium-6{width:50%}.medium-7{width:58.33333%}.medium-8{width:66.66667%}.medium-9{width:75%}.medium-10{width:83.33333%}.medium-11{width:91.66667%}.medium-12{width:100%}.medium-offset-0{margin-left:0 !important}.medium-offset-1{margin-left:8.33333% !important}.medium-offset-2{margin-left:16.66667% !important}.medium-offset-3{margin-left:25% !important}.medium-offset-4{margin-left:33.33333% !important}.medium-offset-5{margin-left:41.66667% !important}.medium-offset-6{margin-left:50% !important}.medium-offset-7{margin-left:58.33333% !important}.medium-offset-8{margin-left:66.66667% !important}.medium-offset-9{margin-left:75% !important}.medium-offset-10{margin-left:83.33333% !important}.medium-offset-11{margin-left:91.66667% !important}.medium-reset-order{float:left;left:auto;margin-left:0;margin-right:0;right:auto}.column.medium-centered,.columns.medium-centered{margin-left:auto;margin-right:auto;float:none}.column.medium-uncentered,.columns.medium-uncentered{float:left;margin-left:0;margin-right:0}.column.medium-centered:last-child,.columns.medium-centered:last-child{float:none}.column.medium-uncentered:last-child,.columns.medium-uncentered:last-child{float:left}.column.medium-uncentered.opposite,.columns.medium-uncentered.opposite{float:right}.row.medium-collapse>.column,.row.medium-collapse>.columns{padding-left:0;padding-right:0}.row.medium-collapse .row{margin-left:0;margin-right:0}.row.medium-uncollapse>.column,.row.medium-uncollapse>.columns{padding-left:0.9375rem;padding-right:0.9375rem;float:left}.push-0{position:relative;left:0;right:auto}.pull-0{position:relative;right:0;left:auto}.push-1{position:relative;left:8.33333%;right:auto}.pull-1{position:relative;right:8.33333%;left:auto}.push-2{position:relative;left:16.66667%;right:auto}.pull-2{position:relative;right:16.66667%;left:auto}.push-3{position:relative;left:25%;right:auto}.pull-3{position:relative;right:25%;left:auto}.push-4{position:relative;left:33.33333%;right:auto}.pull-4{position:relative;right:33.33333%;left:auto}.push-5{position:relative;left:41.66667%;right:auto}.pull-5{position:relative;right:41.66667%;left:auto}.push-6{position:relative;left:50%;right:auto}.pull-6{position:relative;right:50%;left:auto}.push-7{position:relative;left:58.33333%;right:auto}.pull-7{position:relative;right:58.33333%;left:auto}.push-8{position:relative;left:66.66667%;right:auto}.pull-8{position:relative;right:66.66667%;left:auto}.push-9{position:relative;left:75%;right:auto}.pull-9{position:relative;right:75%;left:auto}.push-10{position:relative;left:83.33333%;right:auto}.pull-10{position:relative;right:83.33333%;left:auto}.push-11{position:relative;left:91.66667%;right:auto}.pull-11{position:relative;right:91.66667%;left:auto}}@media only screen and (min-width: 64.0625em){.large-push-0{position:relative;left:0;right:auto}.large-pull-0{position:relative;right:0;left:auto}.large-push-1{position:relative;left:8.33333%;right:auto}.large-pull-1{position:relative;right:8.33333%;left:auto}.large-push-2{position:relative;left:16.66667%;right:auto}.large-pull-2{position:relative;right:16.66667%;left:auto}.large-push-3{position:relative;left:25%;right:auto}.large-pull-3{position:relative;right:25%;left:auto}.large-push-4{position:relative;left:33.33333%;right:auto}.large-pull-4{position:relative;right:33.33333%;left:auto}.large-push-5{position:relative;left:41.66667%;right:auto}.large-pull-5{position:relative;right:41.66667%;left:auto}.large-push-6{position:relative;left:50%;right:auto}.large-pull-6{position:relative;right:50%;left:auto}.large-push-7{position:relative;left:58.33333%;right:auto}.large-pull-7{position:relative;right:58.33333%;left:auto}.large-push-8{position:relative;left:66.66667%;right:auto}.large-pull-8{position:relative;right:66.66667%;left:auto}.large-push-9{position:relative;left:75%;right:auto}.large-pull-9{position:relative;right:75%;left:auto}.large-push-10{position:relative;left:83.33333%;right:auto}.large-pull-10{position:relative;right:83.33333%;left:auto}.large-push-11{position:relative;left:91.66667%;right:auto}.large-pull-11{position:relative;right:91.66667%;left:auto}.column,.columns{position:relative;padding-left:0.9375rem;padding-right:0.9375rem;float:left}.large-1{width:8.33333%}.large-2{width:16.66667%}.large-3{width:25%}.large-4{width:33.33333%}.large-5{width:41.66667%}.large-6{width:50%}.large-7{width:58.33333%}.large-8{width:66.66667%}.large-9{width:75%}.large-10{width:83.33333%}.large-11{width:91.66667%}.large-12{width:100%}.large-offset-0{margin-left:0 !important}.large-offset-1{margin-left:8.33333% !important}.large-offset-2{margin-left:16.66667% !important}.large-offset-3{margin-left:25% !important}.large-offset-4{margin-left:33.33333% !important}.large-offset-5{margin-left:41.66667% !important}.large-offset-6{margin-left:50% !important}.large-offset-7{margin-left:58.33333% !important}.large-offset-8{margin-left:66.66667% !important}.large-offset-9{margin-left:75% !important}.large-offset-10{margin-left:83.33333% !important}.large-offset-11{margin-left:91.66667% !important}.large-reset-order{float:left;left:auto;margin-left:0;margin-right:0;right:auto}.column.large-centered,.columns.large-centered{margin-left:auto;margin-right:auto;float:none}.column.large-uncentered,.columns.large-uncentered{float:left;margin-left:0;margin-right:0}.column.large-centered:last-child,.columns.large-centered:last-child{float:none}.column.large-uncentered:last-child,.columns.large-uncentered:last-child{float:left}.column.large-uncentered.opposite,.columns.large-uncentered.opposite{float:right}.row.large-collapse>.column,.row.large-collapse>.columns{padding-left:0;padding-right:0}.row.large-collapse .row{margin-left:0;margin-right:0}.row.large-uncollapse>.column,.row.large-uncollapse>.columns{padding-left:0.9375rem;padding-right:0.9375rem;float:left}.push-0{position:relative;left:0;right:auto}.pull-0{position:relative;right:0;left:auto}.push-1{position:relative;left:8.33333%;right:auto}.pull-1{position:relative;right:8.33333%;left:auto}.push-2{position:relative;left:16.66667%;right:auto}.pull-2{position:relative;right:16.66667%;left:auto}.push-3{position:relative;left:25%;right:auto}.pull-3{position:relative;right:25%;left:auto}.push-4{position:relative;left:33.33333%;right:auto}.pull-4{position:relative;right:33.33333%;left:auto}.push-5{position:relative;left:41.66667%;right:auto}.pull-5{position:relative;right:41.66667%;left:auto}.push-6{position:relative;left:50%;right:auto}.pull-6{position:relative;right:50%;left:auto}.push-7{position:relative;left:58.33333%;right:auto}.pull-7{position:relative;right:58.33333%;left:auto}.push-8{position:relative;left:66.66667%;right:auto}.pull-8{position:relative;right:66.66667%;left:auto}.push-9{position:relative;left:75%;right:auto}.pull-9{position:relative;right:75%;left:auto}.push-10{position:relative;left:83.33333%;right:auto}.pull-10{position:relative;right:83.33333%;left:auto}.push-11{position:relative;left:91.66667%;right:auto}.pull-11{position:relative;right:91.66667%;left:auto}}button,.button{-webkit-appearance:none;-moz-appearance:none;border-radius:0;border-style:solid;border-width:0;cursor:pointer;font-family:"Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;font-weight:normal;line-height:normal;margin:0 0 1.25rem;position:relative;text-align:center;text-decoration:none;display:inline-block;padding:1rem 2rem 1.0625rem 2rem;font-size:1rem;background-color:#008CBA;border-color:#007095;color:#fff;transition:background-color 300ms ease-out}button:hover,button:focus,.button:hover,.button:focus{background-color:#007095}button:hover,button:focus,.button:hover,.button:focus{color:#fff}button.secondary,.button.secondary{background-color:#e7e7e7;border-color:#b9b9b9;color:#333}button.secondary:hover,button.secondary:focus,.button.secondary:hover,.button.secondary:focus{background-color:#b9b9b9}button.secondary:hover,button.secondary:focus,.button.secondary:hover,.button.secondary:focus{color:#333}button.success,.button.success{background-color:#43AC6A;border-color:#368a55;color:#fff}button.success:hover,button.success:focus,.button.success:hover,.button.success:focus{background-color:#368a55}button.success:hover,button.success:focus,.button.success:hover,.button.success:focus{color:#fff}button.alert,.button.alert{background-color:#f04124;border-color:#cf2a0e;color:#fff}button.alert:hover,button.alert:focus,.button.alert:hover,.button.alert:focus{background-color:#cf2a0e}button.alert:hover,button.alert:focus,.button.alert:hover,.button.alert:focus{color:#fff}button.warning,.button.warning{background-color:#f08a24;border-color:#cf6e0e;color:#fff}button.warning:hover,button.warning:focus,.button.warning:hover,.button.warning:focus{background-color:#cf6e0e}button.warning:hover,button.warning:focus,.button.warning:hover,.button.warning:focus{color:#fff}button.info,.button.info{background-color:#a0d3e8;border-color:#61b6d9;color:#333}button.info:hover,button.info:focus,.button.info:hover,.button.info:focus{background-color:#61b6d9}button.info:hover,button.info:focus,.button.info:hover,.button.info:focus{color:#fff}button.large,.button.large{padding:1.125rem 2.25rem 1.1875rem 2.25rem;font-size:1.25rem}button.small,.button.small{padding:0.875rem 1.75rem 0.9375rem 1.75rem;font-size:0.8125rem}button.tiny,.button.tiny{padding:0.625rem 1.25rem 0.6875rem 1.25rem;font-size:0.6875rem}button.expand,.button.expand{padding-left:0;padding-right:0;width:100%}button.left-align,.button.left-align{text-align:left;text-indent:0.75rem}button.right-align,.button.right-align{text-align:right;padding-right:0.75rem}button.radius,.button.radius{border-radius:3px}button.round,.button.round{border-radius:1000px}button.disabled,button[disabled],.button.disabled,.button[disabled]{background-color:#008CBA;border-color:#007095;color:#fff;box-shadow:none;cursor:default;opacity:0.7}button.disabled:hover,button.disabled:focus,button[disabled]:hover,button[disabled]:focus,.button.disabled:hover,.button.disabled:focus,.button[disabled]:hover,.button[disabled]:focus{background-color:#007095}button.disabled:hover,button.disabled:focus,button[disabled]:hover,button[disabled]:focus,.button.disabled:hover,.button.disabled:focus,.button[disabled]:hover,.button[disabled]:focus{color:#fff}button.disabled:hover,button.disabled:focus,button[disabled]:hover,button[disabled]:focus,.button.disabled:hover,.button.disabled:focus,.button[disabled]:hover,.button[disabled]:focus{background-color:#008CBA}button.disabled.secondary,button[disabled].secondary,.button.disabled.secondary,.button[disabled].secondary{background-color:#e7e7e7;border-color:#b9b9b9;color:#333;box-shadow:none;cursor:default;opacity:0.7}button.disabled.secondary:hover,button.disabled.secondary:focus,button[disabled].secondary:hover,button[disabled].secondary:focus,.button.disabled.secondary:hover,.button.disabled.secondary:focus,.button[disabled].secondary:hover,.button[disabled].secondary:focus{background-color:#b9b9b9}button.disabled.secondary:hover,button.disabled.secondary:focus,button[disabled].secondary:hover,button[disabled].secondary:focus,.button.disabled.secondary:hover,.button.disabled.secondary:focus,.button[disabled].secondary:hover,.button[disabled].secondary:focus{color:#333}button.disabled.secondary:hover,button.disabled.secondary:focus,button[disabled].secondary:hover,button[disabled].secondary:focus,.button.disabled.secondary:hover,.button.disabled.secondary:focus,.button[disabled].secondary:hover,.button[disabled].secondary:focus{background-color:#e7e7e7}button.disabled.success,button[disabled].success,.button.disabled.success,.button[disabled].success{background-color:#43AC6A;border-color:#368a55;color:#fff;box-shadow:none;cursor:default;opacity:0.7}button.disabled.success:hover,button.disabled.success:focus,button[disabled].success:hover,button[disabled].success:focus,.button.disabled.success:hover,.button.disabled.success:focus,.button[disabled].success:hover,.button[disabled].success:focus{background-color:#368a55}button.disabled.success:hover,button.disabled.success:focus,button[disabled].success:hover,button[disabled].success:focus,.button.disabled.success:hover,.button.disabled.success:focus,.button[disabled].success:hover,.button[disabled].success:focus{color:#fff}button.disabled.success:hover,button.disabled.success:focus,button[disabled].success:hover,button[disabled].success:focus,.button.disabled.success:hover,.button.disabled.success:focus,.button[disabled].success:hover,.button[disabled].success:focus{background-color:#43AC6A}button.disabled.alert,button[disabled].alert,.button.disabled.alert,.button[disabled].alert{background-color:#f04124;border-color:#cf2a0e;color:#fff;box-shadow:none;cursor:default;opacity:0.7}button.disabled.alert:hover,button.disabled.alert:focus,button[disabled].alert:hover,button[disabled].alert:focus,.button.disabled.alert:hover,.button.disabled.alert:focus,.button[disabled].alert:hover,.button[disabled].alert:focus{background-color:#cf2a0e}button.disabled.alert:hover,button.disabled.alert:focus,button[disabled].alert:hover,button[disabled].alert:focus,.button.disabled.alert:hover,.button.disabled.alert:focus,.button[disabled].alert:hover,.button[disabled].alert:focus{color:#fff}button.disabled.alert:hover,button.disabled.alert:focus,button[disabled].alert:hover,button[disabled].alert:focus,.button.disabled.alert:hover,.button.disabled.alert:focus,.button[disabled].alert:hover,.button[disabled].alert:focus{background-color:#f04124}button.disabled.warning,button[disabled].warning,.button.disabled.warning,.button[disabled].warning{background-color:#f08a24;border-color:#cf6e0e;color:#fff;box-shadow:none;cursor:default;opacity:0.7}button.disabled.warning:hover,button.disabled.warning:focus,button[disabled].warning:hover,button[disabled].warning:focus,.button.disabled.warning:hover,.button.disabled.warning:focus,.button[disabled].warning:hover,.button[disabled].warning:focus{background-color:#cf6e0e}button.disabled.warning:hover,button.disabled.warning:focus,button[disabled].warning:hover,button[disabled].warning:focus,.button.disabled.warning:hover,.button.disabled.warning:focus,.button[disabled].warning:hover,.button[disabled].warning:focus{color:#fff}button.disabled.warning:hover,button.disabled.warning:focus,button[disabled].warning:hover,button[disabled].warning:focus,.button.disabled.warning:hover,.button.disabled.warning:focus,.button[disabled].warning:hover,.button[disabled].warning:focus{background-color:#f08a24}button.disabled.info,button[disabled].info,.button.disabled.info,.button[disabled].info{background-color:#a0d3e8;border-color:#61b6d9;color:#333;box-shadow:none;cursor:default;opacity:0.7}button.disabled.info:hover,button.disabled.info:focus,button[disabled].info:hover,button[disabled].info:focus,.button.disabled.info:hover,.button.disabled.info:focus,.button[disabled].info:hover,.button[disabled].info:focus{background-color:#61b6d9}button.disabled.info:hover,button.disabled.info:focus,button[disabled].info:hover,button[disabled].info:focus,.button.disabled.info:hover,.button.disabled.info:focus,.button[disabled].info:hover,.button[disabled].info:focus{color:#fff}button.disabled.info:hover,button.disabled.info:focus,button[disabled].info:hover,button[disabled].info:focus,.button.disabled.info:hover,.button.disabled.info:focus,.button[disabled].info:hover,.button[disabled].info:focus{background-color:#a0d3e8}button::-moz-focus-inner{border:0;padding:0}@media only screen and (min-width: 40.0625em){button,.button{display:inline-block}}form{margin:0 0 1rem}form .row .row{margin:0 -0.5rem}form .row .row .column,form .row .row .columns{padding:0 0.5rem}form .row .row.collapse{margin:0}form .row .row.collapse .column,form .row .row.collapse .columns{padding:0}form .row .row.collapse input{-webkit-border-bottom-right-radius:0;-webkit-border-top-right-radius:0;border-bottom-right-radius:0;border-top-right-radius:0}form .row input.column,form .row input.columns,form .row textarea.column,form .row textarea.columns{padding-left:0.5rem}label{color:#4d4d4d;cursor:pointer;display:block;font-size:0.875rem;font-weight:normal;line-height:1.5;margin-bottom:0}label.right{float:none !important;text-align:right}label.inline{margin:0 0 1rem 0;padding:0.5625rem 0}label small{text-transform:capitalize;color:#676767}.prefix,.postfix{border-style:solid;border-width:1px;display:block;font-size:0.875rem;height:2.3125rem;line-height:2.3125rem;overflow:visible;padding-bottom:0;padding-top:0;position:relative;text-align:center;width:100%;z-index:2}.postfix.button{border-color:true}.prefix.button{border:none;padding-left:0;padding-right:0;padding-bottom:0;padding-top:0;text-align:center}.prefix.button.radius{border-radius:0;-webkit-border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-bottom-left-radius:3px;border-top-left-radius:3px}.postfix.button.radius{border-radius:0;-webkit-border-bottom-right-radius:3px;-webkit-border-top-right-radius:3px;border-bottom-right-radius:3px;border-top-right-radius:3px}.prefix.button.round{border-radius:0;-webkit-border-bottom-left-radius:1000px;-webkit-border-top-left-radius:1000px;border-bottom-left-radius:1000px;border-top-left-radius:1000px}.postfix.button.round{border-radius:0;-webkit-border-bottom-right-radius:1000px;-webkit-border-top-right-radius:1000px;border-bottom-right-radius:1000px;border-top-right-radius:1000px}span.prefix,label.prefix{background:#f2f2f2;border-right:none;color:#333;border-color:#ccc}span.postfix,label.postfix{background:#f2f2f2;color:#333;border-color:#ccc}input[type="text"],input[type="password"],input[type="date"],input[type="datetime"],input[type="datetime-local"],input[type="month"],input[type="week"],input[type="email"],input[type="number"],input[type="search"],input[type="tel"],input[type="time"],input[type="url"],input[type="color"],textarea{-webkit-appearance:none;-moz-appearance:none;border-radius:0;background-color:#fff;border-style:solid;border-width:1px;border-color:#ccc;box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);color:rgba(0,0,0,0.75);display:block;font-family:inherit;font-size:0.875rem;height:2.3125rem;margin:0 0 1rem 0;padding:0.5rem;width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:border-color 0.15s linear,background 0.15s linear;-moz-transition:border-color 0.15s linear,background 0.15s linear;-ms-transition:border-color 0.15s linear,background 0.15s linear;-o-transition:border-color 0.15s linear,background 0.15s linear;transition:border-color 0.15s linear,background 0.15s linear}input[type="text"]:focus,input[type="password"]:focus,input[type="date"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="month"]:focus,input[type="week"]:focus,input[type="email"]:focus,input[type="number"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="time"]:focus,input[type="url"]:focus,input[type="color"]:focus,textarea:focus{background:#fafafa;border-color:#999;outline:none}input[type="text"]:disabled,input[type="password"]:disabled,input[type="date"]:disabled,input[type="datetime"]:disabled,input[type="datetime-local"]:disabled,input[type="month"]:disabled,input[type="week"]:disabled,input[type="email"]:disabled,input[type="number"]:disabled,input[type="search"]:disabled,input[type="tel"]:disabled,input[type="time"]:disabled,input[type="url"]:disabled,input[type="color"]:disabled,textarea:disabled{background-color:#ddd;cursor:default}input[type="text"][disabled],input[type="text"][readonly],fieldset[disabled] input[type="text"],input[type="password"][disabled],input[type="password"][readonly],fieldset[disabled] input[type="password"],input[type="date"][disabled],input[type="date"][readonly],fieldset[disabled] input[type="date"],input[type="datetime"][disabled],input[type="datetime"][readonly],fieldset[disabled] input[type="datetime"],input[type="datetime-local"][disabled],input[type="datetime-local"][readonly],fieldset[disabled] input[type="datetime-local"],input[type="month"][disabled],input[type="month"][readonly],fieldset[disabled] input[type="month"],input[type="week"][disabled],input[type="week"][readonly],fieldset[disabled] input[type="week"],input[type="email"][disabled],input[type="email"][readonly],fieldset[disabled] input[type="email"],input[type="number"][disabled],input[type="number"][readonly],fieldset[disabled] input[type="number"],input[type="search"][disabled],input[type="search"][readonly],fieldset[disabled] input[type="search"],input[type="tel"][disabled],input[type="tel"][readonly],fieldset[disabled] input[type="tel"],input[type="time"][disabled],input[type="time"][readonly],fieldset[disabled] input[type="time"],input[type="url"][disabled],input[type="url"][readonly],fieldset[disabled] input[type="url"],input[type="color"][disabled],input[type="color"][readonly],fieldset[disabled] input[type="color"],textarea[disabled],textarea[readonly],fieldset[disabled] textarea{background-color:#ddd;cursor:default}input[type="text"].radius,input[type="password"].radius,input[type="date"].radius,input[type="datetime"].radius,input[type="datetime-local"].radius,input[type="month"].radius,input[type="week"].radius,input[type="email"].radius,input[type="number"].radius,input[type="search"].radius,input[type="tel"].radius,input[type="time"].radius,input[type="url"].radius,input[type="color"].radius,textarea.radius{border-radius:3px}form .row .prefix-radius.row.collapse input,form .row .prefix-radius.row.collapse textarea,form .row .prefix-radius.row.collapse select,form .row .prefix-radius.row.collapse button{border-radius:0;-webkit-border-bottom-right-radius:3px;-webkit-border-top-right-radius:3px;border-bottom-right-radius:3px;border-top-right-radius:3px}form .row .prefix-radius.row.collapse .prefix{border-radius:0;-webkit-border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-bottom-left-radius:3px;border-top-left-radius:3px}form .row .postfix-radius.row.collapse input,form .row .postfix-radius.row.collapse textarea,form .row .postfix-radius.row.collapse select,form .row .postfix-radius.row.collapse button{border-radius:0;-webkit-border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-bottom-left-radius:3px;border-top-left-radius:3px}form .row .postfix-radius.row.collapse .postfix{border-radius:0;-webkit-border-bottom-right-radius:3px;-webkit-border-top-right-radius:3px;border-bottom-right-radius:3px;border-top-right-radius:3px}form .row .prefix-round.row.collapse input,form .row .prefix-round.row.collapse textarea,form .row .prefix-round.row.collapse select,form .row .prefix-round.row.collapse button{border-radius:0;-webkit-border-bottom-right-radius:1000px;-webkit-border-top-right-radius:1000px;border-bottom-right-radius:1000px;border-top-right-radius:1000px}form .row .prefix-round.row.collapse .prefix{border-radius:0;-webkit-border-bottom-left-radius:1000px;-webkit-border-top-left-radius:1000px;border-bottom-left-radius:1000px;border-top-left-radius:1000px}form .row .postfix-round.row.collapse input,form .row .postfix-round.row.collapse textarea,form .row .postfix-round.row.collapse select,form .row .postfix-round.row.collapse button{border-radius:0;-webkit-border-bottom-left-radius:1000px;-webkit-border-top-left-radius:1000px;border-bottom-left-radius:1000px;border-top-left-radius:1000px}form .row .postfix-round.row.collapse .postfix{border-radius:0;-webkit-border-bottom-right-radius:1000px;-webkit-border-top-right-radius:1000px;border-bottom-right-radius:1000px;border-top-right-radius:1000px}input[type="submit"]{-webkit-appearance:none;-moz-appearance:none;border-radius:0}textarea[rows]{height:auto}textarea{max-width:100%}::-webkit-input-placeholder{color:#ccc}:-moz-placeholder{color:#ccc}::-moz-placeholder{color:#ccc}:-ms-input-placeholder{color:#ccc}select{-webkit-appearance:none !important;-moz-appearance:none !important;background-color:#FAFAFA;border-radius:0;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgeD0iMTJweCIgeT0iMHB4IiB3aWR0aD0iMjRweCIgaGVpZ2h0PSIzcHgiIHZpZXdCb3g9IjAgMCA2IDMiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDYgMyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBvbHlnb24gcG9pbnRzPSI1Ljk5MiwwIDIuOTkyLDMgLTAuMDA4LDAgIi8+PC9zdmc+);background-position:100% center;background-repeat:no-repeat;border-style:solid;border-width:1px;border-color:#ccc;color:rgba(0,0,0,0.75);font-family:inherit;font-size:0.875rem;line-height:normal;padding:0.5rem;border-radius:0;height:2.3125rem}select::-ms-expand{display:none}select.radius{border-radius:3px}select:hover{background-color:#f3f3f3;border-color:#999}select:disabled{background-color:#ddd;cursor:default}select[multiple]{height:auto}input[type="file"],input[type="checkbox"],input[type="radio"],select{margin:0 0 1rem 0}input[type="checkbox"]+label,input[type="radio"]+label{display:inline-block;margin-left:0.5rem;margin-right:1rem;margin-bottom:0;vertical-align:baseline}input[type="file"]{width:100%}fieldset{border:1px solid #ddd;margin:1.125rem 0;padding:1.25rem}fieldset legend{background:#fff;font-weight:bold;margin-left:-0.1875rem;margin:0;padding:0 0.1875rem}[data-abide] .error small.error,[data-abide] .error span.error,[data-abide] span.error,[data-abide] small.error{display:block;font-size:0.75rem;font-style:italic;font-weight:normal;margin-bottom:1rem;margin-top:-1px;padding:0.375rem 0.5625rem 0.5625rem;background:#f04124;color:#fff}[data-abide] span.error,[data-abide] small.error{display:none}span.error,small.error{display:block;font-size:0.75rem;font-style:italic;font-weight:normal;margin-bottom:1rem;margin-top:-1px;padding:0.375rem 0.5625rem 0.5625rem;background:#f04124;color:#fff}.error input,.error textarea,.error select{margin-bottom:0}.error input[type="checkbox"],.error input[type="radio"]{margin-bottom:1rem}.error label,.error label.error{color:#f04124}.error small.error{display:block;font-size:0.75rem;font-style:italic;font-weight:normal;margin-bottom:1rem;margin-top:-1px;padding:0.375rem 0.5625rem 0.5625rem;background:#f04124;color:#fff}.error>label>small{background:transparent;color:#676767;display:inline;font-size:60%;font-style:normal;margin:0;padding:0;text-transform:capitalize}.error span.error-message{display:block}input.error,textarea.error,select.error{margin-bottom:0}label.error{color:#f04124}meta.foundation-mq-topbar{font-family:"/only screen and (min-width:40.0625em)/";width:40.0625em}.contain-to-grid{width:100%;background:#333}.contain-to-grid .top-bar{margin-bottom:0}.fixed{position:fixed;top:0;width:100%;z-index:99;left:0}.fixed.expanded:not(.top-bar){height:auto;max-height:100%;overflow-y:auto;width:100%}.fixed.expanded:not(.top-bar) .title-area{position:fixed;width:100%;z-index:99}.fixed.expanded:not(.top-bar) .top-bar-section{margin-top:2.8125rem;z-index:98}.top-bar{background:#333;height:2.8125rem;line-height:2.8125rem;margin-bottom:0;overflow:hidden;position:relative}.top-bar ul{list-style:none;margin-bottom:0}.top-bar .row{max-width:none}.top-bar form,.top-bar input,.top-bar select{margin-bottom:0}.top-bar input,.top-bar select{font-size:0.75rem;height:1.75rem;padding-bottom:.35rem;padding-top:.35rem}.top-bar .button,.top-bar button{font-size:0.75rem;margin-bottom:0;padding-bottom:0.4125rem;padding-top:0.4125rem}@media only screen and (max-width: 40em){.top-bar .button,.top-bar button{position:relative;top:-1px}}.top-bar .title-area{margin:0;position:relative}.top-bar .name{font-size:16px;height:2.8125rem;margin:0}.top-bar .name h1,.top-bar .name h2,.top-bar .name h3,.top-bar .name h4,.top-bar .name p,.top-bar .name span{font-size:1.0625rem;line-height:2.8125rem;margin:0}.top-bar .name h1 a,.top-bar .name h2 a,.top-bar .name h3 a,.top-bar .name h4 a,.top-bar .name p a,.top-bar .name span a{color:#fff;display:block;font-weight:normal;padding:0 0.9375rem;width:75%}.top-bar .toggle-topbar{position:absolute;right:0;top:0}.top-bar .toggle-topbar a{color:#fff;display:block;font-size:0.8125rem;font-weight:bold;height:2.8125rem;line-height:2.8125rem;padding:0 0.9375rem;position:relative;text-transform:uppercase}.top-bar .toggle-topbar.menu-icon{margin-top:-16px;top:50%}.top-bar .toggle-topbar.menu-icon a{color:#fff;height:34px;line-height:33px;padding:0 2.5rem 0 0.9375rem;position:relative}.top-bar .toggle-topbar.menu-icon a span::after{content:"";display:block;height:0;position:absolute;margin-top:-8px;top:50%;right:0.9375rem;box-shadow:0 0 0 1px #fff,0 7px 0 1px #fff,0 14px 0 1px #fff;width:16px}.top-bar .toggle-topbar.menu-icon a span:hover:after{box-shadow:0 0 0 1px "",0 7px 0 1px "",0 14px 0 1px ""}.top-bar.expanded{background:transparent;height:auto}.top-bar.expanded .title-area{background:#333}.top-bar.expanded .toggle-topbar a{color:#888}.top-bar.expanded .toggle-topbar a span::after{box-shadow:0 0 0 1px #888,0 7px 0 1px #888,0 14px 0 1px #888}@media screen and (-webkit-min-device-pixel-ratio: 0){.top-bar.expanded .top-bar-section .has-dropdown.moved>.dropdown,.top-bar.expanded .top-bar-section .dropdown{clip:initial}.top-bar.expanded .top-bar-section .has-dropdown:not(.moved)>ul{padding:0}}.top-bar-section{left:0;position:relative;width:auto;transition:left 300ms ease-out}.top-bar-section ul{display:block;font-size:16px;height:auto;margin:0;padding:0;width:100%}.top-bar-section .divider,.top-bar-section [role="separator"]{border-top:solid 1px #1a1a1a;clear:both;height:1px;width:100%}.top-bar-section ul li{background:#333}.top-bar-section ul li>a{color:#fff;display:block;font-family:"Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;font-size:0.8125rem;font-weight:normal;padding-left:0.9375rem;padding:12px 0 12px 0.9375rem;text-transform:none;width:100%}.top-bar-section ul li>a.button{font-size:0.8125rem;padding-left:0.9375rem;padding-right:0.9375rem;background-color:#008CBA;border-color:#007095;color:#fff}.top-bar-section ul li>a.button:hover,.top-bar-section ul li>a.button:focus{background-color:#007095}.top-bar-section ul li>a.button:hover,.top-bar-section ul li>a.button:focus{color:#fff}.top-bar-section ul li>a.button.secondary{background-color:#e7e7e7;border-color:#b9b9b9;color:#333}.top-bar-section ul li>a.button.secondary:hover,.top-bar-section ul li>a.button.secondary:focus{background-color:#b9b9b9}.top-bar-section ul li>a.button.secondary:hover,.top-bar-section ul li>a.button.secondary:focus{color:#333}.top-bar-section ul li>a.button.success{background-color:#43AC6A;border-color:#368a55;color:#fff}.top-bar-section ul li>a.button.success:hover,.top-bar-section ul li>a.button.success:focus{background-color:#368a55}.top-bar-section ul li>a.button.success:hover,.top-bar-section ul li>a.button.success:focus{color:#fff}.top-bar-section ul li>a.button.alert{background-color:#f04124;border-color:#cf2a0e;color:#fff}.top-bar-section ul li>a.button.alert:hover,.top-bar-section ul li>a.button.alert:focus{background-color:#cf2a0e}.top-bar-section ul li>a.button.alert:hover,.top-bar-section ul li>a.button.alert:focus{color:#fff}.top-bar-section ul li>a.button.warning{background-color:#f08a24;border-color:#cf6e0e;color:#fff}.top-bar-section ul li>a.button.warning:hover,.top-bar-section ul li>a.button.warning:focus{background-color:#cf6e0e}.top-bar-section ul li>a.button.warning:hover,.top-bar-section ul li>a.button.warning:focus{color:#fff}.top-bar-section ul li>a.button.info{background-color:#a0d3e8;border-color:#61b6d9;color:#333}.top-bar-section ul li>a.button.info:hover,.top-bar-section ul li>a.button.info:focus{background-color:#61b6d9}.top-bar-section ul li>a.button.info:hover,.top-bar-section ul li>a.button.info:focus{color:#fff}.top-bar-section ul li>button{font-size:0.8125rem;padding-left:0.9375rem;padding-right:0.9375rem;background-color:#008CBA;border-color:#007095;color:#fff}.top-bar-section ul li>button:hover,.top-bar-section ul li>button:focus{background-color:#007095}.top-bar-section ul li>button:hover,.top-bar-section ul li>button:focus{color:#fff}.top-bar-section ul li>button.secondary{background-color:#e7e7e7;border-color:#b9b9b9;color:#333}.top-bar-section ul li>button.secondary:hover,.top-bar-section ul li>button.secondary:focus{background-color:#b9b9b9}.top-bar-section ul li>button.secondary:hover,.top-bar-section ul li>button.secondary:focus{color:#333}.top-bar-section ul li>button.success{background-color:#43AC6A;border-color:#368a55;color:#fff}.top-bar-section ul li>button.success:hover,.top-bar-section ul li>button.success:focus{background-color:#368a55}.top-bar-section ul li>button.success:hover,.top-bar-section ul li>button.success:focus{color:#fff}.top-bar-section ul li>button.alert{background-color:#f04124;border-color:#cf2a0e;color:#fff}.top-bar-section ul li>button.alert:hover,.top-bar-section ul li>button.alert:focus{background-color:#cf2a0e}.top-bar-section ul li>button.alert:hover,.top-bar-section ul li>button.alert:focus{color:#fff}.top-bar-section ul li>button.warning{background-color:#f08a24;border-color:#cf6e0e;color:#fff}.top-bar-section ul li>button.warning:hover,.top-bar-section ul li>button.warning:focus{background-color:#cf6e0e}.top-bar-section ul li>button.warning:hover,.top-bar-section ul li>button.warning:focus{color:#fff}.top-bar-section ul li>button.info{background-color:#a0d3e8;border-color:#61b6d9;color:#333}.top-bar-section ul li>button.info:hover,.top-bar-section ul li>button.info:focus{background-color:#61b6d9}.top-bar-section ul li>button.info:hover,.top-bar-section ul li>button.info:focus{color:#fff}.top-bar-section ul li:hover:not(.has-form)>a{background-color:#555;color:#fff;background:#222}.top-bar-section ul li.active>a{background:#008CBA;color:#fff}.top-bar-section ul li.active>a:hover{background:#0078a0;color:#fff}.top-bar-section .has-form{padding:0.9375rem}.top-bar-section .has-dropdown{position:relative}.top-bar-section .has-dropdown>a:after{border:inset 5px;content:"";display:block;height:0;width:0;border-color:transparent transparent transparent rgba(255,255,255,0.4);border-left-style:solid;margin-right:0.9375rem;margin-top:-4.5px;position:absolute;top:50%;right:0}.top-bar-section .has-dropdown.moved{position:static}.top-bar-section .has-dropdown.moved>.dropdown{position:static !important;height:auto;width:auto;overflow:visible;clip:auto;display:block;position:absolute !important;width:100%}.top-bar-section .has-dropdown.moved>a:after{display:none}.top-bar-section .dropdown{clip:rect(1px, 1px, 1px, 1px);height:1px;overflow:hidden;position:absolute !important;width:1px;display:block;padding:0;position:absolute;top:0;z-index:99;left:100%}.top-bar-section .dropdown li{height:auto;width:100%}.top-bar-section .dropdown li a{font-weight:normal;padding:8px 0.9375rem}.top-bar-section .dropdown li a.parent-link{font-weight:normal}.top-bar-section .dropdown li.title h5,.top-bar-section .dropdown li.parent-link{margin-bottom:0;margin-top:0;font-size:1.125rem}.top-bar-section .dropdown li.title h5 a,.top-bar-section .dropdown li.parent-link a{color:#fff;display:block}.top-bar-section .dropdown li.title h5 a:hover,.top-bar-section .dropdown li.parent-link a:hover{background:none}.top-bar-section .dropdown li.has-form{padding:8px 0.9375rem}.top-bar-section .dropdown li .button,.top-bar-section .dropdown li button{top:auto}.top-bar-section .dropdown label{color:#777;font-size:0.625rem;font-weight:bold;margin-bottom:0;padding:8px 0.9375rem 2px;text-transform:uppercase}.js-generated{display:block}@media only screen and (min-width: 40.0625em){.top-bar{background:#333;overflow:visible}.top-bar:before,.top-bar:after{content:" ";display:table}.top-bar:after{clear:both}.top-bar .toggle-topbar{display:none}.top-bar .title-area{float:left}.top-bar .name h1 a,.top-bar .name h2 a,.top-bar .name h3 a,.top-bar .name h4 a,.top-bar .name h5 a,.top-bar .name h6 a{width:auto}.top-bar input,.top-bar select,.top-bar .button,.top-bar button{font-size:0.875rem;height:1.75rem;position:relative;top:0.53125rem}.top-bar.expanded{background:#333}.contain-to-grid .top-bar{margin-bottom:0;margin:0 auto;max-width:62.5rem}.top-bar-section{transition:none 0 0;left:0 !important}.top-bar-section ul{display:inline;height:auto !important;width:auto}.top-bar-section ul li{float:left}.top-bar-section ul li .js-generated{display:none}.top-bar-section li.hover>a:not(.button){background-color:#555;background:#222;color:#fff}.top-bar-section li:not(.has-form) a:not(.button){background:#333;line-height:2.8125rem;padding:0 0.9375rem}.top-bar-section li:not(.has-form) a:not(.button):hover{background-color:#555;background:#222}.top-bar-section li.active:not(.has-form) a:not(.button){background:#008CBA;color:#fff;line-height:2.8125rem;padding:0 0.9375rem}.top-bar-section li.active:not(.has-form) a:not(.button):hover{background:#0078a0;color:#fff}.top-bar-section .has-dropdown>a{padding-right:2.1875rem !important}.top-bar-section .has-dropdown>a:after{border:inset 5px;content:"";display:block;height:0;width:0;border-color:rgba(255,255,255,0.4) transparent transparent transparent;border-top-style:solid;margin-top:-2.5px;top:1.40625rem}.top-bar-section .has-dropdown.moved{position:relative}.top-bar-section .has-dropdown.moved>.dropdown{clip:rect(1px, 1px, 1px, 1px);height:1px;overflow:hidden;position:absolute !important;width:1px;display:block}.top-bar-section .has-dropdown.hover>.dropdown,.top-bar-section .has-dropdown.not-click:hover>.dropdown{position:static !important;height:auto;width:auto;overflow:visible;clip:auto;display:block;position:absolute !important}.top-bar-section .has-dropdown>a:focus+.dropdown{position:static !important;height:auto;width:auto;overflow:visible;clip:auto;display:block;position:absolute !important}.top-bar-section .has-dropdown .dropdown li.has-dropdown>a:after{border:none;content:"\00bb";top:0.1875rem;right:5px}.top-bar-section .dropdown{left:0;background:transparent;min-width:100%;top:auto}.top-bar-section .dropdown li a{background:#333;color:#fff;line-height:2.8125rem;padding:12px 0.9375rem;white-space:nowrap}.top-bar-section .dropdown li:not(.has-form):not(.active)>a:not(.button){background:#333;color:#fff}.top-bar-section .dropdown li:not(.has-form):not(.active):hover>a:not(.button){background-color:#555;color:#fff;background:#222}.top-bar-section .dropdown li label{background:#333;white-space:nowrap}.top-bar-section .dropdown li .dropdown{left:100%;top:0}.top-bar-section>ul>.divider,.top-bar-section>ul>[role="separator"]{border-right:solid 1px #4e4e4e;border-bottom:none;border-top:none;clear:none;height:2.8125rem;width:0}.top-bar-section .has-form{background:#333;height:2.8125rem;padding:0 0.9375rem}.top-bar-section .right li .dropdown{left:auto;right:0}.top-bar-section .right li .dropdown li .dropdown{right:100%}.top-bar-section .left li .dropdown{right:auto;left:0}.top-bar-section .left li .dropdown li .dropdown{left:100%}.no-js .top-bar-section ul li:hover>a{background-color:#555;background:#222;color:#fff}.no-js .top-bar-section ul li:active>a{background:#008CBA;color:#fff}.no-js .top-bar-section .has-dropdown:hover>.dropdown{position:static !important;height:auto;width:auto;overflow:visible;clip:auto;display:block;position:absolute !important}.no-js .top-bar-section .has-dropdown>a:focus+.dropdown{position:static !important;height:auto;width:auto;overflow:visible;clip:auto;display:block;position:absolute !important}}.breadcrumbs{border-style:solid;border-width:1px;display:block;list-style:none;margin-left:0;overflow:hidden;padding:0.5625rem 0.875rem 0.5625rem;background-color:#f4f4f4;border-color:#dcdcdc;border-radius:3px}.breadcrumbs>*{color:#008CBA;float:left;font-size:0.6875rem;line-height:0.6875rem;margin:0;text-transform:uppercase}.breadcrumbs>*:hover a,.breadcrumbs>*:focus a{text-decoration:underline}.breadcrumbs>* a{color:#008CBA}.breadcrumbs>*.current{color:#333;cursor:default}.breadcrumbs>*.current a{color:#333;cursor:default}.breadcrumbs>*.current:hover,.breadcrumbs>*.current:hover a,.breadcrumbs>*.current:focus,.breadcrumbs>*.current:focus a{text-decoration:none}.breadcrumbs>*.unavailable{color:#999}.breadcrumbs>*.unavailable a{color:#999}.breadcrumbs>*.unavailable:hover,.breadcrumbs>*.unavailable:hover a,.breadcrumbs>*.unavailable:focus,.breadcrumbs>*.unavailable a:focus{color:#999;cursor:not-allowed;text-decoration:none}.breadcrumbs>*:before{color:#aaa;content:"/";margin:0 0.75rem;position:relative;top:1px}.breadcrumbs>*:first-child:before{content:" ";margin:0}[aria-label="breadcrumbs"] [aria-hidden="true"]:after{content:"/"}.alert-box{border-style:solid;border-width:1px;display:block;font-size:0.8125rem;font-weight:normal;margin-bottom:1.25rem;padding:0.875rem 1.5rem 0.875rem 0.875rem;position:relative;transition:opacity 300ms ease-out;background-color:#008CBA;border-color:#0078a0;color:#fff}.alert-box .close{right:0.25rem;background:inherit;color:#333;font-size:1.375rem;line-height:.9;margin-top:-0.6875rem;opacity:0.3;padding:0 6px 4px;position:absolute;top:50%}.alert-box .close:hover,.alert-box .close:focus{opacity:0.5}.alert-box.radius{border-radius:3px}.alert-box.round{border-radius:1000px}.alert-box.success{background-color:#43AC6A;border-color:#3a945b;color:#fff}.alert-box.alert{background-color:#f04124;border-color:#de2d0f;color:#fff}.alert-box.secondary{background-color:#e7e7e7;border-color:#c7c7c7;color:#4f4f4f}.alert-box.warning{background-color:#f08a24;border-color:#de770f;color:#fff}.alert-box.info{background-color:#a0d3e8;border-color:#74bfdd;color:#4f4f4f}.alert-box.alert-close{opacity:0}.inline-list{list-style:none;margin-left:-1.375rem;margin-right:0;margin:0 auto 1.0625rem auto;overflow:hidden;padding:0}.inline-list>li{display:block;float:left;list-style:none;margin-left:1.375rem}.inline-list>li>*{display:block}.button-group{list-style:none;margin:0;left:0}.button-group:before,.button-group:after{content:" ";display:table}.button-group:after{clear:both}.button-group.even-2 li{display:inline-block;margin:0 -2px;width:50%}.button-group.even-2 li>button,.button-group.even-2 li .button{border-left:1px solid;border-color:rgba(255,255,255,0.5)}.button-group.even-2 li:first-child button,.button-group.even-2 li:first-child .button{border-left:0}.button-group.even-2 li button,.button-group.even-2 li .button{width:100%}.button-group.even-3 li{display:inline-block;margin:0 -2px;width:33.33333%}.button-group.even-3 li>button,.button-group.even-3 li .button{border-left:1px solid;border-color:rgba(255,255,255,0.5)}.button-group.even-3 li:first-child button,.button-group.even-3 li:first-child .button{border-left:0}.button-group.even-3 li button,.button-group.even-3 li .button{width:100%}.button-group.even-4 li{display:inline-block;margin:0 -2px;width:25%}.button-group.even-4 li>button,.button-group.even-4 li .button{border-left:1px solid;border-color:rgba(255,255,255,0.5)}.button-group.even-4 li:first-child button,.button-group.even-4 li:first-child .button{border-left:0}.button-group.even-4 li button,.button-group.even-4 li .button{width:100%}.button-group.even-5 li{display:inline-block;margin:0 -2px;width:20%}.button-group.even-5 li>button,.button-group.even-5 li .button{border-left:1px solid;border-color:rgba(255,255,255,0.5)}.button-group.even-5 li:first-child button,.button-group.even-5 li:first-child .button{border-left:0}.button-group.even-5 li button,.button-group.even-5 li .button{width:100%}.button-group.even-6 li{display:inline-block;margin:0 -2px;width:16.66667%}.button-group.even-6 li>button,.button-group.even-6 li .button{border-left:1px solid;border-color:rgba(255,255,255,0.5)}.button-group.even-6 li:first-child button,.button-group.even-6 li:first-child .button{border-left:0}.button-group.even-6 li button,.button-group.even-6 li .button{width:100%}.button-group.even-7 li{display:inline-block;margin:0 -2px;width:14.28571%}.button-group.even-7 li>button,.button-group.even-7 li .button{border-left:1px solid;border-color:rgba(255,255,255,0.5)}.button-group.even-7 li:first-child button,.button-group.even-7 li:first-child .button{border-left:0}.button-group.even-7 li button,.button-group.even-7 li .button{width:100%}.button-group.even-8 li{display:inline-block;margin:0 -2px;width:12.5%}.button-group.even-8 li>button,.button-group.even-8 li .button{border-left:1px solid;border-color:rgba(255,255,255,0.5)}.button-group.even-8 li:first-child button,.button-group.even-8 li:first-child .button{border-left:0}.button-group.even-8 li button,.button-group.even-8 li .button{width:100%}.button-group>li{display:inline-block;margin:0 -2px}.button-group>li>button,.button-group>li .button{border-left:1px solid;border-color:rgba(255,255,255,0.5)}.button-group>li:first-child button,.button-group>li:first-child .button{border-left:0}.button-group.stack>li{display:block;margin:0;float:none}.button-group.stack>li>button,.button-group.stack>li .button{border-left:1px solid;border-color:rgba(255,255,255,0.5)}.button-group.stack>li:first-child button,.button-group.stack>li:first-child .button{border-left:0}.button-group.stack>li>button,.button-group.stack>li .button{border-color:rgba(255,255,255,0.5);border-left-width:0;border-top:1px solid;display:block;margin:0}.button-group.stack>li>button{width:100%}.button-group.stack>li:first-child button,.button-group.stack>li:first-child .button{border-top:0}.button-group.stack-for-small>li{display:inline-block;margin:0 -2px}.button-group.stack-for-small>li>button,.button-group.stack-for-small>li .button{border-left:1px solid;border-color:rgba(255,255,255,0.5)}.button-group.stack-for-small>li:first-child button,.button-group.stack-for-small>li:first-child .button{border-left:0}@media only screen and (max-width: 40em){.button-group.stack-for-small>li{display:block;margin:0}.button-group.stack-for-small>li>button,.button-group.stack-for-small>li .button{border-left:1px solid;border-color:rgba(255,255,255,0.5)}.button-group.stack-for-small>li:first-child button,.button-group.stack-for-small>li:first-child .button{border-left:0}.button-group.stack-for-small>li>button,.button-group.stack-for-small>li .button{border-color:rgba(255,255,255,0.5);border-left-width:0;border-top:1px solid;display:block;margin:0}.button-group.stack-for-small>li>button{width:100%}.button-group.stack-for-small>li:first-child button,.button-group.stack-for-small>li:first-child .button{border-top:0}}.button-group.radius>*{display:inline-block;margin:0 -2px}.button-group.radius>*>button,.button-group.radius>* .button{border-left:1px solid;border-color:rgba(255,255,255,0.5)}.button-group.radius>*:first-child button,.button-group.radius>*:first-child .button{border-left:0}.button-group.radius>*,.button-group.radius>*>a,.button-group.radius>*>button,.button-group.radius>*>.button{border-radius:0}.button-group.radius>*:first-child,.button-group.radius>*:first-child>a,.button-group.radius>*:first-child>button,.button-group.radius>*:first-child>.button{-webkit-border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-bottom-left-radius:3px;border-top-left-radius:3px}.button-group.radius>*:last-child,.button-group.radius>*:last-child>a,.button-group.radius>*:last-child>button,.button-group.radius>*:last-child>.button{-webkit-border-bottom-right-radius:3px;-webkit-border-top-right-radius:3px;border-bottom-right-radius:3px;border-top-right-radius:3px}.button-group.radius.stack>*{display:block;margin:0}.button-group.radius.stack>*>button,.button-group.radius.stack>* .button{border-left:1px solid;border-color:rgba(255,255,255,0.5)}.button-group.radius.stack>*:first-child button,.button-group.radius.stack>*:first-child .button{border-left:0}.button-group.radius.stack>*>button,.button-group.radius.stack>* .button{border-color:rgba(255,255,255,0.5);border-left-width:0;border-top:1px solid;display:block;margin:0}.button-group.radius.stack>*>button{width:100%}.button-group.radius.stack>*:first-child button,.button-group.radius.stack>*:first-child .button{border-top:0}.button-group.radius.stack>*,.button-group.radius.stack>*>a,.button-group.radius.stack>*>button,.button-group.radius.stack>*>.button{border-radius:0}.button-group.radius.stack>*:first-child,.button-group.radius.stack>*:first-child>a,.button-group.radius.stack>*:first-child>button,.button-group.radius.stack>*:first-child>.button{-webkit-top-left-radius:3px;-webkit-top-right-radius:3px;border-top-left-radius:3px;border-top-right-radius:3px}.button-group.radius.stack>*:last-child,.button-group.radius.stack>*:last-child>a,.button-group.radius.stack>*:last-child>button,.button-group.radius.stack>*:last-child>.button{-webkit-bottom-left-radius:3px;-webkit-bottom-right-radius:3px;border-bottom-left-radius:3px;border-bottom-right-radius:3px}@media only screen and (min-width: 40.0625em){.button-group.radius.stack-for-small>*{display:inline-block;margin:0 -2px}.button-group.radius.stack-for-small>*>button,.button-group.radius.stack-for-small>* .button{border-left:1px solid;border-color:rgba(255,255,255,0.5)}.button-group.radius.stack-for-small>*:first-child button,.button-group.radius.stack-for-small>*:first-child .button{border-left:0}.button-group.radius.stack-for-small>*,.button-group.radius.stack-for-small>*>a,.button-group.radius.stack-for-small>*>button,.button-group.radius.stack-for-small>*>.button{border-radius:0}.button-group.radius.stack-for-small>*:first-child,.button-group.radius.stack-for-small>*:first-child>a,.button-group.radius.stack-for-small>*:first-child>button,.button-group.radius.stack-for-small>*:first-child>.button{-webkit-border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-bottom-left-radius:3px;border-top-left-radius:3px}.button-group.radius.stack-for-small>*:last-child,.button-group.radius.stack-for-small>*:last-child>a,.button-group.radius.stack-for-small>*:last-child>button,.button-group.radius.stack-for-small>*:last-child>.button{-webkit-border-bottom-right-radius:3px;-webkit-border-top-right-radius:3px;border-bottom-right-radius:3px;border-top-right-radius:3px}}@media only screen and (max-width: 40em){.button-group.radius.stack-for-small>*{display:block;margin:0}.button-group.radius.stack-for-small>*>button,.button-group.radius.stack-for-small>* .button{border-left:1px solid;border-color:rgba(255,255,255,0.5)}.button-group.radius.stack-for-small>*:first-child button,.button-group.radius.stack-for-small>*:first-child .button{border-left:0}.button-group.radius.stack-for-small>*>button,.button-group.radius.stack-for-small>* .button{border-color:rgba(255,255,255,0.5);border-left-width:0;border-top:1px solid;display:block;margin:0}.button-group.radius.stack-for-small>*>button{width:100%}.button-group.radius.stack-for-small>*:first-child button,.button-group.radius.stack-for-small>*:first-child .button{border-top:0}.button-group.radius.stack-for-small>*,.button-group.radius.stack-for-small>*>a,.button-group.radius.stack-for-small>*>button,.button-group.radius.stack-for-small>*>.button{border-radius:0}.button-group.radius.stack-for-small>*:first-child,.button-group.radius.stack-for-small>*:first-child>a,.button-group.radius.stack-for-small>*:first-child>button,.button-group.radius.stack-for-small>*:first-child>.button{-webkit-top-left-radius:3px;-webkit-top-right-radius:3px;border-top-left-radius:3px;border-top-right-radius:3px}.button-group.radius.stack-for-small>*:last-child,.button-group.radius.stack-for-small>*:last-child>a,.button-group.radius.stack-for-small>*:last-child>button,.button-group.radius.stack-for-small>*:last-child>.button{-webkit-bottom-left-radius:3px;-webkit-bottom-right-radius:3px;border-bottom-left-radius:3px;border-bottom-right-radius:3px}}.button-group.round>*{display:inline-block;margin:0 -2px}.button-group.round>*>button,.button-group.round>* .button{border-left:1px solid;border-color:rgba(255,255,255,0.5)}.button-group.round>*:first-child button,.button-group.round>*:first-child .button{border-left:0}.button-group.round>*,.button-group.round>*>a,.button-group.round>*>button,.button-group.round>*>.button{border-radius:0}.button-group.round>*:first-child,.button-group.round>*:first-child>a,.button-group.round>*:first-child>button,.button-group.round>*:first-child>.button{-webkit-border-bottom-left-radius:1000px;-webkit-border-top-left-radius:1000px;border-bottom-left-radius:1000px;border-top-left-radius:1000px}.button-group.round>*:last-child,.button-group.round>*:last-child>a,.button-group.round>*:last-child>button,.button-group.round>*:last-child>.button{-webkit-border-bottom-right-radius:1000px;-webkit-border-top-right-radius:1000px;border-bottom-right-radius:1000px;border-top-right-radius:1000px}.button-group.round.stack>*{display:block;margin:0}.button-group.round.stack>*>button,.button-group.round.stack>* .button{border-left:1px solid;border-color:rgba(255,255,255,0.5)}.button-group.round.stack>*:first-child button,.button-group.round.stack>*:first-child .button{border-left:0}.button-group.round.stack>*>button,.button-group.round.stack>* .button{border-color:rgba(255,255,255,0.5);border-left-width:0;border-top:1px solid;display:block;margin:0}.button-group.round.stack>*>button{width:100%}.button-group.round.stack>*:first-child button,.button-group.round.stack>*:first-child .button{border-top:0}.button-group.round.stack>*,.button-group.round.stack>*>a,.button-group.round.stack>*>button,.button-group.round.stack>*>.button{border-radius:0}.button-group.round.stack>*:first-child,.button-group.round.stack>*:first-child>a,.button-group.round.stack>*:first-child>button,.button-group.round.stack>*:first-child>.button{-webkit-top-left-radius:1rem;-webkit-top-right-radius:1rem;border-top-left-radius:1rem;border-top-right-radius:1rem}.button-group.round.stack>*:last-child,.button-group.round.stack>*:last-child>a,.button-group.round.stack>*:last-child>button,.button-group.round.stack>*:last-child>.button{-webkit-bottom-left-radius:1rem;-webkit-bottom-right-radius:1rem;border-bottom-left-radius:1rem;border-bottom-right-radius:1rem}@media only screen and (min-width: 40.0625em){.button-group.round.stack-for-small>*{display:inline-block;margin:0 -2px}.button-group.round.stack-for-small>*>button,.button-group.round.stack-for-small>* .button{border-left:1px solid;border-color:rgba(255,255,255,0.5)}.button-group.round.stack-for-small>*:first-child button,.button-group.round.stack-for-small>*:first-child .button{border-left:0}.button-group.round.stack-for-small>*,.button-group.round.stack-for-small>*>a,.button-group.round.stack-for-small>*>button,.button-group.round.stack-for-small>*>.button{border-radius:0}.button-group.round.stack-for-small>*:first-child,.button-group.round.stack-for-small>*:first-child>a,.button-group.round.stack-for-small>*:first-child>button,.button-group.round.stack-for-small>*:first-child>.button{-webkit-border-bottom-left-radius:1000px;-webkit-border-top-left-radius:1000px;border-bottom-left-radius:1000px;border-top-left-radius:1000px}.button-group.round.stack-for-small>*:last-child,.button-group.round.stack-for-small>*:last-child>a,.button-group.round.stack-for-small>*:last-child>button,.button-group.round.stack-for-small>*:last-child>.button{-webkit-border-bottom-right-radius:1000px;-webkit-border-top-right-radius:1000px;border-bottom-right-radius:1000px;border-top-right-radius:1000px}}@media only screen and (max-width: 40em){.button-group.round.stack-for-small>*{display:block;margin:0}.button-group.round.stack-for-small>*>button,.button-group.round.stack-for-small>* .button{border-left:1px solid;border-color:rgba(255,255,255,0.5)}.button-group.round.stack-for-small>*:first-child button,.button-group.round.stack-for-small>*:first-child .button{border-left:0}.button-group.round.stack-for-small>*>button,.button-group.round.stack-for-small>* .button{border-color:rgba(255,255,255,0.5);border-left-width:0;border-top:1px solid;display:block;margin:0}.button-group.round.stack-for-small>*>button{width:100%}.button-group.round.stack-for-small>*:first-child button,.button-group.round.stack-for-small>*:first-child .button{border-top:0}.button-group.round.stack-for-small>*,.button-group.round.stack-for-small>*>a,.button-group.round.stack-for-small>*>button,.button-group.round.stack-for-small>*>.button{border-radius:0}.button-group.round.stack-for-small>*:first-child,.button-group.round.stack-for-small>*:first-child>a,.button-group.round.stack-for-small>*:first-child>button,.button-group.round.stack-for-small>*:first-child>.button{-webkit-top-left-radius:1rem;-webkit-top-right-radius:1rem;border-top-left-radius:1rem;border-top-right-radius:1rem}.button-group.round.stack-for-small>*:last-child,.button-group.round.stack-for-small>*:last-child>a,.button-group.round.stack-for-small>*:last-child>button,.button-group.round.stack-for-small>*:last-child>.button{-webkit-bottom-left-radius:1rem;-webkit-bottom-right-radius:1rem;border-bottom-left-radius:1rem;border-bottom-right-radius:1rem}}.button-bar:before,.button-bar:after{content:" ";display:table}.button-bar:after{clear:both}.button-bar .button-group{float:left;margin-right:0.625rem}.button-bar .button-group div{overflow:hidden}.panel{border-style:solid;border-width:1px;border-color:#d8d8d8;margin-bottom:1.25rem;padding:1.25rem;background:#f2f2f2;color:#333}.panel>:first-child{margin-top:0}.panel>:last-child{margin-bottom:0}.panel h1,.panel h2,.panel h3,.panel h4,.panel h5,.panel h6,.panel p,.panel li,.panel dl{color:#333}.panel h1,.panel h2,.panel h3,.panel h4,.panel h5,.panel h6{line-height:1;margin-bottom:0.625rem}.panel h1.subheader,.panel h2.subheader,.panel h3.subheader,.panel h4.subheader,.panel h5.subheader,.panel h6.subheader{line-height:1.4}.panel.callout{border-style:solid;border-width:1px;border-color:#d8d8d8;margin-bottom:1.25rem;padding:1.25rem;background:#ecfaff;color:#333}.panel.callout>:first-child{margin-top:0}.panel.callout>:last-child{margin-bottom:0}.panel.callout h1,.panel.callout h2,.panel.callout h3,.panel.callout h4,.panel.callout h5,.panel.callout h6,.panel.callout p,.panel.callout li,.panel.callout dl{color:#333}.panel.callout h1,.panel.callout h2,.panel.callout h3,.panel.callout h4,.panel.callout h5,.panel.callout h6{line-height:1;margin-bottom:0.625rem}.panel.callout h1.subheader,.panel.callout h2.subheader,.panel.callout h3.subheader,.panel.callout h4.subheader,.panel.callout h5.subheader,.panel.callout h6.subheader{line-height:1.4}.panel.callout a:not(.button){color:#008CBA}.panel.callout a:not(.button):hover,.panel.callout a:not(.button):focus{color:#0078a0}.panel.radius{border-radius:3px}.dropdown.button,button.dropdown{position:relative;padding-right:3.5625rem}.dropdown.button::after,button.dropdown::after{border-color:#fff transparent transparent transparent;border-style:solid;content:"";display:block;height:0;position:absolute;top:50%;width:0}.dropdown.button::after,button.dropdown::after{border-width:0.375rem;right:1.40625rem;margin-top:-0.15625rem}.dropdown.button::after,button.dropdown::after{border-color:#fff transparent transparent transparent}.dropdown.button.tiny,button.dropdown.tiny{padding-right:2.625rem}.dropdown.button.tiny:after,button.dropdown.tiny:after{border-width:0.375rem;right:1.125rem;margin-top:-0.125rem}.dropdown.button.tiny::after,button.dropdown.tiny::after{border-color:#fff transparent transparent transparent}.dropdown.button.small,button.dropdown.small{padding-right:3.0625rem}.dropdown.button.small::after,button.dropdown.small::after{border-width:0.4375rem;right:1.3125rem;margin-top:-0.15625rem}.dropdown.button.small::after,button.dropdown.small::after{border-color:#fff transparent transparent transparent}.dropdown.button.large,button.dropdown.large{padding-right:3.625rem}.dropdown.button.large::after,button.dropdown.large::after{border-width:0.3125rem;right:1.71875rem;margin-top:-0.15625rem}.dropdown.button.large::after,button.dropdown.large::after{border-color:#fff transparent transparent transparent}.dropdown.button.secondary:after,button.dropdown.secondary:after{border-color:#333 transparent transparent transparent}.th{border:solid 4px #fff;box-shadow:0 0 0 1px rgba(0,0,0,0.2);display:inline-block;line-height:0;max-width:100%;transition:all 200ms ease-out}.th:hover,.th:focus{box-shadow:0 0 6px 1px rgba(0,140,186,0.5)}.th.radius{border-radius:3px}.pricing-table{border:solid 1px #ddd;margin-left:0;margin-bottom:1.25rem}.pricing-table *{list-style:none;line-height:1}.pricing-table .title{background-color:#333;color:#eee;font-family:"Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;font-size:1rem;font-weight:normal;padding:0.9375rem 1.25rem;text-align:center}.pricing-table .price{background-color:#F6F6F6;color:#333;font-family:"Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;font-size:2rem;font-weight:normal;padding:0.9375rem 1.25rem;text-align:center}.pricing-table .description{background-color:#fff;border-bottom:dotted 1px #ddd;color:#777;font-size:0.75rem;font-weight:normal;line-height:1.4;padding:0.9375rem;text-align:center}.pricing-table .bullet-item{background-color:#fff;border-bottom:dotted 1px #ddd;color:#333;font-size:0.875rem;font-weight:normal;padding:0.9375rem;text-align:center}.pricing-table .cta-button{background-color:#fff;padding:1.25rem 1.25rem 0;text-align:center}@-webkit-keyframes rotate{from{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes rotate{from{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);-ms-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-ms-transform:rotate(360deg);transform:rotate(360deg)}}.slideshow-wrapper{position:relative}.slideshow-wrapper ul{list-style-type:none;margin:0}.slideshow-wrapper ul li,.slideshow-wrapper ul li .orbit-caption{display:none}.slideshow-wrapper ul li:first-child{display:block}.slideshow-wrapper .orbit-container{background-color:transparent}.slideshow-wrapper .orbit-container li{display:block}.slideshow-wrapper .orbit-container li .orbit-caption{display:block}.slideshow-wrapper .orbit-container .orbit-bullets li{display:inline-block}.slideshow-wrapper .preloader{border-radius:1000px;animation-duration:1.5s;animation-iteration-count:infinite;animation-name:rotate;animation-timing-function:linear;border-color:#555 #fff;border:solid 3px;display:block;height:40px;left:50%;margin-left:-20px;margin-top:-20px;position:absolute;top:50%;width:40px}.orbit-container{background:none;overflow:hidden;position:relative;width:100%}.orbit-container .orbit-slides-container{list-style:none;margin:0;padding:0;position:relative;-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-ms-transform:translateZ(0);-o-transform:translateZ(0);transform:translateZ(0)}.orbit-container .orbit-slides-container img{display:block;max-width:100%}.orbit-container .orbit-slides-container>*{position:absolute;top:0;width:100%;margin-left:100%}.orbit-container .orbit-slides-container>*:first-child{margin-left:0}.orbit-container .orbit-slides-container>* .orbit-caption{bottom:0;position:absolute;background-color:rgba(51,51,51,0.8);color:#fff;font-size:0.875rem;padding:0.625rem 0.875rem;width:100%}.orbit-container .orbit-slide-number{left:10px;background:transparent;color:#fff;font-size:12px;position:absolute;top:10px;z-index:10}.orbit-container .orbit-slide-number span{font-weight:700;padding:0.3125rem}.orbit-container .orbit-timer{position:absolute;top:12px;right:10px;height:6px;width:100px;z-index:10}.orbit-container .orbit-timer .orbit-progress{height:3px;background-color:rgba(255,255,255,0.3);display:block;width:0;position:relative;right:20px;top:5px}.orbit-container .orbit-timer>span{border:solid 4px #fff;border-bottom:none;border-top:none;display:none;height:14px;position:absolute;top:0;width:11px;right:0}.orbit-container .orbit-timer.paused>span{top:0;width:11px;height:14px;border:inset 8px;border-left-style:solid;border-color:transparent;border-left-color:#fff;right:-4px}.orbit-container .orbit-timer.paused>span.dark{border-left-color:#333}.orbit-container:hover .orbit-timer>span{display:block}.orbit-container .orbit-prev,.orbit-container .orbit-next{background-color:transparent;color:white;height:60px;line-height:50px;margin-top:-25px;position:absolute;text-indent:-9999px !important;top:45%;width:36px;z-index:10}.orbit-container .orbit-prev:hover,.orbit-container .orbit-next:hover{background-color:rgba(0,0,0,0.3)}.orbit-container .orbit-prev>span,.orbit-container .orbit-next>span{border:inset 10px;display:block;height:0;margin-top:-10px;position:absolute;top:50%;width:0}.orbit-container .orbit-prev{left:0}.orbit-container .orbit-prev>span{border-right-style:solid;border-color:transparent;border-right-color:#fff}.orbit-container .orbit-prev:hover>span{border-right-color:#fff}.orbit-container .orbit-next{right:0}.orbit-container .orbit-next>span{border-color:transparent;border-left-style:solid;border-left-color:#fff;left:50%;margin-left:-4px}.orbit-container .orbit-next:hover>span{border-left-color:#fff}.orbit-bullets-container{text-align:center}.orbit-bullets{display:block;float:none;margin:0 auto 30px auto;overflow:hidden;position:relative;text-align:center;top:10px}.orbit-bullets li{background:#ccc;cursor:pointer;display:inline-block;float:none;height:0.5625rem;margin-right:6px;width:0.5625rem;border-radius:1000px}.orbit-bullets li.active{background:#999}.orbit-bullets li:last-child{margin-right:0}.touch .orbit-container .orbit-prev,.touch .orbit-container .orbit-next{display:none}.touch .orbit-bullets{display:none}@media only screen and (min-width: 40.0625em){.touch .orbit-container .orbit-prev,.touch .orbit-container .orbit-next{display:inherit}.touch .orbit-bullets{display:block}}@media only screen and (max-width: 40em){.orbit-stack-on-small .orbit-slides-container{height:auto !important}.orbit-stack-on-small .orbit-slides-container>*{margin:0 !important;opacity:1 !important;position:relative}.orbit-stack-on-small .orbit-slide-number{display:none}.orbit-timer{display:none}.orbit-next,.orbit-prev{display:none}.orbit-bullets{display:none}}[data-magellan-expedition],[data-magellan-expedition-clone]{background:#fff;min-width:100%;padding:10px;z-index:50}[data-magellan-expedition] .sub-nav,[data-magellan-expedition-clone] .sub-nav{margin-bottom:0}[data-magellan-expedition] .sub-nav dd,[data-magellan-expedition-clone] .sub-nav dd{margin-bottom:0}[data-magellan-expedition] .sub-nav a,[data-magellan-expedition-clone] .sub-nav a{line-height:1.8em}.icon-bar{display:inline-block;font-size:0;width:100%;background:#333}.icon-bar>*{display:block;float:left;font-size:1rem;margin:0 auto;padding:1.25rem;text-align:center;width:25%}.icon-bar>* i,.icon-bar>* img{display:block;margin:0 auto}.icon-bar>* i+label,.icon-bar>* img+label{margin-top:.0625rem}.icon-bar>* i{font-size:1.875rem;vertical-align:middle}.icon-bar>* img{height:1.875rem;width:1.875rem}.icon-bar.label-right>* i,.icon-bar.label-right>* img{display:inline-block;margin:0 .0625rem 0 0}.icon-bar.label-right>* i+label,.icon-bar.label-right>* img+label{margin-top:0}.icon-bar.label-right>* label{display:inline-block}.icon-bar.vertical.label-right>*{text-align:left}.icon-bar.vertical,.icon-bar.small-vertical{height:100%;width:auto}.icon-bar.vertical .item,.icon-bar.small-vertical .item{float:none;margin:auto;width:auto}@media only screen and (min-width: 40.0625em){.icon-bar.medium-vertical{height:100%;width:auto}.icon-bar.medium-vertical .item{float:none;margin:auto;width:auto}}@media only screen and (min-width: 64.0625em){.icon-bar.large-vertical{height:100%;width:auto}.icon-bar.large-vertical .item{float:none;margin:auto;width:auto}}.icon-bar>*{font-size:1rem;padding:1.25rem}.icon-bar>* i+label,.icon-bar>* img+label{margin-top:.0625rem;font-size:1rem}.icon-bar>* i{font-size:1.875rem}.icon-bar>* img{height:1.875rem;width:1.875rem}.icon-bar>* label{color:#fff}.icon-bar>* i{color:#fff}.icon-bar>a:hover{background:#008CBA}.icon-bar>a:hover label{color:#fff}.icon-bar>a:hover i{color:#fff}.icon-bar>a.active{background:#008CBA}.icon-bar>a.active label{color:#fff}.icon-bar>a.active i{color:#fff}.icon-bar .item.disabled{cursor:not-allowed;opacity:0.7;pointer-events:none}.icon-bar .item.disabled>*{opacity:0.7;cursor:not-allowed}.icon-bar.two-up .item{width:50%}.icon-bar.two-up.vertical .item,.icon-bar.two-up.small-vertical .item{width:auto}@media only screen and (min-width: 40.0625em){.icon-bar.two-up.medium-vertical .item{width:auto}}@media only screen and (min-width: 64.0625em){.icon-bar.two-up.large-vertical .item{width:auto}}.icon-bar.three-up .item{width:33.3333%}.icon-bar.three-up.vertical .item,.icon-bar.three-up.small-vertical .item{width:auto}@media only screen and (min-width: 40.0625em){.icon-bar.three-up.medium-vertical .item{width:auto}}@media only screen and (min-width: 64.0625em){.icon-bar.three-up.large-vertical .item{width:auto}}.icon-bar.four-up .item{width:25%}.icon-bar.four-up.vertical .item,.icon-bar.four-up.small-vertical .item{width:auto}@media only screen and (min-width: 40.0625em){.icon-bar.four-up.medium-vertical .item{width:auto}}@media only screen and (min-width: 64.0625em){.icon-bar.four-up.large-vertical .item{width:auto}}.icon-bar.five-up .item{width:20%}.icon-bar.five-up.vertical .item,.icon-bar.five-up.small-vertical .item{width:auto}@media only screen and (min-width: 40.0625em){.icon-bar.five-up.medium-vertical .item{width:auto}}@media only screen and (min-width: 64.0625em){.icon-bar.five-up.large-vertical .item{width:auto}}.icon-bar.six-up .item{width:16.66667%}.icon-bar.six-up.vertical .item,.icon-bar.six-up.small-vertical .item{width:auto}@media only screen and (min-width: 40.0625em){.icon-bar.six-up.medium-vertical .item{width:auto}}@media only screen and (min-width: 64.0625em){.icon-bar.six-up.large-vertical .item{width:auto}}.icon-bar.seven-up .item{width:14.28571%}.icon-bar.seven-up.vertical .item,.icon-bar.seven-up.small-vertical .item{width:auto}@media only screen and (min-width: 40.0625em){.icon-bar.seven-up.medium-vertical .item{width:auto}}@media only screen and (min-width: 64.0625em){.icon-bar.seven-up.large-vertical .item{width:auto}}.icon-bar.eight-up .item{width:12.5%}.icon-bar.eight-up.vertical .item,.icon-bar.eight-up.small-vertical .item{width:auto}@media only screen and (min-width: 40.0625em){.icon-bar.eight-up.medium-vertical .item{width:auto}}@media only screen and (min-width: 64.0625em){.icon-bar.eight-up.large-vertical .item{width:auto}}.icon-bar.two-up .item{width:50%}.icon-bar.two-up.vertical .item,.icon-bar.two-up.small-vertical .item{width:auto}@media only screen and (min-width: 40.0625em){.icon-bar.two-up.medium-vertical .item{width:auto}}@media only screen and (min-width: 64.0625em){.icon-bar.two-up.large-vertical .item{width:auto}}.icon-bar.three-up .item{width:33.3333%}.icon-bar.three-up.vertical .item,.icon-bar.three-up.small-vertical .item{width:auto}@media only screen and (min-width: 40.0625em){.icon-bar.three-up.medium-vertical .item{width:auto}}@media only screen and (min-width: 64.0625em){.icon-bar.three-up.large-vertical .item{width:auto}}.icon-bar.four-up .item{width:25%}.icon-bar.four-up.vertical .item,.icon-bar.four-up.small-vertical .item{width:auto}@media only screen and (min-width: 40.0625em){.icon-bar.four-up.medium-vertical .item{width:auto}}@media only screen and (min-width: 64.0625em){.icon-bar.four-up.large-vertical .item{width:auto}}.icon-bar.five-up .item{width:20%}.icon-bar.five-up.vertical .item,.icon-bar.five-up.small-vertical .item{width:auto}@media only screen and (min-width: 40.0625em){.icon-bar.five-up.medium-vertical .item{width:auto}}@media only screen and (min-width: 64.0625em){.icon-bar.five-up.large-vertical .item{width:auto}}.icon-bar.six-up .item{width:16.66667%}.icon-bar.six-up.vertical .item,.icon-bar.six-up.small-vertical .item{width:auto}@media only screen and (min-width: 40.0625em){.icon-bar.six-up.medium-vertical .item{width:auto}}@media only screen and (min-width: 64.0625em){.icon-bar.six-up.large-vertical .item{width:auto}}.icon-bar.seven-up .item{width:14.28571%}.icon-bar.seven-up.vertical .item,.icon-bar.seven-up.small-vertical .item{width:auto}@media only screen and (min-width: 40.0625em){.icon-bar.seven-up.medium-vertical .item{width:auto}}@media only screen and (min-width: 64.0625em){.icon-bar.seven-up.large-vertical .item{width:auto}}.icon-bar.eight-up .item{width:12.5%}.icon-bar.eight-up.vertical .item,.icon-bar.eight-up.small-vertical .item{width:auto}@media only screen and (min-width: 40.0625em){.icon-bar.eight-up.medium-vertical .item{width:auto}}@media only screen and (min-width: 64.0625em){.icon-bar.eight-up.large-vertical .item{width:auto}}.tabs{margin-bottom:0 !important;margin-left:0}.tabs:before,.tabs:after{content:" ";display:table}.tabs:after{clear:both}.tabs dd,.tabs .tab-title{float:left;list-style:none;margin-bottom:0 !important;position:relative}.tabs dd>a,.tabs .tab-title>a{display:block;background-color:#EFEFEF;color:#222;font-family:"Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;font-size:1rem;padding:1rem 2rem}.tabs dd>a:hover,.tabs .tab-title>a:hover{background-color:#e1e1e1}.tabs dd.active a,.tabs .tab-title.active a{background-color:#fff;color:#222}.tabs.radius dd:first-child a,.tabs.radius .tab:first-child a{-webkit-border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-bottom-left-radius:3px;border-top-left-radius:3px}.tabs.radius dd:last-child a,.tabs.radius .tab:last-child a{-webkit-border-bottom-right-radius:3px;-webkit-border-top-right-radius:3px;border-bottom-right-radius:3px;border-top-right-radius:3px}.tabs.vertical dd,.tabs.vertical .tab-title{position:inherit;float:none;display:block;top:auto}.tabs-content{margin-bottom:1.5rem;width:100%}.tabs-content:before,.tabs-content:after{content:" ";display:table}.tabs-content:after{clear:both}.tabs-content>.content{display:none;float:left;padding:0.9375rem 0;width:100%}.tabs-content>.content.active{display:block;float:none}.tabs-content>.content.contained{padding:0.9375rem}.tabs-content.vertical{display:block}.tabs-content.vertical>.content{padding:0 0.9375rem}@media only screen and (min-width: 40.0625em){.tabs.vertical{float:left;margin:0;margin-bottom:1.25rem !important;max-width:20%;width:20%}.tabs-content.vertical{float:left;margin-left:-1px;max-width:80%;padding-left:1rem;width:80%}}.no-js .tabs-content>.content{display:block;float:none}ul.pagination{display:block;margin-left:-0.3125rem;min-height:1.5rem}ul.pagination li{color:#222;font-size:0.875rem;height:1.5rem;margin-left:0.3125rem}ul.pagination li a,ul.pagination li button{border-radius:3px;transition:background-color 300ms ease-out;background:none;color:#999;display:block;font-size:1em;font-weight:normal;line-height:inherit;padding:0.0625rem 0.625rem 0.0625rem}ul.pagination li:hover a,ul.pagination li a:focus,ul.pagination li:hover button,ul.pagination li button:focus{background:#e6e6e6}ul.pagination li.unavailable a,ul.pagination li.unavailable button{cursor:default;color:#999}ul.pagination li.unavailable:hover a,ul.pagination li.unavailable a:focus,ul.pagination li.unavailable:hover button,ul.pagination li.unavailable button:focus{background:transparent}ul.pagination li.current a,ul.pagination li.current button{background:#008CBA;color:#fff;cursor:default;font-weight:bold}ul.pagination li.current a:hover,ul.pagination li.current a:focus,ul.pagination li.current button:hover,ul.pagination li.current button:focus{background:#008CBA}ul.pagination li{display:block;float:left}.pagination-centered{text-align:center}.pagination-centered ul.pagination li{display:inline-block;float:none}.side-nav{display:block;font-family:"Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;list-style-position:outside;list-style-type:none;margin:0;padding:0.875rem 0}.side-nav li{font-size:0.875rem;font-weight:normal;margin:0 0 0.4375rem 0}.side-nav li a:not(.button){color:#008CBA;display:block;margin:0;padding:0.4375rem 0.875rem}.side-nav li a:not(.button):hover,.side-nav li a:not(.button):focus{background:rgba(0,0,0,0.025);color:#1cc7ff}.side-nav li a:not(.button):active{color:#1cc7ff}.side-nav li.active>a:first-child:not(.button){color:#1cc7ff;font-family:"Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;font-weight:normal}.side-nav li.divider{border-top:1px solid;height:0;list-style:none;padding:0;border-top-color:#e6e6e6}.side-nav li.heading{color:#008CBA;font-size:0.875rem;font-weight:bold;text-transform:uppercase}.accordion{margin-bottom:0}.accordion:before,.accordion:after{content:" ";display:table}.accordion:after{clear:both}.accordion .accordion-navigation,.accordion dd{display:block;margin-bottom:0 !important}.accordion .accordion-navigation.active>a,.accordion dd.active>a{background:#e8e8e8}.accordion .accordion-navigation>a,.accordion dd>a{background:#EFEFEF;color:#222;display:block;font-family:"Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;font-size:1rem;padding:1rem}.accordion .accordion-navigation>a:hover,.accordion dd>a:hover{background:#e3e3e3}.accordion .accordion-navigation>.content,.accordion dd>.content{display:none;padding:0.9375rem}.accordion .accordion-navigation>.content.active,.accordion dd>.content.active{background:#fff;display:block}.text-left{text-align:left !important}.text-right{text-align:right !important}.text-center{text-align:center !important}.text-justify{text-align:justify !important}@media only screen and (max-width: 40em){.small-only-text-left{text-align:left !important}.small-only-text-right{text-align:right !important}.small-only-text-center{text-align:center !important}.small-only-text-justify{text-align:justify !important}}@media only screen{.small-text-left{text-align:left !important}.small-text-right{text-align:right !important}.small-text-center{text-align:center !important}.small-text-justify{text-align:justify !important}}@media only screen and (min-width: 40.0625em) and (max-width: 64em){.medium-only-text-left{text-align:left !important}.medium-only-text-right{text-align:right !important}.medium-only-text-center{text-align:center !important}.medium-only-text-justify{text-align:justify !important}}@media only screen and (min-width: 40.0625em){.medium-text-left{text-align:left !important}.medium-text-right{text-align:right !important}.medium-text-center{text-align:center !important}.medium-text-justify{text-align:justify !important}}@media only screen and (min-width: 64.0625em) and (max-width: 90em){.large-only-text-left{text-align:left !important}.large-only-text-right{text-align:right !important}.large-only-text-center{text-align:center !important}.large-only-text-justify{text-align:justify !important}}@media only screen and (min-width: 64.0625em){.large-text-left{text-align:left !important}.large-text-right{text-align:right !important}.large-text-center{text-align:center !important}.large-text-justify{text-align:justify !important}}@media only screen and (min-width: 90.0625em) and (max-width: 120em){.xlarge-only-text-left{text-align:left !important}.xlarge-only-text-right{text-align:right !important}.xlarge-only-text-center{text-align:center !important}.xlarge-only-text-justify{text-align:justify !important}}@media only screen and (min-width: 90.0625em){.xlarge-text-left{text-align:left !important}.xlarge-text-right{text-align:right !important}.xlarge-text-center{text-align:center !important}.xlarge-text-justify{text-align:justify !important}}@media only screen and (min-width: 120.0625em) and (max-width: 6249999.9375em){.xxlarge-only-text-left{text-align:left !important}.xxlarge-only-text-right{text-align:right !important}.xxlarge-only-text-center{text-align:center !important}.xxlarge-only-text-justify{text-align:justify !important}}@media only screen and (min-width: 120.0625em){.xxlarge-text-left{text-align:left !important}.xxlarge-text-right{text-align:right !important}.xxlarge-text-center{text-align:center !important}.xxlarge-text-justify{text-align:justify !important}}div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0}a{color:#008CBA;line-height:inherit;text-decoration:none}a:hover,a:focus{color:#0078a0}a img{border:none}p{font-family:inherit;font-size:1rem;font-weight:normal;line-height:1.6;margin-bottom:1.25rem;text-rendering:optimizeLegibility}p.lead{font-size:1.21875rem;line-height:1.6}p aside{font-size:0.875rem;font-style:italic;line-height:1.35}h1,h2,h3,h4,h5,h6{color:#222;font-family:"Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;font-style:normal;font-weight:normal;line-height:1.4;margin-bottom:0.5rem;margin-top:0.2rem;text-rendering:optimizeLegibility}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{color:#6f6f6f;font-size:60%;line-height:0}h1{font-size:2.125rem}h2{font-size:1.6875rem}h3{font-size:1.375rem}h4{font-size:1.125rem}h5{font-size:1.125rem}h6{font-size:1rem}.subheader{line-height:1.4;color:#6f6f6f;font-weight:normal;margin-top:0.2rem;margin-bottom:0.5rem}hr{border:solid #ddd;border-width:1px 0 0;clear:both;height:0;margin:1.25rem 0 1.1875rem}em,i{font-style:italic;line-height:inherit}strong,b{font-weight:bold;line-height:inherit}small{font-size:60%;line-height:inherit}code{background-color:#f8f8f8;border-color:#dfdfdf;border-style:solid;border-width:1px;color:#333;font-family:Consolas,"Liberation Mono",Courier,monospace;font-weight:normal;padding:0.125rem 0.3125rem 0.0625rem}ul,ol,dl{font-family:inherit;font-size:1rem;line-height:1.6;list-style-position:outside;margin-bottom:1.25rem}ul{margin-left:1.1rem}ul.no-bullet{margin-left:0}ul.no-bullet li ul,ul.no-bullet li ol{margin-left:1.25rem;margin-bottom:0;list-style:none}ul li ul,ul li ol{margin-left:1.25rem;margin-bottom:0}ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}ul.square{list-style-type:square;margin-left:1.1rem}ul.circle{list-style-type:circle;margin-left:1.1rem}ul.disc{list-style-type:disc;margin-left:1.1rem}ul.no-bullet{list-style:none}ol{margin-left:1.4rem}ol li ul,ol li ol{margin-left:1.25rem;margin-bottom:0}dl dt{margin-bottom:0.3rem;font-weight:bold}dl dd{margin-bottom:0.75rem}abbr,acronym{text-transform:uppercase;font-size:90%;color:#222;cursor:help}abbr{text-transform:none}abbr[title]{border-bottom:1px dotted #ddd}blockquote{margin:0 0 1.25rem;padding:0.5625rem 1.25rem 0 1.1875rem;border-left:1px solid #ddd}blockquote cite{display:block;font-size:0.8125rem;color:#555}blockquote cite:before{content:"\2014 \0020"}blockquote cite a,blockquote cite a:visited{color:#555}blockquote,blockquote p{line-height:1.6;color:#6f6f6f}.vcard{display:inline-block;margin:0 0 1.25rem 0;border:1px solid #ddd;padding:0.625rem 0.75rem}.vcard li{margin:0;display:block}.vcard .fn{font-weight:bold;font-size:0.9375rem}.vevent .summary{font-weight:bold}.vevent abbr{cursor:default;text-decoration:none;font-weight:bold;border:none;padding:0 0.0625rem}@media only screen and (min-width: 40.0625em){h1,h2,h3,h4,h5,h6{line-height:1.4}h1{font-size:2.75rem}h2{font-size:2.3125rem}h3{font-size:1.6875rem}h4{font-size:1.4375rem}h5{font-size:1.125rem}h6{font-size:1rem}}.split.button{position:relative;padding-right:5.0625rem}.split.button span{display:block;height:100%;position:absolute;right:0;top:0;border-left:solid 1px}.split.button span:after{position:absolute;content:"";width:0;height:0;display:block;border-style:inset;top:50%;left:50%}.split.button span:active{background-color:rgba(0,0,0,0.1)}.split.button span{border-left-color:rgba(255,255,255,0.5)}.split.button span{width:3.09375rem}.split.button span:after{border-top-style:solid;border-width:0.375rem;margin-left:-0.375rem;top:48%}.split.button span:after{border-color:#fff transparent transparent transparent}.split.button.secondary span{border-left-color:rgba(255,255,255,0.5)}.split.button.secondary span:after{border-color:#fff transparent transparent transparent}.split.button.alert span{border-left-color:rgba(255,255,255,0.5)}.split.button.success span{border-left-color:rgba(255,255,255,0.5)}.split.button.tiny{padding-right:3.75rem}.split.button.tiny span{width:2.25rem}.split.button.tiny span:after{border-top-style:solid;border-width:0.375rem;margin-left:-0.375rem;top:48%}.split.button.small{padding-right:4.375rem}.split.button.small span{width:2.625rem}.split.button.small span:after{border-top-style:solid;border-width:0.4375rem;margin-left:-0.375rem;top:48%}.split.button.large{padding-right:5.5rem}.split.button.large span{width:3.4375rem}.split.button.large span:after{border-top-style:solid;border-width:0.3125rem;margin-left:-0.375rem;top:48%}.split.button.expand{padding-left:2rem}.split.button.secondary span:after{border-color:#333 transparent transparent transparent}.split.button.radius span{-webkit-border-bottom-right-radius:3px;-webkit-border-top-right-radius:3px;border-bottom-right-radius:3px;border-top-right-radius:3px}.split.button.round span{-webkit-border-bottom-right-radius:1000px;-webkit-border-top-right-radius:1000px;border-bottom-right-radius:1000px;border-top-right-radius:1000px}.split.button.no-pip span:before{border-style:none}.split.button.no-pip span:after{border-style:none}.split.button.no-pip span>i{display:block;left:50%;margin-left:-0.28889em;margin-top:-0.48889em;position:absolute;top:50%}.reveal-modal-bg{background:#000;background:rgba(0,0,0,0.45);bottom:0;display:none;left:0;position:fixed;right:0;top:0;z-index:1004;left:0}.reveal-modal{border-radius:3px;display:none;position:absolute;top:0;visibility:hidden;width:100%;z-index:1005;left:0;background-color:#fff;padding:1.875rem;border:solid 1px #666;box-shadow:0 0 10px rgba(0,0,0,0.4)}@media only screen and (max-width: 40em){.reveal-modal{min-height:100vh}}.reveal-modal .column,.reveal-modal .columns{min-width:0}.reveal-modal>:first-child{margin-top:0}.reveal-modal>:last-child{margin-bottom:0}@media only screen and (min-width: 40.0625em){.reveal-modal{left:0;margin:0 auto;max-width:62.5rem;right:0;width:80%}}@media only screen and (min-width: 40.0625em){.reveal-modal{top:6.25rem}}.reveal-modal.radius{border-radius:3px}.reveal-modal.round{border-radius:1000px}.reveal-modal.collapse{padding:0}@media only screen and (min-width: 40.0625em){.reveal-modal.tiny{left:0;margin:0 auto;max-width:62.5rem;right:0;width:30%}}@media only screen and (min-width: 40.0625em){.reveal-modal.small{left:0;margin:0 auto;max-width:62.5rem;right:0;width:40%}}@media only screen and (min-width: 40.0625em){.reveal-modal.medium{left:0;margin:0 auto;max-width:62.5rem;right:0;width:60%}}@media only screen and (min-width: 40.0625em){.reveal-modal.large{left:0;margin:0 auto;max-width:62.5rem;right:0;width:70%}}@media only screen and (min-width: 40.0625em){.reveal-modal.xlarge{left:0;margin:0 auto;max-width:62.5rem;right:0;width:95%}}.reveal-modal.full{height:100vh;height:100%;left:0;margin-left:0 !important;max-width:none !important;min-height:100vh;top:0}@media only screen and (min-width: 40.0625em){.reveal-modal.full{left:0;margin:0 auto;max-width:62.5rem;right:0;width:100%}}.reveal-modal.toback{z-index:1003}.reveal-modal .close-reveal-modal{color:#aaa;cursor:pointer;font-size:2.5rem;font-weight:bold;line-height:1;position:absolute;top:0.625rem;right:1.375rem}.has-tip{border-bottom:dotted 1px #ccc;color:#333;cursor:help;font-weight:bold}.has-tip:hover,.has-tip:focus{border-bottom:dotted 1px #003f54;color:#008CBA}.has-tip.tip-left,.has-tip.tip-right{float:none !important}.tooltip{background:#333;color:#fff;display:none;font-size:0.875rem;font-weight:normal;line-height:1.3;max-width:300px;padding:0.75rem;position:absolute;width:100%;z-index:1006;left:50%}.tooltip>.nub{border-color:transparent transparent #333 transparent;border:solid 5px;display:block;height:0;pointer-events:none;position:absolute;top:-10px;width:0;left:5px}.tooltip>.nub.rtl{left:auto;right:5px}.tooltip.radius{border-radius:3px}.tooltip.round{border-radius:1000px}.tooltip.round>.nub{left:2rem}.tooltip.opened{border-bottom:dotted 1px #003f54 !important;color:#008CBA !important}.tap-to-close{color:#777;display:block;font-size:0.625rem;font-weight:normal}@media only screen and (min-width: 40.0625em){.tooltip>.nub{border-color:transparent transparent #333 transparent;top:-10px}.tooltip.tip-top>.nub{border-color:#333 transparent transparent transparent;bottom:-10px;top:auto}.tooltip.tip-left,.tooltip.tip-right{float:none !important}.tooltip.tip-left>.nub{border-color:transparent transparent transparent #333;left:auto;margin-top:-5px;right:-10px;top:50%}.tooltip.tip-right>.nub{border-color:transparent #333 transparent transparent;left:-10px;margin-top:-5px;right:auto;top:50%}}.clearing-thumbs,[data-clearing]{list-style:none;margin-left:0;margin-bottom:0}.clearing-thumbs:before,.clearing-thumbs:after,[data-clearing]:before,[data-clearing]:after{content:" ";display:table}.clearing-thumbs:after,[data-clearing]:after{clear:both}.clearing-thumbs li,[data-clearing] li{float:left;margin-right:10px}.clearing-thumbs[class*="block-grid-"] li,[data-clearing][class*="block-grid-"] li{margin-right:0}.clearing-blackout{background:#333;height:100%;position:fixed;top:0;width:100%;z-index:998;left:0}.clearing-blackout .clearing-close{display:block}.clearing-container{height:100%;margin:0;overflow:hidden;position:relative;z-index:998}.clearing-touch-label{color:#aaa;font-size:.6em;left:50%;position:absolute;top:50%}.visible-img{height:95%;position:relative}.visible-img img{position:absolute;left:50%;top:50%;-webkit-transform:translateY(-50%) translateX(-50%);-moz-transform:translateY(-50%) translateX(-50%);-ms-transform:translateY(-50%) translateX(-50%);-o-transform:translateY(-50%) translateX(-50%);transform:translateY(-50%) translateX(-50%);max-height:100%;max-width:100%}.clearing-caption{background:#333;bottom:0;color:#ccc;font-size:0.875em;line-height:1.3;margin-bottom:0;padding:10px 30px 20px;position:absolute;text-align:center;width:100%;left:0}.clearing-close{color:#ccc;display:none;font-size:30px;line-height:1;padding-left:20px;padding-top:10px;z-index:999}.clearing-close:hover,.clearing-close:focus{color:#ccc}.clearing-assembled .clearing-container{height:100%}.clearing-assembled .clearing-container .carousel>ul{display:none}.clearing-feature li{display:none}.clearing-feature li.clearing-featured-img{display:block}@media only screen and (min-width: 40.0625em){.clearing-main-prev,.clearing-main-next{height:100%;position:absolute;top:0;width:40px}.clearing-main-prev>span,.clearing-main-next>span{border:solid 12px;display:block;height:0;position:absolute;top:50%;width:0}.clearing-main-prev>span:hover,.clearing-main-next>span:hover{opacity:.8}.clearing-main-prev{left:0}.clearing-main-prev>span{left:5px;border-color:transparent;border-right-color:#ccc}.clearing-main-next{right:0}.clearing-main-next>span{border-color:transparent;border-left-color:#ccc}.clearing-main-prev.disabled,.clearing-main-next.disabled{opacity:.3}.clearing-assembled .clearing-container .carousel{background:rgba(51,51,51,0.8);height:120px;margin-top:10px;text-align:center}.clearing-assembled .clearing-container .carousel>ul{display:inline-block;z-index:999;height:100%;position:relative;float:none}.clearing-assembled .clearing-container .carousel>ul li{clear:none;cursor:pointer;display:block;float:left;margin-right:0;min-height:inherit;opacity:.4;overflow:hidden;padding:0;position:relative;width:120px}.clearing-assembled .clearing-container .carousel>ul li.fix-height img{height:100%;max-width:none}.clearing-assembled .clearing-container .carousel>ul li a.th{border:none;box-shadow:none;display:block}.clearing-assembled .clearing-container .carousel>ul li img{cursor:pointer !important;width:100% !important}.clearing-assembled .clearing-container .carousel>ul li.visible{opacity:1}.clearing-assembled .clearing-container .carousel>ul li:hover{opacity:.8}.clearing-assembled .clearing-container .visible-img{background:#333;height:85%;overflow:hidden}.clearing-close{padding-left:0;padding-top:0;position:absolute;top:10px;right:20px}}.progress{background-color:#F6F6F6;border:1px solid #fff;height:1.5625rem;margin-bottom:0.625rem;padding:0.125rem}.progress .meter{background:#008CBA;display:block;height:100%}.progress.secondary .meter{background:#e7e7e7;display:block;height:100%}.progress.success .meter{background:#43AC6A;display:block;height:100%}.progress.alert .meter{background:#f04124;display:block;height:100%}.progress.radius{border-radius:3px}.progress.radius .meter{border-radius:2px}.progress.round{border-radius:1000px}.progress.round .meter{border-radius:999px}.sub-nav{display:block;margin:-0.25rem 0 1.125rem;overflow:hidden;padding-top:0.25rem;width:auto}.sub-nav dt{text-transform:uppercase}.sub-nav dt,.sub-nav dd,.sub-nav li{color:#999;float:left;font-family:"Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;font-size:0.875rem;font-weight:normal;margin-left:1rem;margin-bottom:0}.sub-nav dt a,.sub-nav dd a,.sub-nav li a{color:#999;padding:0.1875rem 1rem;text-decoration:none}.sub-nav dt a:hover,.sub-nav dd a:hover,.sub-nav li a:hover{color:#737373}.sub-nav dt.active a,.sub-nav dd.active a,.sub-nav li.active a{border-radius:3px;background:#008CBA;color:#fff;cursor:default;font-weight:normal;padding:0.1875rem 1rem}.sub-nav dt.active a:hover,.sub-nav dd.active a:hover,.sub-nav li.active a:hover{background:#0078a0}.joyride-list{display:none}.joyride-tip-guide{background:#333;color:#fff;display:none;font-family:inherit;font-weight:normal;position:absolute;top:0;width:95%;z-index:101;left:2.5%}.lt-ie9 .joyride-tip-guide{margin-left:-400px;max-width:800px;left:50%}.joyride-content-wrapper{padding:1.125rem 1.25rem 1.5rem;width:100%}.joyride-content-wrapper .button{margin-bottom:0 !important}.joyride-content-wrapper .joyride-prev-tip{margin-right:10px}.joyride-tip-guide .joyride-nub{border:10px solid #333;display:block;height:0;position:absolute;width:0;left:22px}.joyride-tip-guide .joyride-nub.top{border-color:#333;border-top-color:transparent !important;border-top-style:solid;border-left-color:transparent !important;border-right-color:transparent !important;top:-20px}.joyride-tip-guide .joyride-nub.bottom{border-color:#333 !important;border-bottom-color:transparent !important;border-bottom-style:solid;border-left-color:transparent !important;border-right-color:transparent !important;bottom:-20px}.joyride-tip-guide .joyride-nub.right{right:-20px}.joyride-tip-guide .joyride-nub.left{left:-20px}.joyride-tip-guide h1,.joyride-tip-guide h2,.joyride-tip-guide h3,.joyride-tip-guide h4,.joyride-tip-guide h5,.joyride-tip-guide h6{color:#fff;font-weight:bold;line-height:1.25;margin:0}.joyride-tip-guide p{font-size:0.875rem;line-height:1.3;margin:0 0 1.125rem 0}.joyride-timer-indicator-wrap{border:solid 1px #555;bottom:1rem;height:3px;position:absolute;width:50px;right:1.0625rem}.joyride-timer-indicator{background:#666;display:block;height:inherit;width:0}.joyride-close-tip{color:#777 !important;font-size:24px;font-weight:normal;line-height:.5 !important;position:absolute;text-decoration:none;top:10px;right:12px}.joyride-close-tip:hover,.joyride-close-tip:focus{color:#eee !important}.joyride-modal-bg{background:rgba(0,0,0,0.5);cursor:pointer;display:none;height:100%;position:fixed;top:0;width:100%;z-index:100;left:0}.joyride-expose-wrapper{background-color:#fff;border-radius:3px;box-shadow:0 0 15px #fff;position:absolute;z-index:102}.joyride-expose-cover{background:transparent;border-radius:3px;left:0;position:absolute;top:0;z-index:9999}@media only screen and (min-width: 40.0625em){.joyride-tip-guide{width:300px;left:inherit}.joyride-tip-guide .joyride-nub.bottom{border-color:#333 !important;border-bottom-color:transparent !important;border-left-color:transparent !important;border-right-color:transparent !important;bottom:-20px}.joyride-tip-guide .joyride-nub.right{border-color:#333 !important;border-right-color:transparent !important;border-bottom-color:transparent !important;border-top-color:transparent !important;left:auto;right:-20px;top:22px}.joyride-tip-guide .joyride-nub.left{border-color:#333 !important;border-bottom-color:transparent !important;border-left-color:transparent !important;border-top-color:transparent !important;left:-20px;right:auto;top:22px}}.label{display:inline-block;font-family:"Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;font-weight:normal;line-height:1;margin-bottom:auto;position:relative;text-align:center;text-decoration:none;white-space:nowrap;padding:0.25rem 0.5rem 0.25rem;font-size:0.6875rem;background-color:#008CBA;color:#fff}.label.radius{border-radius:3px}.label.round{border-radius:1000px}.label.alert{background-color:#f04124;color:#fff}.label.warning{background-color:#f08a24;color:#fff}.label.success{background-color:#43AC6A;color:#fff}.label.secondary{background-color:#e7e7e7;color:#333}.label.info{background-color:#a0d3e8;color:#333}.off-canvas-wrap{-webkit-backface-visibility:hidden;position:relative;width:100%;overflow:hidden}.off-canvas-wrap.move-right,.off-canvas-wrap.move-left{min-height:100%;-webkit-overflow-scrolling:touch}.inner-wrap{position:relative;width:100%;-webkit-transition:-webkit-transform 500ms ease;-moz-transition:-moz-transform 500ms ease;-ms-transition:-ms-transform 500ms ease;-o-transition:-o-transform 500ms ease;transition:transform 500ms ease}.inner-wrap:before,.inner-wrap:after{content:" ";display:table}.inner-wrap:after{clear:both}.tab-bar{-webkit-backface-visibility:hidden;background:#333;color:#fff;height:2.8125rem;line-height:2.8125rem;position:relative}.tab-bar h1,.tab-bar h2,.tab-bar h3,.tab-bar h4,.tab-bar h5,.tab-bar h6{color:#fff;font-weight:bold;line-height:2.8125rem;margin:0}.tab-bar h1,.tab-bar h2,.tab-bar h3,.tab-bar h4{font-size:1.125rem}.left-small{height:2.8125rem;position:absolute;top:0;width:2.8125rem;border-right:solid 1px #1a1a1a;left:0}.right-small{height:2.8125rem;position:absolute;top:0;width:2.8125rem;border-left:solid 1px #1a1a1a;right:0}.tab-bar-section{height:2.8125rem;padding:0 0.625rem;position:absolute;text-align:center;top:0}.tab-bar-section.left{text-align:left}.tab-bar-section.right{text-align:right}.tab-bar-section.left{left:0;right:2.8125rem}.tab-bar-section.right{left:2.8125rem;right:0}.tab-bar-section.middle{left:2.8125rem;right:2.8125rem}.tab-bar .menu-icon{color:#fff;display:block;height:2.8125rem;padding:0;position:relative;text-indent:2.1875rem;transform:translate3d(0, 0, 0);width:2.8125rem}.tab-bar .menu-icon span::after{content:"";display:block;height:0;position:absolute;top:50%;margin-top:-0.5rem;left:0.90625rem;box-shadow:0 0 0 1px #fff,0 7px 0 1px #fff,0 14px 0 1px #fff;width:1rem}.tab-bar .menu-icon span:hover:after{box-shadow:0 0 0 1px #b3b3b3,0 7px 0 1px #b3b3b3,0 14px 0 1px #b3b3b3}.left-off-canvas-menu{-webkit-backface-visibility:hidden;background:#333;bottom:0;box-sizing:content-box;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;overflow-x:hidden;overflow-y:auto;position:absolute;top:0;transition:transform 500ms ease 0s;width:15.625rem;z-index:1001;-webkit-transform:translate3d(-100%, 0, 0);-moz-transform:translate3d(-100%, 0, 0);-ms-transform:translate(-100%, 0);-ms-transform:translate3d(-100%, 0, 0);-o-transform:translate3d(-100%, 0, 0);transform:translate3d(-100%, 0, 0);left:0}.left-off-canvas-menu *{-webkit-backface-visibility:hidden}.right-off-canvas-menu{-webkit-backface-visibility:hidden;background:#333;bottom:0;box-sizing:content-box;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;overflow-x:hidden;overflow-y:auto;position:absolute;top:0;transition:transform 500ms ease 0s;width:15.625rem;z-index:1001;-webkit-transform:translate3d(100%, 0, 0);-moz-transform:translate3d(100%, 0, 0);-ms-transform:translate(100%, 0);-ms-transform:translate3d(100%, 0, 0);-o-transform:translate3d(100%, 0, 0);transform:translate3d(100%, 0, 0);right:0}.right-off-canvas-menu *{-webkit-backface-visibility:hidden}ul.off-canvas-list{list-style-type:none;margin:0;padding:0}ul.off-canvas-list li label{background:#444;border-bottom:none;border-top:1px solid #5e5e5e;color:#999;display:block;font-size:0.75rem;font-weight:bold;margin:0;padding:0.3rem 0.9375rem;text-transform:uppercase}ul.off-canvas-list li a{border-bottom:1px solid #262626;color:rgba(255,255,255,0.7);display:block;padding:0.66667rem;transition:background 300ms ease}ul.off-canvas-list li a:hover{background:#242424}ul.off-canvas-list li a:active{background:#242424}.move-right>.inner-wrap{-webkit-transform:translate3d(15.625rem, 0, 0);-moz-transform:translate3d(15.625rem, 0, 0);-ms-transform:translate(15.625rem, 0);-ms-transform:translate3d(15.625rem, 0, 0);-o-transform:translate3d(15.625rem, 0, 0);transform:translate3d(15.625rem, 0, 0)}.move-right .exit-off-canvas{-webkit-backface-visibility:hidden;box-shadow:-4px 0 4px rgba(0,0,0,0.5),4px 0 4px rgba(0,0,0,0.5);cursor:pointer;transition:background 300ms ease;-webkit-tap-highlight-color:transparent;background:rgba(255,255,255,0.2);bottom:0;display:block;left:0;position:absolute;right:0;top:0;z-index:1002}@media only screen and (min-width: 40.0625em){.move-right .exit-off-canvas:hover{background:rgba(255,255,255,0.05)}}.move-left>.inner-wrap{-webkit-transform:translate3d(-15.625rem, 0, 0);-moz-transform:translate3d(-15.625rem, 0, 0);-ms-transform:translate(-15.625rem, 0);-ms-transform:translate3d(-15.625rem, 0, 0);-o-transform:translate3d(-15.625rem, 0, 0);transform:translate3d(-15.625rem, 0, 0)}.move-left .exit-off-canvas{-webkit-backface-visibility:hidden;box-shadow:-4px 0 4px rgba(0,0,0,0.5),4px 0 4px rgba(0,0,0,0.5);cursor:pointer;transition:background 300ms ease;-webkit-tap-highlight-color:transparent;background:rgba(255,255,255,0.2);bottom:0;display:block;left:0;position:absolute;right:0;top:0;z-index:1002}@media only screen and (min-width: 40.0625em){.move-left .exit-off-canvas:hover{background:rgba(255,255,255,0.05)}}.offcanvas-overlap .left-off-canvas-menu,.offcanvas-overlap .right-off-canvas-menu{-ms-transform:none;-webkit-transform:none;-moz-transform:none;-o-transform:none;transform:none;z-index:1003}.offcanvas-overlap .exit-off-canvas{-webkit-backface-visibility:hidden;box-shadow:-4px 0 4px rgba(0,0,0,0.5),4px 0 4px rgba(0,0,0,0.5);cursor:pointer;transition:background 300ms ease;-webkit-tap-highlight-color:transparent;background:rgba(255,255,255,0.2);bottom:0;display:block;left:0;position:absolute;right:0;top:0;z-index:1002}@media only screen and (min-width: 40.0625em){.offcanvas-overlap .exit-off-canvas:hover{background:rgba(255,255,255,0.05)}}.offcanvas-overlap-left .right-off-canvas-menu{-ms-transform:none;-webkit-transform:none;-moz-transform:none;-o-transform:none;transform:none;z-index:1003}.offcanvas-overlap-left .exit-off-canvas{-webkit-backface-visibility:hidden;box-shadow:-4px 0 4px rgba(0,0,0,0.5),4px 0 4px rgba(0,0,0,0.5);cursor:pointer;transition:background 300ms ease;-webkit-tap-highlight-color:transparent;background:rgba(255,255,255,0.2);bottom:0;display:block;left:0;position:absolute;right:0;top:0;z-index:1002}@media only screen and (min-width: 40.0625em){.offcanvas-overlap-left .exit-off-canvas:hover{background:rgba(255,255,255,0.05)}}.offcanvas-overlap-right .left-off-canvas-menu{-ms-transform:none;-webkit-transform:none;-moz-transform:none;-o-transform:none;transform:none;z-index:1003}.offcanvas-overlap-right .exit-off-canvas{-webkit-backface-visibility:hidden;box-shadow:-4px 0 4px rgba(0,0,0,0.5),4px 0 4px rgba(0,0,0,0.5);cursor:pointer;transition:background 300ms ease;-webkit-tap-highlight-color:transparent;background:rgba(255,255,255,0.2);bottom:0;display:block;left:0;position:absolute;right:0;top:0;z-index:1002}@media only screen and (min-width: 40.0625em){.offcanvas-overlap-right .exit-off-canvas:hover{background:rgba(255,255,255,0.05)}}.no-csstransforms .left-off-canvas-menu{left:-15.625rem}.no-csstransforms .right-off-canvas-menu{right:-15.625rem}.no-csstransforms .move-left>.inner-wrap{right:15.625rem}.no-csstransforms .move-right>.inner-wrap{left:15.625rem}.left-submenu{-webkit-backface-visibility:hidden;-webkit-overflow-scrolling:touch;background:#333;bottom:0;box-sizing:content-box;margin:0;overflow-x:hidden;overflow-y:auto;position:absolute;top:0;width:15.625rem;z-index:1002;-webkit-transform:translate3d(-100%, 0, 0);-moz-transform:translate3d(-100%, 0, 0);-ms-transform:translate(-100%, 0);-ms-transform:translate3d(-100%, 0, 0);-o-transform:translate3d(-100%, 0, 0);transform:translate3d(-100%, 0, 0);left:0;-webkit-transition:-webkit-transform 500ms ease;-moz-transition:-moz-transform 500ms ease;-ms-transition:-ms-transform 500ms ease;-o-transition:-o-transform 500ms ease;transition:transform 500ms ease}.left-submenu *{-webkit-backface-visibility:hidden}.left-submenu .back>a{background:#444;border-bottom:none;border-top:1px solid #5e5e5e;color:#999;font-weight:bold;padding:0.3rem 0.9375rem;text-transform:uppercase;margin:0}.left-submenu .back>a:hover{background:#303030;border-bottom:none;border-top:1px solid #5e5e5e}.left-submenu .back>a:before{content:"\AB";margin-right:.5rem;display:inline}.left-submenu.move-right,.left-submenu.offcanvas-overlap-right,.left-submenu.offcanvas-overlap{-webkit-transform:translate3d(0%, 0, 0);-moz-transform:translate3d(0%, 0, 0);-ms-transform:translate(0%, 0);-ms-transform:translate3d(0%, 0, 0);-o-transform:translate3d(0%, 0, 0);transform:translate3d(0%, 0, 0)}.right-submenu{-webkit-backface-visibility:hidden;-webkit-overflow-scrolling:touch;background:#333;bottom:0;box-sizing:content-box;margin:0;overflow-x:hidden;overflow-y:auto;position:absolute;top:0;width:15.625rem;z-index:1002;-webkit-transform:translate3d(100%, 0, 0);-moz-transform:translate3d(100%, 0, 0);-ms-transform:translate(100%, 0);-ms-transform:translate3d(100%, 0, 0);-o-transform:translate3d(100%, 0, 0);transform:translate3d(100%, 0, 0);right:0;-webkit-transition:-webkit-transform 500ms ease;-moz-transition:-moz-transform 500ms ease;-ms-transition:-ms-transform 500ms ease;-o-transition:-o-transform 500ms ease;transition:transform 500ms ease}.right-submenu *{-webkit-backface-visibility:hidden}.right-submenu .back>a{background:#444;border-bottom:none;border-top:1px solid #5e5e5e;color:#999;font-weight:bold;padding:0.3rem 0.9375rem;text-transform:uppercase;margin:0}.right-submenu .back>a:hover{background:#303030;border-bottom:none;border-top:1px solid #5e5e5e}.right-submenu .back>a:after{content:"\BB";margin-left:.5rem;display:inline}.right-submenu.move-left,.right-submenu.offcanvas-overlap-left,.right-submenu.offcanvas-overlap{-webkit-transform:translate3d(0%, 0, 0);-moz-transform:translate3d(0%, 0, 0);-ms-transform:translate(0%, 0);-ms-transform:translate3d(0%, 0, 0);-o-transform:translate3d(0%, 0, 0);transform:translate3d(0%, 0, 0)}.left-off-canvas-menu ul.off-canvas-list li.has-submenu>a:after{content:"\BB";margin-left:.5rem;display:inline}.right-off-canvas-menu ul.off-canvas-list li.has-submenu>a:before{content:"\AB";margin-right:.5rem;display:inline}.f-dropdown{display:none;left:-9999px;list-style:none;margin-left:0;position:absolute;background:#fff;border:solid 1px #ccc;font-size:0.875rem;height:auto;max-height:none;width:100%;z-index:89;margin-top:2px;max-width:200px}.f-dropdown.open{display:block}.f-dropdown>*:first-child{margin-top:0}.f-dropdown>*:last-child{margin-bottom:0}.f-dropdown:before{border:inset 6px;content:"";display:block;height:0;width:0;border-color:transparent transparent #fff transparent;border-bottom-style:solid;position:absolute;top:-12px;left:10px;z-index:89}.f-dropdown:after{border:inset 7px;content:"";display:block;height:0;width:0;border-color:transparent transparent #ccc transparent;border-bottom-style:solid;position:absolute;top:-14px;left:9px;z-index:88}.f-dropdown.right:before{left:auto;right:10px}.f-dropdown.right:after{left:auto;right:9px}.f-dropdown.drop-right{display:none;left:-9999px;list-style:none;margin-left:0;position:absolute;background:#fff;border:solid 1px #ccc;font-size:0.875rem;height:auto;max-height:none;width:100%;z-index:89;margin-top:0;margin-left:2px;max-width:200px}.f-dropdown.drop-right.open{display:block}.f-dropdown.drop-right>*:first-child{margin-top:0}.f-dropdown.drop-right>*:last-child{margin-bottom:0}.f-dropdown.drop-right:before{border:inset 6px;content:"";display:block;height:0;width:0;border-color:transparent #fff transparent transparent;border-right-style:solid;position:absolute;top:10px;left:-12px;z-index:89}.f-dropdown.drop-right:after{border:inset 7px;content:"";display:block;height:0;width:0;border-color:transparent #ccc transparent transparent;border-right-style:solid;position:absolute;top:9px;left:-14px;z-index:88}.f-dropdown.drop-left{display:none;left:-9999px;list-style:none;margin-left:0;position:absolute;background:#fff;border:solid 1px #ccc;font-size:0.875rem;height:auto;max-height:none;width:100%;z-index:89;margin-top:0;margin-left:-2px;max-width:200px}.f-dropdown.drop-left.open{display:block}.f-dropdown.drop-left>*:first-child{margin-top:0}.f-dropdown.drop-left>*:last-child{margin-bottom:0}.f-dropdown.drop-left:before{border:inset 6px;content:"";display:block;height:0;width:0;border-color:transparent transparent transparent #fff;border-left-style:solid;position:absolute;top:10px;right:-12px;left:auto;z-index:89}.f-dropdown.drop-left:after{border:inset 7px;content:"";display:block;height:0;width:0;border-color:transparent transparent transparent #ccc;border-left-style:solid;position:absolute;top:9px;right:-14px;left:auto;z-index:88}.f-dropdown.drop-top{display:none;left:-9999px;list-style:none;margin-left:0;position:absolute;background:#fff;border:solid 1px #ccc;font-size:0.875rem;height:auto;max-height:none;width:100%;z-index:89;margin-left:0;margin-top:-2px;max-width:200px}.f-dropdown.drop-top.open{display:block}.f-dropdown.drop-top>*:first-child{margin-top:0}.f-dropdown.drop-top>*:last-child{margin-bottom:0}.f-dropdown.drop-top:before{border:inset 6px;content:"";display:block;height:0;width:0;border-color:#fff transparent transparent transparent;border-top-style:solid;bottom:-12px;position:absolute;top:auto;left:10px;right:auto;z-index:89}.f-dropdown.drop-top:after{border:inset 7px;content:"";display:block;height:0;width:0;border-color:#ccc transparent transparent transparent;border-top-style:solid;bottom:-14px;position:absolute;top:auto;left:9px;right:auto;z-index:88}.f-dropdown li{cursor:pointer;font-size:0.875rem;line-height:1.125rem;margin:0}.f-dropdown li:hover,.f-dropdown li:focus{background:#eee}.f-dropdown li.radius{border-radius:3px}.f-dropdown li a{display:block;padding:0.5rem;color:#555}.f-dropdown.content{display:none;left:-9999px;list-style:none;margin-left:0;position:absolute;background:#fff;border:solid 1px #ccc;font-size:0.875rem;height:auto;max-height:none;padding:1.25rem;width:100%;z-index:89;max-width:200px}.f-dropdown.content.open{display:block}.f-dropdown.content>*:first-child{margin-top:0}.f-dropdown.content>*:last-child{margin-bottom:0}.f-dropdown.tiny{max-width:200px}.f-dropdown.small{max-width:300px}.f-dropdown.medium{max-width:500px}.f-dropdown.large{max-width:800px}.f-dropdown.mega{width:100% !important;max-width:100% !important}.f-dropdown.mega.open{left:0 !important}table{background:#fff;border:solid 1px #ddd;margin-bottom:1.25rem;table-layout:auto}table caption{background:transparent;color:#222;font-size:1rem;font-weight:bold}table thead{background:#F5F5F5}table thead tr th,table thead tr td{color:#222;font-size:0.875rem;font-weight:bold;padding:0.5rem 0.625rem 0.625rem}table tfoot{background:#F5F5F5}table tfoot tr th,table tfoot tr td{color:#222;font-size:0.875rem;font-weight:bold;padding:0.5rem 0.625rem 0.625rem}table tr th,table tr td{color:#222;font-size:0.875rem;padding:0.5625rem 0.625rem;text-align:left}table tr.even,table tr.alt,table tr:nth-of-type(even){background:#F9F9F9}table thead tr th,table tfoot tr th,table tfoot tr td,table tbody tr th,table tbody tr td,table tr td{display:table-cell;line-height:1.125rem}.range-slider{border:1px solid #ddd;margin:1.25rem 0;position:relative;-ms-touch-action:none;touch-action:none;display:block;height:1rem;width:100%;background:#FAFAFA}.range-slider.vertical-range{border:1px solid #ddd;margin:1.25rem 0;position:relative;-ms-touch-action:none;touch-action:none;display:inline-block;height:12.5rem;width:1rem}.range-slider.vertical-range .range-slider-handle{bottom:-10.5rem;margin-left:-0.5rem;margin-top:0;position:absolute}.range-slider.vertical-range .range-slider-active-segment{border-bottom-left-radius:inherit;border-bottom-right-radius:inherit;border-top-left-radius:initial;bottom:0;height:auto;width:0.875rem}.range-slider.radius{background:#FAFAFA;border-radius:3px}.range-slider.radius .range-slider-handle{background:#008CBA;border-radius:3px}.range-slider.radius .range-slider-handle:hover{background:#007ba4}.range-slider.round{background:#FAFAFA;border-radius:1000px}.range-slider.round .range-slider-handle{background:#008CBA;border-radius:1000px}.range-slider.round .range-slider-handle:hover{background:#007ba4}.range-slider.disabled,.range-slider[disabled]{background:#FAFAFA;cursor:not-allowed;opacity:0.7}.range-slider.disabled .range-slider-handle,.range-slider[disabled] .range-slider-handle{background:#008CBA;cursor:default;opacity:0.7}.range-slider.disabled .range-slider-handle:hover,.range-slider[disabled] .range-slider-handle:hover{background:#007ba4}.range-slider-active-segment{background:#e5e5e5;border-bottom-left-radius:inherit;border-top-left-radius:inherit;display:inline-block;height:0.875rem;position:absolute}.range-slider-handle{border:1px solid none;cursor:pointer;display:inline-block;height:1.375rem;position:absolute;top:-0.3125rem;width:2rem;z-index:1;-ms-touch-action:manipulation;touch-action:manipulation;background:#008CBA}.range-slider-handle:hover{background:#007ba4}[class*="block-grid-"]{display:block;padding:0;margin:0 -0.625rem}[class*="block-grid-"]:before,[class*="block-grid-"]:after{content:" ";display:table}[class*="block-grid-"]:after{clear:both}[class*="block-grid-"]>li{display:block;float:left;height:auto;padding:0 0.625rem 1.25rem}@media only screen{.small-block-grid-1>li{list-style:none;width:100%}.small-block-grid-1>li:nth-of-type(1n){clear:none}.small-block-grid-1>li:nth-of-type(1n+1){clear:both}.small-block-grid-2>li{list-style:none;width:50%}.small-block-grid-2>li:nth-of-type(1n){clear:none}.small-block-grid-2>li:nth-of-type(2n+1){clear:both}.small-block-grid-3>li{list-style:none;width:33.33333%}.small-block-grid-3>li:nth-of-type(1n){clear:none}.small-block-grid-3>li:nth-of-type(3n+1){clear:both}.small-block-grid-4>li{list-style:none;width:25%}.small-block-grid-4>li:nth-of-type(1n){clear:none}.small-block-grid-4>li:nth-of-type(4n+1){clear:both}.small-block-grid-5>li{list-style:none;width:20%}.small-block-grid-5>li:nth-of-type(1n){clear:none}.small-block-grid-5>li:nth-of-type(5n+1){clear:both}.small-block-grid-6>li{list-style:none;width:16.66667%}.small-block-grid-6>li:nth-of-type(1n){clear:none}.small-block-grid-6>li:nth-of-type(6n+1){clear:both}.small-block-grid-7>li{list-style:none;width:14.28571%}.small-block-grid-7>li:nth-of-type(1n){clear:none}.small-block-grid-7>li:nth-of-type(7n+1){clear:both}.small-block-grid-8>li{list-style:none;width:12.5%}.small-block-grid-8>li:nth-of-type(1n){clear:none}.small-block-grid-8>li:nth-of-type(8n+1){clear:both}.small-block-grid-9>li{list-style:none;width:11.11111%}.small-block-grid-9>li:nth-of-type(1n){clear:none}.small-block-grid-9>li:nth-of-type(9n+1){clear:both}.small-block-grid-10>li{list-style:none;width:10%}.small-block-grid-10>li:nth-of-type(1n){clear:none}.small-block-grid-10>li:nth-of-type(10n+1){clear:both}.small-block-grid-11>li{list-style:none;width:9.09091%}.small-block-grid-11>li:nth-of-type(1n){clear:none}.small-block-grid-11>li:nth-of-type(11n+1){clear:both}.small-block-grid-12>li{list-style:none;width:8.33333%}.small-block-grid-12>li:nth-of-type(1n){clear:none}.small-block-grid-12>li:nth-of-type(12n+1){clear:both}}@media only screen and (min-width: 40.0625em){.medium-block-grid-1>li{list-style:none;width:100%}.medium-block-grid-1>li:nth-of-type(1n){clear:none}.medium-block-grid-1>li:nth-of-type(1n+1){clear:both}.medium-block-grid-2>li{list-style:none;width:50%}.medium-block-grid-2>li:nth-of-type(1n){clear:none}.medium-block-grid-2>li:nth-of-type(2n+1){clear:both}.medium-block-grid-3>li{list-style:none;width:33.33333%}.medium-block-grid-3>li:nth-of-type(1n){clear:none}.medium-block-grid-3>li:nth-of-type(3n+1){clear:both}.medium-block-grid-4>li{list-style:none;width:25%}.medium-block-grid-4>li:nth-of-type(1n){clear:none}.medium-block-grid-4>li:nth-of-type(4n+1){clear:both}.medium-block-grid-5>li{list-style:none;width:20%}.medium-block-grid-5>li:nth-of-type(1n){clear:none}.medium-block-grid-5>li:nth-of-type(5n+1){clear:both}.medium-block-grid-6>li{list-style:none;width:16.66667%}.medium-block-grid-6>li:nth-of-type(1n){clear:none}.medium-block-grid-6>li:nth-of-type(6n+1){clear:both}.medium-block-grid-7>li{list-style:none;width:14.28571%}.medium-block-grid-7>li:nth-of-type(1n){clear:none}.medium-block-grid-7>li:nth-of-type(7n+1){clear:both}.medium-block-grid-8>li{list-style:none;width:12.5%}.medium-block-grid-8>li:nth-of-type(1n){clear:none}.medium-block-grid-8>li:nth-of-type(8n+1){clear:both}.medium-block-grid-9>li{list-style:none;width:11.11111%}.medium-block-grid-9>li:nth-of-type(1n){clear:none}.medium-block-grid-9>li:nth-of-type(9n+1){clear:both}.medium-block-grid-10>li{list-style:none;width:10%}.medium-block-grid-10>li:nth-of-type(1n){clear:none}.medium-block-grid-10>li:nth-of-type(10n+1){clear:both}.medium-block-grid-11>li{list-style:none;width:9.09091%}.medium-block-grid-11>li:nth-of-type(1n){clear:none}.medium-block-grid-11>li:nth-of-type(11n+1){clear:both}.medium-block-grid-12>li{list-style:none;width:8.33333%}.medium-block-grid-12>li:nth-of-type(1n){clear:none}.medium-block-grid-12>li:nth-of-type(12n+1){clear:both}}@media only screen and (min-width: 64.0625em){.large-block-grid-1>li{list-style:none;width:100%}.large-block-grid-1>li:nth-of-type(1n){clear:none}.large-block-grid-1>li:nth-of-type(1n+1){clear:both}.large-block-grid-2>li{list-style:none;width:50%}.large-block-grid-2>li:nth-of-type(1n){clear:none}.large-block-grid-2>li:nth-of-type(2n+1){clear:both}.large-block-grid-3>li{list-style:none;width:33.33333%}.large-block-grid-3>li:nth-of-type(1n){clear:none}.large-block-grid-3>li:nth-of-type(3n+1){clear:both}.large-block-grid-4>li{list-style:none;width:25%}.large-block-grid-4>li:nth-of-type(1n){clear:none}.large-block-grid-4>li:nth-of-type(4n+1){clear:both}.large-block-grid-5>li{list-style:none;width:20%}.large-block-grid-5>li:nth-of-type(1n){clear:none}.large-block-grid-5>li:nth-of-type(5n+1){clear:both}.large-block-grid-6>li{list-style:none;width:16.66667%}.large-block-grid-6>li:nth-of-type(1n){clear:none}.large-block-grid-6>li:nth-of-type(6n+1){clear:both}.large-block-grid-7>li{list-style:none;width:14.28571%}.large-block-grid-7>li:nth-of-type(1n){clear:none}.large-block-grid-7>li:nth-of-type(7n+1){clear:both}.large-block-grid-8>li{list-style:none;width:12.5%}.large-block-grid-8>li:nth-of-type(1n){clear:none}.large-block-grid-8>li:nth-of-type(8n+1){clear:both}.large-block-grid-9>li{list-style:none;width:11.11111%}.large-block-grid-9>li:nth-of-type(1n){clear:none}.large-block-grid-9>li:nth-of-type(9n+1){clear:both}.large-block-grid-10>li{list-style:none;width:10%}.large-block-grid-10>li:nth-of-type(1n){clear:none}.large-block-grid-10>li:nth-of-type(10n+1){clear:both}.large-block-grid-11>li{list-style:none;width:9.09091%}.large-block-grid-11>li:nth-of-type(1n){clear:none}.large-block-grid-11>li:nth-of-type(11n+1){clear:both}.large-block-grid-12>li{list-style:none;width:8.33333%}.large-block-grid-12>li:nth-of-type(1n){clear:none}.large-block-grid-12>li:nth-of-type(12n+1){clear:both}}.flex-video{height:0;margin-bottom:1rem;overflow:hidden;padding-bottom:67.5%;padding-top:1.5625rem;position:relative}.flex-video.widescreen{padding-bottom:56.34%}.flex-video.vimeo{padding-top:0}.flex-video iframe,.flex-video object,.flex-video embed,.flex-video video{height:100%;position:absolute;top:0;width:100%;left:0}.keystroke,kbd{background-color:#ededed;border-color:#ddd;color:#222;border-style:solid;border-width:1px;font-family:"Consolas","Menlo","Courier",monospace;font-size:inherit;margin:0;padding:0.125rem 0.25rem 0;border-radius:3px}.switch{border:none;margin-bottom:1.5rem;outline:0;padding:0;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch label{background:#ddd;color:transparent;cursor:pointer;display:block;margin-bottom:1rem;position:relative;text-indent:100%;width:4rem;height:2rem;transition:left 0.15s ease-out}.switch input{left:10px;opacity:0;padding:0;position:absolute;top:9px}.switch input+label{margin-left:0;margin-right:0}.switch label:after{background:#fff;content:"";display:block;height:1.5rem;left:.25rem;position:absolute;top:.25rem;width:1.5rem;-webkit-transition:left 0.15s ease-out;-moz-transition:left 0.15s ease-out;-o-transition:translate3d(0, 0, 0);transition:left 0.15s ease-out;-webkit-transform:translate3d(0, 0, 0);-moz-transform:translate3d(0, 0, 0);-ms-transform:translate3d(0, 0, 0);-o-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0)}.switch input:checked+label{background:#008CBA}.switch input:checked+label:after{left:2.25rem}.switch label{height:2rem;width:4rem}.switch label:after{height:1.5rem;width:1.5rem}.switch input:checked+label:after{left:2.25rem}.switch label{color:transparent;background:#ddd}.switch label:after{background:#fff}.switch input:checked+label{background:#008CBA}.switch.large label{height:2.5rem;width:5rem}.switch.large label:after{height:2rem;width:2rem}.switch.large input:checked+label:after{left:2.75rem}.switch.small label{height:1.75rem;width:3.5rem}.switch.small label:after{height:1.25rem;width:1.25rem}.switch.small input:checked+label:after{left:2rem}.switch.tiny label{height:1.5rem;width:3rem}.switch.tiny label:after{height:1rem;width:1rem}.switch.tiny input:checked+label:after{left:1.75rem}.switch.radius label{border-radius:4px}.switch.radius label:after{border-radius:3px}.switch.round{border-radius:1000px}.switch.round label{border-radius:2rem}.switch.round label:after{border-radius:2rem}@media only screen{.show-for-small-only,.show-for-small-up,.show-for-small,.show-for-small-down,.hide-for-medium-only,.hide-for-medium-up,.hide-for-medium,.show-for-medium-down,.hide-for-large-only,.hide-for-large-up,.hide-for-large,.show-for-large-down,.hide-for-xlarge-only,.hide-for-xlarge-up,.hide-for-xlarge,.show-for-xlarge-down,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.hide-for-xxlarge,.show-for-xxlarge-down{display:inherit !important}.hide-for-small-only,.hide-for-small-up,.hide-for-small,.hide-for-small-down,.show-for-medium-only,.show-for-medium-up,.show-for-medium,.hide-for-medium-down,.show-for-large-only,.show-for-large-up,.show-for-large,.hide-for-large-down,.show-for-xlarge-only,.show-for-xlarge-up,.show-for-xlarge,.hide-for-xlarge-down,.show-for-xxlarge-only,.show-for-xxlarge-up,.show-for-xxlarge,.hide-for-xxlarge-down{display:none !important}.visible-for-small-only,.visible-for-small-up,.visible-for-small,.visible-for-small-down,.hidden-for-medium-only,.hidden-for-medium-up,.hidden-for-medium,.visible-for-medium-down,.hidden-for-large-only,.hidden-for-large-up,.hidden-for-large,.visible-for-large-down,.hidden-for-xlarge-only,.hidden-for-xlarge-up,.hidden-for-xlarge,.visible-for-xlarge-down,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.hidden-for-xxlarge,.visible-for-xxlarge-down{position:static !important;height:auto;width:auto;overflow:visible;clip:auto}.hidden-for-small-only,.hidden-for-small-up,.hidden-for-small,.hidden-for-small-down,.visible-for-medium-only,.visible-for-medium-up,.visible-for-medium,.hidden-for-medium-down,.visible-for-large-only,.visible-for-large-up,.visible-for-large,.hidden-for-large-down,.visible-for-xlarge-only,.visible-for-xlarge-up,.visible-for-xlarge,.hidden-for-xlarge-down,.visible-for-xxlarge-only,.visible-for-xxlarge-up,.visible-for-xxlarge,.hidden-for-xxlarge-down{clip:rect(1px, 1px, 1px, 1px);height:1px;overflow:hidden;position:absolute !important;width:1px}table.show-for-small-only,table.show-for-small-up,table.show-for-small,table.show-for-small-down,table.hide-for-medium-only,table.hide-for-medium-up,table.hide-for-medium,table.show-for-medium-down,table.hide-for-large-only,table.hide-for-large-up,table.hide-for-large,table.show-for-large-down,table.hide-for-xlarge-only,table.hide-for-xlarge-up,table.hide-for-xlarge,table.show-for-xlarge-down,table.hide-for-xxlarge-only,table.hide-for-xxlarge-up,table.hide-for-xxlarge,table.show-for-xxlarge-down{display:table !important}thead.show-for-small-only,thead.show-for-small-up,thead.show-for-small,thead.show-for-small-down,thead.hide-for-medium-only,thead.hide-for-medium-up,thead.hide-for-medium,thead.show-for-medium-down,thead.hide-for-large-only,thead.hide-for-large-up,thead.hide-for-large,thead.show-for-large-down,thead.hide-for-xlarge-only,thead.hide-for-xlarge-up,thead.hide-for-xlarge,thead.show-for-xlarge-down,thead.hide-for-xxlarge-only,thead.hide-for-xxlarge-up,thead.hide-for-xxlarge,thead.show-for-xxlarge-down{display:table-header-group !important}tbody.show-for-small-only,tbody.show-for-small-up,tbody.show-for-small,tbody.show-for-small-down,tbody.hide-for-medium-only,tbody.hide-for-medium-up,tbody.hide-for-medium,tbody.show-for-medium-down,tbody.hide-for-large-only,tbody.hide-for-large-up,tbody.hide-for-large,tbody.show-for-large-down,tbody.hide-for-xlarge-only,tbody.hide-for-xlarge-up,tbody.hide-for-xlarge,tbody.show-for-xlarge-down,tbody.hide-for-xxlarge-only,tbody.hide-for-xxlarge-up,tbody.hide-for-xxlarge,tbody.show-for-xxlarge-down{display:table-row-group !important}tr.show-for-small-only,tr.show-for-small-up,tr.show-for-small,tr.show-for-small-down,tr.hide-for-medium-only,tr.hide-for-medium-up,tr.hide-for-medium,tr.show-for-medium-down,tr.hide-for-large-only,tr.hide-for-large-up,tr.hide-for-large,tr.show-for-large-down,tr.hide-for-xlarge-only,tr.hide-for-xlarge-up,tr.hide-for-xlarge,tr.show-for-xlarge-down,tr.hide-for-xxlarge-only,tr.hide-for-xxlarge-up,tr.hide-for-xxlarge,tr.show-for-xxlarge-down{display:table-row}th.show-for-small-only,td.show-for-small-only,th.show-for-small-up,td.show-for-small-up,th.show-for-small,td.show-for-small,th.show-for-small-down,td.show-for-small-down,th.hide-for-medium-only,td.hide-for-medium-only,th.hide-for-medium-up,td.hide-for-medium-up,th.hide-for-medium,td.hide-for-medium,th.show-for-medium-down,td.show-for-medium-down,th.hide-for-large-only,td.hide-for-large-only,th.hide-for-large-up,td.hide-for-large-up,th.hide-for-large,td.hide-for-large,th.show-for-large-down,td.show-for-large-down,th.hide-for-xlarge-only,td.hide-for-xlarge-only,th.hide-for-xlarge-up,td.hide-for-xlarge-up,th.hide-for-xlarge,td.hide-for-xlarge,th.show-for-xlarge-down,td.show-for-xlarge-down,th.hide-for-xxlarge-only,td.hide-for-xxlarge-only,th.hide-for-xxlarge-up,td.hide-for-xxlarge-up,th.hide-for-xxlarge,td.hide-for-xxlarge,th.show-for-xxlarge-down,td.show-for-xxlarge-down{display:table-cell !important}}@media only screen and (min-width: 40.0625em){.hide-for-small-only,.show-for-small-up,.hide-for-small,.hide-for-small-down,.show-for-medium-only,.show-for-medium-up,.show-for-medium,.show-for-medium-down,.hide-for-large-only,.hide-for-large-up,.hide-for-large,.show-for-large-down,.hide-for-xlarge-only,.hide-for-xlarge-up,.hide-for-xlarge,.show-for-xlarge-down,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.hide-for-xxlarge,.show-for-xxlarge-down{display:inherit !important}.show-for-small-only,.hide-for-small-up,.show-for-small,.show-for-small-down,.hide-for-medium-only,.hide-for-medium-up,.hide-for-medium,.hide-for-medium-down,.show-for-large-only,.show-for-large-up,.show-for-large,.hide-for-large-down,.show-for-xlarge-only,.show-for-xlarge-up,.show-for-xlarge,.hide-for-xlarge-down,.show-for-xxlarge-only,.show-for-xxlarge-up,.show-for-xxlarge,.hide-for-xxlarge-down{display:none !important}.hidden-for-small-only,.visible-for-small-up,.hidden-for-small,.hidden-for-small-down,.visible-for-medium-only,.visible-for-medium-up,.visible-for-medium,.visible-for-medium-down,.hidden-for-large-only,.hidden-for-large-up,.hidden-for-large,.visible-for-large-down,.hidden-for-xlarge-only,.hidden-for-xlarge-up,.hidden-for-xlarge,.visible-for-xlarge-down,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.hidden-for-xxlarge,.visible-for-xxlarge-down{position:static !important;height:auto;width:auto;overflow:visible;clip:auto}.visible-for-small-only,.hidden-for-small-up,.visible-for-small,.visible-for-small-down,.hidden-for-medium-only,.hidden-for-medium-up,.hidden-for-medium,.hidden-for-medium-down,.visible-for-large-only,.visible-for-large-up,.visible-for-large,.hidden-for-large-down,.visible-for-xlarge-only,.visible-for-xlarge-up,.visible-for-xlarge,.hidden-for-xlarge-down,.visible-for-xxlarge-only,.visible-for-xxlarge-up,.visible-for-xxlarge,.hidden-for-xxlarge-down{clip:rect(1px, 1px, 1px, 1px);height:1px;overflow:hidden;position:absolute !important;width:1px}table.hide-for-small-only,table.show-for-small-up,table.hide-for-small,table.hide-for-small-down,table.show-for-medium-only,table.show-for-medium-up,table.show-for-medium,table.show-for-medium-down,table.hide-for-large-only,table.hide-for-large-up,table.hide-for-large,table.show-for-large-down,table.hide-for-xlarge-only,table.hide-for-xlarge-up,table.hide-for-xlarge,table.show-for-xlarge-down,table.hide-for-xxlarge-only,table.hide-for-xxlarge-up,table.hide-for-xxlarge,table.show-for-xxlarge-down{display:table !important}thead.hide-for-small-only,thead.show-for-small-up,thead.hide-for-small,thead.hide-for-small-down,thead.show-for-medium-only,thead.show-for-medium-up,thead.show-for-medium,thead.show-for-medium-down,thead.hide-for-large-only,thead.hide-for-large-up,thead.hide-for-large,thead.show-for-large-down,thead.hide-for-xlarge-only,thead.hide-for-xlarge-up,thead.hide-for-xlarge,thead.show-for-xlarge-down,thead.hide-for-xxlarge-only,thead.hide-for-xxlarge-up,thead.hide-for-xxlarge,thead.show-for-xxlarge-down{display:table-header-group !important}tbody.hide-for-small-only,tbody.show-for-small-up,tbody.hide-for-small,tbody.hide-for-small-down,tbody.show-for-medium-only,tbody.show-for-medium-up,tbody.show-for-medium,tbody.show-for-medium-down,tbody.hide-for-large-only,tbody.hide-for-large-up,tbody.hide-for-large,tbody.show-for-large-down,tbody.hide-for-xlarge-only,tbody.hide-for-xlarge-up,tbody.hide-for-xlarge,tbody.show-for-xlarge-down,tbody.hide-for-xxlarge-only,tbody.hide-for-xxlarge-up,tbody.hide-for-xxlarge,tbody.show-for-xxlarge-down{display:table-row-group !important}tr.hide-for-small-only,tr.show-for-small-up,tr.hide-for-small,tr.hide-for-small-down,tr.show-for-medium-only,tr.show-for-medium-up,tr.show-for-medium,tr.show-for-medium-down,tr.hide-for-large-only,tr.hide-for-large-up,tr.hide-for-large,tr.show-for-large-down,tr.hide-for-xlarge-only,tr.hide-for-xlarge-up,tr.hide-for-xlarge,tr.show-for-xlarge-down,tr.hide-for-xxlarge-only,tr.hide-for-xxlarge-up,tr.hide-for-xxlarge,tr.show-for-xxlarge-down{display:table-row}th.hide-for-small-only,td.hide-for-small-only,th.show-for-small-up,td.show-for-small-up,th.hide-for-small,td.hide-for-small,th.hide-for-small-down,td.hide-for-small-down,th.show-for-medium-only,td.show-for-medium-only,th.show-for-medium-up,td.show-for-medium-up,th.show-for-medium,td.show-for-medium,th.show-for-medium-down,td.show-for-medium-down,th.hide-for-large-only,td.hide-for-large-only,th.hide-for-large-up,td.hide-for-large-up,th.hide-for-large,td.hide-for-large,th.show-for-large-down,td.show-for-large-down,th.hide-for-xlarge-only,td.hide-for-xlarge-only,th.hide-for-xlarge-up,td.hide-for-xlarge-up,th.hide-for-xlarge,td.hide-for-xlarge,th.show-for-xlarge-down,td.show-for-xlarge-down,th.hide-for-xxlarge-only,td.hide-for-xxlarge-only,th.hide-for-xxlarge-up,td.hide-for-xxlarge-up,th.hide-for-xxlarge,td.hide-for-xxlarge,th.show-for-xxlarge-down,td.show-for-xxlarge-down{display:table-cell !important}}@media only screen and (min-width: 64.0625em){.hide-for-small-only,.show-for-small-up,.hide-for-small,.hide-for-small-down,.hide-for-medium-only,.show-for-medium-up,.hide-for-medium,.hide-for-medium-down,.show-for-large-only,.show-for-large-up,.show-for-large,.show-for-large-down,.hide-for-xlarge-only,.hide-for-xlarge-up,.hide-for-xlarge,.show-for-xlarge-down,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.hide-for-xxlarge,.show-for-xxlarge-down{display:inherit !important}.show-for-small-only,.hide-for-small-up,.show-for-small,.show-for-small-down,.show-for-medium-only,.hide-for-medium-up,.show-for-medium,.show-for-medium-down,.hide-for-large-only,.hide-for-large-up,.hide-for-large,.hide-for-large-down,.show-for-xlarge-only,.show-for-xlarge-up,.show-for-xlarge,.hide-for-xlarge-down,.show-for-xxlarge-only,.show-for-xxlarge-up,.show-for-xxlarge,.hide-for-xxlarge-down{display:none !important}.hidden-for-small-only,.visible-for-small-up,.hidden-for-small,.hidden-for-small-down,.hidden-for-medium-only,.visible-for-medium-up,.hidden-for-medium,.hidden-for-medium-down,.visible-for-large-only,.visible-for-large-up,.visible-for-large,.visible-for-large-down,.hidden-for-xlarge-only,.hidden-for-xlarge-up,.hidden-for-xlarge,.visible-for-xlarge-down,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.hidden-for-xxlarge,.visible-for-xxlarge-down{position:static !important;height:auto;width:auto;overflow:visible;clip:auto}.visible-for-small-only,.hidden-for-small-up,.visible-for-small,.visible-for-small-down,.visible-for-medium-only,.hidden-for-medium-up,.visible-for-medium,.visible-for-medium-down,.hidden-for-large-only,.hidden-for-large-up,.hidden-for-large,.hidden-for-large-down,.visible-for-xlarge-only,.visible-for-xlarge-up,.visible-for-xlarge,.hidden-for-xlarge-down,.visible-for-xxlarge-only,.visible-for-xxlarge-up,.visible-for-xxlarge,.hidden-for-xxlarge-down{clip:rect(1px, 1px, 1px, 1px);height:1px;overflow:hidden;position:absolute !important;width:1px}table.hide-for-small-only,table.show-for-small-up,table.hide-for-small,table.hide-for-small-down,table.hide-for-medium-only,table.show-for-medium-up,table.hide-for-medium,table.hide-for-medium-down,table.show-for-large-only,table.show-for-large-up,table.show-for-large,table.show-for-large-down,table.hide-for-xlarge-only,table.hide-for-xlarge-up,table.hide-for-xlarge,table.show-for-xlarge-down,table.hide-for-xxlarge-only,table.hide-for-xxlarge-up,table.hide-for-xxlarge,table.show-for-xxlarge-down{display:table !important}thead.hide-for-small-only,thead.show-for-small-up,thead.hide-for-small,thead.hide-for-small-down,thead.hide-for-medium-only,thead.show-for-medium-up,thead.hide-for-medium,thead.hide-for-medium-down,thead.show-for-large-only,thead.show-for-large-up,thead.show-for-large,thead.show-for-large-down,thead.hide-for-xlarge-only,thead.hide-for-xlarge-up,thead.hide-for-xlarge,thead.show-for-xlarge-down,thead.hide-for-xxlarge-only,thead.hide-for-xxlarge-up,thead.hide-for-xxlarge,thead.show-for-xxlarge-down{display:table-header-group !important}tbody.hide-for-small-only,tbody.show-for-small-up,tbody.hide-for-small,tbody.hide-for-small-down,tbody.hide-for-medium-only,tbody.show-for-medium-up,tbody.hide-for-medium,tbody.hide-for-medium-down,tbody.show-for-large-only,tbody.show-for-large-up,tbody.show-for-large,tbody.show-for-large-down,tbody.hide-for-xlarge-only,tbody.hide-for-xlarge-up,tbody.hide-for-xlarge,tbody.show-for-xlarge-down,tbody.hide-for-xxlarge-only,tbody.hide-for-xxlarge-up,tbody.hide-for-xxlarge,tbody.show-for-xxlarge-down{display:table-row-group !important}tr.hide-for-small-only,tr.show-for-small-up,tr.hide-for-small,tr.hide-for-small-down,tr.hide-for-medium-only,tr.show-for-medium-up,tr.hide-for-medium,tr.hide-for-medium-down,tr.show-for-large-only,tr.show-for-large-up,tr.show-for-large,tr.show-for-large-down,tr.hide-for-xlarge-only,tr.hide-for-xlarge-up,tr.hide-for-xlarge,tr.show-for-xlarge-down,tr.hide-for-xxlarge-only,tr.hide-for-xxlarge-up,tr.hide-for-xxlarge,tr.show-for-xxlarge-down{display:table-row}th.hide-for-small-only,td.hide-for-small-only,th.show-for-small-up,td.show-for-small-up,th.hide-for-small,td.hide-for-small,th.hide-for-small-down,td.hide-for-small-down,th.hide-for-medium-only,td.hide-for-medium-only,th.show-for-medium-up,td.show-for-medium-up,th.hide-for-medium,td.hide-for-medium,th.hide-for-medium-down,td.hide-for-medium-down,th.show-for-large-only,td.show-for-large-only,th.show-for-large-up,td.show-for-large-up,th.show-for-large,td.show-for-large,th.show-for-large-down,td.show-for-large-down,th.hide-for-xlarge-only,td.hide-for-xlarge-only,th.hide-for-xlarge-up,td.hide-for-xlarge-up,th.hide-for-xlarge,td.hide-for-xlarge,th.show-for-xlarge-down,td.show-for-xlarge-down,th.hide-for-xxlarge-only,td.hide-for-xxlarge-only,th.hide-for-xxlarge-up,td.hide-for-xxlarge-up,th.hide-for-xxlarge,td.hide-for-xxlarge,th.show-for-xxlarge-down,td.show-for-xxlarge-down{display:table-cell !important}}@media only screen and (min-width: 90.0625em){.hide-for-small-only,.show-for-small-up,.hide-for-small,.hide-for-small-down,.hide-for-medium-only,.show-for-medium-up,.hide-for-medium,.hide-for-medium-down,.hide-for-large-only,.show-for-large-up,.hide-for-large,.hide-for-large-down,.show-for-xlarge-only,.show-for-xlarge-up,.show-for-xlarge,.show-for-xlarge-down,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.hide-for-xxlarge,.show-for-xxlarge-down{display:inherit !important}.show-for-small-only,.hide-for-small-up,.show-for-small,.show-for-small-down,.show-for-medium-only,.hide-for-medium-up,.show-for-medium,.show-for-medium-down,.show-for-large-only,.hide-for-large-up,.show-for-large,.show-for-large-down,.hide-for-xlarge-only,.hide-for-xlarge-up,.hide-for-xlarge,.hide-for-xlarge-down,.show-for-xxlarge-only,.show-for-xxlarge-up,.show-for-xxlarge,.hide-for-xxlarge-down{display:none !important}.hidden-for-small-only,.visible-for-small-up,.hidden-for-small,.hidden-for-small-down,.hidden-for-medium-only,.visible-for-medium-up,.hidden-for-medium,.hidden-for-medium-down,.hidden-for-large-only,.visible-for-large-up,.hidden-for-large,.hidden-for-large-down,.visible-for-xlarge-only,.visible-for-xlarge-up,.visible-for-xlarge,.visible-for-xlarge-down,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.hidden-for-xxlarge,.visible-for-xxlarge-down{position:static !important;height:auto;width:auto;overflow:visible;clip:auto}.visible-for-small-only,.hidden-for-small-up,.visible-for-small,.visible-for-small-down,.visible-for-medium-only,.hidden-for-medium-up,.visible-for-medium,.visible-for-medium-down,.visible-for-large-only,.hidden-for-large-up,.visible-for-large,.visible-for-large-down,.hidden-for-xlarge-only,.hidden-for-xlarge-up,.hidden-for-xlarge,.hidden-for-xlarge-down,.visible-for-xxlarge-only,.visible-for-xxlarge-up,.visible-for-xxlarge,.hidden-for-xxlarge-down{clip:rect(1px, 1px, 1px, 1px);height:1px;overflow:hidden;position:absolute !important;width:1px}table.hide-for-small-only,table.show-for-small-up,table.hide-for-small,table.hide-for-small-down,table.hide-for-medium-only,table.show-for-medium-up,table.hide-for-medium,table.hide-for-medium-down,table.hide-for-large-only,table.show-for-large-up,table.hide-for-large,table.hide-for-large-down,table.show-for-xlarge-only,table.show-for-xlarge-up,table.show-for-xlarge,table.show-for-xlarge-down,table.hide-for-xxlarge-only,table.hide-for-xxlarge-up,table.hide-for-xxlarge,table.show-for-xxlarge-down{display:table !important}thead.hide-for-small-only,thead.show-for-small-up,thead.hide-for-small,thead.hide-for-small-down,thead.hide-for-medium-only,thead.show-for-medium-up,thead.hide-for-medium,thead.hide-for-medium-down,thead.hide-for-large-only,thead.show-for-large-up,thead.hide-for-large,thead.hide-for-large-down,thead.show-for-xlarge-only,thead.show-for-xlarge-up,thead.show-for-xlarge,thead.show-for-xlarge-down,thead.hide-for-xxlarge-only,thead.hide-for-xxlarge-up,thead.hide-for-xxlarge,thead.show-for-xxlarge-down{display:table-header-group !important}tbody.hide-for-small-only,tbody.show-for-small-up,tbody.hide-for-small,tbody.hide-for-small-down,tbody.hide-for-medium-only,tbody.show-for-medium-up,tbody.hide-for-medium,tbody.hide-for-medium-down,tbody.hide-for-large-only,tbody.show-for-large-up,tbody.hide-for-large,tbody.hide-for-large-down,tbody.show-for-xlarge-only,tbody.show-for-xlarge-up,tbody.show-for-xlarge,tbody.show-for-xlarge-down,tbody.hide-for-xxlarge-only,tbody.hide-for-xxlarge-up,tbody.hide-for-xxlarge,tbody.show-for-xxlarge-down{display:table-row-group !important}tr.hide-for-small-only,tr.show-for-small-up,tr.hide-for-small,tr.hide-for-small-down,tr.hide-for-medium-only,tr.show-for-medium-up,tr.hide-for-medium,tr.hide-for-medium-down,tr.hide-for-large-only,tr.show-for-large-up,tr.hide-for-large,tr.hide-for-large-down,tr.show-for-xlarge-only,tr.show-for-xlarge-up,tr.show-for-xlarge,tr.show-for-xlarge-down,tr.hide-for-xxlarge-only,tr.hide-for-xxlarge-up,tr.hide-for-xxlarge,tr.show-for-xxlarge-down{display:table-row}th.hide-for-small-only,td.hide-for-small-only,th.show-for-small-up,td.show-for-small-up,th.hide-for-small,td.hide-for-small,th.hide-for-small-down,td.hide-for-small-down,th.hide-for-medium-only,td.hide-for-medium-only,th.show-for-medium-up,td.show-for-medium-up,th.hide-for-medium,td.hide-for-medium,th.hide-for-medium-down,td.hide-for-medium-down,th.hide-for-large-only,td.hide-for-large-only,th.show-for-large-up,td.show-for-large-up,th.hide-for-large,td.hide-for-large,th.hide-for-large-down,td.hide-for-large-down,th.show-for-xlarge-only,td.show-for-xlarge-only,th.show-for-xlarge-up,td.show-for-xlarge-up,th.show-for-xlarge,td.show-for-xlarge,th.show-for-xlarge-down,td.show-for-xlarge-down,th.hide-for-xxlarge-only,td.hide-for-xxlarge-only,th.hide-for-xxlarge-up,td.hide-for-xxlarge-up,th.hide-for-xxlarge,td.hide-for-xxlarge,th.show-for-xxlarge-down,td.show-for-xxlarge-down{display:table-cell !important}}@media only screen and (min-width: 120.0625em){.hide-for-small-only,.show-for-small-up,.hide-for-small,.hide-for-small-down,.hide-for-medium-only,.show-for-medium-up,.hide-for-medium,.hide-for-medium-down,.hide-for-large-only,.show-for-large-up,.hide-for-large,.hide-for-large-down,.hide-for-xlarge-only,.show-for-xlarge-up,.hide-for-xlarge,.hide-for-xlarge-down,.show-for-xxlarge-only,.show-for-xxlarge-up,.show-for-xxlarge,.show-for-xxlarge-down{display:inherit !important}.show-for-small-only,.hide-for-small-up,.show-for-small,.show-for-small-down,.show-for-medium-only,.hide-for-medium-up,.show-for-medium,.show-for-medium-down,.show-for-large-only,.hide-for-large-up,.show-for-large,.show-for-large-down,.show-for-xlarge-only,.hide-for-xlarge-up,.show-for-xlarge,.show-for-xlarge-down,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.hide-for-xxlarge,.hide-for-xxlarge-down{display:none !important}.hidden-for-small-only,.visible-for-small-up,.hidden-for-small,.hidden-for-small-down,.hidden-for-medium-only,.visible-for-medium-up,.hidden-for-medium,.hidden-for-medium-down,.hidden-for-large-only,.visible-for-large-up,.hidden-for-large,.hidden-for-large-down,.hidden-for-xlarge-only,.visible-for-xlarge-up,.hidden-for-xlarge,.hidden-for-xlarge-down,.visible-for-xxlarge-only,.visible-for-xxlarge-up,.visible-for-xxlarge,.visible-for-xxlarge-down{position:static !important;height:auto;width:auto;overflow:visible;clip:auto}.visible-for-small-only,.hidden-for-small-up,.visible-for-small,.visible-for-small-down,.visible-for-medium-only,.hidden-for-medium-up,.visible-for-medium,.visible-for-medium-down,.visible-for-large-only,.hidden-for-large-up,.visible-for-large,.visible-for-large-down,.visible-for-xlarge-only,.hidden-for-xlarge-up,.visible-for-xlarge,.visible-for-xlarge-down,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.hidden-for-xxlarge,.hidden-for-xxlarge-down{clip:rect(1px, 1px, 1px, 1px);height:1px;overflow:hidden;position:absolute !important;width:1px}table.hide-for-small-only,table.show-for-small-up,table.hide-for-small,table.hide-for-small-down,table.hide-for-medium-only,table.show-for-medium-up,table.hide-for-medium,table.hide-for-medium-down,table.hide-for-large-only,table.show-for-large-up,table.hide-for-large,table.hide-for-large-down,table.hide-for-xlarge-only,table.show-for-xlarge-up,table.hide-for-xlarge,table.hide-for-xlarge-down,table.show-for-xxlarge-only,table.show-for-xxlarge-up,table.show-for-xxlarge,table.show-for-xxlarge-down{display:table !important}thead.hide-for-small-only,thead.show-for-small-up,thead.hide-for-small,thead.hide-for-small-down,thead.hide-for-medium-only,thead.show-for-medium-up,thead.hide-for-medium,thead.hide-for-medium-down,thead.hide-for-large-only,thead.show-for-large-up,thead.hide-for-large,thead.hide-for-large-down,thead.hide-for-xlarge-only,thead.show-for-xlarge-up,thead.hide-for-xlarge,thead.hide-for-xlarge-down,thead.show-for-xxlarge-only,thead.show-for-xxlarge-up,thead.show-for-xxlarge,thead.show-for-xxlarge-down{display:table-header-group !important}tbody.hide-for-small-only,tbody.show-for-small-up,tbody.hide-for-small,tbody.hide-for-small-down,tbody.hide-for-medium-only,tbody.show-for-medium-up,tbody.hide-for-medium,tbody.hide-for-medium-down,tbody.hide-for-large-only,tbody.show-for-large-up,tbody.hide-for-large,tbody.hide-for-large-down,tbody.hide-for-xlarge-only,tbody.show-for-xlarge-up,tbody.hide-for-xlarge,tbody.hide-for-xlarge-down,tbody.show-for-xxlarge-only,tbody.show-for-xxlarge-up,tbody.show-for-xxlarge,tbody.show-for-xxlarge-down{display:table-row-group !important}tr.hide-for-small-only,tr.show-for-small-up,tr.hide-for-small,tr.hide-for-small-down,tr.hide-for-medium-only,tr.show-for-medium-up,tr.hide-for-medium,tr.hide-for-medium-down,tr.hide-for-large-only,tr.show-for-large-up,tr.hide-for-large,tr.hide-for-large-down,tr.hide-for-xlarge-only,tr.show-for-xlarge-up,tr.hide-for-xlarge,tr.hide-for-xlarge-down,tr.show-for-xxlarge-only,tr.show-for-xxlarge-up,tr.show-for-xxlarge,tr.show-for-xxlarge-down{display:table-row}th.hide-for-small-only,td.hide-for-small-only,th.show-for-small-up,td.show-for-small-up,th.hide-for-small,td.hide-for-small,th.hide-for-small-down,td.hide-for-small-down,th.hide-for-medium-only,td.hide-for-medium-only,th.show-for-medium-up,td.show-for-medium-up,th.hide-for-medium,td.hide-for-medium,th.hide-for-medium-down,td.hide-for-medium-down,th.hide-for-large-only,td.hide-for-large-only,th.show-for-large-up,td.show-for-large-up,th.hide-for-large,td.hide-for-large,th.hide-for-large-down,td.hide-for-large-down,th.hide-for-xlarge-only,td.hide-for-xlarge-only,th.show-for-xlarge-up,td.show-for-xlarge-up,th.hide-for-xlarge,td.hide-for-xlarge,th.hide-for-xlarge-down,td.hide-for-xlarge-down,th.show-for-xxlarge-only,td.show-for-xxlarge-only,th.show-for-xxlarge-up,td.show-for-xxlarge-up,th.show-for-xxlarge,td.show-for-xxlarge,th.show-for-xxlarge-down,td.show-for-xxlarge-down{display:table-cell !important}}.show-for-landscape,.hide-for-portrait{display:inherit !important}.hide-for-landscape,.show-for-portrait{display:none !important}table.hide-for-landscape,table.show-for-portrait{display:table !important}thead.hide-for-landscape,thead.show-for-portrait{display:table-header-group !important}tbody.hide-for-landscape,tbody.show-for-portrait{display:table-row-group !important}tr.hide-for-landscape,tr.show-for-portrait{display:table-row !important}td.hide-for-landscape,td.show-for-portrait,th.hide-for-landscape,th.show-for-portrait{display:table-cell !important}@media only screen and (orientation: landscape){.show-for-landscape,.hide-for-portrait{display:inherit !important}.hide-for-landscape,.show-for-portrait{display:none !important}table.show-for-landscape,table.hide-for-portrait{display:table !important}thead.show-for-landscape,thead.hide-for-portrait{display:table-header-group !important}tbody.show-for-landscape,tbody.hide-for-portrait{display:table-row-group !important}tr.show-for-landscape,tr.hide-for-portrait{display:table-row !important}td.show-for-landscape,td.hide-for-portrait,th.show-for-landscape,th.hide-for-portrait{display:table-cell !important}}@media only screen and (orientation: portrait){.show-for-portrait,.hide-for-landscape{display:inherit !important}.hide-for-portrait,.show-for-landscape{display:none !important}table.show-for-portrait,table.hide-for-landscape{display:table !important}thead.show-for-portrait,thead.hide-for-landscape{display:table-header-group !important}tbody.show-for-portrait,tbody.hide-for-landscape{display:table-row-group !important}tr.show-for-portrait,tr.hide-for-landscape{display:table-row !important}td.show-for-portrait,td.hide-for-landscape,th.show-for-portrait,th.hide-for-landscape{display:table-cell !important}}.show-for-touch{display:none !important}.hide-for-touch{display:inherit !important}.touch .show-for-touch{display:inherit !important}.touch .hide-for-touch{display:none !important}table.hide-for-touch{display:table !important}.touch table.show-for-touch{display:table !important}thead.hide-for-touch{display:table-header-group !important}.touch thead.show-for-touch{display:table-header-group !important}tbody.hide-for-touch{display:table-row-group !important}.touch tbody.show-for-touch{display:table-row-group !important}tr.hide-for-touch{display:table-row !important}.touch tr.show-for-touch{display:table-row !important}td.hide-for-touch{display:table-cell !important}.touch td.show-for-touch{display:table-cell !important}th.hide-for-touch{display:table-cell !important}.touch th.show-for-touch{display:table-cell !important}.show-for-sr{clip:rect(1px, 1px, 1px, 1px);height:1px;overflow:hidden;position:absolute !important;width:1px}.show-on-focus{clip:rect(1px, 1px, 1px, 1px);height:1px;overflow:hidden;position:absolute !important;width:1px}.show-on-focus:focus,.show-on-focus:active{position:static !important;height:auto;width:auto;overflow:visible;clip:auto}.print-only{display:none !important}@media print{*{background:transparent !important;box-shadow:none !important;color:#000 !important;text-shadow:none !important}.show-for-print{display:block}.hide-for-print{display:none}table.show-for-print{display:table !important}thead.show-for-print{display:table-header-group !important}tbody.show-for-print{display:table-row-group !important}tr.show-for-print{display:table-row !important}td.show-for-print{display:table-cell !important}th.show-for-print{display:table-cell !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}.hide-on-print{display:none !important}.print-only{display:block !important}.hide-for-print{display:none !important}.show-for-print{display:inherit !important}}@media print{.show-for-print{display:block}.hide-for-print{display:none}table.show-for-print{display:table !important}thead.show-for-print{display:table-header-group !important}tbody.show-for-print{display:table-row-group !important}tr.show-for-print{display:table-row !important}td.show-for-print{display:table-cell !important}th.show-for-print{display:table-cell !important}}@media not print{.show-for-print{display:none !important}} diff --git a/tests/Frameworks/CakePHP/Version_3_10/webroot/css/home.css b/tests/Frameworks/CakePHP/Version_3_10/webroot/css/home.css new file mode 100644 index 0000000000..6e2312f91e --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/webroot/css/home.css @@ -0,0 +1,240 @@ +@font-face { + font-family: 'cakefont'; + src: url('../font/cakedingbats-webfont.eot'); + src: url('../font/cakedingbats-webfont.eot?#iefix') format('embedded-opentype'), + url('../font/cakedingbats-webfont.woff2') format('woff2'), + url('../font/cakedingbats-webfont.woff') format('woff'), + url('../font/cakedingbats-webfont.ttf') format('truetype'), + url('../font/cakedingbats-webfont.svg#cake_dingbatsregular') format('svg'); + font-weight: normal; + font-style: normal; +} + +.home { + font-family: 'Roboto', sans-serif; + font-size: 14px; + line-height: 27px; + color: #404041; +} + +a { + color: #0071BC; + -webkit-transition: all 0.2s; + -moz-transition: all 0.2s; + -ms-transition: all 0.2s; + -o-transition: all 0.2s; + transition: all 0.2s; +} + +a:hover, a:active { + color: #d33d44; + -webkit-transition: all 0.2s; + -moz-transition: all 0.2s; + -ms-transition: all 0.2s; + -o-transition: all 0.2s; + transition: all 0.2s; +} + +ul, ol, dl, p { + font-size: 0.85rem; +} + +p { + line-height: 2; +} + +header { + height: auto; + line-height: 1em; + padding: 0; + box-shadow: none; +} + +header.row { + margin-bottom: 30px; +} + +header .header-image { + text-align: center; + padding: 64px 0; +} + +header .header-title { + padding: 0; + display: block; + background: #404041; + text-align: center; +} + +header .header-title h1 { + font-family: 'Raleway', sans-serif; + margin: 0; + font-style: italic; + font-size: 18px; + font-weight: 500; + padding: 18px 30px; + color: #DEDED5; +} + +header h1 { + color: #fff; +} + +h3, h4 { + font-family: 'Roboto', sans-serif; + font-size: 27px; + line-height: 30px; + font-weight: 300; + -webkit-font-smoothing: antialiased; + margin-top: 0; + margin-bottom: 20px; +} + +.more { + color: #ffffff; + background-color: #d33d44; + padding: 15px; + margin-top: 10px; +} + +.row { + max-width: 1000px; +} + +.alert { + background-color: #fff9e1; + font-size: 12px; + text-align: center; + display: block; + padding: 12px; + border-bottom: 2px solid #ffcf06; +} + +.alert { + background-color: #fff9e1; + font-size: 12px; + display: block; + padding: 12px; + border-bottom: 2px solid #ffcf06; + margin-bottom: 30px; + color: #404041; +} + +.alert p { + margin: 0; + font-size: 12px; + line-height: 1.4; +} + +.alert p:before { + color: #ffcf06; + content: "\0055"; + font-family: 'cakefont', sans-serif; + font-size: 21px; + margin-left: -0.8em; + width: 2.3em; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + padding: 0 10px 0 15px; + vertical-align: -2px; +} + +.alert ul { + margin: 0; + font-size: 12px; +} + +.alert.url-rewriting { + background-color: #F0F0F0; + border-color: #cccccc; + display: none; +} + +.text-center { + text-align: center; +} + +ul { + list-style-type: none; + margin: 0 0 30px 0; +} + +li { + padding-left: 1.8em; +} + +ul li ul, ul li ul li { + margin: 0; + padding: 0; +} + +.bullet:before { + font-family: 'cakefont', sans-serif; + font-size: 18px; + display: inline-block; + margin-left: -1.3em; + width: 1.2em; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + vertical-align: -1px; +} + +.success:before { + color: #88c671; + content: "\0056"; +} + +.problem:before { + color: #d33d44; + content: "\0057"; +} + +.cutlery:before { + color: #404041; + content: "\0059"; +} + +.book:before { + color: #404041; + content: "\0042"; + width: 1.7em; +} + +hr { + border-bottom: 1px solid #e7e7e7; + border-top: 0; + margin-bottom: 35px; + margin-left: 30px; + margin-right: 30px; +} + + +.icon { + color: #404041; + font-style: normal; + font-family: 'cakefont', sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +.icon.support { + font-size: 60px; +} +.icon.docs { + font-size: 57px; +} +.icon.training { + font-size: 39px; +} + +@media (min-width: 768px) { + .columns { + padding-left: 30px; + padding-right: 30px; + } +} + +@media (min-width: 992px) { + header.row { + max-width: 940px; + } +} diff --git a/tests/Frameworks/CakePHP/Version_3_10/webroot/css/style.css b/tests/Frameworks/CakePHP/Version_3_10/webroot/css/style.css new file mode 100644 index 0000000000..40c1d2a9f9 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/webroot/css/style.css @@ -0,0 +1,524 @@ +.disabled a, +a.disabled { + pointer-events: none; +} + +a:hover { + color: #15848F; +} + +a { + color: #1798A5; +} + +.side-nav li a:not(.button) { + color: #15848F; +} + +.side-nav li a:not(.button):hover { + color: #15848F; +} + +header { + background-color: #D33C44; + color: #ffffff; + font-size: 30px; + height: 84px; + line-height: 64px; + padding: 16px 0px; + box-shadow: 0px 1px rgba(0, 0, 0, 0.24); +} + +header .header-title { + padding-left:80px +} + +legend { + color:#15848F; +} + +.row { + max-width: 80rem; +} + +.actions.columns { + margin-top:1rem; + border-left: 5px solid #15848F; + padding-left: 15px; + padding: 32px 20px; +} + +.actions.columns h3 { + color:#15848F; +} + +.related table { + border: 0; + width: 100%; + table-layout: fixed; +} + +.index table thead { + height: 3.5rem; +} + +.header-help { + float: right; + margin-right:2rem; + margin-top: -80px; + font-size:16px; +} + +.header-help span { + font-weight: normal; + text-align: center; + text-decoration: none; + line-height: 1; + white-space: nowrap; + display: inline-block; + padding: 0.25rem 0.5rem 0.375rem; + font-size: 0.8rem; + background-color: #0097a7; + color: #FFF; + border-radius: 1000px; +} + +.header-help a { + color: #fff; +} + +ul.pagination li a { + color: rgba(0, 0 ,0 , 0.54); +} + +ul.pagination li.active a { + background-color: #DCE47E; + color: #FFF; + font-weight: bold; + cursor: default; +} +ul.pagination .disabled:hover a { + background: none; +} + +.paginator { + text-align: center; +} + +.paginator ul.pagination li { + float: none; + display: inline-block; +} + +.paginator p { + text-align: right; + color: rgba(0, 0 ,0 , 0.54); +} + +.asc:after { + content: " \2193"; +} +.desc:after { + content: " \2191"; +} + +.form .error-message { + display: block; + padding: 0.375rem 0.5625rem 0.5625rem; + margin-top: -1px; + margin-bottom: 1rem; + font-size: 0.75rem; + font-weight: normal; + font-style: italic; + color: rgba(0, 0, 0, 0.54); +} + +.required > label { + font-weight: bold; +} +.required > label:after { + content: ' *'; + color: #C3232D; +} + +select[multiple] { + min-height:150px; + background: none; +} +input[type=checkbox], +input[type=radio] { + margin-right: 0.5em; +} + +.date select, +.time select, +.datetime select { + display: inline; + width: auto; + margin-right: 10px; +} + +.error label, +.error label.error { + color: #C3232D; +} + +.view h2 { + color: #6F6F6F; +} + +.view .columns.strings { + border-radius: 3px; + box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.24); + margin-right:0.7rem; +} + +.view .numbers { + background-color: #B7E3EC; + color: #FFF; + border-radius: 3px; + box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.24); + margin-right: 0.7rem; +} + +.view .columns.dates { + border-radius: 3px; + box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.24); + margin-right:0.7rem; + background-color:#DCE47E; + color: #fff; +} + +.view .columns.booleans { + border-radius: 3px; + box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.24); + margin-right:0.7rem; + background-color: #8D6E65; + color: #fff; +} + +.view .strings p { + border-bottom: 1px solid #eee; +} +.view .numbers .subheader, .view .dates .subheader { + color:#747474; +} +.view .booleans .subheader { + color: #E9E9E9 +} + +.view .texts .columns { + margin-top:1.2rem; + border-bottom: 1px solid #eee; +} + +/** Notices and Errors **/ +.cake-error, +.cake-debug, +.notice, +p.error, +p.notice { + display: block; + clear: both; + background-repeat: repeat-x; + margin-bottom: 18px; + padding: 7px 14px; + border-radius: 3px; + box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.24); +} + +.cake-debug, +.notice, +p.notice { + color: #000000; + background: #ffcc00; +} + +.cake-error, +p.error { + color: #fff; + background: #C3232D; +} + +pre { + background: none repeat scroll 0% 0% #FFF; + box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.24); + margin: 15px 0px; + color: rgba(0, 0 ,0 , 0.74); + padding:5px; +} + +.cake-error .cake-stack-trace { + margin-top:10px; +} + +.cake-stack-trace code { + background: inherit; + border:0; +} + +.cake-code-dump .code-highlight { + display: block; + background-color: #FFC600; +} + +.cake-error a, +.cake-error a:hover { + color:#fff; + text-decoration: underline; +} + +.checks { + padding:30px; + color: #626262; + background-color: #B7E3EC; + border-radius: 3px; + box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.24); + margin-bottom: 2em; +} + +.checks h4 { + margin-bottom: 1.5rem; +} + +.checks hr { + border: 0; + height: 0; + border-top: 1px solid rgba(0, 0, 0, 0.1); + border-bottom: 1px solid rgba(255, 255, 255, 0.3); +} + +.checks .success, +.checks .problem { + margin-left: 10px; +} +.checks .success:before, +.checks .problem:before { + line-height: 0px; + font-size: 28px; + height: 12px; + width: 12px; + border-radius: 15px; + text-align: center; + vertical-align: middle; + display: inline-block; + position: relative; + left: -11px; +} + +.checks .success:before { + content: "✓"; + color: green; + margin-right: 9px; +} + +.checks .problem:before { + content: "✘"; + color: red; + margin-right: 9px; +} + +.top-bar.expanded .title-area { + background: #01545b; +} + +.top-bar.expanded, .top-bar,.top-bar-section ul li,.top-bar-section li:not(.has-form) a:not(.button) { + background: #116d76; +} + +.top-bar-section li:not(.has-form) a:not(.button):hover { + background-color: #308e97; + background: #308e97; +} + +.side-nav li.heading { + color: #1798A5; + font-size: 0.875rem; + font-weight: bold; + text-transform: uppercase; + padding: 0.4375rem 0.875rem; +} + +#actions-sidebar { + background: #fafafa; +} + +.index table { + margin-top: 0rem; + border: 0; + width: 100%; + table-layout: fixed; +} + +table { + background: #fff; + margin-bottom: 1.25rem; + border: none; + table-layout: fixed; + width: 100%; +} + +table thead { + background: none; +} + +table tr { + border-bottom: 1px solid #ebebec; +} + +table thead tr { + border-bottom: 1px solid #1798A5; +} + +table tr th { + padding: 0.5625rem 0.625rem; + font-size: 0.875rem; + color: #1798A5; + text-align: left; + border-bottom: 2px solid #1798A5; +} + +table tr:nth-of-type(even) { + background: none; +} + +fieldset { + border: none; + padding: 1.25rem; + margin: 1.125rem 0; +} + +fieldset legend { + border-bottom: 2px solid #1798A5; + width: 100%; + line-height: 2rem; +} + +.form button[type="submit"] { + float: right; + text-transform: uppercase; + box-shadow: none; +} + +.form button:hover, .form button:focus { + background: #BE840B; + box-shadow: none; +} + +button { + background: #966600; +} + +div.message { + text-align: center; + cursor: pointer; + display: block; + font-weight: normal; + padding: 0 1.5rem 0 1.5rem; + transition: height 300ms ease-out 0s; + background-color: #a0d3e8; + color: #626262; + top: 15px; + right: 15px; + z-index: 999; + overflow: hidden; + height: 50px; + line-height: 2.5em; +} + +div.message:before { + line-height: 0px; + font-size: 20px; + height: 12px; + width: 12px; + border-radius: 15px; + text-align: center; + vertical-align: middle; + display: inline-block; + position: relative; + left: -11px; + background-color: #FFF; + padding: 12px 14px 12px 10px; + content: "i"; + color: #a0d3e8; +} + +div.message.error { + background-color: #C3232D; + color: #FFF; +} + +div.message.error:before { + padding: 11px 16px 14px 7px; + color: #C3232D; + content: "x"; +} +div.message.hidden { + height: 0; +} + + +.vertical-table th { + padding: 0.5625rem 0.625rem; + font-size: 0.875rem; + color: #1798A5; + border: none; + text-align: left; +} + +.vertical-table { + vertical-align: middle; +} + +.vertical-table td { + text-align: right; +} + +.content { + padding: 2rem; +} + +/* Use 'one true layout' methods to get equal height columns */ +.container { + overflow: hidden; + min-height: 92%; /* full height almost always */ +} + +/* Force equal height by overflowing */ +.content, +#actions-sidebar { + margin-bottom: -99999px; + padding-bottom: 99999px; +} +@media(max-width: 640px) { + #actions-sidebar { + padding-bottom: 2rem; + margin-bottom: 0; + } +} + +.content h3 { + color: #be140b; + padding-bottom: 0.5rem; + margin-bottom: 20px; +} + +.content h4 { + color: #be140b; + padding-bottom: 0.5rem; + margin-bottom: 20px; + border-bottom: 2px solid #be140b; +} + +.content .related h4 { + color: #4d8f97; + padding-bottom: 0.5rem; + margin-top: 20px; + margin-bottom: 10px; + border-bottom: 0px; +} + +table td { + vertical-align: top; + word-break: break-all; +} diff --git a/tests/Frameworks/CakePHP/Version_3_10/webroot/favicon.ico b/tests/Frameworks/CakePHP/Version_3_10/webroot/favicon.ico new file mode 100644 index 0000000000..49a060fc46 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_3_10/webroot/favicon.ico differ diff --git a/tests/Frameworks/CakePHP/Version_3_10/webroot/font/cakedingbats-webfont.eot b/tests/Frameworks/CakePHP/Version_3_10/webroot/font/cakedingbats-webfont.eot new file mode 100644 index 0000000000..e8605d9268 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_3_10/webroot/font/cakedingbats-webfont.eot differ diff --git a/tests/Frameworks/CakePHP/Version_3_10/webroot/font/cakedingbats-webfont.svg b/tests/Frameworks/CakePHP/Version_3_10/webroot/font/cakedingbats-webfont.svg new file mode 100644 index 0000000000..d1e0c98f7a --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/webroot/font/cakedingbats-webfont.svg @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/Frameworks/CakePHP/Version_3_10/webroot/font/cakedingbats-webfont.ttf b/tests/Frameworks/CakePHP/Version_3_10/webroot/font/cakedingbats-webfont.ttf new file mode 100644 index 0000000000..13d54454e7 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_3_10/webroot/font/cakedingbats-webfont.ttf differ diff --git a/tests/Frameworks/CakePHP/Version_3_10/webroot/font/cakedingbats-webfont.woff b/tests/Frameworks/CakePHP/Version_3_10/webroot/font/cakedingbats-webfont.woff new file mode 100644 index 0000000000..073baab113 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_3_10/webroot/font/cakedingbats-webfont.woff differ diff --git a/tests/Frameworks/CakePHP/Version_3_10/webroot/font/cakedingbats-webfont.woff2 b/tests/Frameworks/CakePHP/Version_3_10/webroot/font/cakedingbats-webfont.woff2 new file mode 100644 index 0000000000..6e71eaf53e Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_3_10/webroot/font/cakedingbats-webfont.woff2 differ diff --git a/tests/Frameworks/CakePHP/Version_3_10/webroot/img/cake-logo.png b/tests/Frameworks/CakePHP/Version_3_10/webroot/img/cake-logo.png new file mode 100644 index 0000000000..41939ef5a5 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_3_10/webroot/img/cake-logo.png differ diff --git a/tests/Frameworks/CakePHP/Version_3_10/webroot/img/cake.icon.png b/tests/Frameworks/CakePHP/Version_3_10/webroot/img/cake.icon.png new file mode 100644 index 0000000000..394fa42d51 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_3_10/webroot/img/cake.icon.png differ diff --git a/tests/Frameworks/CakePHP/Version_3_10/webroot/img/cake.logo.svg b/tests/Frameworks/CakePHP/Version_3_10/webroot/img/cake.logo.svg new file mode 100644 index 0000000000..e73abb54bc --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/webroot/img/cake.logo.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/Frameworks/CakePHP/Version_3_10/webroot/img/cake.power.gif b/tests/Frameworks/CakePHP/Version_3_10/webroot/img/cake.power.gif new file mode 100644 index 0000000000..8f8d570a2e Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_3_10/webroot/img/cake.power.gif differ diff --git a/tests/Frameworks/CakePHP/Version_3_10/webroot/index.php b/tests/Frameworks/CakePHP/Version_3_10/webroot/index.php new file mode 100644 index 0000000000..6bc06dc56c --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_3_10/webroot/index.php @@ -0,0 +1,40 @@ +emit($server->run()); diff --git a/tests/Frameworks/CakePHP/Version_3_10/webroot/js/empty b/tests/Frameworks/CakePHP/Version_3_10/webroot/js/empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Frameworks/CakePHP/Version_4_5/.editorconfig b/tests/Frameworks/CakePHP/Version_4_5/.editorconfig new file mode 100644 index 0000000000..a7b4d46fee --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/.editorconfig @@ -0,0 +1,23 @@ +; This file is for unifying the coding style for different editors and IDEs. +; More information at https://editorconfig.org + +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.bat] +end_of_line = crlf + +[*.yml] +indent_size = 2 + +[*.twig] +insert_final_newline = false + +[Makefile] +indent_style = tab diff --git a/tests/Frameworks/CakePHP/Version_4_5/.gitattributes b/tests/Frameworks/CakePHP/Version_4_5/.gitattributes new file mode 100644 index 0000000000..1ebf0b221e --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/.gitattributes @@ -0,0 +1,36 @@ +# Define the line ending behavior of the different file extensions +# Set default behavior, in case users don't have core.autocrlf set. +* text text=auto eol=lf + +# Declare files that will always have CRLF line endings on checkout. +*.bat eol=crlf + +# Declare files that will always have LF line endings on checkout. +*.pem eol=lf + +# Denote all files that are truly binary and should not be modified. +*.png binary +*.jpg binary +*.jpeg binary +*.gif binary +*.webp binary +*.avif binary +*.ico binary +*.mo binary +*.pdf binary +*.xls binary +*.xlsx binary +*.phar binary +*.woff binary +*.woff2 binary +*.ttc binary +*.ttf binary +*.otf binary +*.eot binary +*.gz binary +*.bz2 binary +*.7z binary +*.zip binary +*.webm binary +*.mp4 binary +*.ogv binary diff --git a/tests/Frameworks/CakePHP/Version_4_5/.gitignore b/tests/Frameworks/CakePHP/Version_4_5/.gitignore new file mode 100644 index 0000000000..9432fd0b90 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/.gitignore @@ -0,0 +1,52 @@ +# CakePHP specific files # +########################## +/config/app_local.php +/config/.env +/logs/* +/tmp/* +/vendor/* + +# OS generated files # +###################### +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +# Icon must end with two \r +Icon +ehthumbs.db +Thumbs.db +.directory + +# Tool specific files # +####################### +# PHPUnit +.phpunit.result.cache +tests.sqlite +# vim +*~ +*.swp +*.swo +# sublime text & textmate +*.sublime-* +*.stTheme.cache +*.tmlanguage.cache +*.tmPreferences.cache +# Eclipse +.settings/* +# JetBrains, aka PHPStorm, IntelliJ IDEA +.idea/* +# NetBeans +nbproject/* +# Visual Studio Code +.vscode +# nova +.nova +# Sass preprocessor +.sass-cache/ +# node +/node_modules/* +# yarn +yarn-debug.log +yarn-error.log diff --git a/tests/Frameworks/CakePHP/Version_4_5/.htaccess b/tests/Frameworks/CakePHP/Version_4_5/.htaccess new file mode 100644 index 0000000000..54b08e82e1 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/.htaccess @@ -0,0 +1,12 @@ +# Uncomment the following to prevent the httpoxy vulnerability +# See: https://httpoxy.org/ +# +# RequestHeader unset Proxy +# + + + RewriteEngine on + RewriteRule ^(\.well-known/.*)$ $1 [L] + RewriteRule ^$ webroot/ [L] + RewriteRule (.*) webroot/$1 [L] + diff --git a/tests/Frameworks/CakePHP/Version_4_5/README.md b/tests/Frameworks/CakePHP/Version_4_5/README.md new file mode 100644 index 0000000000..f0b0e973ea --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/README.md @@ -0,0 +1,53 @@ +# CakePHP Application Skeleton + +![Build Status](https://github.com/cakephp/app/actions/workflows/ci.yml/badge.svg?branch=master) +[![Total Downloads](https://img.shields.io/packagist/dt/cakephp/app.svg?style=flat-square)](https://packagist.org/packages/cakephp/app) +[![PHPStan](https://img.shields.io/badge/PHPStan-level%207-brightgreen.svg?style=flat-square)](https://github.com/phpstan/phpstan) + +A skeleton for creating applications with [CakePHP](https://cakephp.org) 4.x. + +The framework source code can be found here: [cakephp/cakephp](https://github.com/cakephp/cakephp). + +## Installation + +1. Download [Composer](https://getcomposer.org/doc/00-intro.md) or update `composer self-update`. +2. Run `php composer.phar create-project --prefer-dist cakephp/app [app_name]`. + +If Composer is installed globally, run + +```bash +composer create-project --prefer-dist cakephp/app +``` + +In case you want to use a custom app dir name (e.g. `/myapp/`): + +```bash +composer create-project --prefer-dist cakephp/app myapp +``` + +You can now either use your machine's webserver to view the default home page, or start +up the built-in webserver with: + +```bash +bin/cake server -p 8765 +``` + +Then visit `http://localhost:8765` to see the welcome page. + +## Update + +Since this skeleton is a starting point for your application and various files +would have been modified as per your needs, there isn't a way to provide +automated upgrades, so you have to do any updates manually. + +## Configuration + +Read and edit the environment specific `config/app_local.php` and set up the +`'Datasources'` and any other configuration relevant for your application. +Other environment agnostic settings can be changed in `config/app.php`. + +## Layout + +The app skeleton uses [Milligram](https://milligram.io/) (v1.3) minimalist CSS +framework by default. You can, however, replace it with any other library or +custom styles. diff --git a/tests/Frameworks/CakePHP/Version_4_5/bin/bash_completion.sh b/tests/Frameworks/CakePHP/Version_4_5/bin/bash_completion.sh new file mode 100644 index 0000000000..a3d3feba94 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/bin/bash_completion.sh @@ -0,0 +1,47 @@ +# +# Bash completion file for CakePHP console. +# Copy this file to a file named `cake` under `/etc/bash_completion.d/`. +# For more info check https://book.cakephp.org/4/en/console-commands/completion.html#how-to-enable-bash-autocompletion-for-the-cakephp-console +# + +_cake() +{ + local cur prev opts cake + COMPREPLY=() + cake="${COMP_WORDS[0]}" + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + if [[ "$cur" == -* ]] ; then + if [[ ${COMP_CWORD} = 1 ]] ; then + opts=$(${cake} completion options) + elif [[ ${COMP_CWORD} = 2 ]] ; then + opts=$(${cake} completion options "${COMP_WORDS[1]}") + else + opts=$(${cake} completion options "${COMP_WORDS[1]}" "${COMP_WORDS[2]}") + fi + + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 + fi + + if [[ ${COMP_CWORD} = 1 ]] ; then + opts=$(${cake} completion commands) + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 + fi + + if [[ ${COMP_CWORD} = 2 ]] ; then + opts=$(${cake} completion subcommands $prev) + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + if [[ $COMPREPLY = "" ]] ; then + _filedir + return 0 + fi + return 0 + fi + + return 0 +} + +complete -F _cake cake bin/cake diff --git a/tests/Frameworks/CakePHP/Version_4_5/bin/cake b/tests/Frameworks/CakePHP/Version_4_5/bin/cake new file mode 100755 index 0000000000..4b696c883f --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/bin/cake @@ -0,0 +1,75 @@ +#!/usr/bin/env sh +################################################################################ +# +# Cake is a shell script for invoking CakePHP shell commands +# +# CakePHP(tm) : Rapid Development Framework (https://cakephp.org) +# Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) +# +# Licensed under The MIT License +# For full copyright and license information, please see the LICENSE.txt +# Redistributions of files must retain the above copyright notice. +# +# @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) +# @link https://cakephp.org CakePHP(tm) Project +# @since 1.2.0 +# @license https://opensource.org/licenses/mit-license.php MIT License +# +################################################################################ + +# Canonicalize by following every symlink of the given name recursively +canonicalize() { + NAME="$1" + if [ -f "$NAME" ] + then + DIR=$(dirname -- "$NAME") + NAME=$(cd -P "$DIR" > /dev/null && pwd -P)/$(basename -- "$NAME") + fi + while [ -h "$NAME" ]; do + DIR=$(dirname -- "$NAME") + SYM=$(readlink "$NAME") + NAME=$(cd "$DIR" > /dev/null && cd "$(dirname -- "$SYM")" > /dev/null && pwd)/$(basename -- "$SYM") + done + echo "$NAME" +} + +# Find a CLI version of PHP +findCliPhp() { + for TESTEXEC in php php-cli /usr/local/bin/php + do + SAPI=$(echo "" | $TESTEXEC 2>/dev/null) + if [ "$SAPI" = "cli" ] + then + echo $TESTEXEC + return + fi + done + echo "Failed to find a CLI version of PHP; falling back to system standard php executable" >&2 + echo "php"; +} + +# If current path is a symlink, resolve to real path +realname="$0" +if [ -L "$realname" ] +then + realname=$(readlink -f "$0") +fi + +CONSOLE=$(dirname -- "$(canonicalize "$realname")") +APP=$(dirname "$CONSOLE") + +# If your CLI PHP is somewhere that this doesn't find, you can define a PHP environment +# variable with the correct path in it. +if [ -z "$PHP" ] +then + PHP=$(findCliPhp) +fi + +if [ "$(basename "$realname")" != 'cake' ] +then + exec "$PHP" "$CONSOLE"/cake.php "$(basename "$realname")" "$@" +else + exec "$PHP" "$CONSOLE"/cake.php "$@" +fi + +exit diff --git a/tests/Frameworks/CakePHP/Version_4_5/bin/cake.bat b/tests/Frameworks/CakePHP/Version_4_5/bin/cake.bat new file mode 100644 index 0000000000..ad13782298 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/bin/cake.bat @@ -0,0 +1,27 @@ +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:: +:: Cake is a Windows batch script for invoking CakePHP shell commands +:: +:: CakePHP(tm) : Rapid Development Framework (https://cakephp.org) +:: Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) +:: +:: Licensed under The MIT License +:: Redistributions of files must retain the above copyright notice. +:: +:: @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) +:: @link https://cakephp.org CakePHP(tm) Project +:: @since 2.0.0 +:: @license https://opensource.org/licenses/mit-license.php MIT License +:: +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +@echo off + +SET app=%0 +SET lib=%~dp0 + +php "%lib%cake.php" %* + +echo. + +exit /B %ERRORLEVEL% diff --git a/tests/Frameworks/CakePHP/Version_4_5/bin/cake.php b/tests/Frameworks/CakePHP/Version_4_5/bin/cake.php new file mode 100644 index 0000000000..320ee36439 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/bin/cake.php @@ -0,0 +1,12 @@ +#!/usr/bin/php -q +run($argv)); diff --git a/tests/Frameworks/CakePHP/Version_4_5/composer.json b/tests/Frameworks/CakePHP/Version_4_5/composer.json new file mode 100644 index 0000000000..2bf43ba101 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/composer.json @@ -0,0 +1,58 @@ +{ + "name": "cakephp/app", + "description": "CakePHP skeleton app", + "homepage": "https://cakephp.org", + "type": "project", + "license": "MIT", + "require": { + "php": ">=7.4", + "cakephp/cakephp": "^4.5.0", + "cakephp/migrations": "^3.7", + "cakephp/plugin-installer": "^1.3", + "mobiledetect/mobiledetectlib": "^3.74" + }, + "require-dev": { + "cakephp/bake": "^2.8", + "cakephp/cakephp-codesniffer": "^4.5", + "cakephp/debug_kit": "^4.9", + "josegonzalez/dotenv": "^4.0", + "phpunit/phpunit": "^9.6" + }, + "suggest": { + "markstory/asset_compress": "An asset compression plugin which provides file concatenation and a flexible filter system for preprocessing and minification.", + "dereuromark/cakephp-ide-helper": "After baking your code, this keeps your annotations in sync with the code evolving from there on for maximum IDE and PHPStan/Psalm compatibility.", + "phpstan/phpstan": "PHPStan focuses on finding errors in your code without actually running it. It catches whole classes of bugs even before you write tests for the code.", + "cakephp/repl": "Console tools for a REPL interface for CakePHP applications." + }, + "autoload": { + "psr-4": { + "App\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "App\\Test\\": "tests/", + "Cake\\Test\\": "vendor/cakephp/cakephp/tests/" + } + }, + "scripts": { + "post-install-cmd": "App\\Console\\Installer::postInstall", + "post-create-project-cmd": "App\\Console\\Installer::postInstall", + "check": [ + "@test", + "@cs-check" + ], + "cs-check": "phpcs --colors -p", + "cs-fix": "phpcbf --colors -p", + "test": "phpunit --colors=always" + }, + "minimum-stability": "dev", + "prefer-stable": true, + "config": { + "sort-packages": true, + "allow-plugins": { + "cakephp/plugin-installer": true, + "dealerdirect/phpcodesniffer-composer-installer": true + } + } +} diff --git a/tests/Frameworks/CakePHP/Version_4_5/config/.env.example b/tests/Frameworks/CakePHP/Version_4_5/config/.env.example new file mode 100644 index 0000000000..e90937b65c --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/config/.env.example @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# Used as a default to seed config/.env which +# enables you to use environment variables to configure +# the aspects of your application that vary by +# environment. +# +# Having this file in production is considered a **SECURITY RISK** and also decreases +# the bootstrap performance of your application. +# +# To use this file, first copy it into `config/.env`. Also ensure the related +# code block for loading this file is uncommented in `config/bootstrap.php` +# +# In development .env files are parsed by PHP +# and set into the environment. This provides a simpler +# development workflow over standard environment variables. +export APP_NAME="__APP_NAME__" +export DEBUG="true" +export APP_ENCODING="UTF-8" +export APP_DEFAULT_LOCALE="en_US" +export APP_DEFAULT_TIMEZONE="UTC" +export SECURITY_SALT="__SALT__" + +# Uncomment these to define cache configuration via environment variables. +#export CACHE_DURATION="+2 minutes" +#export CACHE_DEFAULT_URL="file:///path/to/tmp/cache/?prefix=${APP_NAME}_default_&duration=${CACHE_DURATION}" +#export CACHE_CAKECORE_URL="file:///path/to/tmp/cache/persistent?prefix=${APP_NAME}_cake_core_&serialize=true&duration=${CACHE_DURATION}" +#export CACHE_CAKEMODEL_URL="file:///path/to/tmp/cache/models?prefix=${APP_NAME}_cake_model_&serialize=true&duration=${CACHE_DURATION}" + +# Uncomment these to define email transport configuration via environment variables. +#export EMAIL_TRANSPORT_DEFAULT_URL="" + +# Uncomment these to define database configuration via environment variables. +#export DATABASE_URL="mysql://my_app:secret@localhost/${APP_NAME}?encoding=utf8&timezone=UTC&cacheMetadata=true"eIdentifiers=false&persistent=false" +#export DATABASE_TEST_URL="mysql://my_app:secret@localhost/test_${APP_NAME}?encoding=utf8&timezone=UTC&cacheMetadata=true"eIdentifiers=false&persistent=false" + +# Uncomment these to define logging configuration via environment variables. +#export LOG_DEBUG_URL="file:///path/to/logs/?levels[]=notice&levels[]=info&levels[]=debug&file=debug" +#export LOG_ERROR_URL="file:///path/to/logs/?levels[]=warning&levels[]=error&levels[]=critical&levels[]=alert&levels[]=emergency&file=error" diff --git a/tests/Frameworks/CakePHP/Version_4_5/config/app.php b/tests/Frameworks/CakePHP/Version_4_5/config/app.php new file mode 100644 index 0000000000..ae2b65cc85 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/config/app.php @@ -0,0 +1,424 @@ + filter_var(env('DEBUG', false), FILTER_VALIDATE_BOOLEAN), + + /* + * Configure basic information about the application. + * + * - namespace - The namespace to find app classes under. + * - defaultLocale - The default locale for translation, formatting currencies and numbers, date and time. + * - encoding - The encoding used for HTML + database connections. + * - base - The base directory the app resides in. If false this + * will be auto detected. + * - dir - Name of app directory. + * - webroot - The webroot directory. + * - wwwRoot - The file path to webroot. + * - baseUrl - To configure CakePHP to *not* use mod_rewrite and to + * use CakePHP pretty URLs, remove these .htaccess + * files: + * /.htaccess + * /webroot/.htaccess + * And uncomment the baseUrl key below. + * - fullBaseUrl - A base URL to use for absolute links. When set to false (default) + * CakePHP generates required value based on `HTTP_HOST` environment variable. + * However, you can define it manually to optimize performance or if you + * are concerned about people manipulating the `Host` header. + * - imageBaseUrl - Web path to the public images directory under webroot. + * - cssBaseUrl - Web path to the public css directory under webroot. + * - jsBaseUrl - Web path to the public js directory under webroot. + * - paths - Configure paths for non class based resources. Supports the + * `plugins`, `templates`, `locales` subkeys, which allow the definition of + * paths for plugins, view templates and locale files respectively. + */ + 'App' => [ + 'namespace' => 'App', + 'encoding' => env('APP_ENCODING', 'UTF-8'), + 'defaultLocale' => env('APP_DEFAULT_LOCALE', 'en_US'), + 'defaultTimezone' => env('APP_DEFAULT_TIMEZONE', 'UTC'), + 'base' => false, + 'dir' => 'src', + 'webroot' => 'webroot', + 'wwwRoot' => WWW_ROOT, + //'baseUrl' => env('SCRIPT_NAME'), + 'fullBaseUrl' => false, + 'imageBaseUrl' => 'img/', + 'cssBaseUrl' => 'css/', + 'jsBaseUrl' => 'js/', + 'paths' => [ + 'plugins' => [ROOT . DS . 'plugins' . DS], + 'templates' => [ROOT . DS . 'templates' . DS], + 'locales' => [RESOURCES . 'locales' . DS], + ], + ], + + /* + * Security and encryption configuration + * + * - salt - A random string used in security hashing methods. + * The salt value is also used as the encryption key. + * You should treat it as extremely sensitive data. + */ + 'Security' => [ + 'salt' => env('SECURITY_SALT', 'dfc123c6c22d84f4bc12273f3df67c6ae55009696e4126b36ac2f755778faccc'), + ], + + /* + * Apply timestamps with the last modified time to static assets (js, css, images). + * Will append a querystring parameter containing the time the file was modified. + * This is useful for busting browser caches. + * + * Set to true to apply timestamps when debug is true. Set to 'force' to always + * enable timestamping regardless of debug value. + */ + 'Asset' => [ + //'timestamp' => true, + // 'cacheTime' => '+1 year' + ], + + /* + * Configure the cache adapters. + */ + 'Cache' => [ + 'default' => [ + 'className' => FileEngine::class, + 'path' => CACHE, + 'url' => env('CACHE_DEFAULT_URL', null), + ], + + /* + * Configure the cache used for general framework caching. + * Translation cache files are stored with this configuration. + * Duration will be set to '+2 minutes' in bootstrap.php when debug = true + * If you set 'className' => 'Null' core cache will be disabled. + */ + '_cake_core_' => [ + 'className' => FileEngine::class, + 'prefix' => 'myapp_cake_core_', + 'path' => CACHE . 'persistent' . DS, + 'serialize' => true, + 'duration' => '+1 years', + 'url' => env('CACHE_CAKECORE_URL', null), + ], + + /* + * Configure the cache for model and datasource caches. This cache + * configuration is used to store schema descriptions, and table listings + * in connections. + * Duration will be set to '+2 minutes' in bootstrap.php when debug = true + */ + '_cake_model_' => [ + 'className' => FileEngine::class, + 'prefix' => 'myapp_cake_model_', + 'path' => CACHE . 'models' . DS, + 'serialize' => true, + 'duration' => '+1 years', + 'url' => env('CACHE_CAKEMODEL_URL', null), + ], + + /* + * Configure the cache for routes. The cached routes collection is built the + * first time the routes are processed through `config/routes.php`. + * Duration will be set to '+2 seconds' in bootstrap.php when debug = true + */ + '_cake_routes_' => [ + 'className' => FileEngine::class, + 'prefix' => 'myapp_cake_routes_', + 'path' => CACHE, + 'serialize' => true, + 'duration' => '+1 years', + 'url' => env('CACHE_CAKEROUTES_URL', null), + ], + ], + + /* + * Configure the Error and Exception handlers used by your application. + * + * By default errors are displayed using Debugger, when debug is true and logged + * by Cake\Log\Log when debug is false. + * + * In CLI environments exceptions will be printed to stderr with a backtrace. + * In web environments an HTML page will be displayed for the exception. + * With debug true, framework errors like Missing Controller will be displayed. + * When debug is false, framework errors will be coerced into generic HTTP errors. + * + * Options: + * + * - `errorLevel` - int - The level of errors you are interested in capturing. + * - `trace` - boolean - Whether or not backtraces should be included in + * logged errors/exceptions. + * - `log` - boolean - Whether or not you want exceptions logged. + * - `exceptionRenderer` - string - The class responsible for rendering uncaught exceptions. + * The chosen class will be used for for both CLI and web environments. If you want different + * classes used in CLI and web environments you'll need to write that conditional logic as well. + * The conventional location for custom renderers is in `src/Error`. Your exception renderer needs to + * implement the `render()` method and return either a string or Http\Response. + * `errorRenderer` - string - The class responsible for rendering PHP errors. The selected + * class will be used for both web and CLI contexts. If you want different classes for each environment + * you'll need to write that conditional logic as well. Error renderers need to + * to implement the `Cake\Error\ErrorRendererInterface`. + * - `skipLog` - array - List of exceptions to skip for logging. Exceptions that + * extend one of the listed exceptions will also be skipped for logging. + * E.g.: + * `'skipLog' => ['Cake\Http\Exception\NotFoundException', 'Cake\Http\Exception\UnauthorizedException']` + * - `extraFatalErrorMemory` - int - The number of megabytes to increase the memory limit by + * when a fatal error is encountered. This allows + * breathing room to complete logging or error handling. + * - `ignoredDeprecationPaths` - array - A list of glob compatible file paths that deprecations + * should be ignored in. Use this to ignore deprecations for plugins or parts of + * your application that still emit deprecations. + */ + 'Error' => [ + 'errorLevel' => E_ALL, + 'skipLog' => [], + 'log' => true, + 'trace' => true, + 'ignoredDeprecationPaths' => [], + ], + + /* + * Debugger configuration + * + * Define development error values for Cake\Error\Debugger + * + * - `editor` Set the editor URL format you want to use. + * By default atom, emacs, macvim, phpstorm, sublime, textmate, and vscode are + * available. You can add additional editor link formats using + * `Debugger::addEditor()` during your application bootstrap. + * - `outputMask` A mapping of `key` to `replacement` values that + * `Debugger` should replace in dumped data and logs generated by `Debugger`. + */ + 'Debugger' => [ + 'editor' => 'phpstorm', + ], + + /* + * Email configuration. + * + * By defining transports separately from delivery profiles you can easily + * re-use transport configuration across multiple profiles. + * + * You can specify multiple configurations for production, development and + * testing. + * + * Each transport needs a `className`. Valid options are as follows: + * + * Mail - Send using PHP mail function + * Smtp - Send using SMTP + * Debug - Do not send the email, just return the result + * + * You can add custom transports (or override existing transports) by adding the + * appropriate file to src/Mailer/Transport. Transports should be named + * 'YourTransport.php', where 'Your' is the name of the transport. + */ + 'EmailTransport' => [ + 'default' => [ + 'className' => MailTransport::class, + /* + * The keys host, port, timeout, username, password, client and tls + * are used in SMTP transports + */ + 'host' => 'localhost', + 'port' => 25, + 'timeout' => 30, + /* + * It is recommended to set these options through your environment or app_local.php + */ + //'username' => null, + //'password' => null, + 'client' => null, + 'tls' => false, + 'url' => env('EMAIL_TRANSPORT_DEFAULT_URL', null), + ], + ], + + /* + * Email delivery profiles + * + * Delivery profiles allow you to predefine various properties about email + * messages from your application and give the settings a name. This saves + * duplication across your application and makes maintenance and development + * easier. Each profile accepts a number of keys. See `Cake\Mailer\Email` + * for more information. + */ + 'Email' => [ + 'default' => [ + 'transport' => 'default', + 'from' => 'you@localhost', + /* + * Will by default be set to config value of App.encoding, if that exists otherwise to UTF-8. + */ + //'charset' => 'utf-8', + //'headerCharset' => 'utf-8', + ], + ], + + /* + * Connection information used by the ORM to connect + * to your application's datastores. + * + * ### Notes + * - Drivers include Mysql Postgres Sqlite Sqlserver + * See vendor\cakephp\cakephp\src\Database\Driver for complete list + * - Do not use periods in database name - it may lead to error. + * See https://github.com/cakephp/cakephp/issues/6471 for details. + * - 'encoding' is recommended to be set to full UTF-8 4-Byte support. + * E.g set it to 'utf8mb4' in MariaDB and MySQL and 'utf8' for any + * other RDBMS. + */ + 'Datasources' => [ + /* + * These configurations should contain permanent settings used + * by all environments. + * + * The values in app_local.php will override any values set here + * and should be used for local and per-environment configurations. + * + * Environment variable based configurations can be loaded here or + * in app_local.php depending on the applications needs. + */ + 'default' => [ + 'className' => Connection::class, + 'driver' => Mysql::class, + 'persistent' => false, + 'timezone' => 'UTC', + + /* + * For MariaDB/MySQL the internal default changed from utf8 to utf8mb4, aka full utf-8 support, in CakePHP 3.6 + */ + //'encoding' => 'utf8mb4', + + /* + * If your MySQL server is configured with `skip-character-set-client-handshake` + * then you MUST use the `flags` config to set your charset encoding. + * For e.g. `'flags' => [\PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4']` + */ + 'flags' => [], + 'cacheMetadata' => true, + 'log' => false, + + /* + * Set identifier quoting to true if you are using reserved words or + * special characters in your table or column names. Enabling this + * setting will result in queries built using the Query Builder having + * identifiers quoted when creating SQL. It should be noted that this + * decreases performance because each query needs to be traversed and + * manipulated before being executed. + */ + 'quoteIdentifiers' => false, + + /* + * During development, if using MySQL < 5.6, uncommenting the + * following line could boost the speed at which schema metadata is + * fetched from the database. It can also be set directly with the + * mysql configuration directive 'innodb_stats_on_metadata = 0' + * which is the recommended value in production environments + */ + //'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'], + ], + + /* + * The test connection is used during the test suite. + */ + 'test' => [ + 'className' => Connection::class, + 'driver' => Mysql::class, + 'persistent' => false, + 'timezone' => 'UTC', + //'encoding' => 'utf8mb4', + 'flags' => [], + 'cacheMetadata' => true, + 'quoteIdentifiers' => false, + 'log' => false, + //'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'], + ], + ], + + /* + * Configures logging options + */ + 'Log' => [ + 'debug' => [ + 'className' => FileLog::class, + 'path' => LOGS, + 'file' => 'debug', + 'url' => env('LOG_DEBUG_URL', null), + 'scopes' => false, + 'levels' => ['notice', 'info', 'debug'], + ], + 'error' => [ + 'className' => FileLog::class, + 'path' => LOGS, + 'file' => 'error', + 'url' => env('LOG_ERROR_URL', null), + 'scopes' => false, + 'levels' => ['warning', 'error', 'critical', 'alert', 'emergency'], + ], + // To enable this dedicated query log, you need set your datasource's log flag to true + 'queries' => [ + 'className' => FileLog::class, + 'path' => LOGS, + 'file' => 'queries', + 'url' => env('LOG_QUERIES_URL', null), + 'scopes' => ['queriesLog'], + ], + ], + + /* + * Session configuration. + * + * Contains an array of settings to use for session configuration. The + * `defaults` key is used to define a default preset to use for sessions, any + * settings declared here will override the settings of the default config. + * + * ## Options + * + * - `cookie` - The name of the cookie to use. Defaults to value set for `session.name` php.ini config. + * Avoid using `.` in cookie names, as PHP will drop sessions from cookies with `.` in the name. + * - `cookiePath` - The url path for which session cookie is set. Maps to the + * `session.cookie_path` php.ini config. Defaults to base path of app. + * - `timeout` - The time in minutes the session should be valid for. + * Pass 0 to disable checking timeout. + * Please note that php.ini's session.gc_maxlifetime must be equal to or greater + * than the largest Session['timeout'] in all served websites for it to have the + * desired effect. + * - `defaults` - The default configuration set to use as a basis for your session. + * There are four built-in options: php, cake, cache, database. + * - `handler` - Can be used to enable a custom session handler. Expects an + * array with at least the `engine` key, being the name of the Session engine + * class to use for managing the session. CakePHP bundles the `CacheSession` + * and `DatabaseSession` engines. + * - `ini` - An associative array of additional 'session.*` ini values to set. + * + * The built-in `defaults` options are: + * + * - 'php' - Uses settings defined in your php.ini. + * - 'cake' - Saves session files in CakePHP's /tmp directory. + * - 'database' - Uses CakePHP's database sessions. + * - 'cache' - Use the Cache class to save sessions. + * + * To define a custom session handler, save it at src/Http/Session/.php. + * Make sure the class implements PHP's `SessionHandlerInterface` and set + * Session.handler to + * + * To use database sessions, load the SQL file located at config/schema/sessions.sql + */ + 'Session' => [ + 'defaults' => 'php', + ], +]; diff --git a/tests/Frameworks/CakePHP/Version_4_5/config/app_local.example.php b/tests/Frameworks/CakePHP/Version_4_5/config/app_local.example.php new file mode 100644 index 0000000000..8bdb855dd5 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/config/app_local.example.php @@ -0,0 +1,94 @@ + filter_var(env('DEBUG', true), FILTER_VALIDATE_BOOLEAN), + + /* + * Security and encryption configuration + * + * - salt - A random string used in security hashing methods. + * The salt value is also used as the encryption key. + * You should treat it as extremely sensitive data. + */ + 'Security' => [ + 'salt' => env('SECURITY_SALT', '__SALT__'), + ], + + /* + * Connection information used by the ORM to connect + * to your application's datastores. + * + * See app.php for more configuration options. + */ + 'Datasources' => [ + 'default' => [ + 'host' => 'localhost', + /* + * CakePHP will use the default DB port based on the driver selected + * MySQL on MAMP uses port 8889, MAMP users will want to uncomment + * the following line and set the port accordingly + */ + //'port' => 'non_standard_port_number', + + 'username' => 'my_app', + 'password' => 'secret', + + 'database' => 'my_app', + /* + * If not using the default 'public' schema with the PostgreSQL driver + * set it here. + */ + //'schema' => 'myapp', + + /* + * You can use a DSN string to set the entire configuration + */ + 'url' => env('DATABASE_URL', null), + ], + + /* + * The test connection is used during the test suite. + */ + 'test' => [ + 'host' => 'localhost', + //'port' => 'non_standard_port_number', + 'username' => 'my_app', + 'password' => 'secret', + 'database' => 'test_myapp', + //'schema' => 'myapp', + 'url' => env('DATABASE_TEST_URL', 'sqlite://127.0.0.1/tmp/tests.sqlite'), + ], + ], + + /* + * Email configuration. + * + * Host and credential configuration in case you are using SmtpTransport + * + * See app.php for more configuration options. + */ + 'EmailTransport' => [ + 'default' => [ + 'host' => 'localhost', + 'port' => 25, + 'username' => null, + 'password' => null, + 'client' => null, + 'url' => env('EMAIL_TRANSPORT_DEFAULT_URL', null), + ], + ], +]; diff --git a/tests/Frameworks/CakePHP/Version_4_5/config/bootstrap.php b/tests/Frameworks/CakePHP/Version_4_5/config/bootstrap.php new file mode 100644 index 0000000000..5374a159be --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/config/bootstrap.php @@ -0,0 +1,229 @@ +parse() +// ->putenv() +// ->toEnv() +// ->toServer(); +// } + +/* + * Read configuration file and inject configuration into various + * CakePHP classes. + * + * By default there is only one configuration file. It is often a good + * idea to create multiple configuration files, and separate the configuration + * that changes from configuration that does not. This makes deployment simpler. + */ +try { + Configure::config('default', new PhpConfig()); + Configure::load('app', 'default', false); +} catch (\Exception $e) { + exit($e->getMessage() . "\n"); +} + +/* + * Load an environment local configuration file to provide overrides to your configuration. + * Notice: For security reasons app_local.php **should not** be included in your git repo. + */ +if (file_exists(CONFIG . 'app_local.php')) { + Configure::load('app_local', 'default'); +} + +/* + * When debug = true the metadata cache should only last + * for a short time. + */ +if (Configure::read('debug')) { + Configure::write('Cache._cake_model_.duration', '+2 minutes'); + Configure::write('Cache._cake_core_.duration', '+2 minutes'); + // disable router cache during development + Configure::write('Cache._cake_routes_.duration', '+2 seconds'); +} + +/* + * Set the default server timezone. Using UTC makes time calculations / conversions easier. + * Check https://php.net/manual/en/timezones.php for list of valid timezone strings. + */ +date_default_timezone_set(Configure::read('App.defaultTimezone')); + +/* + * Configure the mbstring extension to use the correct encoding. + */ +mb_internal_encoding(Configure::read('App.encoding')); + +/* + * Set the default locale. This controls how dates, number and currency is + * formatted and sets the default language to use for translations. + */ +ini_set('intl.default_locale', Configure::read('App.defaultLocale')); + +/* + * Register application error and exception handlers. + */ +(new ErrorTrap(Configure::read('Error')))->register(); +(new ExceptionTrap(Configure::read('Error')))->register(); + +/* + * Include the CLI bootstrap overrides. + */ +if (PHP_SAPI === 'cli') { + require CONFIG . 'bootstrap_cli.php'; +} + +/* + * Set the full base URL. + * This URL is used as the base of all absolute links. + */ +$fullBaseUrl = Configure::read('App.fullBaseUrl'); +if (!$fullBaseUrl) { + /* + * When using proxies or load balancers, SSL/TLS connections might + * get terminated before reaching the server. If you trust the proxy, + * you can enable `$trustProxy` to rely on the `X-Forwarded-Proto` + * header to determine whether to generate URLs using `https`. + * + * See also https://book.cakephp.org/4/en/controllers/request-response.html#trusting-proxy-headers + */ + $trustProxy = false; + + $s = null; + if (env('HTTPS') || ($trustProxy && env('HTTP_X_FORWARDED_PROTO') === 'https')) { + $s = 's'; + } + + $httpHost = env('HTTP_HOST'); + if (isset($httpHost)) { + $fullBaseUrl = 'http' . $s . '://' . $httpHost; + } + unset($httpHost, $s); +} +if ($fullBaseUrl) { + Router::fullBaseUrl($fullBaseUrl); +} +unset($fullBaseUrl); + +Cache::setConfig(Configure::consume('Cache')); +ConnectionManager::setConfig(Configure::consume('Datasources')); +TransportFactory::setConfig(Configure::consume('EmailTransport')); +Mailer::setConfig(Configure::consume('Email')); +Log::setConfig(Configure::consume('Log')); +Security::setSalt(Configure::consume('Security.salt')); + +/* + * Setup detectors for mobile and tablet. + * If you don't use these checks you can safely remove this code + * and the mobiledetect package from composer.json. + */ +ServerRequest::addDetector('mobile', function ($request) { + $detector = new \Detection\MobileDetect(); + + return $detector->isMobile(); +}); +ServerRequest::addDetector('tablet', function ($request) { + $detector = new \Detection\MobileDetect(); + + return $detector->isTablet(); +}); + +/* + * You can enable default locale format parsing by adding calls + * to `useLocaleParser()`. This enables the automatic conversion of + * locale specific date formats. For details see + * @link https://book.cakephp.org/4/en/core-libraries/internationalization-and-localization.html#parsing-localized-datetime-data + */ +// \Cake\Database\TypeFactory::build('time') +// ->useLocaleParser(); +// \Cake\Database\TypeFactory::build('date') +// ->useLocaleParser(); +// \Cake\Database\TypeFactory::build('datetime') +// ->useLocaleParser(); +// \Cake\Database\TypeFactory::build('timestamp') +// ->useLocaleParser(); +// \Cake\Database\TypeFactory::build('datetimefractional') +// ->useLocaleParser(); +// \Cake\Database\TypeFactory::build('timestampfractional') +// ->useLocaleParser(); +// \Cake\Database\TypeFactory::build('datetimetimezone') +// ->useLocaleParser(); +// \Cake\Database\TypeFactory::build('timestamptimezone') +// ->useLocaleParser(); + +// There is no time-specific type in Cake +TypeFactory::map('time', StringType::class); + +/* + * Custom Inflector rules, can be set to correctly pluralize or singularize + * table, model, controller names or whatever other string is passed to the + * inflection functions. + */ +//Inflector::rules('plural', ['/^(inflect)or$/i' => '\1ables']); +//Inflector::rules('irregular', ['red' => 'redlings']); +//Inflector::rules('uninflected', ['dontinflectme']); + +// set a custom date and time format +// see https://book.cakephp.org/4/en/core-libraries/time.html#setting-the-default-locale-and-format-string +// and https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax +//\Cake\I18n\FrozenDate::setToStringFormat('dd.MM.yyyy'); +//\Cake\I18n\FrozenTime::setToStringFormat('dd.MM.yyyy HH:mm'); diff --git a/tests/Frameworks/CakePHP/Version_4_5/config/bootstrap_cli.php b/tests/Frameworks/CakePHP/Version_4_5/config/bootstrap_cli.php new file mode 100644 index 0000000000..fc0dc30bb5 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/config/bootstrap_cli.php @@ -0,0 +1,35 @@ += 50.1 is needed to use CakePHP. Please update the `libicu` package of your system.' . PHP_EOL, + E_USER_ERROR + ); +} + +/* + * You can remove this if you are confident you have mbstring installed. + */ +if (!extension_loaded('mbstring')) { + trigger_error('You must enable the mbstring extension to use CakePHP.', E_USER_ERROR); +} diff --git a/tests/Frameworks/CakePHP/Version_4_5/config/routes.php b/tests/Frameworks/CakePHP/Version_4_5/config/routes.php new file mode 100644 index 0000000000..5fcffd8056 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/config/routes.php @@ -0,0 +1,101 @@ +setRouteClass(DashedRoute::class); + + $routes->scope('/', function (RouteBuilder $builder): void { + /* + * Here, we are connecting '/' (base path) to a controller called 'Pages', + * its action called 'display', and we pass a param to select the view file + * to use (in this case, templates/Pages/home.php)... + */ + $builder->connect('/', ['controller' => 'Pages', 'action' => 'display', 'home']); + + /* + * ...and connect the rest of 'Pages' controller's URLs. + */ + $builder->connect('/pages/*', 'Pages::display'); + + $builder->connect('/parameterized/{param}', + ['controller' => 'Parameterized', 'action' => 'customAction'], + ['pass' => ['param']] + ); + + /* + * Connect catchall routes for all controllers. + * + * The `fallbacks` method is a shortcut for + * + * ``` + * $builder->connect('/{controller}', ['action' => 'index']); + * $builder->connect('/{controller}/{action}/*', []); + * ``` + * + * You can remove these routes once you've connected the + * routes you want in your application. + */ + $builder->fallbacks(); + }); + + /* + * If you need a different set of middleware or none at all, + * open new scope and define routes there. + * + * ``` + * $routes->scope('/api', function (RouteBuilder $builder): void { + * // No $builder->applyMiddleware() here. + * + * // Parse specified extensions from URLs + * // $builder->setExtensions(['json', 'xml']); + * + * // Connect API actions here. + * }); + * ``` + */ +}; diff --git a/tests/Frameworks/CakePHP/Version_4_5/config/schema/i18n.sql b/tests/Frameworks/CakePHP/Version_4_5/config/schema/i18n.sql new file mode 100644 index 0000000000..e59d1e6511 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/config/schema/i18n.sql @@ -0,0 +1,18 @@ +# Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) +# +# Licensed under The MIT License +# For full copyright and license information, please see the LICENSE.txt +# Redistributions of files must retain the above copyright notice. +# MIT License (https://opensource.org/licenses/mit-license.php) + +CREATE TABLE i18n ( + id int NOT NULL auto_increment, + locale varchar(6) NOT NULL, + model varchar(255) NOT NULL, + foreign_key int(10) NOT NULL, + field varchar(255) NOT NULL, + content text, + PRIMARY KEY (id), + UNIQUE INDEX I18N_LOCALE_FIELD(locale, model, foreign_key, field), + INDEX I18N_FIELD(model, foreign_key, field) +); diff --git a/tests/Frameworks/CakePHP/Version_4_5/config/schema/sessions.sql b/tests/Frameworks/CakePHP/Version_4_5/config/schema/sessions.sql new file mode 100644 index 0000000000..1aa0a0f54e --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/config/schema/sessions.sql @@ -0,0 +1,15 @@ +# Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) +# +# Licensed under The MIT License +# For full copyright and license information, please see the LICENSE.txt +# Redistributions of files must retain the above copyright notice. +# MIT License (https://opensource.org/licenses/mit-license.php) + +CREATE TABLE `sessions` ( + `id` char(40) CHARACTER SET ascii COLLATE ascii_bin NOT NULL, + `created` datetime DEFAULT CURRENT_TIMESTAMP, -- optional, requires MySQL 5.6.5+ + `modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- optional, requires MySQL 5.6.5+ + `data` blob DEFAULT NULL, -- for PostgreSQL use bytea instead of blob + `expires` int(10) unsigned DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/tests/Frameworks/CakePHP/Version_4_5/index.php b/tests/Frameworks/CakePHP/Version_4_5/index.php new file mode 100644 index 0000000000..4591769163 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/index.php @@ -0,0 +1,16 @@ + + + + + + + src/ + tests/ + diff --git a/tests/Frameworks/CakePHP/Version_4_5/phpstan.neon b/tests/Frameworks/CakePHP/Version_4_5/phpstan.neon new file mode 100644 index 0000000000..da361a890d --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/phpstan.neon @@ -0,0 +1,9 @@ +parameters: + level: 8 + checkMissingIterableValueType: false + treatPhpDocTypesAsCertain: false + checkGenericClassInNonGenericObjectType: false + paths: + - src/ + excludePaths: + - src/Console/Installer.php diff --git a/tests/Frameworks/CakePHP/Version_4_5/phpunit.xml.dist b/tests/Frameworks/CakePHP/Version_4_5/phpunit.xml.dist new file mode 100644 index 0000000000..1f587f900e --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/phpunit.xml.dist @@ -0,0 +1,36 @@ + + + + + + + + + + + tests/TestCase/ + + + + + + + + + + + + + src/ + plugins/*/src/ + + src/Console/Installer.php + + + + diff --git a/tests/Frameworks/CakePHP/Version_4_5/plugins/.gitkeep b/tests/Frameworks/CakePHP/Version_4_5/plugins/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Frameworks/CakePHP/Version_4_5/resources/.gitkeep b/tests/Frameworks/CakePHP/Version_4_5/resources/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Frameworks/CakePHP/Version_4_5/src/Application.php b/tests/Frameworks/CakePHP/Version_4_5/src/Application.php new file mode 100644 index 0000000000..496aa3a9ef --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/src/Application.php @@ -0,0 +1,133 @@ +bootstrapCli(); + } else { + FactoryLocator::add( + 'Table', + (new TableLocator())->allowFallbackClass(false) + ); + } + + /* + * Only try to load DebugKit in development mode + * Debug Kit should not be installed on a production system + */ + if (Configure::read('debug')) { + $this->addPlugin('DebugKit'); + } + + // Load more plugins here + } + + /** + * Setup the middleware queue your application will use. + * + * @param \Cake\Http\MiddlewareQueue $middlewareQueue The middleware queue to setup. + * @return \Cake\Http\MiddlewareQueue The updated middleware queue. + */ + public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue + { + $middlewareQueue + // Catch any exceptions in the lower layers, + // and make an error page/response + ->add(new ErrorHandlerMiddleware(Configure::read('Error'), $this)) + + // Handle plugin/theme assets like CakePHP normally does. + ->add(new AssetMiddleware([ + 'cacheTime' => Configure::read('Asset.cacheTime'), + ])) + + // Add routing middleware. + // If you have a large number of routes connected, turning on routes + // caching in production could improve performance. + // See https://github.com/CakeDC/cakephp-cached-routing + ->add(new RoutingMiddleware($this)) + + // Parse various types of encoded request bodies so that they are + // available as array through $request->getData() + // https://book.cakephp.org/4/en/controllers/middleware.html#body-parser-middleware + ->add(new BodyParserMiddleware()) + + // Cross Site Request Forgery (CSRF) Protection Middleware + // https://book.cakephp.org/4/en/security/csrf.html#cross-site-request-forgery-csrf-middleware + ->add(new CsrfProtectionMiddleware([ + 'httponly' => true, + ])); + + return $middlewareQueue; + } + + /** + * Register application container services. + * + * @param \Cake\Core\ContainerInterface $container The Container to update. + * @return void + * @link https://book.cakephp.org/4/en/development/dependency-injection.html#dependency-injection + */ + public function services(ContainerInterface $container): void + { + } + + /** + * Bootstrapping for CLI application. + * + * That is when running commands. + * + * @return void + */ + protected function bootstrapCli(): void + { + $this->addOptionalPlugin('Bake'); + + $this->addPlugin('Migrations'); + + // Load more plugins here + } +} diff --git a/tests/Frameworks/CakePHP/Version_4_5/src/Console/Installer.php b/tests/Frameworks/CakePHP/Version_4_5/src/Console/Installer.php new file mode 100644 index 0000000000..4bdccc104d --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/src/Console/Installer.php @@ -0,0 +1,246 @@ +getIO(); + + $rootDir = dirname(dirname(__DIR__)); + + static::createAppLocalConfig($rootDir, $io); + static::createWritableDirectories($rootDir, $io); + + static::setFolderPermissions($rootDir, $io); + static::setSecuritySalt($rootDir, $io); + + if (class_exists(CodeceptionInstaller::class)) { + CodeceptionInstaller::customizeCodeceptionBinary($event); + } + } + + /** + * Create config/app_local.php file if it does not exist. + * + * @param string $dir The application's root directory. + * @param \Composer\IO\IOInterface $io IO interface to write to console. + * @return void + */ + public static function createAppLocalConfig($dir, $io) + { + $appLocalConfig = $dir . '/config/app_local.php'; + $appLocalConfigTemplate = $dir . '/config/app_local.example.php'; + if (!file_exists($appLocalConfig)) { + copy($appLocalConfigTemplate, $appLocalConfig); + $io->write('Created `config/app_local.php` file'); + } + } + + /** + * Create the `logs` and `tmp` directories. + * + * @param string $dir The application's root directory. + * @param \Composer\IO\IOInterface $io IO interface to write to console. + * @return void + */ + public static function createWritableDirectories($dir, $io) + { + foreach (static::WRITABLE_DIRS as $path) { + $path = $dir . '/' . $path; + if (!file_exists($path)) { + mkdir($path); + $io->write('Created `' . $path . '` directory'); + } + } + } + + /** + * Set globally writable permissions on the "tmp" and "logs" directory. + * + * This is not the most secure default, but it gets people up and running quickly. + * + * @param string $dir The application's root directory. + * @param \Composer\IO\IOInterface $io IO interface to write to console. + * @return void + */ + public static function setFolderPermissions($dir, $io) + { + // ask if the permissions should be changed + if ($io->isInteractive()) { + $validator = function ($arg) { + if (in_array($arg, ['Y', 'y', 'N', 'n'])) { + return $arg; + } + throw new Exception('This is not a valid answer. Please choose Y or n.'); + }; + $setFolderPermissions = $io->askAndValidate( + 'Set Folder Permissions ? (Default to Y) [Y,n]? ', + $validator, + 10, + 'Y' + ); + + if (in_array($setFolderPermissions, ['n', 'N'])) { + return; + } + } + + // Change the permissions on a path and output the results. + $changePerms = function ($path) use ($io) { + $currentPerms = fileperms($path) & 0777; + $worldWritable = $currentPerms | 0007; + if ($worldWritable == $currentPerms) { + return; + } + + $res = chmod($path, $worldWritable); + if ($res) { + $io->write('Permissions set on ' . $path); + } else { + $io->write('Failed to set permissions on ' . $path); + } + }; + + $walker = function ($dir) use (&$walker, $changePerms) { + $files = array_diff(scandir($dir), ['.', '..']); + foreach ($files as $file) { + $path = $dir . '/' . $file; + + if (!is_dir($path)) { + continue; + } + + $changePerms($path); + $walker($path); + } + }; + + $walker($dir . '/tmp'); + $changePerms($dir . '/tmp'); + $changePerms($dir . '/logs'); + } + + /** + * Set the security.salt value in the application's config file. + * + * @param string $dir The application's root directory. + * @param \Composer\IO\IOInterface $io IO interface to write to console. + * @return void + */ + public static function setSecuritySalt($dir, $io) + { + $newKey = hash('sha256', Security::randomBytes(64)); + static::setSecuritySaltInFile($dir, $io, $newKey, 'app_local.php'); + } + + /** + * Set the security.salt value in a given file + * + * @param string $dir The application's root directory. + * @param \Composer\IO\IOInterface $io IO interface to write to console. + * @param string $newKey key to set in the file + * @param string $file A path to a file relative to the application's root + * @return void + */ + public static function setSecuritySaltInFile($dir, $io, $newKey, $file) + { + $config = $dir . '/config/' . $file; + $content = file_get_contents($config); + + $content = str_replace('__SALT__', $newKey, $content, $count); + + if ($count == 0) { + $io->write('No Security.salt placeholder to replace.'); + + return; + } + + $result = file_put_contents($config, $content); + if ($result) { + $io->write('Updated Security.salt value in config/' . $file); + + return; + } + $io->write('Unable to update Security.salt value.'); + } + + /** + * Set the APP_NAME value in a given file + * + * @param string $dir The application's root directory. + * @param \Composer\IO\IOInterface $io IO interface to write to console. + * @param string $appName app name to set in the file + * @param string $file A path to a file relative to the application's root + * @return void + */ + public static function setAppNameInFile($dir, $io, $appName, $file) + { + $config = $dir . '/config/' . $file; + $content = file_get_contents($config); + $content = str_replace('__APP_NAME__', $appName, $content, $count); + + if ($count == 0) { + $io->write('No __APP_NAME__ placeholder to replace.'); + + return; + } + + $result = file_put_contents($config, $content); + if ($result) { + $io->write('Updated __APP_NAME__ value in config/' . $file); + + return; + } + $io->write('Unable to update __APP_NAME__ value.'); + } +} diff --git a/tests/Frameworks/CakePHP/Version_4_5/src/Controller/AppController.php b/tests/Frameworks/CakePHP/Version_4_5/src/Controller/AppController.php new file mode 100644 index 0000000000..809c93d434 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/src/Controller/AppController.php @@ -0,0 +1,53 @@ +loadComponent('FormProtection');` + * + * @return void + */ + public function initialize(): void + { + parent::initialize(); + + $this->loadComponent('RequestHandler'); + $this->loadComponent('Flash'); + + /* + * Enable the following component for recommended CakePHP form protection settings. + * see https://book.cakephp.org/4/en/controllers/components/form-protection.html + */ + //$this->loadComponent('FormProtection'); + } +} diff --git a/tests/Frameworks/CakePHP/Version_4_5/src/Controller/Component/.gitkeep b/tests/Frameworks/CakePHP/Version_4_5/src/Controller/Component/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Frameworks/CakePHP/Version_4_5/src/Controller/ErrorController.php b/tests/Frameworks/CakePHP/Version_4_5/src/Controller/ErrorController.php new file mode 100644 index 0000000000..c6a12b15d0 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/src/Controller/ErrorController.php @@ -0,0 +1,75 @@ +loadComponent('RequestHandler'); + } + + /** + * beforeFilter callback. + * + * @param \Cake\Event\EventInterface<\App\Controller\ErrorController> $event Event. + * @return \Cake\Http\Response|null|void + */ + public function beforeFilter(EventInterface $event) + { + } + + /** + * beforeRender callback. + * + * @param \Cake\Event\EventInterface<\App\Controller\ErrorController> $event Event. + * @return \Cake\Http\Response|null|void + */ + public function beforeRender(EventInterface $event) + { + parent::beforeRender($event); + + $this->viewBuilder()->setTemplatePath('Error'); + } + + /** + * afterFilter callback. + * + * @param \Cake\Event\EventInterface<\App\Controller\ErrorController> $event Event. + * @return \Cake\Http\Response|null|void + */ + public function afterFilter(EventInterface $event) + { + } + + public function index() + { + throw new \Exception('Foo error'); + } +} diff --git a/tests/Frameworks/CakePHP/Version_4_5/src/Controller/PagesController.php b/tests/Frameworks/CakePHP/Version_4_5/src/Controller/PagesController.php new file mode 100644 index 0000000000..a51bd4b386 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/src/Controller/PagesController.php @@ -0,0 +1,73 @@ +redirect('/'); + } + if (in_array('..', $path, true) || in_array('.', $path, true)) { + throw new ForbiddenException(); + } + $page = $subpage = null; + + if (!empty($path[0])) { + $page = $path[0]; + } + if (!empty($path[1])) { + $subpage = $path[1]; + } + $this->set(compact('page', 'subpage')); + + try { + return $this->render(implode('/', $path)); + } catch (MissingTemplateException $exception) { + if (Configure::read('debug')) { + throw $exception; + } + throw new NotFoundException(); + } + } +} diff --git a/tests/Frameworks/CakePHP/Version_4_5/src/Controller/ParameterizedController.php b/tests/Frameworks/CakePHP/Version_4_5/src/Controller/ParameterizedController.php new file mode 100644 index 0000000000..f41e3ec2f1 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/src/Controller/ParameterizedController.php @@ -0,0 +1,12 @@ +autoRender = false; + echo "Hello $param"; + } +} diff --git a/tests/Frameworks/CakePHP/Version_4_5/src/Controller/SimpleController.php b/tests/Frameworks/CakePHP/Version_4_5/src/Controller/SimpleController.php new file mode 100644 index 0000000000..fbdd428881 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/src/Controller/SimpleController.php @@ -0,0 +1,12 @@ +autoRender = false; + echo 'Hello.'; + } +} diff --git a/tests/Frameworks/CakePHP/Version_4_5/src/Controller/Simple_viewController.php b/tests/Frameworks/CakePHP/Version_4_5/src/Controller/Simple_viewController.php new file mode 100644 index 0000000000..87462eec32 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/src/Controller/Simple_viewController.php @@ -0,0 +1,10 @@ +response = $this->response->withType('ajax'); + } +} diff --git a/tests/Frameworks/CakePHP/Version_4_5/src/View/AppView.php b/tests/Frameworks/CakePHP/Version_4_5/src/View/AppView.php new file mode 100644 index 0000000000..7ccc7c2e99 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/src/View/AppView.php @@ -0,0 +1,41 @@ +loadHelper('Html');` + * + * @return void + */ + public function initialize(): void + { + } +} diff --git a/tests/Frameworks/CakePHP/Version_4_5/src/View/Cell/.gitkeep b/tests/Frameworks/CakePHP/Version_4_5/src/View/Cell/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Frameworks/CakePHP/Version_4_5/src/View/Helper/.gitkeep b/tests/Frameworks/CakePHP/Version_4_5/src/View/Helper/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Frameworks/CakePHP/Version_4_5/templates/Error/error400.php b/tests/Frameworks/CakePHP/Version_4_5/templates/Error/error400.php new file mode 100644 index 0000000000..9ead1656c8 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/templates/Error/error400.php @@ -0,0 +1,42 @@ +layout = 'error'; + +if (Configure::read('debug')) : + $this->layout = 'dev_error'; + + $this->assign('title', $message); + $this->assign('templateName', 'error400.php'); + + $this->start('file'); +?> +queryString)) : ?> +

+ SQL Query: + queryString) ?> +

+ +params)) : ?> + SQL Query Params: + params) ?> + + +element('auto_table_warning'); + + $this->end(); +endif; +?> +

+

+ : + '{$url}'") ?> +

diff --git a/tests/Frameworks/CakePHP/Version_4_5/templates/Error/error500.php b/tests/Frameworks/CakePHP/Version_4_5/templates/Error/error500.php new file mode 100644 index 0000000000..4f08488e90 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/templates/Error/error500.php @@ -0,0 +1,47 @@ +layout = 'error'; + +if (Configure::read('debug')) : + $this->layout = 'dev_error'; + + $this->assign('title', $message); + $this->assign('templateName', 'error500.php'); + + $this->start('file'); +?> +queryString)) : ?> +

+ SQL Query: + queryString) ?> +

+ +params)) : ?> + SQL Query Params: + params) ?> + + + getFile() ?> + getLine() ?> + Error in: + Html->link(sprintf('%s, line %s', Debugger::trimPath($file), $line), Debugger::editorUrl($file, $line)); ?> + +element('auto_table_warning'); + + $this->end(); +endif; +?> +

+

+ : + +

diff --git a/tests/Frameworks/CakePHP/Version_4_5/templates/Pages/home.php b/tests/Frameworks/CakePHP/Version_4_5/templates/Pages/home.php new file mode 100644 index 0000000000..6d111cc4cf --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/templates/Pages/home.php @@ -0,0 +1,239 @@ +disableAutoLayout(); + +$checkConnection = function (string $name) { + $error = null; + $connected = false; + try { + $connection = ConnectionManager::get($name); + $connected = $connection->connect(); + } catch (Exception $connectionError) { + $error = $connectionError->getMessage(); + if (method_exists($connectionError, 'getAttributes')) { + $attributes = $connectionError->getAttributes(); + if (isset($attributes['message'])) { + $error .= '
' . $attributes['message']; + } + } + if ($name === 'debug_kit') { + $error = 'Try adding your current top level domain to the + DebugKit.safeTld + config and reload.'; + if (!in_array('sqlite', \PDO::getAvailableDrivers())) { + $error .= '
You need to install the PHP extension pdo_sqlite so DebugKit can work properly.'; + } + } + } + + return compact('connected', 'error'); +}; + +if (!Configure::read('debug')) : + throw new NotFoundException( + 'Please replace templates/Pages/home.php with your own version or re-enable debug mode.' + ); +endif; + +?> + + + + Html->charset() ?> + + + CakePHP: the rapid development PHP framework: + <?= $this->fetch('title') ?> + + Html->meta('icon') ?> + + Html->css(['normalize.min', 'milligram.min', 'fonts', 'cake', 'home']) ?> + + fetch('meta') ?> + fetch('css') ?> + fetch('script') ?> + + +
+
+ + CakePHP + +

+ Welcome to CakePHP Strawberry (🍓) +

+
+
+
+
+
+
+
+
+ Please be aware that this page will not be shown if you turn off debug mode unless you replace templates/Pages/home.php with your own version. +
+
+ +
+ +
+
+
+
+

Environment

+
    + =')) : ?> +
  • Your version of PHP is 7.4.0 or higher (detected ).
  • + +
  • Your version of PHP is too low. You need PHP 7.4.0 or higher to use CakePHP (detected ).
  • + + + +
  • Your version of PHP has the mbstring extension loaded.
  • + +
  • Your version of PHP does NOT have the mbstring extension loaded.
  • + + + +
  • Your version of PHP has the openssl extension loaded.
  • + +
  • Your version of PHP has the mcrypt extension loaded.
  • + +
  • Your version of PHP does NOT have the openssl or mcrypt extension loaded.
  • + + + +
  • Your version of PHP has the intl extension loaded.
  • + +
  • Your version of PHP does NOT have the intl extension loaded.
  • + +
+
+
+

Filesystem

+
    + +
  • Your tmp directory is writable.
  • + +
  • Your tmp directory is NOT writable.
  • + + + +
  • Your logs directory is writable.
  • + +
  • Your logs directory is NOT writable.
  • + + + + +
  • The is being used for core caching. To change the config edit config/app.php
  • + +
  • Your cache is NOT working. Please check the settings in config/app.php
  • + +
+
+
+
+
+
+

Database

+ +
    + +
  • CakePHP is able to connect to the database.
  • + +
  • CakePHP is NOT able to connect to the database.
  • + +
+
+
+

DebugKit

+
    + +
  • DebugKit is loaded.
  • + + +
  • DebugKit can connect to the database.
  • + +
  • There are configuration problems present which need to be fixed:
  • + + +
  • DebugKit is not loaded.
  • + +
+
+
+
+
+ +
+
+
+ +
+
+ +
+
+ +
+
+
+
+ + diff --git a/tests/Frameworks/CakePHP/Version_4_5/templates/Simple_view/index.php b/tests/Frameworks/CakePHP/Version_4_5/templates/Simple_view/index.php new file mode 100644 index 0000000000..60ab36c4a4 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/templates/Simple_view/index.php @@ -0,0 +1,2 @@ +

Simple HTML view

+

Hello.

diff --git a/tests/Frameworks/CakePHP/Version_4_5/templates/cell/.gitkeep b/tests/Frameworks/CakePHP/Version_4_5/templates/cell/.gitkeep new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/templates/cell/.gitkeep @@ -0,0 +1 @@ + diff --git a/tests/Frameworks/CakePHP/Version_4_5/templates/element/flash/default.php b/tests/Frameworks/CakePHP/Version_4_5/templates/element/flash/default.php new file mode 100644 index 0000000000..061c700920 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/templates/element/flash/default.php @@ -0,0 +1,15 @@ + +
diff --git a/tests/Frameworks/CakePHP/Version_4_5/templates/element/flash/error.php b/tests/Frameworks/CakePHP/Version_4_5/templates/element/flash/error.php new file mode 100644 index 0000000000..2ebf2357c0 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/templates/element/flash/error.php @@ -0,0 +1,11 @@ + +
diff --git a/tests/Frameworks/CakePHP/Version_4_5/templates/element/flash/info.php b/tests/Frameworks/CakePHP/Version_4_5/templates/element/flash/info.php new file mode 100644 index 0000000000..e25b730c4f --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/templates/element/flash/info.php @@ -0,0 +1,11 @@ + +
diff --git a/tests/Frameworks/CakePHP/Version_4_5/templates/element/flash/success.php b/tests/Frameworks/CakePHP/Version_4_5/templates/element/flash/success.php new file mode 100644 index 0000000000..73eaac48d3 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/templates/element/flash/success.php @@ -0,0 +1,11 @@ + +
diff --git a/tests/Frameworks/CakePHP/Version_4_5/templates/element/flash/warning.php b/tests/Frameworks/CakePHP/Version_4_5/templates/element/flash/warning.php new file mode 100644 index 0000000000..605537c7e2 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/templates/element/flash/warning.php @@ -0,0 +1,11 @@ + +
diff --git a/tests/Frameworks/CakePHP/Version_4_5/templates/email/html/default.php b/tests/Frameworks/CakePHP/Version_4_5/templates/email/html/default.php new file mode 100644 index 0000000000..70a6cd4492 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/templates/email/html/default.php @@ -0,0 +1,22 @@ + ' . $line . "

\n"; +endforeach; diff --git a/tests/Frameworks/CakePHP/Version_4_5/templates/email/text/default.php b/tests/Frameworks/CakePHP/Version_4_5/templates/email/text/default.php new file mode 100644 index 0000000000..cb1f378451 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/templates/email/text/default.php @@ -0,0 +1,18 @@ +fetch('content'); diff --git a/tests/Frameworks/CakePHP/Version_4_5/templates/layout/default.php b/tests/Frameworks/CakePHP/Version_4_5/templates/layout/default.php new file mode 100644 index 0000000000..f300d2ad41 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/templates/layout/default.php @@ -0,0 +1,55 @@ + + + + + Html->charset() ?> + + + <?= $cakeDescription ?>: + <?= $this->fetch('title') ?> + + Html->meta('icon') ?> + + Html->css(['normalize.min', 'milligram.min', 'fonts', 'cake']) ?> + + fetch('meta') ?> + fetch('css') ?> + fetch('script') ?> + + + +
+
+ Flash->render() ?> + fetch('content') ?> +
+
+
+
+ + diff --git a/tests/Frameworks/CakePHP/Version_4_5/templates/layout/email/html/default.php b/tests/Frameworks/CakePHP/Version_4_5/templates/layout/email/html/default.php new file mode 100644 index 0000000000..96b0e7318f --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/templates/layout/email/html/default.php @@ -0,0 +1,25 @@ + + + + + <?= $this->fetch('title') ?> + + + fetch('content') ?> + + diff --git a/tests/Frameworks/CakePHP/Version_4_5/templates/layout/email/text/default.php b/tests/Frameworks/CakePHP/Version_4_5/templates/layout/email/text/default.php new file mode 100644 index 0000000000..cd51169db7 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/templates/layout/email/text/default.php @@ -0,0 +1,17 @@ +fetch('content'); diff --git a/tests/Frameworks/CakePHP/Version_4_5/templates/layout/error.php b/tests/Frameworks/CakePHP/Version_4_5/templates/layout/error.php new file mode 100644 index 0000000000..2b26a16da0 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/templates/layout/error.php @@ -0,0 +1,39 @@ + + + + + Html->charset() ?> + + <?= $this->fetch('title') ?> + + Html->meta('icon') ?> + + Html->css(['normalize.min', 'milligram.min', 'fonts', 'cake']) ?> + + fetch('meta') ?> + fetch('css') ?> + fetch('script') ?> + + +
+ Flash->render() ?> + fetch('content') ?> + Html->link(__('Back'), 'javascript:history.back()') ?> +
+ + diff --git a/tests/Frameworks/CakePHP/Version_4_5/tests/Fixture/.gitkeep b/tests/Frameworks/CakePHP/Version_4_5/tests/Fixture/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Frameworks/CakePHP/Version_4_5/tests/TestCase/ApplicationTest.php b/tests/Frameworks/CakePHP/Version_4_5/tests/TestCase/ApplicationTest.php new file mode 100644 index 0000000000..7c42d856dc --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/tests/TestCase/ApplicationTest.php @@ -0,0 +1,106 @@ +bootstrap(); + $plugins = $app->getPlugins(); + + $this->assertTrue($plugins->has('Bake'), 'plugins has Bake?'); + $this->assertFalse($plugins->has('DebugKit'), 'plugins has DebugKit?'); + $this->assertTrue($plugins->has('Migrations'), 'plugins has Migrations?'); + } + + /** + * Test bootstrap add DebugKit plugin in debug mode. + * + * @return void + */ + public function testBootstrapInDebug() + { + Configure::write('debug', true); + $app = new Application(dirname(dirname(__DIR__)) . '/config'); + $app->bootstrap(); + $plugins = $app->getPlugins(); + + $this->assertTrue($plugins->has('DebugKit'), 'plugins has DebugKit?'); + } + + /** + * testBootstrapPluginWitoutHalt + * + * @return void + */ + public function testBootstrapPluginWithoutHalt() + { + $this->expectException(InvalidArgumentException::class); + + $app = $this->getMockBuilder(Application::class) + ->setConstructorArgs([dirname(dirname(__DIR__)) . '/config']) + ->onlyMethods(['addPlugin']) + ->getMock(); + + $app->method('addPlugin') + ->will($this->throwException(new InvalidArgumentException('test exception.'))); + + $app->bootstrap(); + } + + /** + * testMiddleware + * + * @return void + */ + public function testMiddleware() + { + $app = new Application(dirname(dirname(__DIR__)) . '/config'); + $middleware = new MiddlewareQueue(); + + $middleware = $app->middleware($middleware); + + $this->assertInstanceOf(ErrorHandlerMiddleware::class, $middleware->current()); + $middleware->seek(1); + $this->assertInstanceOf(AssetMiddleware::class, $middleware->current()); + $middleware->seek(2); + $this->assertInstanceOf(RoutingMiddleware::class, $middleware->current()); + } +} diff --git a/tests/Frameworks/CakePHP/Version_4_5/tests/TestCase/Controller/Component/.gitkeep b/tests/Frameworks/CakePHP/Version_4_5/tests/TestCase/Controller/Component/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Frameworks/CakePHP/Version_4_5/tests/TestCase/Controller/PagesControllerTest.php b/tests/Frameworks/CakePHP/Version_4_5/tests/TestCase/Controller/PagesControllerTest.php new file mode 100644 index 0000000000..407d6d8f22 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/tests/TestCase/Controller/PagesControllerTest.php @@ -0,0 +1,115 @@ +get('/pages/home'); + $this->assertResponseOk(); + $this->assertResponseContains('CakePHP'); + $this->assertResponseContains(''); + } + + /** + * Test that missing template renders 404 page in production + * + * @return void + */ + public function testMissingTemplate() + { + Configure::write('debug', false); + $this->get('/pages/not_existing'); + + $this->assertResponseError(); + $this->assertResponseContains('Error'); + } + + /** + * Test that missing template in debug mode renders missing_template error page + * + * @return void + */ + public function testMissingTemplateInDebug() + { + Configure::write('debug', true); + $this->get('/pages/not_existing'); + + $this->assertResponseFailure(); + $this->assertResponseContains('Missing Template'); + $this->assertResponseContains('Stacktrace'); + $this->assertResponseContains('not_existing.php'); + } + + /** + * Test directory traversal protection + * + * @return void + */ + public function testDirectoryTraversalProtection() + { + $this->get('/pages/../Layout/ajax'); + $this->assertResponseCode(403); + $this->assertResponseContains('Forbidden'); + } + + /** + * Test that CSRF protection is applied to page rendering. + * + * @return void + */ + public function testCsrfAppliedError() + { + $this->post('/pages/home', ['hello' => 'world']); + + $this->assertResponseCode(403); + $this->assertResponseContains('CSRF'); + } + + /** + * Test that CSRF protection is applied to page rendering. + * + * @return void + */ + public function testCsrfAppliedOk() + { + $this->enableCsrfToken(); + $this->post('/pages/home', ['hello' => 'world']); + + $this->assertThat(403, $this->logicalNot(new StatusCode($this->_response))); + $this->assertResponseNotContains('CSRF'); + } +} diff --git a/tests/Frameworks/CakePHP/Version_4_5/tests/TestCase/Model/Behavior/.gitkeep b/tests/Frameworks/CakePHP/Version_4_5/tests/TestCase/Model/Behavior/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Frameworks/CakePHP/Version_4_5/tests/TestCase/View/Helper/.gitkeep b/tests/Frameworks/CakePHP/Version_4_5/tests/TestCase/View/Helper/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Frameworks/CakePHP/Version_4_5/tests/bootstrap.php b/tests/Frameworks/CakePHP/Version_4_5/tests/bootstrap.php new file mode 100644 index 0000000000..79e1918752 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/tests/bootstrap.php @@ -0,0 +1,65 @@ + 'Cake\Database\Connection', + 'driver' => 'Cake\Database\Driver\Sqlite', + 'database' => TMP . 'debug_kit.sqlite', + 'encoding' => 'utf8', + 'cacheMetadata' => true, + 'quoteIdentifiers' => false, +]); + +ConnectionManager::alias('test_debug_kit', 'debug_kit'); + +// Fixate sessionid early on, as php7.2+ +// does not allow the sessionid to be set after stdout +// has been written to. +session_id('cli'); + +// Use migrations to build test database schema. +// +// Will rebuild the database if the migration state differs +// from the migration history in files. +// +// If you are not using CakePHP's migrations you can +// hook into your migration tool of choice here or +// load schema from a SQL dump file with +// use Cake\TestSuite\Fixture\SchemaLoader; +// (new SchemaLoader())->loadSqlFiles('./tests/schema.sql', 'test'); +(new Migrator())->run(); diff --git a/tests/Frameworks/CakePHP/Version_4_5/tests/schema.sql b/tests/Frameworks/CakePHP/Version_4_5/tests/schema.sql new file mode 100644 index 0000000000..c7e4d3f7e8 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/tests/schema.sql @@ -0,0 +1,4 @@ +-- Test database schema. +-- +-- If you are not using CakePHP migrations you can put +-- your application's schema in this file and use it in tests. diff --git a/tests/Frameworks/CakePHP/Version_4_5/webroot/.htaccess b/tests/Frameworks/CakePHP/Version_4_5/webroot/.htaccess new file mode 100644 index 0000000000..f5f2d631cd --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/webroot/.htaccess @@ -0,0 +1,5 @@ + + RewriteEngine On + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^ index.php [L] + diff --git a/tests/Frameworks/CakePHP/Version_4_5/webroot/css/cake.css b/tests/Frameworks/CakePHP/Version_4_5/webroot/css/cake.css new file mode 100644 index 0000000000..f8da0bc1bf --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/webroot/css/cake.css @@ -0,0 +1,224 @@ +/* Miligram overrides */ +body { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 400; +} + +.top-nav-links, +.side-nav, +h1, h2, h3, h4, h5, h6 { + font-family: "Raleway", sans-serif; +} + +h1, h2, h3, h4, h5, h6 { + font-weight: 400; + color: #363637; +} + +a { + color:#2f85ae; + -webkit-transition:all 0.2s linear; + transition:all 0.2s linear; +} + +a:hover, +a:focus, +a:active { + color:#2a6496; + -webkit-transition:all 0.2s easeout; + transition:all 0.2s ease-out; +} + +.side-nav a, +.top-nav-links a, +th a, +.actions a { + color: #606c76; +} + +.side-nav a:hover, +.side-nav a:focus, +.actions a:hover, +.actions a:focus { + color:#2f85ae; +} + +/* Utility */ +.table-responsive { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; +} + +/* Main */ +body { + background: #f5f7fa; +} +.content { + padding: 2rem; + background: #ffffff; + border-radius: 0.4rem; + /* Thanks Stripe */ + box-shadow: 0 7px 14px 0 rgba(60, 66, 87, 0.1), + 0 3px 6px 0 rgba(0, 0, 0, 0.07); +} +.actions a { + font-weight: bold; + padding: 0 0.4rem; +} +.actions a:first-child { + padding-left: 0; +} +th { + white-space: nowrap; +} + +/* Nav bar */ +.top-nav { + display: flex; + align-items: center; + justify-content: space-between; + max-width: 112rem; + padding: 2rem; + margin: 0 auto 2rem; +} +.top-nav-title a { + font-size: 2.4rem; + color: #d33c43; +} +.top-nav-title span { + color: #404041; +} +.top-nav-links a { + margin: 0 0.5rem; +} +.top-nav-title a, +.top-nav-links a { + font-weight: bold; +} + +.side-nav-item { + display: block; + padding: 0.5rem 0; +} + +/* View action */ +.view.content .text { + margin-top: 1.2rem; +} +.related { + margin-top: 2rem; +} + +/* Flash messages */ +.message { + padding: 1rem; + + background: #eff8ff; + color: #2779bd; + + border-color: #6cb2eb; + border-width: 1px; + border-style: solid; + border-radius: 4px; + margin-bottom: 2rem; +} +.message.hidden { + display: none; +} +.message.success { + background: #e3fcec; + color: #1f9d55; + border-color: #51d88a; +} +.message.warning { + background: #fffabc; + color: #8d7b00; + border-color: #d3b800; +} +.message.error { + background: #fcebea; + color: #cc1f1a; + border-color: #ef5753; +} + +/* Forms */ +.input.radio, +.input.checkbox { + margin-bottom: 2.0rem; +} +.input.radio input, +.input.checkbox input { + margin: 0; +} +.input.radio label, +.input.checkbox label { + margin: 0; + display: flex; + align-items: center; +} +.input.radio label > input, +.input.checkbox label > input { + margin-right: 1.0rem; +} +.input.radio label:first-of-type { + margin-bottom: 2.0rem; +} + +/* Paginator */ +.paginator { + text-align: right; +} +.pagination { + display: flex; + justify-content: center; + list-style: none; + padding: 0; + margin: 0 0 1rem; +} +.pagination li { + margin: 0 0.5rem; +} +.prev.disabled a, +.next.disabled a { + cursor: not-allowed; + color: #606c76; +} +.asc:after { + content: " \2193"; +} +.desc:after { + content: " \2191"; +} + +/* Error */ +.error-container { + align-items: center; + display: flex; + flex-direction: column; + height: 100vh; + justify-content: center; +} + +@media screen and (max-width: 640px) { + .top-nav { + margin: 0 auto; + } + .side-nav { + margin-bottom: 1rem; + } + .heading { + margin-bottom: 1rem; + } + .side-nav-item { + display: inline; + margin: 0 1.5rem 0 0; + } + .asc:after { + content: " \2192"; + } + .desc:after { + content: " \2190"; + } +} diff --git a/tests/Frameworks/CakePHP/Version_4_5/webroot/css/fonts.css b/tests/Frameworks/CakePHP/Version_4_5/webroot/css/fonts.css new file mode 100644 index 0000000000..1ba4808f40 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/webroot/css/fonts.css @@ -0,0 +1,80 @@ +/* cyrillic-ext */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 400; + src: url('../font/raleway-400-cyrillic-ext.woff2') format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 400; + src: url('../font/raleway-400-cyrillic.woff2') format('woff2'); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* vietnamese */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 400; + src: url('../font/raleway-400-vietnamese.woff2') format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 400; + src: url('../font/raleway-400-latin-ext.woff2') format('woff2'); + unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 400; + src: url('../font/raleway-400-latin.woff2') format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 700; + src: url('../font/raleway-700-cyrillic-ext.woff2') format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 700; + src: url('../font/raleway-700-cyrillic.woff2') format('woff2'); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* vietnamese */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 700; + src: url('../font/raleway-700-vietnamese.woff2') format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 700; + src: url('../font/raleway-700-latin-ext.woff2') format('woff2'); + unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 700; + src: url('../font/raleway-700-latin.woff2') format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} diff --git a/tests/Frameworks/CakePHP/Version_4_5/webroot/css/home.css b/tests/Frameworks/CakePHP/Version_4_5/webroot/css/home.css new file mode 100644 index 0000000000..4648ed314d --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/webroot/css/home.css @@ -0,0 +1,75 @@ +/* Home page styles */ +@font-face { + font-family: 'cakefont'; + src: url('../font/cakedingbats-webfont.eot'); + src: url('../font/cakedingbats-webfont.eot?#iefix') format('embedded-opentype'), + url('../font/cakedingbats-webfont.woff2') format('woff2'), + url('../font/cakedingbats-webfont.woff') format('woff'), + url('../font/cakedingbats-webfont.ttf') format('truetype'), + url('../font/cakedingbats-webfont.svg#cake_dingbatsregular') format('svg'); + font-weight: normal; + font-style: normal; +} +body { + padding: 60px 0; +} +header { + margin-bottom: 60px; +} +img { + margin-bottom: 30px; +} +h1 { + font-weight: bold; +} +ul { + list-style-type: none; + margin: 0 0 30px 0; + padding-left: 25px; +} +a { + color: #0071BC; + text-decoration: underline; +} +hr { + border-bottom: 1px solid #e7e7e7; + border-top: 0; + margin-bottom: 35px; +} + +.text-center { + text-align: center; +} +.links a { + margin-right: 10px; +} +.release-name { + color: #D33C43; + font-weight: 400; + font-style: italic; +} +.bullet:before { + font-family: 'cakefont', sans-serif; + font-size: 18px; + display: inline-block; + margin-left: -1.3em; + width: 1.2em; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + vertical-align: -1px; +} +.success:before { + color: #88c671; + content: "\0056"; +} +.problem:before { + color: #d33d44; + content: "\0057"; +} +.cake-error { + padding: 10px; + margin: 10px 0; +} +#url-rewriting-warning { + display: none; +} diff --git a/tests/Frameworks/CakePHP/Version_4_5/webroot/css/milligram.min.css b/tests/Frameworks/CakePHP/Version_4_5/webroot/css/milligram.min.css new file mode 100644 index 0000000000..9d93dc57e6 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/webroot/css/milligram.min.css @@ -0,0 +1,9 @@ +/*! + * Milligram v1.3.0 + * https://milligram.io + * + * Copyright (c) 2019 CJ Patoilo + * Licensed under the MIT license + */ + +*,*:after,*:before{box-sizing:inherit}html{box-sizing:border-box;font-size:62.5%}body{color:#606c76;font-family:'Roboto', 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;font-size:1.6em;font-weight:300;letter-spacing:.01em;line-height:1.6}blockquote{border-left:0.3rem solid #d1d1d1;margin-left:0;margin-right:0;padding:1rem 1.5rem}blockquote *:last-child{margin-bottom:0}.button,button,input[type='button'],input[type='reset'],input[type='submit']{background-color:#d33c43;border:0.1rem solid #d33c43;border-radius:.4rem;color:#fff;cursor:pointer;display:inline-block;font-size:1.1rem;font-weight:700;height:3.8rem;letter-spacing:.1rem;line-height:3.8rem;padding:0 3.0rem;text-align:center;text-decoration:none;text-transform:uppercase;white-space:nowrap}.button:focus,.button:hover,button:focus,button:hover,input[type='button']:focus,input[type='button']:hover,input[type='reset']:focus,input[type='reset']:hover,input[type='submit']:focus,input[type='submit']:hover{background-color:#606c76;border-color:#606c76;color:#fff;outline:0}.button[disabled],button[disabled],input[type='button'][disabled],input[type='reset'][disabled],input[type='submit'][disabled]{cursor:default;opacity:.5}.button[disabled]:focus,.button[disabled]:hover,button[disabled]:focus,button[disabled]:hover,input[type='button'][disabled]:focus,input[type='button'][disabled]:hover,input[type='reset'][disabled]:focus,input[type='reset'][disabled]:hover,input[type='submit'][disabled]:focus,input[type='submit'][disabled]:hover{background-color:#d33c43;border-color:#d33c43}.button.button-outline,button.button-outline,input[type='button'].button-outline,input[type='reset'].button-outline,input[type='submit'].button-outline{background-color:transparent;color:#d33c43}.button.button-outline:focus,.button.button-outline:hover,button.button-outline:focus,button.button-outline:hover,input[type='button'].button-outline:focus,input[type='button'].button-outline:hover,input[type='reset'].button-outline:focus,input[type='reset'].button-outline:hover,input[type='submit'].button-outline:focus,input[type='submit'].button-outline:hover{background-color:transparent;border-color:#606c76;color:#606c76}.button.button-outline[disabled]:focus,.button.button-outline[disabled]:hover,button.button-outline[disabled]:focus,button.button-outline[disabled]:hover,input[type='button'].button-outline[disabled]:focus,input[type='button'].button-outline[disabled]:hover,input[type='reset'].button-outline[disabled]:focus,input[type='reset'].button-outline[disabled]:hover,input[type='submit'].button-outline[disabled]:focus,input[type='submit'].button-outline[disabled]:hover{border-color:inherit;color:#d33c43}.button.button-clear,button.button-clear,input[type='button'].button-clear,input[type='reset'].button-clear,input[type='submit'].button-clear{background-color:transparent;border-color:transparent;color:#d33c43}.button.button-clear:focus,.button.button-clear:hover,button.button-clear:focus,button.button-clear:hover,input[type='button'].button-clear:focus,input[type='button'].button-clear:hover,input[type='reset'].button-clear:focus,input[type='reset'].button-clear:hover,input[type='submit'].button-clear:focus,input[type='submit'].button-clear:hover{background-color:transparent;border-color:transparent;color:#606c76}.button.button-clear[disabled]:focus,.button.button-clear[disabled]:hover,button.button-clear[disabled]:focus,button.button-clear[disabled]:hover,input[type='button'].button-clear[disabled]:focus,input[type='button'].button-clear[disabled]:hover,input[type='reset'].button-clear[disabled]:focus,input[type='reset'].button-clear[disabled]:hover,input[type='submit'].button-clear[disabled]:focus,input[type='submit'].button-clear[disabled]:hover{color:#d33c43}code{background:#f4f5f6;border-radius:.4rem;font-size:86%;margin:0 .2rem;padding:.2rem .5rem;white-space:nowrap}pre{background:#f4f5f6;border-left:0.3rem solid #d33c43;overflow-y:hidden}pre>code{border-radius:0;display:block;padding:1rem 1.5rem;white-space:pre}hr{border:0;border-top:0.1rem solid #f4f5f6;margin:3.0rem 0}input[type='email'],input[type='number'],input[type='password'],input[type='search'],input[type='tel'],input[type='text'],input[type='url'],input[type='color'],input[type='date'],input[type='month'],input[type='week'],input[type='datetime'],input[type='datetime-local'],input:not([type]),textarea,select{background-color:transparent;border:0.1rem solid #d1d1d1;border-radius:.4rem;box-shadow:none;box-sizing:inherit;height:3.8rem;padding:.6rem 1.0rem;width:100%}input[type='email']:focus,input[type='number']:focus,input[type='password']:focus,input[type='search']:focus,input[type='tel']:focus,input[type='text']:focus,input[type='url']:focus,input[type='color']:focus,input[type='date']:focus,input[type='month']:focus,input[type='week']:focus,input[type='datetime']:focus,input[type='datetime-local']:focus,input:not([type]):focus,textarea:focus,select:focus{border-color:#606c76;outline:0}select{padding-right:3.0rem}textarea{min-height:6.5rem}label,legend{display:block;font-size:2.0rem;font-weight:700;margin-bottom:2.0rem}fieldset{border-width:0;padding:0}input[type='checkbox'],input[type='radio']{display:inline}.label-inline{display:inline-block;font-weight:normal;margin-left:.5rem}.container{margin:0 auto;max-width:112.0rem;padding:0 2.0rem;position:relative;width:100%}.row{display:flex;flex-direction:column;padding:0;width:100%}.row.row-no-padding{padding:0}.row.row-no-padding>.column{padding:0}.row.row-wrap{flex-wrap:wrap}.row.row-top{align-items:flex-start}.row.row-bottom{align-items:flex-end}.row.row-center{align-items:center}.row.row-stretch{align-items:stretch}.row.row-baseline{align-items:baseline}.row .column{display:block;flex:1 1 auto;margin-left:0;max-width:100%;width:100%}.row .column.column-offset-10{margin-left:10%}.row .column.column-offset-20{margin-left:20%}.row .column.column-offset-25{margin-left:25%}.row .column.column-offset-33,.row .column.column-offset-34{margin-left:33.3333%}.row .column.column-offset-50{margin-left:50%}.row .column.column-offset-66,.row .column.column-offset-67{margin-left:66.6666%}.row .column.column-offset-75{margin-left:75%}.row .column.column-offset-80{margin-left:80%}.row .column.column-offset-90{margin-left:90%}.row .column.column-10{flex:0 0 10%;max-width:10%}.row .column.column-20{flex:0 0 20%;max-width:20%}.row .column.column-25{flex:0 0 25%;max-width:25%}.row .column.column-33,.row .column.column-34{flex:0 0 33.3333%;max-width:33.3333%}.row .column.column-40{flex:0 0 40%;max-width:40%}.row .column.column-50{flex:0 0 50%;max-width:50%}.row .column.column-60{flex:0 0 60%;max-width:60%}.row .column.column-66,.row .column.column-67{flex:0 0 66.6666%;max-width:66.6666%}.row .column.column-75{flex:0 0 75%;max-width:75%}.row .column.column-80{flex:0 0 80%;max-width:80%}.row .column.column-90{flex:0 0 90%;max-width:90%}.row .column .column-top{align-self:flex-start}.row .column .column-bottom{align-self:flex-end}.row .column .column-center{-ms-grid-row-align:center;align-self:center}.row .column-responsive{display:block;flex:1 1 auto;margin-left:0;max-width:100%;width:100%}@media (min-width: 640px){.row{flex-direction:row;margin-left:-1.0rem;width:calc(100% + 2.0rem)}.row .column{margin-bottom:inherit;padding:0 1.0rem}.row .column-responsive{margin-bottom:inherit;padding:0 1.0rem}.row .column-responsive.column-10{flex:0 0 10%;max-width:10%}.row .column-responsive.column-20{flex:0 0 20%;max-width:20%}.row .column-responsive.column-25{flex:0 0 25%;max-width:25%}.row .column-responsive.column-33,.row .column-responsive.column-34{flex:0 0 33.3333%;max-width:33.3333%}.row .column-responsive.column-40{flex:0 0 40%;max-width:40%}.row .column-responsive.column-50{flex:0 0 50%;max-width:50%}.row .column-responsive.column-60{flex:0 0 60%;max-width:60%}.row .column-responsive.column-66,.row .column-responsive.column-67{flex:0 0 66.6666%;max-width:66.6666%}.row .column-responsive.column-75{flex:0 0 75%;max-width:75%}.row .column-responsive.column-80{flex:0 0 80%;max-width:80%}.row .column-responsive.column-90{flex:0 0 90%;max-width:90%}}a{color:#d33c43;text-decoration:none}a:focus,a:hover{color:#606c76}dl,ol,ul{list-style:none;margin-top:0;padding-left:0}dl dl,dl ol,dl ul,ol dl,ol ol,ol ul,ul dl,ul ol,ul ul{font-size:90%;margin:1.5rem 0 1.5rem 3.0rem}ol{list-style:decimal inside}ul{list-style:circle inside}.button,button,dd,dt,li{margin-bottom:1.0rem}fieldset,input,select,textarea{margin-bottom:1.5rem}blockquote,dl,figure,form,ol,p,pre,table,ul{margin-bottom:0}table{border-spacing:0;width:100%}td,th{border-bottom:0.1rem solid #e1e1e1;padding:1.2rem 1.5rem;text-align:left}td:first-child,th:first-child{padding-left:0}td:last-child,th:last-child{padding-right:0}@media screen and (max-width: 640px){table{border-spacing:0;display:flex;width:100%}table thead{border-right:solid 0.1rem #e1e1e1}table thead td,table thead th{padding-left:0}table thead td:first-child,table thead th:first-child{padding-left:0}table thead td:last-child,table thead th:last-child{padding-right:1.2rem}table tbody{display:flex;overflow-x:auto;white-space:nowrap}table tbody tr{border-right:solid 0.1rem #e1e1e1}table tbody tr:last-child{border-right:none}table td,table th{display:block}table td:first-child,table th:first-child{padding-left:1.2rem}table td:last-child,table th:last-child{padding-right:1.2rem}}b,strong{font-weight:bold}p{margin-top:0}h1,h2,h3,h4,h5,h6{font-weight:300;letter-spacing:-.1rem;margin-bottom:2.0rem;margin-top:0}h1{font-size:4.6rem;line-height:1.2}h2{font-size:3.6rem;line-height:1.25}h3{font-size:2.8rem;line-height:1.3}h4{font-size:2.2rem;letter-spacing:-.08rem;line-height:1.35}h5{font-size:1.8rem;letter-spacing:-.05rem;line-height:1.5}h6{font-size:1.6rem;letter-spacing:0;line-height:1.4}img{max-width:100%}.clearfix:after{clear:both;content:' ';display:table}.float-left{float:left}.float-right{float:right} diff --git a/tests/Frameworks/CakePHP/Version_4_5/webroot/css/normalize.min.css b/tests/Frameworks/CakePHP/Version_4_5/webroot/css/normalize.min.css new file mode 100644 index 0000000000..bde07fcb52 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/webroot/css/normalize.min.css @@ -0,0 +1,8 @@ +/** + * Minified by jsDelivr using clean-css v4.2.1. + * Original file: /npm/normalize.css@8.0.1/normalize.css + * + * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files + */ +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ +html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none} diff --git a/tests/Frameworks/CakePHP/Version_4_5/webroot/favicon.ico b/tests/Frameworks/CakePHP/Version_4_5/webroot/favicon.ico new file mode 100644 index 0000000000..49a060fc46 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_4_5/webroot/favicon.ico differ diff --git a/tests/Frameworks/CakePHP/Version_4_5/webroot/font/cakedingbats-webfont.eot b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/cakedingbats-webfont.eot new file mode 100644 index 0000000000..e8605d9268 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/cakedingbats-webfont.eot differ diff --git a/tests/Frameworks/CakePHP/Version_4_5/webroot/font/cakedingbats-webfont.svg b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/cakedingbats-webfont.svg new file mode 100644 index 0000000000..d1e0c98f7a --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/cakedingbats-webfont.svg @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/Frameworks/CakePHP/Version_4_5/webroot/font/cakedingbats-webfont.ttf b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/cakedingbats-webfont.ttf new file mode 100644 index 0000000000..13d54454e7 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/cakedingbats-webfont.ttf differ diff --git a/tests/Frameworks/CakePHP/Version_4_5/webroot/font/cakedingbats-webfont.woff b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/cakedingbats-webfont.woff new file mode 100644 index 0000000000..073baab113 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/cakedingbats-webfont.woff differ diff --git a/tests/Frameworks/CakePHP/Version_4_5/webroot/font/cakedingbats-webfont.woff2 b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/cakedingbats-webfont.woff2 new file mode 100644 index 0000000000..6e71eaf53e Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/cakedingbats-webfont.woff2 differ diff --git a/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-400-cyrillic-ext.woff2 b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-400-cyrillic-ext.woff2 new file mode 100644 index 0000000000..039269ecd6 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-400-cyrillic-ext.woff2 differ diff --git a/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-400-cyrillic.woff2 b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-400-cyrillic.woff2 new file mode 100644 index 0000000000..48b9d896c2 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-400-cyrillic.woff2 differ diff --git a/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-400-latin-ext.woff2 b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-400-latin-ext.woff2 new file mode 100644 index 0000000000..0eedc5bb67 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-400-latin-ext.woff2 differ diff --git a/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-400-latin.woff2 b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-400-latin.woff2 new file mode 100644 index 0000000000..d0e6f01908 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-400-latin.woff2 differ diff --git a/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-400-vietnamese.woff2 b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-400-vietnamese.woff2 new file mode 100644 index 0000000000..405fb25048 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-400-vietnamese.woff2 differ diff --git a/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-700-cyrillic-ext.woff2 b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-700-cyrillic-ext.woff2 new file mode 100644 index 0000000000..039269ecd6 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-700-cyrillic-ext.woff2 differ diff --git a/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-700-cyrillic.woff2 b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-700-cyrillic.woff2 new file mode 100644 index 0000000000..48b9d896c2 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-700-cyrillic.woff2 differ diff --git a/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-700-latin-ext.woff2 b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-700-latin-ext.woff2 new file mode 100644 index 0000000000..0eedc5bb67 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-700-latin-ext.woff2 differ diff --git a/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-700-latin.woff2 b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-700-latin.woff2 new file mode 100644 index 0000000000..d0e6f01908 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-700-latin.woff2 differ diff --git a/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-700-vietnamese.woff2 b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-700-vietnamese.woff2 new file mode 100644 index 0000000000..405fb25048 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_4_5/webroot/font/raleway-700-vietnamese.woff2 differ diff --git a/tests/Frameworks/CakePHP/Version_4_5/webroot/img/cake-logo.png b/tests/Frameworks/CakePHP/Version_4_5/webroot/img/cake-logo.png new file mode 100644 index 0000000000..41939ef5a5 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_4_5/webroot/img/cake-logo.png differ diff --git a/tests/Frameworks/CakePHP/Version_4_5/webroot/img/cake.icon.png b/tests/Frameworks/CakePHP/Version_4_5/webroot/img/cake.icon.png new file mode 100644 index 0000000000..394fa42d51 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_4_5/webroot/img/cake.icon.png differ diff --git a/tests/Frameworks/CakePHP/Version_4_5/webroot/img/cake.logo.svg b/tests/Frameworks/CakePHP/Version_4_5/webroot/img/cake.logo.svg new file mode 100644 index 0000000000..e73abb54bc --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/webroot/img/cake.logo.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/Frameworks/CakePHP/Version_4_5/webroot/img/cake.power.gif b/tests/Frameworks/CakePHP/Version_4_5/webroot/img/cake.power.gif new file mode 100644 index 0000000000..8f8d570a2e Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_4_5/webroot/img/cake.power.gif differ diff --git a/tests/Frameworks/CakePHP/Version_4_5/webroot/index.php b/tests/Frameworks/CakePHP/Version_4_5/webroot/index.php new file mode 100644 index 0000000000..6bc06dc56c --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_4_5/webroot/index.php @@ -0,0 +1,40 @@ +emit($server->run()); diff --git a/tests/Frameworks/CakePHP/Version_4_5/webroot/js/.gitkeep b/tests/Frameworks/CakePHP/Version_4_5/webroot/js/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Frameworks/CakePHP/Version_5_0/.editorconfig b/tests/Frameworks/CakePHP/Version_5_0/.editorconfig new file mode 100644 index 0000000000..87b5178e61 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/.editorconfig @@ -0,0 +1,26 @@ +; This file is for unifying the coding style for different editors and IDEs. +; More information at https://editorconfig.org + +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.bat] +end_of_line = crlf + +[*.yml] +indent_size = 2 + +[*.twig] +insert_final_newline = false + +[*.neon] +indent_style = tab + +[Makefile] +indent_style = tab diff --git a/tests/Frameworks/CakePHP/Version_5_0/.gitattributes b/tests/Frameworks/CakePHP/Version_5_0/.gitattributes new file mode 100644 index 0000000000..1ebf0b221e --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/.gitattributes @@ -0,0 +1,36 @@ +# Define the line ending behavior of the different file extensions +# Set default behavior, in case users don't have core.autocrlf set. +* text text=auto eol=lf + +# Declare files that will always have CRLF line endings on checkout. +*.bat eol=crlf + +# Declare files that will always have LF line endings on checkout. +*.pem eol=lf + +# Denote all files that are truly binary and should not be modified. +*.png binary +*.jpg binary +*.jpeg binary +*.gif binary +*.webp binary +*.avif binary +*.ico binary +*.mo binary +*.pdf binary +*.xls binary +*.xlsx binary +*.phar binary +*.woff binary +*.woff2 binary +*.ttc binary +*.ttf binary +*.otf binary +*.eot binary +*.gz binary +*.bz2 binary +*.7z binary +*.zip binary +*.webm binary +*.mp4 binary +*.ogv binary diff --git a/tests/Frameworks/CakePHP/Version_5_0/.gitignore b/tests/Frameworks/CakePHP/Version_5_0/.gitignore new file mode 100644 index 0000000000..03ee77c4f4 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/.gitignore @@ -0,0 +1,52 @@ +# CakePHP specific files # +########################## +/config/app_local.php +/config/.env +/logs/* +/tmp/* +/vendor/* + +# OS generated files # +###################### +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +# Icon must end with two \r +Icon +ehthumbs.db +Thumbs.db +.directory + +# Tool specific files # +####################### +# PHPUnit +.phpunit.cache +tests.sqlite +# vim +*~ +*.swp +*.swo +# sublime text & textmate +*.sublime-* +*.stTheme.cache +*.tmlanguage.cache +*.tmPreferences.cache +# Eclipse +.settings/* +# JetBrains, aka PHPStorm, IntelliJ IDEA +.idea/* +# NetBeans +nbproject/* +# Visual Studio Code +.vscode +# nova +.nova +# Sass preprocessor +.sass-cache/ +# node +/node_modules/* +# yarn +yarn-debug.log +yarn-error.log diff --git a/tests/Frameworks/CakePHP/Version_5_0/.htaccess b/tests/Frameworks/CakePHP/Version_5_0/.htaccess new file mode 100644 index 0000000000..54b08e82e1 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/.htaccess @@ -0,0 +1,12 @@ +# Uncomment the following to prevent the httpoxy vulnerability +# See: https://httpoxy.org/ +# +# RequestHeader unset Proxy +# + + + RewriteEngine on + RewriteRule ^(\.well-known/.*)$ $1 [L] + RewriteRule ^$ webroot/ [L] + RewriteRule (.*) webroot/$1 [L] + diff --git a/tests/Frameworks/CakePHP/Version_5_0/README.md b/tests/Frameworks/CakePHP/Version_5_0/README.md new file mode 100644 index 0000000000..4d1eccde19 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/README.md @@ -0,0 +1,53 @@ +# CakePHP Application Skeleton + +![Build Status](https://github.com/cakephp/app/actions/workflows/ci.yml/badge.svg?branch=master) +[![Total Downloads](https://img.shields.io/packagist/dt/cakephp/app.svg?style=flat-square)](https://packagist.org/packages/cakephp/app) +[![PHPStan](https://img.shields.io/badge/PHPStan-level%207-brightgreen.svg?style=flat-square)](https://github.com/phpstan/phpstan) + +A skeleton for creating applications with [CakePHP](https://cakephp.org) 5.x. + +The framework source code can be found here: [cakephp/cakephp](https://github.com/cakephp/cakephp). + +## Installation + +1. Download [Composer](https://getcomposer.org/doc/00-intro.md) or update `composer self-update`. +2. Run `php composer.phar create-project --prefer-dist cakephp/app [app_name]`. + +If Composer is installed globally, run + +```bash +composer create-project --prefer-dist cakephp/app +``` + +In case you want to use a custom app dir name (e.g. `/myapp/`): + +```bash +composer create-project --prefer-dist cakephp/app myapp +``` + +You can now either use your machine's webserver to view the default home page, or start +up the built-in webserver with: + +```bash +bin/cake server -p 8765 +``` + +Then visit `http://localhost:8765` to see the welcome page. + +## Update + +Since this skeleton is a starting point for your application and various files +would have been modified as per your needs, there isn't a way to provide +automated upgrades, so you have to do any updates manually. + +## Configuration + +Read and edit the environment specific `config/app_local.php` and set up the +`'Datasources'` and any other configuration relevant for your application. +Other environment agnostic settings can be changed in `config/app.php`. + +## Layout + +The app skeleton uses [Milligram](https://milligram.io/) (v1.3) minimalist CSS +framework by default. You can, however, replace it with any other library or +custom styles. diff --git a/tests/Frameworks/CakePHP/Version_5_0/bin/bash_completion.sh b/tests/Frameworks/CakePHP/Version_5_0/bin/bash_completion.sh new file mode 100644 index 0000000000..a3d3feba94 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/bin/bash_completion.sh @@ -0,0 +1,47 @@ +# +# Bash completion file for CakePHP console. +# Copy this file to a file named `cake` under `/etc/bash_completion.d/`. +# For more info check https://book.cakephp.org/4/en/console-commands/completion.html#how-to-enable-bash-autocompletion-for-the-cakephp-console +# + +_cake() +{ + local cur prev opts cake + COMPREPLY=() + cake="${COMP_WORDS[0]}" + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + if [[ "$cur" == -* ]] ; then + if [[ ${COMP_CWORD} = 1 ]] ; then + opts=$(${cake} completion options) + elif [[ ${COMP_CWORD} = 2 ]] ; then + opts=$(${cake} completion options "${COMP_WORDS[1]}") + else + opts=$(${cake} completion options "${COMP_WORDS[1]}" "${COMP_WORDS[2]}") + fi + + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 + fi + + if [[ ${COMP_CWORD} = 1 ]] ; then + opts=$(${cake} completion commands) + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 + fi + + if [[ ${COMP_CWORD} = 2 ]] ; then + opts=$(${cake} completion subcommands $prev) + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + if [[ $COMPREPLY = "" ]] ; then + _filedir + return 0 + fi + return 0 + fi + + return 0 +} + +complete -F _cake cake bin/cake diff --git a/tests/Frameworks/CakePHP/Version_5_0/bin/cake b/tests/Frameworks/CakePHP/Version_5_0/bin/cake new file mode 100755 index 0000000000..4b696c883f --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/bin/cake @@ -0,0 +1,75 @@ +#!/usr/bin/env sh +################################################################################ +# +# Cake is a shell script for invoking CakePHP shell commands +# +# CakePHP(tm) : Rapid Development Framework (https://cakephp.org) +# Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) +# +# Licensed under The MIT License +# For full copyright and license information, please see the LICENSE.txt +# Redistributions of files must retain the above copyright notice. +# +# @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) +# @link https://cakephp.org CakePHP(tm) Project +# @since 1.2.0 +# @license https://opensource.org/licenses/mit-license.php MIT License +# +################################################################################ + +# Canonicalize by following every symlink of the given name recursively +canonicalize() { + NAME="$1" + if [ -f "$NAME" ] + then + DIR=$(dirname -- "$NAME") + NAME=$(cd -P "$DIR" > /dev/null && pwd -P)/$(basename -- "$NAME") + fi + while [ -h "$NAME" ]; do + DIR=$(dirname -- "$NAME") + SYM=$(readlink "$NAME") + NAME=$(cd "$DIR" > /dev/null && cd "$(dirname -- "$SYM")" > /dev/null && pwd)/$(basename -- "$SYM") + done + echo "$NAME" +} + +# Find a CLI version of PHP +findCliPhp() { + for TESTEXEC in php php-cli /usr/local/bin/php + do + SAPI=$(echo "" | $TESTEXEC 2>/dev/null) + if [ "$SAPI" = "cli" ] + then + echo $TESTEXEC + return + fi + done + echo "Failed to find a CLI version of PHP; falling back to system standard php executable" >&2 + echo "php"; +} + +# If current path is a symlink, resolve to real path +realname="$0" +if [ -L "$realname" ] +then + realname=$(readlink -f "$0") +fi + +CONSOLE=$(dirname -- "$(canonicalize "$realname")") +APP=$(dirname "$CONSOLE") + +# If your CLI PHP is somewhere that this doesn't find, you can define a PHP environment +# variable with the correct path in it. +if [ -z "$PHP" ] +then + PHP=$(findCliPhp) +fi + +if [ "$(basename "$realname")" != 'cake' ] +then + exec "$PHP" "$CONSOLE"/cake.php "$(basename "$realname")" "$@" +else + exec "$PHP" "$CONSOLE"/cake.php "$@" +fi + +exit diff --git a/tests/Frameworks/CakePHP/Version_5_0/bin/cake.bat b/tests/Frameworks/CakePHP/Version_5_0/bin/cake.bat new file mode 100644 index 0000000000..ad13782298 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/bin/cake.bat @@ -0,0 +1,27 @@ +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:: +:: Cake is a Windows batch script for invoking CakePHP shell commands +:: +:: CakePHP(tm) : Rapid Development Framework (https://cakephp.org) +:: Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) +:: +:: Licensed under The MIT License +:: Redistributions of files must retain the above copyright notice. +:: +:: @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) +:: @link https://cakephp.org CakePHP(tm) Project +:: @since 2.0.0 +:: @license https://opensource.org/licenses/mit-license.php MIT License +:: +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +@echo off + +SET app=%0 +SET lib=%~dp0 + +php "%lib%cake.php" %* + +echo. + +exit /B %ERRORLEVEL% diff --git a/tests/Frameworks/CakePHP/Version_5_0/bin/cake.php b/tests/Frameworks/CakePHP/Version_5_0/bin/cake.php new file mode 100644 index 0000000000..aab8d9fe12 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/bin/cake.php @@ -0,0 +1,10 @@ +#!/usr/bin/php -q +run($argv)); diff --git a/tests/Frameworks/CakePHP/Version_5_0/composer.json b/tests/Frameworks/CakePHP/Version_5_0/composer.json new file mode 100644 index 0000000000..bbcb4956fc --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/composer.json @@ -0,0 +1,58 @@ +{ + "name": "cakephp/app", + "description": "CakePHP skeleton app", + "homepage": "https://cakephp.org", + "type": "project", + "license": "MIT", + "require": { + "php": ">=8.1", + "cakephp/cakephp": "^5.0.1", + "cakephp/migrations": "^4.0.0", + "cakephp/plugin-installer": "^2.0", + "mobiledetect/mobiledetectlib": "^3.74" + }, + "require-dev": { + "cakephp/bake": "^3.0.0", + "cakephp/cakephp-codesniffer": "^5.0", + "cakephp/debug_kit": "^5.0.0", + "josegonzalez/dotenv": "^4.0", + "phpunit/phpunit": "^10.1.0" + }, + "suggest": { + "markstory/asset_compress": "An asset compression plugin which provides file concatenation and a flexible filter system for preprocessing and minification.", + "dereuromark/cakephp-ide-helper": "After baking your code, this keeps your annotations in sync with the code evolving from there on for maximum IDE and PHPStan/Psalm compatibility.", + "phpstan/phpstan": "PHPStan focuses on finding errors in your code without actually running it. It catches whole classes of bugs even before you write tests for the code.", + "cakephp/repl": "Console tools for a REPL interface for CakePHP applications." + }, + "autoload": { + "psr-4": { + "App\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "App\\Test\\": "tests/", + "Cake\\Test\\": "vendor/cakephp/cakephp/tests/" + } + }, + "scripts": { + "post-install-cmd": "App\\Console\\Installer::postInstall", + "post-create-project-cmd": "App\\Console\\Installer::postInstall", + "check": [ + "@test", + "@cs-check" + ], + "cs-check": "phpcs --colors -p", + "cs-fix": "phpcbf --colors -p", + "stan": "phpstan analyse", + "test": "phpunit --colors=always" + }, + "config": { + "platform-check": true, + "sort-packages": true, + "allow-plugins": { + "cakephp/plugin-installer": true, + "dealerdirect/phpcodesniffer-composer-installer": true + } + } +} diff --git a/tests/Frameworks/CakePHP/Version_5_0/config/.env.example b/tests/Frameworks/CakePHP/Version_5_0/config/.env.example new file mode 100644 index 0000000000..e90937b65c --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/config/.env.example @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# Used as a default to seed config/.env which +# enables you to use environment variables to configure +# the aspects of your application that vary by +# environment. +# +# Having this file in production is considered a **SECURITY RISK** and also decreases +# the bootstrap performance of your application. +# +# To use this file, first copy it into `config/.env`. Also ensure the related +# code block for loading this file is uncommented in `config/bootstrap.php` +# +# In development .env files are parsed by PHP +# and set into the environment. This provides a simpler +# development workflow over standard environment variables. +export APP_NAME="__APP_NAME__" +export DEBUG="true" +export APP_ENCODING="UTF-8" +export APP_DEFAULT_LOCALE="en_US" +export APP_DEFAULT_TIMEZONE="UTC" +export SECURITY_SALT="__SALT__" + +# Uncomment these to define cache configuration via environment variables. +#export CACHE_DURATION="+2 minutes" +#export CACHE_DEFAULT_URL="file:///path/to/tmp/cache/?prefix=${APP_NAME}_default_&duration=${CACHE_DURATION}" +#export CACHE_CAKECORE_URL="file:///path/to/tmp/cache/persistent?prefix=${APP_NAME}_cake_core_&serialize=true&duration=${CACHE_DURATION}" +#export CACHE_CAKEMODEL_URL="file:///path/to/tmp/cache/models?prefix=${APP_NAME}_cake_model_&serialize=true&duration=${CACHE_DURATION}" + +# Uncomment these to define email transport configuration via environment variables. +#export EMAIL_TRANSPORT_DEFAULT_URL="" + +# Uncomment these to define database configuration via environment variables. +#export DATABASE_URL="mysql://my_app:secret@localhost/${APP_NAME}?encoding=utf8&timezone=UTC&cacheMetadata=true"eIdentifiers=false&persistent=false" +#export DATABASE_TEST_URL="mysql://my_app:secret@localhost/test_${APP_NAME}?encoding=utf8&timezone=UTC&cacheMetadata=true"eIdentifiers=false&persistent=false" + +# Uncomment these to define logging configuration via environment variables. +#export LOG_DEBUG_URL="file:///path/to/logs/?levels[]=notice&levels[]=info&levels[]=debug&file=debug" +#export LOG_ERROR_URL="file:///path/to/logs/?levels[]=warning&levels[]=error&levels[]=critical&levels[]=alert&levels[]=emergency&file=error" diff --git a/tests/Frameworks/CakePHP/Version_5_0/config/app.php b/tests/Frameworks/CakePHP/Version_5_0/config/app.php new file mode 100644 index 0000000000..94232d5880 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/config/app.php @@ -0,0 +1,410 @@ + filter_var(env('DEBUG', false), FILTER_VALIDATE_BOOLEAN), + + /* + * Configure basic information about the application. + * + * - namespace - The namespace to find app classes under. + * - defaultLocale - The default locale for translation, formatting currencies and numbers, date and time. + * - encoding - The encoding used for HTML + database connections. + * - base - The base directory the app resides in. If false this + * will be auto detected. + * - dir - Name of app directory. + * - webroot - The webroot directory. + * - wwwRoot - The file path to webroot. + * - baseUrl - To configure CakePHP to *not* use mod_rewrite and to + * use CakePHP pretty URLs, remove these .htaccess + * files: + * /.htaccess + * /webroot/.htaccess + * And uncomment the baseUrl key below. + * - fullBaseUrl - A base URL to use for absolute links. When set to false (default) + * CakePHP generates required value based on `HTTP_HOST` environment variable. + * However, you can define it manually to optimize performance or if you + * are concerned about people manipulating the `Host` header. + * - imageBaseUrl - Web path to the public images directory under webroot. + * - cssBaseUrl - Web path to the public css directory under webroot. + * - jsBaseUrl - Web path to the public js directory under webroot. + * - paths - Configure paths for non class based resources. Supports the + * `plugins`, `templates`, `locales` subkeys, which allow the definition of + * paths for plugins, view templates and locale files respectively. + */ + 'App' => [ + 'namespace' => 'App', + 'encoding' => env('APP_ENCODING', 'UTF-8'), + 'defaultLocale' => env('APP_DEFAULT_LOCALE', 'en_US'), + 'defaultTimezone' => env('APP_DEFAULT_TIMEZONE', 'UTC'), + 'base' => false, + 'dir' => 'src', + 'webroot' => 'webroot', + 'wwwRoot' => WWW_ROOT, + //'baseUrl' => env('SCRIPT_NAME'), + 'fullBaseUrl' => false, + 'imageBaseUrl' => 'img/', + 'cssBaseUrl' => 'css/', + 'jsBaseUrl' => 'js/', + 'paths' => [ + 'plugins' => [ROOT . DS . 'plugins' . DS], + 'templates' => [ROOT . DS . 'templates' . DS], + 'locales' => [RESOURCES . 'locales' . DS], + ], + ], + + /* + * Security and encryption configuration + * + * - salt - A random string used in security hashing methods. + * The salt value is also used as the encryption key. + * You should treat it as extremely sensitive data. + */ + 'Security' => [ + 'salt' => env('SECURITY_SALT', 'dfc123c6c22d84f4bc12273f3df67c6ae55009696e4126b36ac2f755778faccc'), + ], + + /* + * Apply timestamps with the last modified time to static assets (js, css, images). + * Will append a querystring parameter containing the time the file was modified. + * This is useful for busting browser caches. + * + * Set to true to apply timestamps when debug is true. Set to 'force' to always + * enable timestamping regardless of debug value. + */ + 'Asset' => [ + //'timestamp' => true, + // 'cacheTime' => '+1 year' + ], + + /* + * Configure the cache adapters. + */ + 'Cache' => [ + 'default' => [ + 'className' => FileEngine::class, + 'path' => CACHE, + 'url' => env('CACHE_DEFAULT_URL', null), + ], + + /* + * Configure the cache used for general framework caching. + * Translation cache files are stored with this configuration. + * Duration will be set to '+2 minutes' in bootstrap.php when debug = true + * If you set 'className' => 'Null' core cache will be disabled. + */ + '_cake_core_' => [ + 'className' => FileEngine::class, + 'prefix' => 'myapp_cake_core_', + 'path' => CACHE . 'persistent' . DS, + 'serialize' => true, + 'duration' => '+1 years', + 'url' => env('CACHE_CAKECORE_URL', null), + ], + + /* + * Configure the cache for model and datasource caches. This cache + * configuration is used to store schema descriptions, and table listings + * in connections. + * Duration will be set to '+2 minutes' in bootstrap.php when debug = true + */ + '_cake_model_' => [ + 'className' => FileEngine::class, + 'prefix' => 'myapp_cake_model_', + 'path' => CACHE . 'models' . DS, + 'serialize' => true, + 'duration' => '+1 years', + 'url' => env('CACHE_CAKEMODEL_URL', null), + ], + ], + + /* + * Configure the Error and Exception handlers used by your application. + * + * By default errors are displayed using Debugger, when debug is true and logged + * by Cake\Log\Log when debug is false. + * + * In CLI environments exceptions will be printed to stderr with a backtrace. + * In web environments an HTML page will be displayed for the exception. + * With debug true, framework errors like Missing Controller will be displayed. + * When debug is false, framework errors will be coerced into generic HTTP errors. + * + * Options: + * + * - `errorLevel` - int - The level of errors you are interested in capturing. + * - `trace` - boolean - Whether backtraces should be included in + * logged errors/exceptions. + * - `log` - boolean - Whether you want exceptions logged. + * - `exceptionRenderer` - string - The class responsible for rendering uncaught exceptions. + * The chosen class will be used for both CLI and web environments. If you want different + * classes used in CLI and web environments you'll need to write that conditional logic as well. + * The conventional location for custom renderers is in `src/Error`. Your exception renderer needs to + * implement the `render()` method and return either a string or Http\Response. + * `errorRenderer` - string - The class responsible for rendering PHP errors. The selected + * class will be used for both web and CLI contexts. If you want different classes for each environment + * you'll need to write that conditional logic as well. Error renderers need to + * to implement the `Cake\Error\ErrorRendererInterface`. + * - `skipLog` - array - List of exceptions to skip for logging. Exceptions that + * extend one of the listed exceptions will also be skipped for logging. + * E.g.: + * `'skipLog' => ['Cake\Http\Exception\NotFoundException', 'Cake\Http\Exception\UnauthorizedException']` + * - `extraFatalErrorMemory` - int - The number of megabytes to increase the memory limit by + * when a fatal error is encountered. This allows + * breathing room to complete logging or error handling. + * - `ignoredDeprecationPaths` - array - A list of glob compatible file paths that deprecations + * should be ignored in. Use this to ignore deprecations for plugins or parts of + * your application that still emit deprecations. + */ + 'Error' => [ + 'errorLevel' => E_ALL, + 'skipLog' => [], + 'log' => true, + 'trace' => true, + 'ignoredDeprecationPaths' => [], + ], + + /* + * Debugger configuration + * + * Define development error values for Cake\Error\Debugger + * + * - `editor` Set the editor URL format you want to use. + * By default atom, emacs, macvim, phpstorm, sublime, textmate, and vscode are + * available. You can add additional editor link formats using + * `Debugger::addEditor()` during your application bootstrap. + * - `outputMask` A mapping of `key` to `replacement` values that + * `Debugger` should replace in dumped data and logs generated by `Debugger`. + */ + 'Debugger' => [ + 'editor' => 'phpstorm', + ], + + /* + * Email configuration. + * + * By defining transports separately from delivery profiles you can easily + * re-use transport configuration across multiple profiles. + * + * You can specify multiple configurations for production, development and + * testing. + * + * Each transport needs a `className`. Valid options are as follows: + * + * Mail - Send using PHP mail function + * Smtp - Send using SMTP + * Debug - Do not send the email, just return the result + * + * You can add custom transports (or override existing transports) by adding the + * appropriate file to src/Mailer/Transport. Transports should be named + * 'YourTransport.php', where 'Your' is the name of the transport. + */ + 'EmailTransport' => [ + 'default' => [ + 'className' => MailTransport::class, + /* + * The keys host, port, timeout, username, password, client and tls + * are used in SMTP transports + */ + 'host' => 'localhost', + 'port' => 25, + 'timeout' => 30, + /* + * It is recommended to set these options through your environment or app_local.php + */ + //'username' => null, + //'password' => null, + 'client' => null, + 'tls' => false, + 'url' => env('EMAIL_TRANSPORT_DEFAULT_URL', null), + ], + ], + + /* + * Email delivery profiles + * + * Delivery profiles allow you to predefine various properties about email + * messages from your application and give the settings a name. This saves + * duplication across your application and makes maintenance and development + * easier. Each profile accepts a number of keys. See `Cake\Mailer\Email` + * for more information. + */ + 'Email' => [ + 'default' => [ + 'transport' => 'default', + 'from' => 'you@localhost', + /* + * Will by default be set to config value of App.encoding, if that exists otherwise to UTF-8. + */ + //'charset' => 'utf-8', + //'headerCharset' => 'utf-8', + ], + ], + + /* + * Connection information used by the ORM to connect + * to your application's datastores. + * + * ### Notes + * - Drivers include Mysql Postgres Sqlite Sqlserver + * See vendor\cakephp\cakephp\src\Database\Driver for complete list + * - Do not use periods in database name - it may lead to error. + * See https://github.com/cakephp/cakephp/issues/6471 for details. + * - 'encoding' is recommended to be set to full UTF-8 4-Byte support. + * E.g set it to 'utf8mb4' in MariaDB and MySQL and 'utf8' for any + * other RDBMS. + */ + 'Datasources' => [ + /* + * These configurations should contain permanent settings used + * by all environments. + * + * The values in app_local.php will override any values set here + * and should be used for local and per-environment configurations. + * + * Environment variable based configurations can be loaded here or + * in app_local.php depending on the applications needs. + */ + 'default' => [ + 'className' => Connection::class, + 'driver' => Mysql::class, + 'persistent' => false, + 'timezone' => 'UTC', + + /* + * For MariaDB/MySQL the internal default changed from utf8 to utf8mb4, aka full utf-8 support, in CakePHP 3.6 + */ + //'encoding' => 'utf8mb4', + + /* + * If your MySQL server is configured with `skip-character-set-client-handshake` + * then you MUST use the `flags` config to set your charset encoding. + * For e.g. `'flags' => [\PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4']` + */ + 'flags' => [], + 'cacheMetadata' => true, + 'log' => false, + + /* + * Set identifier quoting to true if you are using reserved words or + * special characters in your table or column names. Enabling this + * setting will result in queries built using the Query Builder having + * identifiers quoted when creating SQL. It should be noted that this + * decreases performance because each query needs to be traversed and + * manipulated before being executed. + */ + 'quoteIdentifiers' => false, + + /* + * During development, if using MySQL < 5.6, uncommenting the + * following line could boost the speed at which schema metadata is + * fetched from the database. It can also be set directly with the + * mysql configuration directive 'innodb_stats_on_metadata = 0' + * which is the recommended value in production environments + */ + //'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'], + ], + + /* + * The test connection is used during the test suite. + */ + 'test' => [ + 'className' => Connection::class, + 'driver' => Mysql::class, + 'persistent' => false, + 'timezone' => 'UTC', + //'encoding' => 'utf8mb4', + 'flags' => [], + 'cacheMetadata' => true, + 'quoteIdentifiers' => false, + 'log' => false, + //'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'], + ], + ], + + /* + * Configures logging options + */ + 'Log' => [ + 'debug' => [ + 'className' => FileLog::class, + 'path' => LOGS, + 'file' => 'debug', + 'url' => env('LOG_DEBUG_URL', null), + 'scopes' => null, + 'levels' => ['notice', 'info', 'debug'], + ], + 'error' => [ + 'className' => FileLog::class, + 'path' => LOGS, + 'file' => 'error', + 'url' => env('LOG_ERROR_URL', null), + 'scopes' => null, + 'levels' => ['warning', 'error', 'critical', 'alert', 'emergency'], + ], + // To enable this dedicated query log, you need set your datasource's log flag to true + 'queries' => [ + 'className' => FileLog::class, + 'path' => LOGS, + 'file' => 'queries', + 'url' => env('LOG_QUERIES_URL', null), + 'scopes' => ['cake.database.queries'], + ], + ], + + /* + * Session configuration. + * + * Contains an array of settings to use for session configuration. The + * `defaults` key is used to define a default preset to use for sessions, any + * settings declared here will override the settings of the default config. + * + * ## Options + * + * - `cookie` - The name of the cookie to use. Defaults to value set for `session.name` php.ini config. + * Avoid using `.` in cookie names, as PHP will drop sessions from cookies with `.` in the name. + * - `cookiePath` - The url path for which session cookie is set. Maps to the + * `session.cookie_path` php.ini config. Defaults to base path of app. + * - `timeout` - The time in minutes the session should be valid for. + * Pass 0 to disable checking timeout. + * Please note that php.ini's session.gc_maxlifetime must be equal to or greater + * than the largest Session['timeout'] in all served websites for it to have the + * desired effect. + * - `defaults` - The default configuration set to use as a basis for your session. + * There are four built-in options: php, cake, cache, database. + * - `handler` - Can be used to enable a custom session handler. Expects an + * array with at least the `engine` key, being the name of the Session engine + * class to use for managing the session. CakePHP bundles the `CacheSession` + * and `DatabaseSession` engines. + * - `ini` - An associative array of additional 'session.*` ini values to set. + * + * The built-in `defaults` options are: + * + * - 'php' - Uses settings defined in your php.ini. + * - 'cake' - Saves session files in CakePHP's /tmp directory. + * - 'database' - Uses CakePHP's database sessions. + * - 'cache' - Use the Cache class to save sessions. + * + * To define a custom session handler, save it at src/Http/Session/.php. + * Make sure the class implements PHP's `SessionHandlerInterface` and set + * Session.handler to + * + * To use database sessions, load the SQL file located at config/schema/sessions.sql + */ + 'Session' => [ + 'defaults' => 'php', + ], +]; diff --git a/tests/Frameworks/CakePHP/Version_5_0/config/app_local.example.php b/tests/Frameworks/CakePHP/Version_5_0/config/app_local.example.php new file mode 100644 index 0000000000..8bdb855dd5 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/config/app_local.example.php @@ -0,0 +1,94 @@ + filter_var(env('DEBUG', true), FILTER_VALIDATE_BOOLEAN), + + /* + * Security and encryption configuration + * + * - salt - A random string used in security hashing methods. + * The salt value is also used as the encryption key. + * You should treat it as extremely sensitive data. + */ + 'Security' => [ + 'salt' => env('SECURITY_SALT', '__SALT__'), + ], + + /* + * Connection information used by the ORM to connect + * to your application's datastores. + * + * See app.php for more configuration options. + */ + 'Datasources' => [ + 'default' => [ + 'host' => 'localhost', + /* + * CakePHP will use the default DB port based on the driver selected + * MySQL on MAMP uses port 8889, MAMP users will want to uncomment + * the following line and set the port accordingly + */ + //'port' => 'non_standard_port_number', + + 'username' => 'my_app', + 'password' => 'secret', + + 'database' => 'my_app', + /* + * If not using the default 'public' schema with the PostgreSQL driver + * set it here. + */ + //'schema' => 'myapp', + + /* + * You can use a DSN string to set the entire configuration + */ + 'url' => env('DATABASE_URL', null), + ], + + /* + * The test connection is used during the test suite. + */ + 'test' => [ + 'host' => 'localhost', + //'port' => 'non_standard_port_number', + 'username' => 'my_app', + 'password' => 'secret', + 'database' => 'test_myapp', + //'schema' => 'myapp', + 'url' => env('DATABASE_TEST_URL', 'sqlite://127.0.0.1/tmp/tests.sqlite'), + ], + ], + + /* + * Email configuration. + * + * Host and credential configuration in case you are using SmtpTransport + * + * See app.php for more configuration options. + */ + 'EmailTransport' => [ + 'default' => [ + 'host' => 'localhost', + 'port' => 25, + 'username' => null, + 'password' => null, + 'client' => null, + 'url' => env('EMAIL_TRANSPORT_DEFAULT_URL', null), + ], + ], +]; diff --git a/tests/Frameworks/CakePHP/Version_5_0/config/bootstrap.php b/tests/Frameworks/CakePHP/Version_5_0/config/bootstrap.php new file mode 100644 index 0000000000..9c0aaaa5d5 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/config/bootstrap.php @@ -0,0 +1,231 @@ +parse() +// ->putenv() +// ->toEnv() +// ->toServer(); +// } + +/* + * Read configuration file and inject configuration into various + * CakePHP classes. + * + * By default there is only one configuration file. It is often a good + * idea to create multiple configuration files, and separate the configuration + * that changes from configuration that does not. This makes deployment simpler. + */ +try { + Configure::config('default', new PhpConfig()); + Configure::load('app', 'default', false); +} catch (\Exception $e) { + exit($e->getMessage() . "\n"); +} + +/* + * Load an environment local configuration file to provide overrides to your configuration. + * Notice: For security reasons app_local.php **should not** be included in your git repo. + */ +if (file_exists(CONFIG . 'app_local.php')) { + Configure::load('app_local', 'default'); +} + +/* + * When debug = true the metadata cache should only last + * for a short time. + */ +if (Configure::read('debug')) { + Configure::write('Cache._cake_model_.duration', '+2 minutes'); + Configure::write('Cache._cake_core_.duration', '+2 minutes'); + // disable router cache during development + Configure::write('Cache._cake_routes_.duration', '+2 seconds'); +} + +/* + * Set the default server timezone. Using UTC makes time calculations / conversions easier. + * Check https://php.net/manual/en/timezones.php for list of valid timezone strings. + */ +date_default_timezone_set(Configure::read('App.defaultTimezone')); + +/* + * Configure the mbstring extension to use the correct encoding. + */ +mb_internal_encoding(Configure::read('App.encoding')); + +/* + * Set the default locale. This controls how dates, number and currency is + * formatted and sets the default language to use for translations. + */ +ini_set('intl.default_locale', Configure::read('App.defaultLocale')); + +/* + * Register application error and exception handlers. + */ +(new ErrorTrap(Configure::read('Error')))->register(); +(new ExceptionTrap(Configure::read('Error')))->register(); + +/* + * Include the CLI bootstrap overrides. + */ +if (PHP_SAPI === 'cli') { + require CONFIG . 'bootstrap_cli.php'; +} + +/* + * Set the full base URL. + * This URL is used as the base of all absolute links. + */ +$fullBaseUrl = Configure::read('App.fullBaseUrl'); +if (!$fullBaseUrl) { + /* + * When using proxies or load balancers, SSL/TLS connections might + * get terminated before reaching the server. If you trust the proxy, + * you can enable `$trustProxy` to rely on the `X-Forwarded-Proto` + * header to determine whether to generate URLs using `https`. + * + * See also https://book.cakephp.org/4/en/controllers/request-response.html#trusting-proxy-headers + */ + $trustProxy = false; + + $s = null; + if (env('HTTPS') || ($trustProxy && env('HTTP_X_FORWARDED_PROTO') === 'https')) { + $s = 's'; + } + + $httpHost = env('HTTP_HOST'); + if (isset($httpHost)) { + $fullBaseUrl = 'http' . $s . '://' . $httpHost; + } + unset($httpHost, $s); +} +if ($fullBaseUrl) { + Router::fullBaseUrl($fullBaseUrl); +} +unset($fullBaseUrl); + +Cache::setConfig(Configure::consume('Cache')); +ConnectionManager::setConfig(Configure::consume('Datasources')); +TransportFactory::setConfig(Configure::consume('EmailTransport')); +Mailer::setConfig(Configure::consume('Email')); +Log::setConfig(Configure::consume('Log')); +Security::setSalt(Configure::consume('Security.salt')); + +/* + * Setup detectors for mobile and tablet. + * If you don't use these checks you can safely remove this code + * and the mobiledetect package from composer.json. + */ +ServerRequest::addDetector('mobile', function ($request) { + $detector = new \Detection\MobileDetect(); + + return $detector->isMobile(); +}); +ServerRequest::addDetector('tablet', function ($request) { + $detector = new \Detection\MobileDetect(); + + return $detector->isTablet(); +}); + +/* + * You can enable default locale format parsing by adding calls + * to `useLocaleParser()`. This enables the automatic conversion of + * locale specific date formats. For details see + * @link https://book.cakephp.org/4/en/core-libraries/internationalization-and-localization.html#parsing-localized-datetime-data + */ +// \Cake\Database\TypeFactory::build('time') +// ->useLocaleParser(); +// \Cake\Database\TypeFactory::build('date') +// ->useLocaleParser(); +// \Cake\Database\TypeFactory::build('datetime') +// ->useLocaleParser(); +// \Cake\Database\TypeFactory::build('timestamp') +// ->useLocaleParser(); +// \Cake\Database\TypeFactory::build('datetimefractional') +// ->useLocaleParser(); +// \Cake\Database\TypeFactory::build('timestampfractional') +// ->useLocaleParser(); +// \Cake\Database\TypeFactory::build('datetimetimezone') +// ->useLocaleParser(); +// \Cake\Database\TypeFactory::build('timestamptimezone') +// ->useLocaleParser(); + +/* + * Custom Inflector rules, can be set to correctly pluralize or singularize + * table, model, controller names or whatever other string is passed to the + * inflection functions. + */ +//Inflector::rules('plural', ['/^(inflect)or$/i' => '\1ables']); +//Inflector::rules('irregular', ['red' => 'redlings']); +//Inflector::rules('uninflected', ['dontinflectme']); + +// set a custom date and time format +// see https://book.cakephp.org/4/en/core-libraries/time.html#setting-the-default-locale-and-format-string +// and https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax +//\Cake\I18n\FrozenDate::setToStringFormat('dd.MM.yyyy'); +//\Cake\I18n\FrozenTime::setToStringFormat('dd.MM.yyyy HH:mm'); diff --git a/tests/Frameworks/CakePHP/Version_5_0/config/bootstrap_cli.php b/tests/Frameworks/CakePHP/Version_5_0/config/bootstrap_cli.php new file mode 100644 index 0000000000..fc0dc30bb5 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/config/bootstrap_cli.php @@ -0,0 +1,35 @@ + ['onlyDebug' => true], + + // Optional plugins which are only needed in CLI commands + 'Bake' => ['onlyCli' => true, 'optional' => true], + + // Required plugins only in CLI commands + 'Migrations' => ['onlyCli' => true], + + // Add your custom plugins here +]; diff --git a/tests/Frameworks/CakePHP/Version_5_0/config/routes.php b/tests/Frameworks/CakePHP/Version_5_0/config/routes.php new file mode 100644 index 0000000000..4825620d15 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/config/routes.php @@ -0,0 +1,100 @@ +setRouteClass(DashedRoute::class); + + $routes->scope('/', function (RouteBuilder $builder): void { + $builder->connect('/parameterized/{param}', + ['controller' => 'Parameterized', 'action' => 'customAction'] + )->setPass(['param']); + + /* + * Here, we are connecting '/' (base path) to a controller called 'Pages', + * its action called 'display', and we pass a param to select the view file + * to use (in this case, templates/Pages/home.php)... + */ + $builder->connect('/', ['controller' => 'Pages', 'action' => 'display', 'home']); + + /* + * ...and connect the rest of 'Pages' controller's URLs. + */ + $builder->connect('/pages/*', 'Pages::display'); + + /* + * Connect catchall routes for all controllers. + * + * The `fallbacks` method is a shortcut for + * + * ``` + * $builder->connect('/{controller}', ['action' => 'index']); + * $builder->connect('/{controller}/{action}/*', []); + * ``` + * + * You can remove these routes once you've connected the + * routes you want in your application. + */ + $builder->fallbacks(); + }); + + /* + * If you need a different set of middleware or none at all, + * open new scope and define routes there. + * + * ``` + * $routes->scope('/api', function (RouteBuilder $builder): void { + * // No $builder->applyMiddleware() here. + * + * // Parse specified extensions from URLs + * // $builder->setExtensions(['json', 'xml']); + * + * // Connect API actions here. + * }); + * ``` + */ +}; diff --git a/tests/Frameworks/CakePHP/Version_5_0/config/schema/i18n.sql b/tests/Frameworks/CakePHP/Version_5_0/config/schema/i18n.sql new file mode 100644 index 0000000000..e59d1e6511 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/config/schema/i18n.sql @@ -0,0 +1,18 @@ +# Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) +# +# Licensed under The MIT License +# For full copyright and license information, please see the LICENSE.txt +# Redistributions of files must retain the above copyright notice. +# MIT License (https://opensource.org/licenses/mit-license.php) + +CREATE TABLE i18n ( + id int NOT NULL auto_increment, + locale varchar(6) NOT NULL, + model varchar(255) NOT NULL, + foreign_key int(10) NOT NULL, + field varchar(255) NOT NULL, + content text, + PRIMARY KEY (id), + UNIQUE INDEX I18N_LOCALE_FIELD(locale, model, foreign_key, field), + INDEX I18N_FIELD(model, foreign_key, field) +); diff --git a/tests/Frameworks/CakePHP/Version_5_0/config/schema/sessions.sql b/tests/Frameworks/CakePHP/Version_5_0/config/schema/sessions.sql new file mode 100644 index 0000000000..1aa0a0f54e --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/config/schema/sessions.sql @@ -0,0 +1,15 @@ +# Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) +# +# Licensed under The MIT License +# For full copyright and license information, please see the LICENSE.txt +# Redistributions of files must retain the above copyright notice. +# MIT License (https://opensource.org/licenses/mit-license.php) + +CREATE TABLE `sessions` ( + `id` char(40) CHARACTER SET ascii COLLATE ascii_bin NOT NULL, + `created` datetime DEFAULT CURRENT_TIMESTAMP, -- optional, requires MySQL 5.6.5+ + `modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- optional, requires MySQL 5.6.5+ + `data` blob DEFAULT NULL, -- for PostgreSQL use bytea instead of blob + `expires` int(10) unsigned DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/tests/Frameworks/CakePHP/Version_5_0/index.php b/tests/Frameworks/CakePHP/Version_5_0/index.php new file mode 100644 index 0000000000..4591769163 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/index.php @@ -0,0 +1,16 @@ + + + + + + + */src/Controller/* + + + src/ + tests/ + diff --git a/tests/Frameworks/CakePHP/Version_5_0/phpstan.neon b/tests/Frameworks/CakePHP/Version_5_0/phpstan.neon new file mode 100644 index 0000000000..c131decf0b --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/phpstan.neon @@ -0,0 +1,6 @@ +parameters: + level: 8 + treatPhpDocTypesAsCertain: false + checkGenericClassInNonGenericObjectType: false + paths: + - src/ diff --git a/tests/Frameworks/CakePHP/Version_5_0/phpunit.xml.dist b/tests/Frameworks/CakePHP/Version_5_0/phpunit.xml.dist new file mode 100644 index 0000000000..4dfd186a3c --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/phpunit.xml.dist @@ -0,0 +1,37 @@ + + + + + + + + + + + tests/TestCase/ + + + + + + + + + + + + + src/ + plugins/*/src/ + + + src/Console/Installer.php + + + diff --git a/tests/Frameworks/CakePHP/Version_5_0/plugins/.gitkeep b/tests/Frameworks/CakePHP/Version_5_0/plugins/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Frameworks/CakePHP/Version_5_0/psalm.xml b/tests/Frameworks/CakePHP/Version_5_0/psalm.xml new file mode 100644 index 0000000000..4e9226bdb1 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/psalm.xml @@ -0,0 +1,15 @@ + + + + + + + + + diff --git a/tests/Frameworks/CakePHP/Version_5_0/resources/.gitkeep b/tests/Frameworks/CakePHP/Version_5_0/resources/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Frameworks/CakePHP/Version_5_0/src/Application.php b/tests/Frameworks/CakePHP/Version_5_0/src/Application.php new file mode 100644 index 0000000000..c85a1ecdb2 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/src/Application.php @@ -0,0 +1,107 @@ + + */ +class Application extends BaseApplication +{ + /** + * Load all the application configuration and bootstrap logic. + * + * @return void + */ + public function bootstrap(): void + { + // Call parent to load bootstrap from files. + parent::bootstrap(); + + if (PHP_SAPI !== 'cli') { + FactoryLocator::add( + 'Table', + (new TableLocator())->allowFallbackClass(false) + ); + } + } + + /** + * Setup the middleware queue your application will use. + * + * @param \Cake\Http\MiddlewareQueue $middlewareQueue The middleware queue to setup. + * @return \Cake\Http\MiddlewareQueue The updated middleware queue. + */ + public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue + { + $middlewareQueue + // Catch any exceptions in the lower layers, + // and make an error page/response + ->add(new ErrorHandlerMiddleware(Configure::read('Error'), $this)) + + // Handle plugin/theme assets like CakePHP normally does. + ->add(new AssetMiddleware([ + 'cacheTime' => Configure::read('Asset.cacheTime'), + ])) + + // Add routing middleware. + // If you have a large number of routes connected, turning on routes + // caching in production could improve performance. + // See https://github.com/CakeDC/cakephp-cached-routing + ->add(new RoutingMiddleware($this)) + + // Parse various types of encoded request bodies so that they are + // available as array through $request->getData() + // https://book.cakephp.org/4/en/controllers/middleware.html#body-parser-middleware + ->add(new BodyParserMiddleware()) + + // Cross Site Request Forgery (CSRF) Protection Middleware + // https://book.cakephp.org/4/en/security/csrf.html#cross-site-request-forgery-csrf-middleware + ->add(new CsrfProtectionMiddleware([ + 'httponly' => true, + ])); + + return $middlewareQueue; + } + + /** + * Register application container services. + * + * @param \Cake\Core\ContainerInterface $container The Container to update. + * @return void + * @link https://book.cakephp.org/4/en/development/dependency-injection.html#dependency-injection + */ + public function services(ContainerInterface $container): void + { + } +} diff --git a/tests/Frameworks/CakePHP/Version_5_0/src/Console/Installer.php b/tests/Frameworks/CakePHP/Version_5_0/src/Console/Installer.php new file mode 100644 index 0000000000..6f5579829b --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/src/Console/Installer.php @@ -0,0 +1,250 @@ +getIO(); + + $rootDir = dirname(__DIR__, 2); + + static::createAppLocalConfig($rootDir, $io); + static::createWritableDirectories($rootDir, $io); + + static::setFolderPermissions($rootDir, $io); + static::setSecuritySalt($rootDir, $io); + + if (class_exists(CodeceptionInstaller::class)) { + CodeceptionInstaller::customizeCodeceptionBinary($event); + } + } + + /** + * Create config/app_local.php file if it does not exist. + * + * @param string $dir The application's root directory. + * @param \Composer\IO\IOInterface $io IO interface to write to console. + * @return void + */ + public static function createAppLocalConfig(string $dir, IOInterface $io): void + { + $appLocalConfig = $dir . '/config/app_local.php'; + $appLocalConfigTemplate = $dir . '/config/app_local.example.php'; + if (!file_exists($appLocalConfig)) { + copy($appLocalConfigTemplate, $appLocalConfig); + $io->write('Created `config/app_local.php` file'); + } + } + + /** + * Create the `logs` and `tmp` directories. + * + * @param string $dir The application's root directory. + * @param \Composer\IO\IOInterface $io IO interface to write to console. + * @return void + */ + public static function createWritableDirectories(string $dir, IOInterface $io): void + { + foreach (static::WRITABLE_DIRS as $path) { + $path = $dir . '/' . $path; + if (!file_exists($path)) { + mkdir($path); + $io->write('Created `' . $path . '` directory'); + } + } + } + + /** + * Set globally writable permissions on the "tmp" and "logs" directory. + * + * This is not the most secure default, but it gets people up and running quickly. + * + * @param string $dir The application's root directory. + * @param \Composer\IO\IOInterface $io IO interface to write to console. + * @return void + */ + public static function setFolderPermissions(string $dir, IOInterface $io): void + { + // ask if the permissions should be changed + if ($io->isInteractive()) { + $validator = function (string $arg): string { + if (in_array($arg, ['Y', 'y', 'N', 'n'])) { + return $arg; + } + throw new Exception('This is not a valid answer. Please choose Y or n.'); + }; + $setFolderPermissions = $io->askAndValidate( + 'Set Folder Permissions ? (Default to Y) [Y,n]? ', + $validator, + 10, + 'Y' + ); + + if (in_array($setFolderPermissions, ['n', 'N'])) { + return; + } + } + + // Change the permissions on a path and output the results. + $changePerms = function (string $path) use ($io): void { + $currentPerms = fileperms($path) & 0777; + $worldWritable = $currentPerms | 0007; + if ($worldWritable == $currentPerms) { + return; + } + + $res = chmod($path, $worldWritable); + if ($res) { + $io->write('Permissions set on ' . $path); + } else { + $io->write('Failed to set permissions on ' . $path); + } + }; + + $walker = function (string $dir) use (&$walker, $changePerms): void { + /** @phpstan-ignore-next-line */ + $files = array_diff(scandir($dir), ['.', '..']); + foreach ($files as $file) { + $path = $dir . '/' . $file; + + if (!is_dir($path)) { + continue; + } + + $changePerms($path); + $walker($path); + } + }; + + $walker($dir . '/tmp'); + $changePerms($dir . '/tmp'); + $changePerms($dir . '/logs'); + } + + /** + * Set the security.salt value in the application's config file. + * + * @param string $dir The application's root directory. + * @param \Composer\IO\IOInterface $io IO interface to write to console. + * @return void + */ + public static function setSecuritySalt(string $dir, IOInterface $io): void + { + $newKey = hash('sha256', Security::randomBytes(64)); + static::setSecuritySaltInFile($dir, $io, $newKey, 'app_local.php'); + } + + /** + * Set the security.salt value in a given file + * + * @param string $dir The application's root directory. + * @param \Composer\IO\IOInterface $io IO interface to write to console. + * @param string $newKey key to set in the file + * @param string $file A path to a file relative to the application's root + * @return void + */ + public static function setSecuritySaltInFile(string $dir, IOInterface $io, string $newKey, string $file): void + { + $config = $dir . '/config/' . $file; + $content = file_get_contents($config); + + /** @phpstan-ignore-next-line */ + $content = str_replace('__SALT__', $newKey, $content, $count); + + if ($count == 0) { + $io->write('No Security.salt placeholder to replace.'); + + return; + } + + $result = file_put_contents($config, $content); + if ($result) { + $io->write('Updated Security.salt value in config/' . $file); + + return; + } + $io->write('Unable to update Security.salt value.'); + } + + /** + * Set the APP_NAME value in a given file + * + * @param string $dir The application's root directory. + * @param \Composer\IO\IOInterface $io IO interface to write to console. + * @param string $appName app name to set in the file + * @param string $file A path to a file relative to the application's root + * @return void + */ + public static function setAppNameInFile(string $dir, IOInterface $io, string $appName, string $file): void + { + $config = $dir . '/config/' . $file; + $content = file_get_contents($config); + /** @phpstan-ignore-next-line */ + $content = str_replace('__APP_NAME__', $appName, $content, $count); + + if ($count == 0) { + $io->write('No __APP_NAME__ placeholder to replace.'); + + return; + } + + $result = file_put_contents($config, $content); + if ($result) { + $io->write('Updated __APP_NAME__ value in config/' . $file); + + return; + } + $io->write('Unable to update __APP_NAME__ value.'); + } +} diff --git a/tests/Frameworks/CakePHP/Version_5_0/src/Controller/AppController.php b/tests/Frameworks/CakePHP/Version_5_0/src/Controller/AppController.php new file mode 100644 index 0000000000..2042d469d4 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/src/Controller/AppController.php @@ -0,0 +1,52 @@ +loadComponent('FormProtection');` + * + * @return void + */ + public function initialize(): void + { + parent::initialize(); + + $this->loadComponent('Flash'); + + /* + * Enable the following component for recommended CakePHP form protection settings. + * see https://book.cakephp.org/4/en/controllers/components/form-protection.html + */ + //$this->loadComponent('FormProtection'); + } +} diff --git a/tests/Frameworks/CakePHP/Version_5_0/src/Controller/Component/.gitkeep b/tests/Frameworks/CakePHP/Version_5_0/src/Controller/Component/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Frameworks/CakePHP/Version_5_0/src/Controller/ErrorController.php b/tests/Frameworks/CakePHP/Version_5_0/src/Controller/ErrorController.php new file mode 100644 index 0000000000..7251108d89 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/src/Controller/ErrorController.php @@ -0,0 +1,75 @@ + $event Event. + * @return \Cake\Http\Response|null|void + */ + public function beforeFilter(EventInterface $event) + { + } + + /** + * beforeRender callback. + * + * @param \Cake\Event\EventInterface<\Cake\Controller\Controller> $event Event. + * @return \Cake\Http\Response|null|void + */ + public function beforeRender(EventInterface $event) + { + parent::beforeRender($event); + + $this->viewBuilder()->setTemplatePath('Error'); + } + + /** + * afterFilter callback. + * + * @param \Cake\Event\EventInterface<\Cake\Controller\Controller> $event Event. + * @return \Cake\Http\Response|null|void + */ + public function afterFilter(EventInterface $event) + { + } + + public function index() + { + throw new \Exception('Foo error'); + } +} diff --git a/tests/Frameworks/CakePHP/Version_5_0/src/Controller/PagesController.php b/tests/Frameworks/CakePHP/Version_5_0/src/Controller/PagesController.php new file mode 100644 index 0000000000..a51bd4b386 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/src/Controller/PagesController.php @@ -0,0 +1,73 @@ +redirect('/'); + } + if (in_array('..', $path, true) || in_array('.', $path, true)) { + throw new ForbiddenException(); + } + $page = $subpage = null; + + if (!empty($path[0])) { + $page = $path[0]; + } + if (!empty($path[1])) { + $subpage = $path[1]; + } + $this->set(compact('page', 'subpage')); + + try { + return $this->render(implode('/', $path)); + } catch (MissingTemplateException $exception) { + if (Configure::read('debug')) { + throw $exception; + } + throw new NotFoundException(); + } + } +} diff --git a/tests/Frameworks/CakePHP/Version_5_0/src/Controller/ParameterizedController.php b/tests/Frameworks/CakePHP/Version_5_0/src/Controller/ParameterizedController.php new file mode 100644 index 0000000000..f41e3ec2f1 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/src/Controller/ParameterizedController.php @@ -0,0 +1,12 @@ +autoRender = false; + echo "Hello $param"; + } +} diff --git a/tests/Frameworks/CakePHP/Version_5_0/src/Controller/SimpleController.php b/tests/Frameworks/CakePHP/Version_5_0/src/Controller/SimpleController.php new file mode 100644 index 0000000000..fbdd428881 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/src/Controller/SimpleController.php @@ -0,0 +1,12 @@ +autoRender = false; + echo 'Hello.'; + } +} diff --git a/tests/Frameworks/CakePHP/Version_5_0/src/Controller/Simple_viewController.php b/tests/Frameworks/CakePHP/Version_5_0/src/Controller/Simple_viewController.php new file mode 100644 index 0000000000..87462eec32 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/src/Controller/Simple_viewController.php @@ -0,0 +1,10 @@ +response = $this->response->withType('ajax'); + } +} diff --git a/tests/Frameworks/CakePHP/Version_5_0/src/View/AppView.php b/tests/Frameworks/CakePHP/Version_5_0/src/View/AppView.php new file mode 100644 index 0000000000..9c9fc01b38 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/src/View/AppView.php @@ -0,0 +1,41 @@ +addHelper('Html');` + * + * @return void + */ + public function initialize(): void + { + } +} diff --git a/tests/Frameworks/CakePHP/Version_5_0/src/View/Cell/.gitkeep b/tests/Frameworks/CakePHP/Version_5_0/src/View/Cell/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Frameworks/CakePHP/Version_5_0/src/View/Helper/.gitkeep b/tests/Frameworks/CakePHP/Version_5_0/src/View/Helper/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Frameworks/CakePHP/Version_5_0/templates/Error/error400.php b/tests/Frameworks/CakePHP/Version_5_0/templates/Error/error400.php new file mode 100644 index 0000000000..9ead1656c8 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/templates/Error/error400.php @@ -0,0 +1,42 @@ +layout = 'error'; + +if (Configure::read('debug')) : + $this->layout = 'dev_error'; + + $this->assign('title', $message); + $this->assign('templateName', 'error400.php'); + + $this->start('file'); +?> +queryString)) : ?> +

+ SQL Query: + queryString) ?> +

+ +params)) : ?> + SQL Query Params: + params) ?> + + +element('auto_table_warning'); + + $this->end(); +endif; +?> +

+

+ : + '{$url}'") ?> +

diff --git a/tests/Frameworks/CakePHP/Version_5_0/templates/Error/error500.php b/tests/Frameworks/CakePHP/Version_5_0/templates/Error/error500.php new file mode 100644 index 0000000000..4f08488e90 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/templates/Error/error500.php @@ -0,0 +1,47 @@ +layout = 'error'; + +if (Configure::read('debug')) : + $this->layout = 'dev_error'; + + $this->assign('title', $message); + $this->assign('templateName', 'error500.php'); + + $this->start('file'); +?> +queryString)) : ?> +

+ SQL Query: + queryString) ?> +

+ +params)) : ?> + SQL Query Params: + params) ?> + + + getFile() ?> + getLine() ?> + Error in: + Html->link(sprintf('%s, line %s', Debugger::trimPath($file), $line), Debugger::editorUrl($file, $line)); ?> + +element('auto_table_warning'); + + $this->end(); +endif; +?> +

+

+ : + +

diff --git a/tests/Frameworks/CakePHP/Version_5_0/templates/Pages/home.php b/tests/Frameworks/CakePHP/Version_5_0/templates/Pages/home.php new file mode 100644 index 0000000000..39084db71f --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/templates/Pages/home.php @@ -0,0 +1,239 @@ +disableAutoLayout(); + +$checkConnection = function (string $name) { + $error = null; + $connected = false; + try { + ConnectionManager::get($name)->getDriver()->connect(); + // No exception means success + $connected = true; + } catch (Exception $connectionError) { + $error = $connectionError->getMessage(); + if (method_exists($connectionError, 'getAttributes')) { + $attributes = $connectionError->getAttributes(); + if (isset($attributes['message'])) { + $error .= '
' . $attributes['message']; + } + } + if ($name === 'debug_kit') { + $error = 'Try adding your current top level domain to the + DebugKit.safeTld + config and reload.'; + if (!in_array('sqlite', \PDO::getAvailableDrivers())) { + $error .= '
You need to install the PHP extension pdo_sqlite so DebugKit can work properly.'; + } + } + } + + return compact('connected', 'error'); +}; + +if (!Configure::read('debug')) : + throw new NotFoundException( + 'Please replace templates/Pages/home.php with your own version or re-enable debug mode.' + ); +endif; + +?> + + + + Html->charset() ?> + + + CakePHP: the rapid development PHP framework: + <?= $this->fetch('title') ?> + + Html->meta('icon') ?> + + Html->css(['normalize.min', 'milligram.min', 'fonts', 'cake', 'home']) ?> + + fetch('meta') ?> + fetch('css') ?> + fetch('script') ?> + + +
+
+ + CakePHP + +

+ Welcome to CakePHP Chiffon (🍰) +

+
+
+
+
+
+
+
+
+ Please be aware that this page will not be shown if you turn off debug mode unless you replace templates/Pages/home.php with your own version. +
+
+ +
+ +
+
+
+
+

Environment

+
    + =')) : ?> +
  • Your version of PHP is 8.1.0 or higher (detected ).
  • + +
  • Your version of PHP is too low. You need PHP 8.1.0 or higher to use CakePHP (detected ).
  • + + + +
  • Your version of PHP has the mbstring extension loaded.
  • + +
  • Your version of PHP does NOT have the mbstring extension loaded.
  • + + + +
  • Your version of PHP has the openssl extension loaded.
  • + +
  • Your version of PHP has the mcrypt extension loaded.
  • + +
  • Your version of PHP does NOT have the openssl or mcrypt extension loaded.
  • + + + +
  • Your version of PHP has the intl extension loaded.
  • + +
  • Your version of PHP does NOT have the intl extension loaded.
  • + +
+
+
+

Filesystem

+
    + +
  • Your tmp directory is writable.
  • + +
  • Your tmp directory is NOT writable.
  • + + + +
  • Your logs directory is writable.
  • + +
  • Your logs directory is NOT writable.
  • + + + + +
  • The is being used for core caching. To change the config edit config/app.php
  • + +
  • Your cache is NOT working. Please check the settings in config/app.php
  • + +
+
+
+
+
+
+

Database

+ +
    + +
  • CakePHP is able to connect to the database.
  • + +
  • CakePHP is NOT able to connect to the database.
  • + +
+
+
+

DebugKit

+
    + +
  • DebugKit is loaded.
  • + + +
  • DebugKit can connect to the database.
  • + +
  • There are configuration problems present which need to be fixed:
  • + + +
  • DebugKit is not loaded.
  • + +
+
+
+
+
+ +
+
+
+ +
+
+ +
+
+ +
+
+
+
+ + diff --git a/tests/Frameworks/CakePHP/Version_5_0/templates/Simple_view/index.php b/tests/Frameworks/CakePHP/Version_5_0/templates/Simple_view/index.php new file mode 100644 index 0000000000..60ab36c4a4 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/templates/Simple_view/index.php @@ -0,0 +1,2 @@ +

Simple HTML view

+

Hello.

diff --git a/tests/Frameworks/CakePHP/Version_5_0/templates/cell/.gitkeep b/tests/Frameworks/CakePHP/Version_5_0/templates/cell/.gitkeep new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/templates/cell/.gitkeep @@ -0,0 +1 @@ + diff --git a/tests/Frameworks/CakePHP/Version_5_0/templates/element/flash/default.php b/tests/Frameworks/CakePHP/Version_5_0/templates/element/flash/default.php new file mode 100644 index 0000000000..061c700920 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/templates/element/flash/default.php @@ -0,0 +1,15 @@ + +
diff --git a/tests/Frameworks/CakePHP/Version_5_0/templates/element/flash/error.php b/tests/Frameworks/CakePHP/Version_5_0/templates/element/flash/error.php new file mode 100644 index 0000000000..2ebf2357c0 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/templates/element/flash/error.php @@ -0,0 +1,11 @@ + +
diff --git a/tests/Frameworks/CakePHP/Version_5_0/templates/element/flash/info.php b/tests/Frameworks/CakePHP/Version_5_0/templates/element/flash/info.php new file mode 100644 index 0000000000..e25b730c4f --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/templates/element/flash/info.php @@ -0,0 +1,11 @@ + +
diff --git a/tests/Frameworks/CakePHP/Version_5_0/templates/element/flash/success.php b/tests/Frameworks/CakePHP/Version_5_0/templates/element/flash/success.php new file mode 100644 index 0000000000..73eaac48d3 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/templates/element/flash/success.php @@ -0,0 +1,11 @@ + +
diff --git a/tests/Frameworks/CakePHP/Version_5_0/templates/element/flash/warning.php b/tests/Frameworks/CakePHP/Version_5_0/templates/element/flash/warning.php new file mode 100644 index 0000000000..605537c7e2 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/templates/element/flash/warning.php @@ -0,0 +1,11 @@ + +
diff --git a/tests/Frameworks/CakePHP/Version_5_0/templates/email/html/default.php b/tests/Frameworks/CakePHP/Version_5_0/templates/email/html/default.php new file mode 100644 index 0000000000..70a6cd4492 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/templates/email/html/default.php @@ -0,0 +1,22 @@ + ' . $line . "

\n"; +endforeach; diff --git a/tests/Frameworks/CakePHP/Version_5_0/templates/email/text/default.php b/tests/Frameworks/CakePHP/Version_5_0/templates/email/text/default.php new file mode 100644 index 0000000000..cb1f378451 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/templates/email/text/default.php @@ -0,0 +1,18 @@ +fetch('content'); diff --git a/tests/Frameworks/CakePHP/Version_5_0/templates/layout/default.php b/tests/Frameworks/CakePHP/Version_5_0/templates/layout/default.php new file mode 100644 index 0000000000..84d321705d --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/templates/layout/default.php @@ -0,0 +1,55 @@ + + + + + Html->charset() ?> + + + <?= $cakeDescription ?>: + <?= $this->fetch('title') ?> + + Html->meta('icon') ?> + + Html->css(['normalize.min', 'milligram.min', 'fonts', 'cake']) ?> + + fetch('meta') ?> + fetch('css') ?> + fetch('script') ?> + + + +
+
+ Flash->render() ?> + fetch('content') ?> +
+
+
+
+ + diff --git a/tests/Frameworks/CakePHP/Version_5_0/templates/layout/email/html/default.php b/tests/Frameworks/CakePHP/Version_5_0/templates/layout/email/html/default.php new file mode 100644 index 0000000000..96b0e7318f --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/templates/layout/email/html/default.php @@ -0,0 +1,25 @@ + + + + + <?= $this->fetch('title') ?> + + + fetch('content') ?> + + diff --git a/tests/Frameworks/CakePHP/Version_5_0/templates/layout/email/text/default.php b/tests/Frameworks/CakePHP/Version_5_0/templates/layout/email/text/default.php new file mode 100644 index 0000000000..cd51169db7 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/templates/layout/email/text/default.php @@ -0,0 +1,17 @@ +fetch('content'); diff --git a/tests/Frameworks/CakePHP/Version_5_0/templates/layout/error.php b/tests/Frameworks/CakePHP/Version_5_0/templates/layout/error.php new file mode 100644 index 0000000000..2b26a16da0 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/templates/layout/error.php @@ -0,0 +1,39 @@ + + + + + Html->charset() ?> + + <?= $this->fetch('title') ?> + + Html->meta('icon') ?> + + Html->css(['normalize.min', 'milligram.min', 'fonts', 'cake']) ?> + + fetch('meta') ?> + fetch('css') ?> + fetch('script') ?> + + +
+ Flash->render() ?> + fetch('content') ?> + Html->link(__('Back'), 'javascript:history.back()') ?> +
+ + diff --git a/tests/Frameworks/CakePHP/Version_5_0/tests/Fixture/.gitkeep b/tests/Frameworks/CakePHP/Version_5_0/tests/Fixture/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Frameworks/CakePHP/Version_5_0/tests/TestCase/ApplicationTest.php b/tests/Frameworks/CakePHP/Version_5_0/tests/TestCase/ApplicationTest.php new file mode 100644 index 0000000000..6a65c52bde --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/tests/TestCase/ApplicationTest.php @@ -0,0 +1,85 @@ +bootstrap(); + $plugins = $app->getPlugins(); + + $this->assertTrue($plugins->has('Bake'), 'plugins has Bake?'); + $this->assertFalse($plugins->has('DebugKit'), 'plugins has DebugKit?'); + $this->assertTrue($plugins->has('Migrations'), 'plugins has Migrations?'); + } + + /** + * Test bootstrap add DebugKit plugin in debug mode. + * + * @return void + */ + public function testBootstrapInDebug() + { + Configure::write('debug', true); + $app = new Application(dirname(__DIR__, 2) . '/config'); + $app->bootstrap(); + $plugins = $app->getPlugins(); + + $this->assertTrue($plugins->has('DebugKit'), 'plugins has DebugKit?'); + } + + /** + * testMiddleware + * + * @return void + */ + public function testMiddleware() + { + $app = new Application(dirname(__DIR__, 2) . '/config'); + $middleware = new MiddlewareQueue(); + + $middleware = $app->middleware($middleware); + + $this->assertInstanceOf(ErrorHandlerMiddleware::class, $middleware->current()); + $middleware->seek(1); + $this->assertInstanceOf(AssetMiddleware::class, $middleware->current()); + $middleware->seek(2); + $this->assertInstanceOf(RoutingMiddleware::class, $middleware->current()); + } +} diff --git a/tests/Frameworks/CakePHP/Version_5_0/tests/TestCase/Controller/Component/.gitkeep b/tests/Frameworks/CakePHP/Version_5_0/tests/TestCase/Controller/Component/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Frameworks/CakePHP/Version_5_0/tests/TestCase/Controller/PagesControllerTest.php b/tests/Frameworks/CakePHP/Version_5_0/tests/TestCase/Controller/PagesControllerTest.php new file mode 100644 index 0000000000..73f9452479 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/tests/TestCase/Controller/PagesControllerTest.php @@ -0,0 +1,115 @@ +get('/pages/home'); + $this->assertResponseOk(); + $this->assertResponseContains('CakePHP'); + $this->assertResponseContains(''); + } + + /** + * Test that missing template renders 404 page in production + * + * @return void + */ + public function testMissingTemplate() + { + Configure::write('debug', false); + $this->get('/pages/not_existing'); + + $this->assertResponseError(); + $this->assertResponseContains('Error'); + } + + /** + * Test that missing template in debug mode renders missing_template error page + * + * @return void + */ + public function testMissingTemplateInDebug() + { + Configure::write('debug', true); + $this->get('/pages/not_existing'); + + $this->assertResponseFailure(); + $this->assertResponseContains('Missing Template'); + $this->assertResponseContains('stack-frames'); + $this->assertResponseContains('not_existing.php'); + } + + /** + * Test directory traversal protection + * + * @return void + */ + public function testDirectoryTraversalProtection() + { + $this->get('/pages/../Layout/ajax'); + $this->assertResponseCode(403); + $this->assertResponseContains('Forbidden'); + } + + /** + * Test that CSRF protection is applied to page rendering. + * + * @return void + */ + public function testCsrfAppliedError() + { + $this->post('/pages/home', ['hello' => 'world']); + + $this->assertResponseCode(403); + $this->assertResponseContains('CSRF'); + } + + /** + * Test that CSRF protection is applied to page rendering. + * + * @return void + */ + public function testCsrfAppliedOk() + { + $this->enableCsrfToken(); + $this->post('/pages/home', ['hello' => 'world']); + + $this->assertThat(403, $this->logicalNot(new StatusCode($this->_response))); + $this->assertResponseNotContains('CSRF'); + } +} diff --git a/tests/Frameworks/CakePHP/Version_5_0/tests/TestCase/Model/Behavior/.gitkeep b/tests/Frameworks/CakePHP/Version_5_0/tests/TestCase/Model/Behavior/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Frameworks/CakePHP/Version_5_0/tests/TestCase/View/Helper/.gitkeep b/tests/Frameworks/CakePHP/Version_5_0/tests/TestCase/View/Helper/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Frameworks/CakePHP/Version_5_0/tests/bootstrap.php b/tests/Frameworks/CakePHP/Version_5_0/tests/bootstrap.php new file mode 100644 index 0000000000..1cb386d25d --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/tests/bootstrap.php @@ -0,0 +1,66 @@ + 'Cake\Database\Connection', + 'driver' => 'Cake\Database\Driver\Sqlite', + 'database' => TMP . 'debug_kit.sqlite', + 'encoding' => 'utf8', + 'cacheMetadata' => true, + 'quoteIdentifiers' => false, +]); + +ConnectionManager::alias('test_debug_kit', 'debug_kit'); + +// Fixate sessionid early on, as php7.2+ +// does not allow the sessionid to be set after stdout +// has been written to. +session_id('cli'); + +// Use migrations to build test database schema. +// +// Will rebuild the database if the migration state differs +// from the migration history in files. +// +// If you are not using CakePHP's migrations you can +// hook into your migration tool of choice here or +// load schema from a SQL dump file with +// use Cake\TestSuite\Fixture\SchemaLoader; +// (new SchemaLoader())->loadSqlFiles('./tests/schema.sql', 'test'); + +(new Migrator())->run(); diff --git a/tests/Frameworks/CakePHP/Version_5_0/tests/schema.sql b/tests/Frameworks/CakePHP/Version_5_0/tests/schema.sql new file mode 100644 index 0000000000..c7e4d3f7e8 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/tests/schema.sql @@ -0,0 +1,4 @@ +-- Test database schema. +-- +-- If you are not using CakePHP migrations you can put +-- your application's schema in this file and use it in tests. diff --git a/tests/Frameworks/CakePHP/Version_5_0/webroot/.htaccess b/tests/Frameworks/CakePHP/Version_5_0/webroot/.htaccess new file mode 100644 index 0000000000..f5f2d631cd --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/webroot/.htaccess @@ -0,0 +1,5 @@ + + RewriteEngine On + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^ index.php [L] + diff --git a/tests/Frameworks/CakePHP/Version_5_0/webroot/css/cake.css b/tests/Frameworks/CakePHP/Version_5_0/webroot/css/cake.css new file mode 100644 index 0000000000..fbb0de9761 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/webroot/css/cake.css @@ -0,0 +1,299 @@ +/* Milligram overrides */ +:root { + /* The following are official CakePHP colors */ + --color-cakephp-red: #d33c43; + --color-cakephp-gray: #404041; + --color-cakephp-blue: #2f85ae; + --color-cakephp-lightblue: #34bdd7; + + /* These are additional colors */ + --color-lightgray: #606c76; + --color-white: #fff; + + --color-main-bg: #f5f7fa; + --color-links: var(--color-cakephp-blue); + --color-links-active: #2a6496; + --color-headings: #363637; + + --color-message-success-bg: #e3fcec; + --color-message-success-text: #1f9d55; + --color-message-success-border: #51d88a; + + --color-message-warning-bg: #fffabc; + --color-message-warning-text: #8d7b00; + --color-message-warning-border: #d3b800; + + --color-message-error-bg: #fcebea; + --color-message-error-text: #cc1f1a; + --color-message-error-border: #ef5753; + + --color-message-info-bg: #eff8ff; + --color-message-info-text: #2779bd; + --color-message-info-border: #6cb2eb; +} + +.button, button, input[type='button'], input[type='reset'], input[type='submit'] { + background-color: var(--color-cakephp-red); + border-color: var(--color-cakephp-red); +} + +body { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 400; + background: var(--color-main-bg); +} + +.top-nav-links, +.side-nav, +h1, h2, h3, h4, h5, h6 { + font-family: "Raleway", sans-serif; +} + +h1, h2, h3, h4, h5, h6 { + font-weight: 400; + color: var(--color-headings); +} + +a { + color: var(--color-links); + transition: color 0.2s linear; +} + +a:hover, +a:focus, +a:active { + color: var(--color-links-active); + transition: color 0.2s ease-out; +} + +.side-nav a, +.top-nav-links a, +th a, +.actions a { + color: var(--color-lightgray); +} + +.side-nav a:hover, +.side-nav a:focus, +.actions a:hover, +.actions a:focus { + color: var(--color-links-active); +} + +/* Utility */ +.table-responsive { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; +} + +/* Main */ +.content { + padding: 2rem; + background: var(--color-white); + border-radius: 0.4rem; + /* Thanks Stripe */ + box-shadow: 0 7px 14px 0 rgba(60, 66, 87, 0.1), + 0 3px 6px 0 rgba(0, 0, 0, 0.07); +} +.content form { + margin: 0; +} +.actions a { + font-weight: bold; + padding: 0 0.4rem; +} +.actions a:first-child { + padding-left: 0; +} +th { + white-space: nowrap; +} + +/* Nav bar */ +.top-nav { + display: flex; + align-items: center; + justify-content: space-between; + max-width: 112rem; + padding: 2rem; + margin: 0 auto; +} +.top-nav-title a { + font-size: 2.4rem; + color: var(--color-cakephp-red); +} +.top-nav-title span { + color: var(--color-cakephp-gray); +} +.top-nav-links a { + margin: 0 0.5rem; +} +.top-nav-title a, +.top-nav-links a { + font-weight: bold; +} +.side-nav-item { + display: block; + padding: 0.5rem 0; +} + +/* View action */ +.view.content .text { + margin-top: 1.2rem; +} +.related { + margin-top: 2rem; +} + +/* Flash messages */ +.message { + padding: .5rem 1rem; + background: var(--color-message-info-bg); + color: var(--color-message-info-text); + border-color: var(--color-message-info-border); + border-width: 1px; + border-style: solid; + border-radius: 4px; + margin-bottom: 1rem; + cursor: pointer; +} +.message.hidden { + display: none; +} +.message.success { + background: var(--color-message-success-bg); + color: var(--color-message-success-text); + border-color: var(--color-message-success-border); +} +.message.warning { + background: var(--color-message-warning-bg); + color: var(--color-message-warning-text); + border-color: var(--color-message-warning-border); +} +.message.error { + background: var(--color-message-error-bg); + color: var(--color-message-error-text); + border-color: var(--color-message-error-border); +} + +/* Forms */ +.input.radio, +.input.checkbox, +.input.multicheckbox { + margin-bottom: 2.0rem; +} +.input.radio input, +.input.checkbox input, +.input.multicheckbox input { + margin: 0; +} +.input.radio label, +.input.checkbox label, +.input.multicheckbox label { + margin: 0; + display: flex; + align-items: center; +} +.input.radio label > input, +.input.checkbox label > input, +.input.multicheckbox label > input { + margin-right: 1.0rem; +} +input[type='color'] { + max-width: 4rem; + padding: 0.3rem .5rem 0.3rem; +} + +/* Paginator */ +.paginator { + text-align: right; +} +.paginator p { + margin-bottom: 0; +} +.pagination { + display: flex; + justify-content: center; + list-style: none; + margin: 0 0 1rem 0; + padding: 0; +} +.pagination li { + display: inline-block; + margin: 0.25em; + text-align: center; +} +.pagination a { + color: var(--color-cakephp-blue); + display: inline-block; + font-size: 1.25rem; + line-height: 3rem; + min-width: 3rem; + padding: 0; + position: relative; + text-decoration: none; + transition: background .3s,color .3s; +} +.pagination li.active a, +.pagination a:hover { + text-decoration: underline; +} +.pagination .disabled a { + cursor: not-allowed; + color: var(--color-lightgray); + text-decoration: none; +} +.first a, +.prev a, +.next a, +.last a { + padding: 0 .75rem; +} +.disabled a:hover { + background: initial; + color: initial; +} +.asc:after { + content: " \2193"; +} +.desc:after { + content: " \2191"; +} + +/* Error in non debug mode */ +.error-container { + align-items: center; + display: flex; + flex-direction: column; + height: 100vh; + justify-content: center; +} + +@media screen and (max-width: 640px) { + /* Fix milligram not having a responsive column system */ + .row .column[class*='column-'] { + flex: 0 0 100%; + max-width: 100% + } + .top-nav { + margin: 0 auto; + } + .side-nav { + margin-bottom: 1rem; + } + .heading { + margin-bottom: 1rem; + } + .side-nav-item { + display: inline; + margin: 0 1.5rem 0 0; + } + .asc:after { + content: " \2192"; + } + .desc:after { + content: " \2190"; + } +} diff --git a/tests/Frameworks/CakePHP/Version_5_0/webroot/css/fonts.css b/tests/Frameworks/CakePHP/Version_5_0/webroot/css/fonts.css new file mode 100644 index 0000000000..1ba4808f40 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/webroot/css/fonts.css @@ -0,0 +1,80 @@ +/* cyrillic-ext */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 400; + src: url('../font/raleway-400-cyrillic-ext.woff2') format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 400; + src: url('../font/raleway-400-cyrillic.woff2') format('woff2'); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* vietnamese */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 400; + src: url('../font/raleway-400-vietnamese.woff2') format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 400; + src: url('../font/raleway-400-latin-ext.woff2') format('woff2'); + unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 400; + src: url('../font/raleway-400-latin.woff2') format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 700; + src: url('../font/raleway-700-cyrillic-ext.woff2') format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 700; + src: url('../font/raleway-700-cyrillic.woff2') format('woff2'); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* vietnamese */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 700; + src: url('../font/raleway-700-vietnamese.woff2') format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 700; + src: url('../font/raleway-700-latin-ext.woff2') format('woff2'); + unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Raleway'; + font-style: normal; + font-weight: 700; + src: url('../font/raleway-700-latin.woff2') format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} diff --git a/tests/Frameworks/CakePHP/Version_5_0/webroot/css/home.css b/tests/Frameworks/CakePHP/Version_5_0/webroot/css/home.css new file mode 100644 index 0000000000..4648ed314d --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/webroot/css/home.css @@ -0,0 +1,75 @@ +/* Home page styles */ +@font-face { + font-family: 'cakefont'; + src: url('../font/cakedingbats-webfont.eot'); + src: url('../font/cakedingbats-webfont.eot?#iefix') format('embedded-opentype'), + url('../font/cakedingbats-webfont.woff2') format('woff2'), + url('../font/cakedingbats-webfont.woff') format('woff'), + url('../font/cakedingbats-webfont.ttf') format('truetype'), + url('../font/cakedingbats-webfont.svg#cake_dingbatsregular') format('svg'); + font-weight: normal; + font-style: normal; +} +body { + padding: 60px 0; +} +header { + margin-bottom: 60px; +} +img { + margin-bottom: 30px; +} +h1 { + font-weight: bold; +} +ul { + list-style-type: none; + margin: 0 0 30px 0; + padding-left: 25px; +} +a { + color: #0071BC; + text-decoration: underline; +} +hr { + border-bottom: 1px solid #e7e7e7; + border-top: 0; + margin-bottom: 35px; +} + +.text-center { + text-align: center; +} +.links a { + margin-right: 10px; +} +.release-name { + color: #D33C43; + font-weight: 400; + font-style: italic; +} +.bullet:before { + font-family: 'cakefont', sans-serif; + font-size: 18px; + display: inline-block; + margin-left: -1.3em; + width: 1.2em; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + vertical-align: -1px; +} +.success:before { + color: #88c671; + content: "\0056"; +} +.problem:before { + color: #d33d44; + content: "\0057"; +} +.cake-error { + padding: 10px; + margin: 10px 0; +} +#url-rewriting-warning { + display: none; +} diff --git a/tests/Frameworks/CakePHP/Version_5_0/webroot/css/milligram.min.css b/tests/Frameworks/CakePHP/Version_5_0/webroot/css/milligram.min.css new file mode 100644 index 0000000000..958f687da4 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/webroot/css/milligram.min.css @@ -0,0 +1,9 @@ +/*! + * Milligram v1.4.1 + * https://milligram.io + * + * Copyright (c) 2020 CJ Patoilo + * Licensed under the MIT license + */ + +*,*:after,*:before{box-sizing:inherit}html{box-sizing:border-box;font-size:62.5%}body{color:#606c76;font-family:'Roboto', 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;font-size:1.6em;font-weight:300;letter-spacing:.01em;line-height:1.6}blockquote{border-left:0.3rem solid #d1d1d1;margin-left:0;margin-right:0;padding:1rem 1.5rem}blockquote *:last-child{margin-bottom:0}.button,button,input[type='button'],input[type='reset'],input[type='submit']{background-color:#9b4dca;border:0.1rem solid #9b4dca;border-radius:.4rem;color:#fff;cursor:pointer;display:inline-block;font-size:1.1rem;font-weight:700;height:3.8rem;letter-spacing:.1rem;line-height:3.8rem;padding:0 3.0rem;text-align:center;text-decoration:none;text-transform:uppercase;white-space:nowrap}.button:focus,.button:hover,button:focus,button:hover,input[type='button']:focus,input[type='button']:hover,input[type='reset']:focus,input[type='reset']:hover,input[type='submit']:focus,input[type='submit']:hover{background-color:#606c76;border-color:#606c76;color:#fff;outline:0}.button[disabled],button[disabled],input[type='button'][disabled],input[type='reset'][disabled],input[type='submit'][disabled]{cursor:default;opacity:.5}.button[disabled]:focus,.button[disabled]:hover,button[disabled]:focus,button[disabled]:hover,input[type='button'][disabled]:focus,input[type='button'][disabled]:hover,input[type='reset'][disabled]:focus,input[type='reset'][disabled]:hover,input[type='submit'][disabled]:focus,input[type='submit'][disabled]:hover{background-color:#9b4dca;border-color:#9b4dca}.button.button-outline,button.button-outline,input[type='button'].button-outline,input[type='reset'].button-outline,input[type='submit'].button-outline{background-color:transparent;color:#9b4dca}.button.button-outline:focus,.button.button-outline:hover,button.button-outline:focus,button.button-outline:hover,input[type='button'].button-outline:focus,input[type='button'].button-outline:hover,input[type='reset'].button-outline:focus,input[type='reset'].button-outline:hover,input[type='submit'].button-outline:focus,input[type='submit'].button-outline:hover{background-color:transparent;border-color:#606c76;color:#606c76}.button.button-outline[disabled]:focus,.button.button-outline[disabled]:hover,button.button-outline[disabled]:focus,button.button-outline[disabled]:hover,input[type='button'].button-outline[disabled]:focus,input[type='button'].button-outline[disabled]:hover,input[type='reset'].button-outline[disabled]:focus,input[type='reset'].button-outline[disabled]:hover,input[type='submit'].button-outline[disabled]:focus,input[type='submit'].button-outline[disabled]:hover{border-color:inherit;color:#9b4dca}.button.button-clear,button.button-clear,input[type='button'].button-clear,input[type='reset'].button-clear,input[type='submit'].button-clear{background-color:transparent;border-color:transparent;color:#9b4dca}.button.button-clear:focus,.button.button-clear:hover,button.button-clear:focus,button.button-clear:hover,input[type='button'].button-clear:focus,input[type='button'].button-clear:hover,input[type='reset'].button-clear:focus,input[type='reset'].button-clear:hover,input[type='submit'].button-clear:focus,input[type='submit'].button-clear:hover{background-color:transparent;border-color:transparent;color:#606c76}.button.button-clear[disabled]:focus,.button.button-clear[disabled]:hover,button.button-clear[disabled]:focus,button.button-clear[disabled]:hover,input[type='button'].button-clear[disabled]:focus,input[type='button'].button-clear[disabled]:hover,input[type='reset'].button-clear[disabled]:focus,input[type='reset'].button-clear[disabled]:hover,input[type='submit'].button-clear[disabled]:focus,input[type='submit'].button-clear[disabled]:hover{color:#9b4dca}code{background:#f4f5f6;border-radius:.4rem;font-size:86%;margin:0 .2rem;padding:.2rem .5rem;white-space:nowrap}pre{background:#f4f5f6;border-left:0.3rem solid #9b4dca;overflow-y:hidden}pre>code{border-radius:0;display:block;padding:1rem 1.5rem;white-space:pre}hr{border:0;border-top:0.1rem solid #f4f5f6;margin:3.0rem 0}input[type='color'],input[type='date'],input[type='datetime'],input[type='datetime-local'],input[type='email'],input[type='month'],input[type='number'],input[type='password'],input[type='search'],input[type='tel'],input[type='text'],input[type='url'],input[type='week'],input:not([type]),textarea,select{-webkit-appearance:none;background-color:transparent;border:0.1rem solid #d1d1d1;border-radius:.4rem;box-shadow:none;box-sizing:inherit;height:3.8rem;padding:.6rem 1.0rem .7rem;width:100%}input[type='color']:focus,input[type='date']:focus,input[type='datetime']:focus,input[type='datetime-local']:focus,input[type='email']:focus,input[type='month']:focus,input[type='number']:focus,input[type='password']:focus,input[type='search']:focus,input[type='tel']:focus,input[type='text']:focus,input[type='url']:focus,input[type='week']:focus,input:not([type]):focus,textarea:focus,select:focus{border-color:#9b4dca;outline:0}select{background:url('data:image/svg+xml;utf8,') center right no-repeat;padding-right:3.0rem}select:focus{background-image:url('data:image/svg+xml;utf8,')}select[multiple]{background:none;height:auto}textarea{min-height:6.5rem}label,legend{display:block;font-size:1.6rem;font-weight:700;margin-bottom:.5rem}fieldset{border-width:0;padding:0}input[type='checkbox'],input[type='radio']{display:inline}.label-inline{display:inline-block;font-weight:normal;margin-left:.5rem}.container{margin:0 auto;max-width:112.0rem;padding:0 2.0rem;position:relative;width:100%}.row{display:flex;flex-direction:column;padding:0;width:100%}.row.row-no-padding{padding:0}.row.row-no-padding>.column{padding:0}.row.row-wrap{flex-wrap:wrap}.row.row-top{align-items:flex-start}.row.row-bottom{align-items:flex-end}.row.row-center{align-items:center}.row.row-stretch{align-items:stretch}.row.row-baseline{align-items:baseline}.row .column{display:block;flex:1 1 auto;margin-left:0;max-width:100%;width:100%}.row .column.column-offset-10{margin-left:10%}.row .column.column-offset-20{margin-left:20%}.row .column.column-offset-25{margin-left:25%}.row .column.column-offset-33,.row .column.column-offset-34{margin-left:33.3333%}.row .column.column-offset-40{margin-left:40%}.row .column.column-offset-50{margin-left:50%}.row .column.column-offset-60{margin-left:60%}.row .column.column-offset-66,.row .column.column-offset-67{margin-left:66.6666%}.row .column.column-offset-75{margin-left:75%}.row .column.column-offset-80{margin-left:80%}.row .column.column-offset-90{margin-left:90%}.row .column.column-10{flex:0 0 10%;max-width:10%}.row .column.column-20{flex:0 0 20%;max-width:20%}.row .column.column-25{flex:0 0 25%;max-width:25%}.row .column.column-33,.row .column.column-34{flex:0 0 33.3333%;max-width:33.3333%}.row .column.column-40{flex:0 0 40%;max-width:40%}.row .column.column-50{flex:0 0 50%;max-width:50%}.row .column.column-60{flex:0 0 60%;max-width:60%}.row .column.column-66,.row .column.column-67{flex:0 0 66.6666%;max-width:66.6666%}.row .column.column-75{flex:0 0 75%;max-width:75%}.row .column.column-80{flex:0 0 80%;max-width:80%}.row .column.column-90{flex:0 0 90%;max-width:90%}.row .column .column-top{align-self:flex-start}.row .column .column-bottom{align-self:flex-end}.row .column .column-center{align-self:center}@media (min-width: 40rem){.row{flex-direction:row;margin-left:-1.0rem;width:calc(100% + 2.0rem)}.row .column{margin-bottom:inherit;padding:0 1.0rem}}a{color:#9b4dca;text-decoration:none}a:focus,a:hover{color:#606c76}dl,ol,ul{list-style:none;margin-top:0;padding-left:0}dl dl,dl ol,dl ul,ol dl,ol ol,ol ul,ul dl,ul ol,ul ul{font-size:90%;margin:1.5rem 0 1.5rem 3.0rem}ol{list-style:decimal inside}ul{list-style:circle inside}.button,button,dd,dt,li{margin-bottom:1.0rem}fieldset,input,select,textarea{margin-bottom:1.5rem}blockquote,dl,figure,form,ol,p,pre,table,ul{margin-bottom:2.5rem}table{border-spacing:0;overflow-x:auto;text-align:left;width:100%}td,th{border-bottom:0.1rem solid #e1e1e1;padding:1.2rem 1.5rem}td:first-child,th:first-child{padding-left:0}td:last-child,th:last-child{padding-right:0}@media (min-width: 40rem){table{display:table;overflow-x:initial}}b,strong{font-weight:bold}p{margin-top:0}h1,h2,h3,h4,h5,h6{font-weight:300;letter-spacing:-.1rem;margin-bottom:2.0rem;margin-top:0}h1{font-size:4.6rem;line-height:1.2}h2{font-size:3.6rem;line-height:1.25}h3{font-size:2.8rem;line-height:1.3}h4{font-size:2.2rem;letter-spacing:-.08rem;line-height:1.35}h5{font-size:1.8rem;letter-spacing:-.05rem;line-height:1.5}h6{font-size:1.6rem;letter-spacing:0;line-height:1.4}img{max-width:100%}.clearfix:after{clear:both;content:' ';display:table}.float-left{float:left}.float-right{float:right} diff --git a/tests/Frameworks/CakePHP/Version_5_0/webroot/css/normalize.min.css b/tests/Frameworks/CakePHP/Version_5_0/webroot/css/normalize.min.css new file mode 100644 index 0000000000..bde07fcb52 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/webroot/css/normalize.min.css @@ -0,0 +1,8 @@ +/** + * Minified by jsDelivr using clean-css v4.2.1. + * Original file: /npm/normalize.css@8.0.1/normalize.css + * + * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files + */ +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ +html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none} diff --git a/tests/Frameworks/CakePHP/Version_5_0/webroot/favicon.ico b/tests/Frameworks/CakePHP/Version_5_0/webroot/favicon.ico new file mode 100644 index 0000000000..49a060fc46 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_5_0/webroot/favicon.ico differ diff --git a/tests/Frameworks/CakePHP/Version_5_0/webroot/font/Raleway-License.txt b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/Raleway-License.txt new file mode 100644 index 0000000000..94dce24495 --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/Raleway-License.txt @@ -0,0 +1,51 @@ +License for 'Raleway' +SIL Open Font License +Copyright (c) 2010, Matt McInerney (matt@pixelspread.com), +Copyright (c) 2011, Pablo Impallari (www.impallari.com|impallari@gmail.com), +Copyright (c) 2011, Rodrigo Fuenzalida (www.rfuenzalida.com|hello@rfuenzalida.com), with Reserved Font Name Raleway + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + +—————————————————————————————- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +—————————————————————————————- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others. + +The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives. + +DEFINITIONS +“Font Software” refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation. + +“Reserved Font Name” refers to any names specified as such after the copyright statement(s). + +“Original Version” refers to the collection of Font Software components as distributed by the Copyright Holder(s). + +“Modified Version” refers to any derivative made by adding to, deleting, or substituting—in part or in whole—any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment. + +“Author” refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission. + +5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/tests/Frameworks/CakePHP/Version_5_0/webroot/font/cakedingbats-webfont.eot b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/cakedingbats-webfont.eot new file mode 100644 index 0000000000..e8605d9268 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/cakedingbats-webfont.eot differ diff --git a/tests/Frameworks/CakePHP/Version_5_0/webroot/font/cakedingbats-webfont.svg b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/cakedingbats-webfont.svg new file mode 100644 index 0000000000..d1e0c98f7a --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/cakedingbats-webfont.svg @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/Frameworks/CakePHP/Version_5_0/webroot/font/cakedingbats-webfont.ttf b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/cakedingbats-webfont.ttf new file mode 100644 index 0000000000..13d54454e7 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/cakedingbats-webfont.ttf differ diff --git a/tests/Frameworks/CakePHP/Version_5_0/webroot/font/cakedingbats-webfont.woff b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/cakedingbats-webfont.woff new file mode 100644 index 0000000000..073baab113 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/cakedingbats-webfont.woff differ diff --git a/tests/Frameworks/CakePHP/Version_5_0/webroot/font/cakedingbats-webfont.woff2 b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/cakedingbats-webfont.woff2 new file mode 100644 index 0000000000..6e71eaf53e Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/cakedingbats-webfont.woff2 differ diff --git a/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-400-cyrillic-ext.woff2 b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-400-cyrillic-ext.woff2 new file mode 100644 index 0000000000..039269ecd6 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-400-cyrillic-ext.woff2 differ diff --git a/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-400-cyrillic.woff2 b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-400-cyrillic.woff2 new file mode 100644 index 0000000000..48b9d896c2 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-400-cyrillic.woff2 differ diff --git a/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-400-latin-ext.woff2 b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-400-latin-ext.woff2 new file mode 100644 index 0000000000..0eedc5bb67 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-400-latin-ext.woff2 differ diff --git a/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-400-latin.woff2 b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-400-latin.woff2 new file mode 100644 index 0000000000..d0e6f01908 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-400-latin.woff2 differ diff --git a/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-400-vietnamese.woff2 b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-400-vietnamese.woff2 new file mode 100644 index 0000000000..405fb25048 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-400-vietnamese.woff2 differ diff --git a/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-700-cyrillic-ext.woff2 b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-700-cyrillic-ext.woff2 new file mode 100644 index 0000000000..039269ecd6 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-700-cyrillic-ext.woff2 differ diff --git a/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-700-cyrillic.woff2 b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-700-cyrillic.woff2 new file mode 100644 index 0000000000..48b9d896c2 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-700-cyrillic.woff2 differ diff --git a/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-700-latin-ext.woff2 b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-700-latin-ext.woff2 new file mode 100644 index 0000000000..0eedc5bb67 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-700-latin-ext.woff2 differ diff --git a/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-700-latin.woff2 b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-700-latin.woff2 new file mode 100644 index 0000000000..d0e6f01908 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-700-latin.woff2 differ diff --git a/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-700-vietnamese.woff2 b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-700-vietnamese.woff2 new file mode 100644 index 0000000000..405fb25048 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_5_0/webroot/font/raleway-700-vietnamese.woff2 differ diff --git a/tests/Frameworks/CakePHP/Version_5_0/webroot/img/cake-logo.png b/tests/Frameworks/CakePHP/Version_5_0/webroot/img/cake-logo.png new file mode 100644 index 0000000000..41939ef5a5 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_5_0/webroot/img/cake-logo.png differ diff --git a/tests/Frameworks/CakePHP/Version_5_0/webroot/img/cake.icon.png b/tests/Frameworks/CakePHP/Version_5_0/webroot/img/cake.icon.png new file mode 100644 index 0000000000..394fa42d51 Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_5_0/webroot/img/cake.icon.png differ diff --git a/tests/Frameworks/CakePHP/Version_5_0/webroot/img/cake.logo.svg b/tests/Frameworks/CakePHP/Version_5_0/webroot/img/cake.logo.svg new file mode 100644 index 0000000000..e73abb54bc --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/webroot/img/cake.logo.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/Frameworks/CakePHP/Version_5_0/webroot/img/cake.power.gif b/tests/Frameworks/CakePHP/Version_5_0/webroot/img/cake.power.gif new file mode 100644 index 0000000000..8f8d570a2e Binary files /dev/null and b/tests/Frameworks/CakePHP/Version_5_0/webroot/img/cake.power.gif differ diff --git a/tests/Frameworks/CakePHP/Version_5_0/webroot/index.php b/tests/Frameworks/CakePHP/Version_5_0/webroot/index.php new file mode 100644 index 0000000000..544b47972b --- /dev/null +++ b/tests/Frameworks/CakePHP/Version_5_0/webroot/index.php @@ -0,0 +1,37 @@ +emit($server->run()); diff --git a/tests/Frameworks/CakePHP/Version_5_0/webroot/js/.gitkeep b/tests/Frameworks/CakePHP/Version_5_0/webroot/js/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Integrations/CLI/CakePHP/V3_10/CommonScenariosTest.php b/tests/Integrations/CLI/CakePHP/V3_10/CommonScenariosTest.php new file mode 100644 index 0000000000..ce09096bd6 --- /dev/null +++ b/tests/Integrations/CLI/CakePHP/V3_10/CommonScenariosTest.php @@ -0,0 +1,55 @@ + 'cake_console_test_app', + 'DD_TRACE_GENERATE_ROOT_SPAN' => 'true', + ]); + } + + public function testCommandWithNoArguments() + { + $traces = $this->getTracesFromCommand(); + + $this->assertSpans($traces, [ + SpanAssertion::build( + 'cakephp.console', + 'cake_console_test_app', + 'cli', + 'cake_console' + )->withExactTags([ + Tag::COMPONENT => 'cakephp', + ]) + ]); + } + + public function testCommandWithArgument() + { + $traces = $this->getTracesFromCommand('routes'); + + $this->assertSpans($traces, [ + SpanAssertion::build( + 'cakephp.console', + 'cake_console_test_app', + 'cli', + 'cake_console routes' + )->withExactTags([ + Tag::COMPONENT => 'cakephp', + ]) + ]); + } +} diff --git a/tests/Integrations/CLI/CakePHP/V4_5/CommonScenariosTest.php b/tests/Integrations/CLI/CakePHP/V4_5/CommonScenariosTest.php new file mode 100644 index 0000000000..6deb31d8cf --- /dev/null +++ b/tests/Integrations/CLI/CakePHP/V4_5/CommonScenariosTest.php @@ -0,0 +1,15 @@ + 'cakephp_test_app', + 'DD_TRACE_DEBUG' => 'true', + ]); + } + + /** + * @dataProvider provideSpecs + * @param RequestSpec $spec + * @param array $spanExpectations + * @throws \Exception + */ + public function testScenario(RequestSpec $spec, array $spanExpectations) + { + $traces = $this->tracesFromWebRequest(function () use ($spec) { + $this->call($spec); + }); + + $this->assertFlameGraph($traces, $spanExpectations); + } + + public function provideSpecs() + { + return $this->buildDataProvider( + [ + 'A simple GET request returning a string' => [ + SpanAssertion::build( + 'cakephp.request', + 'cakephp_test_app', + 'web', + 'GET SimpleController@index' + )->withExactTags([ + 'cakephp.route.controller' => 'Simple', + 'cakephp.route.action' => 'index', + 'http.method' => 'GET', + 'http.url' => 'http://localhost:9999/simple?key=value&', + 'http.status_code' => '200', + 'http.route' => '/{controller}', + Tag::SPAN_KIND => 'server', + Tag::COMPONENT => 'cakephp', + ])->withChildren([ + SpanAssertion::build( + 'Controller.invokeAction', + 'cakephp_test_app', + 'web', + 'Controller.invokeAction' + )->withExactTags([ + Tag::COMPONENT => 'cakephp', + ]) + ]), + ], + 'A simple GET request with a view' => [ + SpanAssertion::build( + 'cakephp.request', + 'cakephp_test_app', + 'web', + 'GET Simple_viewController@index' + )->withExactTags([ + 'cakephp.route.controller' => 'Simple_view', + 'cakephp.route.action' => 'index', + 'http.method' => 'GET', + 'http.url' => 'http://localhost:9999/simple_view?key=value&', + 'http.status_code' => '200', + 'http.route' => '/{controller}', + Tag::SPAN_KIND => 'server', + Tag::COMPONENT => 'cakephp', + ])->withChildren([ + SpanAssertion::build( + 'Controller.invokeAction', + 'cakephp_test_app', + 'web', + 'Controller.invokeAction' + )->withExactTags([ + Tag::COMPONENT => 'cakephp', + ]), + SpanAssertion::build( + 'cakephp.view', + 'cakephp_test_app', + 'web', + 'Simple_view/index.ctp' + )->withExactTags([ + 'cakephp.view' => 'Simple_view/index.ctp', + Tag::COMPONENT => 'cakephp', + ]), + ]), + ], + 'A GET request with an exception' => [ + SpanAssertion::build( + 'cakephp.request', + 'cakephp_test_app', + 'web', + 'GET ErrorController@index' + )->withExactTags([ + 'cakephp.route.controller' => 'Error', + 'cakephp.route.action' => 'index', + 'http.method' => 'GET', + 'http.url' => 'http://localhost:9999/error?key=value&', + 'http.status_code' => '500', + 'http.route' => '/{controller}', + Tag::SPAN_KIND => 'server', + Tag::COMPONENT => 'cakephp', + ])->withExistingTagsNames([ + 'error.stack' + ])->setError( + 'Exception', + 'Foo error' + )->withChildren([ + SpanAssertion::build( + 'Controller.invokeAction', + 'cakephp_test_app', + 'web', + 'Controller.invokeAction' + )->withExactTags([ + Tag::COMPONENT => 'cakephp', + ])->withExistingTagsNames([ + 'error.stack', + ])->setError('Exception', 'Foo error'), + SpanAssertion::build( + 'cakephp.view', + 'cakephp_test_app', + 'web', + 'Error/index.ctp' + )->withExactTags([ + 'cakephp.view' => 'Error/index.ctp', + Tag::COMPONENT => 'cakephp', + ]), + ]), + ], + 'A GET request to a route with a parameter' => [ + SpanAssertion::build( + 'cakephp.request', + 'cakephp_test_app', + 'web', + 'GET ParameterizedController@customAction' + )->withExactTags([ + 'cakephp.route.controller' => 'Parameterized', + 'cakephp.route.action' => 'customAction', + 'http.method' => 'GET', + 'http.url' => 'http://localhost:9999/parameterized/paramValue', + 'http.status_code' => '200', + 'http.route' => '/parameterized/:param', + Tag::SPAN_KIND => 'server', + Tag::COMPONENT => 'cakephp', + ])->withChildren([ + SpanAssertion::build( + 'Controller.invokeAction', + 'cakephp_test_app', + 'web', + 'Controller.invokeAction' + )->withExactTags([ + Tag::COMPONENT => 'cakephp', + ]) + ]), + ] + ] + ); + } +} diff --git a/tests/Integrations/CakePHP/V4_5/CommonScenariosTest.php b/tests/Integrations/CakePHP/V4_5/CommonScenariosTest.php new file mode 100644 index 0000000000..84fa30ac6d --- /dev/null +++ b/tests/Integrations/CakePHP/V4_5/CommonScenariosTest.php @@ -0,0 +1,177 @@ + 'cakephp_test_app', + 'DD_TRACE_DEBUG' => 'true', + ]); + } + + /** + * @dataProvider provideSpecs + * @param RequestSpec $spec + * @param array $spanExpectations + * @throws \Exception + */ + public function testScenario(RequestSpec $spec, array $spanExpectations) + { + $traces = $this->tracesFromWebRequest(function () use ($spec) { + $this->call($spec); + }); + + $this->assertFlameGraph($traces, $spanExpectations); + } + + public function provideSpecs() + { + return $this->buildDataProvider( + [ + 'A simple GET request returning a string' => [ + SpanAssertion::build( + 'cakephp.request', + 'cakephp_test_app', + 'web', + 'GET SimpleController@index' + )->withExactTags([ + 'cakephp.route.controller' => 'Simple', + 'cakephp.route.action' => 'index', + 'http.method' => 'GET', + 'http.url' => 'http://localhost:9999/simple?key=value&', + 'http.status_code' => '200', + 'http.route' => '/{controller}', + Tag::SPAN_KIND => 'server', + Tag::COMPONENT => 'cakephp', + ])->withChildren([ + SpanAssertion::build( + 'Controller.invokeAction', + 'cakephp_test_app', + 'web', + 'Controller.invokeAction' + )->withExactTags([ + Tag::COMPONENT => 'cakephp', + ]) + ]), + ], + 'A simple GET request with a view' => [ + SpanAssertion::build( + 'cakephp.request', + 'cakephp_test_app', + 'web', + 'GET Simple_viewController@index' + )->withExactTags([ + 'cakephp.route.controller' => 'Simple_view', + 'cakephp.route.action' => 'index', + 'http.method' => 'GET', + 'http.url' => 'http://localhost:9999/simple_view?key=value&', + 'http.status_code' => '200', + 'http.route' => '/{controller}', + Tag::SPAN_KIND => 'server', + Tag::COMPONENT => 'cakephp', + ])->withChildren([ + SpanAssertion::build( + 'Controller.invokeAction', + 'cakephp_test_app', + 'web', + 'Controller.invokeAction' + )->withExactTags([ + Tag::COMPONENT => 'cakephp', + ])->withChildren([ + SpanAssertion::build( + 'cakephp.view', + 'cakephp_test_app', + 'web', + 'Simple_view/index.php' + )->withExactTags([ + 'cakephp.view' => 'Simple_view/index.php', + Tag::COMPONENT => 'cakephp', + ]), + ]), + ]), + ], + 'A GET request with an exception' => [ + SpanAssertion::build( + 'cakephp.request', + 'cakephp_test_app', + 'web', + 'GET ErrorController@index' + )->withExactTags([ + 'cakephp.route.controller' => 'Error', + 'cakephp.route.action' => 'index', + 'http.method' => 'GET', + 'http.url' => 'http://localhost:9999/error?key=value&', + 'http.status_code' => '500', + 'http.route' => '/{controller}', + Tag::SPAN_KIND => 'server', + Tag::COMPONENT => 'cakephp', + ])->withExistingTagsNames([ + 'error.stack' + ])->setError( + 'Exception', + 'Foo error' + )->withChildren([ + SpanAssertion::build( + 'Controller.invokeAction', + 'cakephp_test_app', + 'web', + 'Controller.invokeAction' + )->withExactTags([ + Tag::COMPONENT => 'cakephp', + ])->withExistingTagsNames([ + 'error.stack', + ])->setError('Exception', 'Foo error'), + SpanAssertion::build( + 'cakephp.view', + 'cakephp_test_app', + 'web', + 'Error/error500.php' + )->withExactTags([ + 'cakephp.view' => 'Error/error500.php', + Tag::COMPONENT => 'cakephp', + ]), + ]), + ], + 'A GET request to a route with a parameter' => [ + SpanAssertion::build( + 'cakephp.request', + 'cakephp_test_app', + 'web', + 'GET ParameterizedController@customAction' + )->withExactTags([ + 'cakephp.route.controller' => 'Parameterized', + 'cakephp.route.action' => 'customAction', + 'http.method' => 'GET', + 'http.url' => 'http://localhost:9999/parameterized/paramValue', + 'http.status_code' => '200', + 'http.route' => '/parameterized/{param}', + Tag::SPAN_KIND => 'server', + Tag::COMPONENT => 'cakephp', + ])->withChildren([ + SpanAssertion::build( + 'Controller.invokeAction', + 'cakephp_test_app', + 'web', + 'Controller.invokeAction' + )->withExactTags([ + Tag::COMPONENT => 'cakephp', + ]) + ]), + ] + ] + ); + } +} diff --git a/tests/Integrations/CakePHP/V5_0/CommonScenariosTest.php b/tests/Integrations/CakePHP/V5_0/CommonScenariosTest.php new file mode 100644 index 0000000000..7ce5d4400c --- /dev/null +++ b/tests/Integrations/CakePHP/V5_0/CommonScenariosTest.php @@ -0,0 +1,16 @@ +./Integrations/CakePHP/V2_8 ./Integrations/CLI/CakePHP/V2_8 + + ./Integrations/CakePHP/V3_10 + ./Integrations/CLI/CakePHP/V3_10 + + + ./Integrations/CakePHP/V4_5 + ./Integrations/CLI/CakePHP/V4_5 + + + ./Integrations/CakePHP/V5_0 + ./Integrations/CLI/CakePHP/V5_0 + ./Integrations/CodeIgniter/V2_2